From 85f0bc4ed13c736436ade4cc51708af9d4593c01 Mon Sep 17 00:00:00 2001 From: krahets Date: Wed, 1 May 2024 06:47:42 +0800 Subject: [PATCH] deploy --- .../permutations_problem/index.html | 2 +- chapter_sorting/bucket_sort/index.html | 30 +- chapter_sorting/heap_sort/index.html | 35 +- chapter_sorting/merge_sort/index.html | 50 +- en/404.html | 1461 +++- .../contribution.assets/edit_markdown.png | Bin 0 -> 87838 bytes en/chapter_appendix/contribution/index.html | 3899 ++++++++++ en/chapter_appendix/index.html | 3787 ++++++++++ .../vscode_extension_installation.png | Bin 0 -> 126853 bytes .../vscode_installation.png | Bin 0 -> 105600 bytes en/chapter_appendix/installation/index.html | 4104 +++++++++++ en/chapter_appendix/terminology/index.html | 4423 ++++++++++++ .../array/index.html | 1461 +++- en/chapter_array_and_linkedlist/index.html | 1463 +++- .../linked_list/index.html | 1461 +++- .../list/index.html | 1469 +++- .../ram_and_cache/index.html | 1467 +++- .../summary/index.html | 1469 +++- .../backtrack_remove_return_or_not.png | Bin 0 -> 34916 bytes .../preorder_find_constrained_paths.png | Bin 0 -> 27929 bytes .../preorder_find_nodes.png | Bin 0 -> 26658 bytes .../preorder_find_paths_step1.png | Bin 0 -> 16693 bytes .../preorder_find_paths_step10.png | Bin 0 -> 29614 bytes .../preorder_find_paths_step11.png | Bin 0 -> 27628 bytes .../preorder_find_paths_step2.png | Bin 0 -> 21516 bytes .../preorder_find_paths_step3.png | Bin 0 -> 20204 bytes .../preorder_find_paths_step4.png | Bin 0 -> 20175 bytes .../preorder_find_paths_step5.png | Bin 0 -> 21675 bytes .../preorder_find_paths_step6.png | Bin 0 -> 22421 bytes .../preorder_find_paths_step7.png | Bin 0 -> 23149 bytes .../preorder_find_paths_step8.png | Bin 0 -> 24876 bytes .../preorder_find_paths_step9.png | Bin 0 -> 24646 bytes .../backtracking_algorithm/index.html | 5750 +++++++++++++++ en/chapter_backtracking/index.html | 3794 ++++++++++ .../n_queens_cols_diagonals.png | Bin 0 -> 33727 bytes .../n_queens_constraints.png | Bin 0 -> 25825 bytes .../n_queens_placing.png | Bin 0 -> 23941 bytes .../solution_4_queens.png | Bin 0 -> 7583 bytes .../n_queens_problem/index.html | 4548 ++++++++++++ .../permutations_i.png | Bin 0 -> 16921 bytes .../permutations_i_pruning.png | Bin 0 -> 29181 bytes .../permutations_ii.png | Bin 0 -> 20303 bytes .../permutations_ii_pruning.png | Bin 0 -> 25580 bytes .../permutations_ii_pruning_summary.png | Bin 0 -> 22836 bytes .../permutations_problem/index.html | 4959 +++++++++++++ .../subset_sum_i.png | Bin 0 -> 37962 bytes .../subset_sum_i_naive.png | Bin 0 -> 31916 bytes .../subset_sum_i_pruning.png | Bin 0 -> 31253 bytes .../subset_sum_ii.png | Bin 0 -> 36016 bytes .../subset_sum_ii_repeat.png | Bin 0 -> 18114 bytes .../subset_sum_problem/index.html | 5482 +++++++++++++++ en/chapter_backtracking/summary/index.html | 3867 ++++++++++ .../index.html | 1461 +++- .../iteration_and_recursion/index.html | 1461 +++- .../performance_evaluation/index.html | 1461 +++- .../space_complexity/index.html | 1461 +++- .../summary/index.html | 1461 +++- .../time_complexity/index.html | 1461 +++- .../basic_data_types/index.html | 1461 +++- .../character_encoding/index.html | 1461 +++- .../index.html | 1461 +++- en/chapter_data_structure/index.html | 1461 +++- .../number_encoding/index.html | 1461 +++- en/chapter_data_structure/summary/index.html | 1461 +++- .../binary_search_recur.png | Bin 0 -> 16844 bytes .../binary_search_recur/index.html | 4234 +++++++++++ .../build_tree_division_pointers.png | Bin 0 -> 15362 bytes .../build_tree_example.png | Bin 0 -> 13759 bytes .../build_tree_preorder_inorder_division.png | Bin 0 -> 25136 bytes .../built_tree_overall.png | Bin 0 -> 25815 bytes .../built_tree_step1.png | Bin 0 -> 10404 bytes .../built_tree_step2.png | Bin 0 -> 10758 bytes .../built_tree_step3.png | Bin 0 -> 12042 bytes .../built_tree_step4.png | Bin 0 -> 12462 bytes .../built_tree_step5.png | Bin 0 -> 12587 bytes .../built_tree_step6.png | Bin 0 -> 13876 bytes .../built_tree_step7.png | Bin 0 -> 13985 bytes .../built_tree_step8.png | Bin 0 -> 15233 bytes .../built_tree_step9.png | Bin 0 -> 15889 bytes .../build_binary_tree_problem/index.html | 4405 ++++++++++++ .../divide_and_conquer_bubble_sort.png | Bin 0 -> 24306 bytes .../divide_and_conquer_merge_sort.png | Bin 0 -> 25855 bytes .../divide_and_conquer_parallel_computing.png | Bin 0 -> 15428 bytes .../divide_and_conquer/index.html | 3988 +++++++++++ .../hanota_divide_and_conquer.png | Bin 0 -> 32200 bytes .../hanota_problem.assets/hanota_example.png | Bin 0 -> 12261 bytes .../hanota_problem.assets/hanota_f1_step1.png | Bin 0 -> 5732 bytes .../hanota_problem.assets/hanota_f1_step2.png | Bin 0 -> 9103 bytes .../hanota_problem.assets/hanota_f2_step1.png | Bin 0 -> 6150 bytes .../hanota_problem.assets/hanota_f2_step2.png | Bin 0 -> 9400 bytes .../hanota_problem.assets/hanota_f2_step3.png | Bin 0 -> 11972 bytes .../hanota_problem.assets/hanota_f2_step4.png | Bin 0 -> 14501 bytes .../hanota_problem.assets/hanota_f3_step1.png | Bin 0 -> 9571 bytes .../hanota_problem.assets/hanota_f3_step2.png | Bin 0 -> 10201 bytes .../hanota_problem.assets/hanota_f3_step3.png | Bin 0 -> 13132 bytes .../hanota_problem.assets/hanota_f3_step4.png | Bin 0 -> 15960 bytes .../hanota_recursive_tree.png | Bin 0 -> 18093 bytes .../hanota_problem/index.html | 4378 ++++++++++++ en/chapter_divide_and_conquer/index.html | 3794 ++++++++++ .../summary/index.html | 3784 ++++++++++ .../climbing_stairs_constraint_example.png | Bin 0 -> 21575 bytes ...mbing_stairs_constraint_state_transfer.png | Bin 0 -> 19318 bytes .../min_cost_cs_dp.png | Bin 0 -> 20674 bytes .../min_cost_cs_example.png | Bin 0 -> 19703 bytes .../dp_problem_features/index.html | 4719 +++++++++++++ .../min_path_sum_dfs.png | Bin 0 -> 30886 bytes .../min_path_sum_dfs_mem.png | Bin 0 -> 21409 bytes .../min_path_sum_dp_step1.png | Bin 0 -> 11645 bytes .../min_path_sum_dp_step10.png | Bin 0 -> 16335 bytes .../min_path_sum_dp_step11.png | Bin 0 -> 16233 bytes .../min_path_sum_dp_step12.png | Bin 0 -> 12722 bytes .../min_path_sum_dp_step2.png | Bin 0 -> 19384 bytes .../min_path_sum_dp_step3.png | Bin 0 -> 16575 bytes .../min_path_sum_dp_step4.png | Bin 0 -> 16487 bytes .../min_path_sum_dp_step5.png | Bin 0 -> 16419 bytes .../min_path_sum_dp_step6.png | Bin 0 -> 16429 bytes .../min_path_sum_dp_step7.png | Bin 0 -> 16538 bytes .../min_path_sum_dp_step8.png | Bin 0 -> 16315 bytes .../min_path_sum_dp_step9.png | Bin 0 -> 16464 bytes .../min_path_sum_example.png | Bin 0 -> 14388 bytes .../min_path_sum_solution_initial_state.png | Bin 0 -> 21522 bytes ...min_path_sum_solution_state_definition.png | Bin 0 -> 22014 bytes ...min_path_sum_solution_state_transition.png | Bin 0 -> 18925 bytes .../dp_solution_pipeline/index.html | 5345 ++++++++++++++ .../edit_distance_decision_tree.png | Bin 0 -> 20980 bytes .../edit_distance_dp_step1.png | Bin 0 -> 13587 bytes .../edit_distance_dp_step10.png | Bin 0 -> 14770 bytes .../edit_distance_dp_step11.png | Bin 0 -> 14786 bytes .../edit_distance_dp_step12.png | Bin 0 -> 14705 bytes .../edit_distance_dp_step13.png | Bin 0 -> 14821 bytes .../edit_distance_dp_step14.png | Bin 0 -> 14765 bytes .../edit_distance_dp_step15.png | Bin 0 -> 10954 bytes .../edit_distance_dp_step2.png | Bin 0 -> 11831 bytes .../edit_distance_dp_step3.png | Bin 0 -> 14658 bytes .../edit_distance_dp_step4.png | Bin 0 -> 14617 bytes .../edit_distance_dp_step5.png | Bin 0 -> 14568 bytes .../edit_distance_dp_step6.png | Bin 0 -> 14624 bytes .../edit_distance_dp_step7.png | Bin 0 -> 14634 bytes .../edit_distance_dp_step8.png | Bin 0 -> 13233 bytes .../edit_distance_dp_step9.png | Bin 0 -> 14602 bytes .../edit_distance_example.png | Bin 0 -> 13040 bytes .../edit_distance_state_transfer.png | Bin 0 -> 23300 bytes .../edit_distance_problem/index.html | 4780 +++++++++++++ en/chapter_dynamic_programming/index.html | 3796 ++++++++++ .../climbing_stairs_dfs_memo_tree.png | Bin 0 -> 25900 bytes .../climbing_stairs_dfs_tree.png | Bin 0 -> 23066 bytes .../climbing_stairs_dp.png | Bin 0 -> 16566 bytes .../climbing_stairs_example.png | Bin 0 -> 16571 bytes .../climbing_stairs_state_transfer.png | Bin 0 -> 17293 bytes .../intro_to_dynamic_programming/index.html | 5365 ++++++++++++++ .../knapsack_problem.assets/knapsack_dfs.png | Bin 0 -> 34107 bytes .../knapsack_dfs_mem.png | Bin 0 -> 34471 bytes .../knapsack_dp_comp_step1.png | Bin 0 -> 18865 bytes .../knapsack_dp_comp_step2.png | Bin 0 -> 19879 bytes .../knapsack_dp_comp_step3.png | Bin 0 -> 20120 bytes .../knapsack_dp_comp_step4.png | Bin 0 -> 20124 bytes .../knapsack_dp_comp_step5.png | Bin 0 -> 19436 bytes .../knapsack_dp_comp_step6.png | Bin 0 -> 19906 bytes .../knapsack_dp_step1.png | Bin 0 -> 18202 bytes .../knapsack_dp_step10.png | Bin 0 -> 18157 bytes .../knapsack_dp_step11.png | Bin 0 -> 18243 bytes .../knapsack_dp_step12.png | Bin 0 -> 19220 bytes .../knapsack_dp_step13.png | Bin 0 -> 19186 bytes .../knapsack_dp_step14.png | Bin 0 -> 16967 bytes .../knapsack_dp_step2.png | Bin 0 -> 18482 bytes .../knapsack_dp_step3.png | Bin 0 -> 18803 bytes .../knapsack_dp_step4.png | Bin 0 -> 18661 bytes .../knapsack_dp_step5.png | Bin 0 -> 18560 bytes .../knapsack_dp_step6.png | Bin 0 -> 18044 bytes .../knapsack_dp_step7.png | Bin 0 -> 18629 bytes .../knapsack_dp_step8.png | Bin 0 -> 18842 bytes .../knapsack_dp_step9.png | Bin 0 -> 18973 bytes .../knapsack_example.png | Bin 0 -> 19632 bytes .../knapsack_problem/index.html | 5234 ++++++++++++++ .../summary/index.html | 3796 ++++++++++ .../coin_change_dp_step1.png | Bin 0 -> 17527 bytes .../coin_change_dp_step10.png | Bin 0 -> 18419 bytes .../coin_change_dp_step11.png | Bin 0 -> 17871 bytes .../coin_change_dp_step12.png | Bin 0 -> 18048 bytes .../coin_change_dp_step13.png | Bin 0 -> 18208 bytes .../coin_change_dp_step14.png | Bin 0 -> 18214 bytes .../coin_change_dp_step15.png | Bin 0 -> 16542 bytes .../coin_change_dp_step2.png | Bin 0 -> 18526 bytes .../coin_change_dp_step3.png | Bin 0 -> 18353 bytes .../coin_change_dp_step4.png | Bin 0 -> 18623 bytes .../coin_change_dp_step5.png | Bin 0 -> 18659 bytes .../coin_change_dp_step6.png | Bin 0 -> 18579 bytes .../coin_change_dp_step7.png | Bin 0 -> 17876 bytes .../coin_change_dp_step8.png | Bin 0 -> 18306 bytes .../coin_change_dp_step9.png | Bin 0 -> 18334 bytes .../coin_change_example.png | Bin 0 -> 14932 bytes .../coin_change_ii_example.png | Bin 0 -> 17306 bytes .../unbounded_knapsack_dp_comp_step1.png | Bin 0 -> 19655 bytes .../unbounded_knapsack_dp_comp_step2.png | Bin 0 -> 19664 bytes .../unbounded_knapsack_dp_comp_step3.png | Bin 0 -> 20182 bytes .../unbounded_knapsack_dp_comp_step4.png | Bin 0 -> 20449 bytes .../unbounded_knapsack_dp_comp_step5.png | Bin 0 -> 20098 bytes .../unbounded_knapsack_dp_comp_step6.png | Bin 0 -> 20810 bytes .../unbounded_knapsack_example.png | Bin 0 -> 20687 bytes .../unbounded_knapsack_problem/index.html | 6259 +++++++++++++++++ en/chapter_graph/graph/index.html | 1461 +++- en/chapter_graph/graph_operations/index.html | 1461 +++- en/chapter_graph/graph_traversal/index.html | 1461 +++- en/chapter_graph/index.html | 1461 +++- en/chapter_graph/summary/index.html | 1500 +++- .../fractional_knapsack_area_chart.png | Bin 0 -> 12437 bytes .../fractional_knapsack_example.png | Bin 0 -> 23915 bytes .../fractional_knapsack_greedy_strategy.png | Bin 0 -> 20678 bytes .../fractional_knapsack_unit_value.png | Bin 0 -> 20898 bytes .../fractional_knapsack_problem/index.html | 4353 ++++++++++++ .../coin_change_greedy_strategy.png | Bin 0 -> 30492 bytes .../coin_change_greedy_vs_dp.png | Bin 0 -> 20841 bytes en/chapter_greedy/greedy_algorithm/index.html | 4231 +++++++++++ en/chapter_greedy/index.html | 3794 ++++++++++ .../max_capacity_example.png | Bin 0 -> 11436 bytes .../max_capacity_greedy_step1.png | Bin 0 -> 15563 bytes .../max_capacity_greedy_step2.png | Bin 0 -> 17319 bytes .../max_capacity_greedy_step3.png | Bin 0 -> 17598 bytes .../max_capacity_greedy_step4.png | Bin 0 -> 17967 bytes .../max_capacity_greedy_step5.png | Bin 0 -> 17910 bytes .../max_capacity_greedy_step6.png | Bin 0 -> 18430 bytes .../max_capacity_greedy_step7.png | Bin 0 -> 18099 bytes .../max_capacity_greedy_step8.png | Bin 0 -> 18496 bytes .../max_capacity_greedy_step9.png | Bin 0 -> 15366 bytes .../max_capacity_initial_state.png | Bin 0 -> 14995 bytes .../max_capacity_moving_long_board.png | Bin 0 -> 16031 bytes .../max_capacity_moving_short_board.png | Bin 0 -> 16028 bytes .../max_capacity_skipped_states.png | Bin 0 -> 22811 bytes .../max_capacity_problem/index.html | 4244 +++++++++++ .../max_product_cutting_definition.png | Bin 0 -> 10708 bytes ...max_product_cutting_greedy_calculation.png | Bin 0 -> 6485 bytes .../max_product_cutting_greedy_infer1.png | Bin 0 -> 9497 bytes .../max_product_cutting_greedy_infer2.png | Bin 0 -> 9373 bytes .../max_product_cutting_problem/index.html | 4218 +++++++++++ en/chapter_greedy/summary/index.html | 3785 ++++++++++ en/chapter_hashing/hash_algorithm/index.html | 1461 +++- en/chapter_hashing/hash_collision/index.html | 1461 +++- en/chapter_hashing/hash_map/index.html | 1461 +++- en/chapter_hashing/index.html | 1461 +++- en/chapter_hashing/summary/index.html | 1461 +++- en/chapter_heap/build_heap/index.html | 1461 +++- en/chapter_heap/heap/index.html | 1461 +++- en/chapter_heap/index.html | 1461 +++- en/chapter_heap/summary/index.html | 1461 +++- en/chapter_heap/top_k/index.html | 1461 +++- en/chapter_hello_algo/index.html | 1465 +++- .../algorithms_are_everywhere/index.html | 1461 +++- en/chapter_introduction/index.html | 1461 +++- en/chapter_introduction/summary/index.html | 1461 +++- .../what_is_dsa/index.html | 1461 +++- en/chapter_preface/about_the_book/index.html | 1461 +++- en/chapter_preface/index.html | 1461 +++- en/chapter_preface/suggestions/index.html | 1461 +++- en/chapter_preface/summary/index.html | 1461 +++- en/chapter_reference/index.html | 3679 ++++++++++ .../binary_search_example.png | Bin 0 -> 16862 bytes .../binary_search_ranges.png | Bin 0 -> 26366 bytes .../binary_search_step1.png | Bin 0 -> 15623 bytes .../binary_search_step2.png | Bin 0 -> 13595 bytes .../binary_search_step3.png | Bin 0 -> 16961 bytes .../binary_search_step4.png | Bin 0 -> 13035 bytes .../binary_search_step5.png | Bin 0 -> 16829 bytes .../binary_search_step6.png | Bin 0 -> 13027 bytes .../binary_search_step7.png | Bin 0 -> 14751 bytes en/chapter_searching/binary_search/index.html | 4546 ++++++++++++ .../binary_search_edge_by_element.png | Bin 0 -> 14311 bytes .../binary_search_right_edge_by_left_edge.png | Bin 0 -> 13399 bytes .../binary_search_edge/index.html | 4343 ++++++++++++ .../binary_search_insertion_example.png | Bin 0 -> 16290 bytes .../binary_search_insertion_naive.png | Bin 0 -> 12330 bytes .../binary_search_insertion_step1.png | Bin 0 -> 15249 bytes .../binary_search_insertion_step2.png | Bin 0 -> 13156 bytes .../binary_search_insertion_step3.png | Bin 0 -> 17056 bytes .../binary_search_insertion_step4.png | Bin 0 -> 12964 bytes .../binary_search_insertion_step5.png | Bin 0 -> 16653 bytes .../binary_search_insertion_step6.png | Bin 0 -> 13192 bytes .../binary_search_insertion_step7.png | Bin 0 -> 16273 bytes .../binary_search_insertion_step8.png | Bin 0 -> 12570 bytes .../binary_search_insertion/index.html | 4466 ++++++++++++ en/chapter_searching/index.html | 3795 ++++++++++ .../two_sum_brute_force.png | Bin 0 -> 13071 bytes .../two_sum_hashtable_step1.png | Bin 0 -> 14421 bytes .../two_sum_hashtable_step2.png | Bin 0 -> 14673 bytes .../two_sum_hashtable_step3.png | Bin 0 -> 14597 bytes .../replace_linear_by_hashing/index.html | 4375 ++++++++++++ .../searching_algorithms.png | Bin 0 -> 34523 bytes .../searching_algorithm_revisited/index.html | 3985 +++++++++++ en/chapter_searching/summary/index.html | 3781 ++++++++++ .../bubble_operation_step1.png | Bin 0 -> 11251 bytes .../bubble_operation_step2.png | Bin 0 -> 12772 bytes .../bubble_operation_step3.png | Bin 0 -> 12662 bytes .../bubble_operation_step4.png | Bin 0 -> 12581 bytes .../bubble_operation_step5.png | Bin 0 -> 11032 bytes .../bubble_operation_step6.png | Bin 0 -> 12775 bytes .../bubble_operation_step7.png | Bin 0 -> 11740 bytes .../bubble_sort_overview.png | Bin 0 -> 27110 bytes en/chapter_sorting/bubble_sort/index.html | 4435 ++++++++++++ .../bucket_sort_overview.png | Bin 0 -> 43157 bytes .../scatter_in_buckets_distribution.png | Bin 0 -> 17639 bytes .../scatter_in_buckets_recursively.png | Bin 0 -> 37145 bytes en/chapter_sorting/bucket_sort/index.html | 4299 +++++++++++ .../counting_sort_overview.png | Bin 0 -> 30527 bytes .../counting_sort_step1.png | Bin 0 -> 21734 bytes .../counting_sort_step2.png | Bin 0 -> 21000 bytes .../counting_sort_step3.png | Bin 0 -> 25992 bytes .../counting_sort_step4.png | Bin 0 -> 25860 bytes .../counting_sort_step5.png | Bin 0 -> 26026 bytes .../counting_sort_step6.png | Bin 0 -> 26126 bytes .../counting_sort_step7.png | Bin 0 -> 21272 bytes .../counting_sort_step8.png | Bin 0 -> 16518 bytes en/chapter_sorting/counting_sort/index.html | 4703 +++++++++++++ .../heap_sort.assets/heap_sort_step1.png | Bin 0 -> 23764 bytes .../heap_sort.assets/heap_sort_step10.png | Bin 0 -> 18100 bytes .../heap_sort.assets/heap_sort_step11.png | Bin 0 -> 19456 bytes .../heap_sort.assets/heap_sort_step12.png | Bin 0 -> 21022 bytes .../heap_sort.assets/heap_sort_step2.png | Bin 0 -> 20697 bytes .../heap_sort.assets/heap_sort_step3.png | Bin 0 -> 22261 bytes .../heap_sort.assets/heap_sort_step4.png | Bin 0 -> 20159 bytes .../heap_sort.assets/heap_sort_step5.png | Bin 0 -> 21991 bytes .../heap_sort.assets/heap_sort_step6.png | Bin 0 -> 19357 bytes .../heap_sort.assets/heap_sort_step7.png | Bin 0 -> 20906 bytes .../heap_sort.assets/heap_sort_step8.png | Bin 0 -> 18400 bytes .../heap_sort.assets/heap_sort_step9.png | Bin 0 -> 20489 bytes en/chapter_sorting/heap_sort/index.html | 4455 ++++++++++++ en/chapter_sorting/index.html | 3800 ++++++++++ .../insertion_operation.png | Bin 0 -> 27207 bytes .../insertion_sort_overview.png | Bin 0 -> 24752 bytes en/chapter_sorting/insertion_sort/index.html | 4140 +++++++++++ .../merge_sort.assets/merge_sort_overview.png | Bin 0 -> 25986 bytes .../merge_sort.assets/merge_sort_step1.png | Bin 0 -> 8581 bytes .../merge_sort.assets/merge_sort_step10.png | Bin 0 -> 14895 bytes .../merge_sort.assets/merge_sort_step2.png | Bin 0 -> 9346 bytes .../merge_sort.assets/merge_sort_step3.png | Bin 0 -> 9922 bytes .../merge_sort.assets/merge_sort_step4.png | Bin 0 -> 10210 bytes .../merge_sort.assets/merge_sort_step5.png | Bin 0 -> 11245 bytes .../merge_sort.assets/merge_sort_step6.png | Bin 0 -> 11992 bytes .../merge_sort.assets/merge_sort_step7.png | Bin 0 -> 12223 bytes .../merge_sort.assets/merge_sort_step8.png | Bin 0 -> 12346 bytes .../merge_sort.assets/merge_sort_step9.png | Bin 0 -> 13181 bytes en/chapter_sorting/merge_sort/index.html | 4588 ++++++++++++ .../pivot_division_step1.png | Bin 0 -> 31804 bytes .../pivot_division_step2.png | Bin 0 -> 31803 bytes .../pivot_division_step3.png | Bin 0 -> 31739 bytes .../pivot_division_step4.png | Bin 0 -> 32538 bytes .../pivot_division_step5.png | Bin 0 -> 31685 bytes .../pivot_division_step6.png | Bin 0 -> 31883 bytes .../pivot_division_step7.png | Bin 0 -> 31756 bytes .../pivot_division_step8.png | Bin 0 -> 32688 bytes .../pivot_division_step9.png | Bin 0 -> 14662 bytes .../quick_sort.assets/quick_sort_overview.png | Bin 0 -> 26189 bytes en/chapter_sorting/quick_sort/index.html | 5199 ++++++++++++++ .../radix_sort.assets/radix_sort_overview.png | Bin 0 -> 46860 bytes en/chapter_sorting/radix_sort/index.html | 4575 ++++++++++++ .../selection_sort_instability.png | Bin 0 -> 15511 bytes .../selection_sort_step1.png | Bin 0 -> 11421 bytes .../selection_sort_step10.png | Bin 0 -> 16798 bytes .../selection_sort_step11.png | Bin 0 -> 8307 bytes .../selection_sort_step2.png | Bin 0 -> 16574 bytes .../selection_sort_step3.png | Bin 0 -> 11707 bytes .../selection_sort_step4.png | Bin 0 -> 16781 bytes .../selection_sort_step5.png | Bin 0 -> 11726 bytes .../selection_sort_step6.png | Bin 0 -> 17086 bytes .../selection_sort_step7.png | Bin 0 -> 11636 bytes .../selection_sort_step8.png | Bin 0 -> 16896 bytes .../selection_sort_step9.png | Bin 0 -> 11610 bytes en/chapter_sorting/selection_sort/index.html | 4131 +++++++++++ .../sorting_examples.png | Bin 0 -> 16395 bytes .../sorting_algorithm/index.html | 3880 ++++++++++ .../sorting_algorithms_comparison.png | Bin 0 -> 59466 bytes en/chapter_sorting/summary/index.html | 3878 ++++++++++ en/chapter_stack_and_queue/deque/index.html | 1461 +++- en/chapter_stack_and_queue/index.html | 1461 +++- en/chapter_stack_and_queue/queue/index.html | 1461 +++- en/chapter_stack_and_queue/stack/index.html | 1461 +++- en/chapter_stack_and_queue/summary/index.html | 1461 +++- .../array_representation_of_tree/index.html | 1469 +++- en/chapter_tree/avl_tree/index.html | 1461 +++- en/chapter_tree/binary_search_tree/index.html | 1461 +++- en/chapter_tree/binary_tree/index.html | 1469 +++- .../binary_tree_traversal/index.html | 1467 +++- en/chapter_tree/index.html | 1463 +++- en/chapter_tree/summary/index.html | 1461 +++- en/index.html | 510 +- en/search/search_index.json | 2 +- en/sitemap.xml | 360 +- en/sitemap.xml.gz | Bin 605 -> 1007 bytes search/search_index.json | 2 +- sitemap.xml | 212 +- sitemap.xml.gz | Bin 1011 -> 1011 bytes zh-hant/sitemap.xml | 210 +- zh-hant/sitemap.xml.gz | Bin 1010 -> 1009 bytes 391 files changed, 299613 insertions(+), 414 deletions(-) create mode 100644 en/chapter_appendix/contribution.assets/edit_markdown.png create mode 100644 en/chapter_appendix/contribution/index.html create mode 100644 en/chapter_appendix/index.html create mode 100644 en/chapter_appendix/installation.assets/vscode_extension_installation.png create mode 100644 en/chapter_appendix/installation.assets/vscode_installation.png create mode 100644 en/chapter_appendix/installation/index.html create mode 100644 en/chapter_appendix/terminology/index.html create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/backtrack_remove_return_or_not.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_constrained_paths.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_nodes.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step1.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step10.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step11.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step2.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step3.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step4.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step5.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step6.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step7.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step8.png create mode 100644 en/chapter_backtracking/backtracking_algorithm.assets/preorder_find_paths_step9.png create mode 100644 en/chapter_backtracking/backtracking_algorithm/index.html create mode 100644 en/chapter_backtracking/index.html create mode 100644 en/chapter_backtracking/n_queens_problem.assets/n_queens_cols_diagonals.png create mode 100644 en/chapter_backtracking/n_queens_problem.assets/n_queens_constraints.png create mode 100644 en/chapter_backtracking/n_queens_problem.assets/n_queens_placing.png create mode 100644 en/chapter_backtracking/n_queens_problem.assets/solution_4_queens.png create mode 100644 en/chapter_backtracking/n_queens_problem/index.html create mode 100644 en/chapter_backtracking/permutations_problem.assets/permutations_i.png create mode 100644 en/chapter_backtracking/permutations_problem.assets/permutations_i_pruning.png create mode 100644 en/chapter_backtracking/permutations_problem.assets/permutations_ii.png create mode 100644 en/chapter_backtracking/permutations_problem.assets/permutations_ii_pruning.png create mode 100644 en/chapter_backtracking/permutations_problem.assets/permutations_ii_pruning_summary.png create mode 100644 en/chapter_backtracking/permutations_problem/index.html create mode 100644 en/chapter_backtracking/subset_sum_problem.assets/subset_sum_i.png create mode 100644 en/chapter_backtracking/subset_sum_problem.assets/subset_sum_i_naive.png create mode 100644 en/chapter_backtracking/subset_sum_problem.assets/subset_sum_i_pruning.png create mode 100644 en/chapter_backtracking/subset_sum_problem.assets/subset_sum_ii.png create mode 100644 en/chapter_backtracking/subset_sum_problem.assets/subset_sum_ii_repeat.png create mode 100644 en/chapter_backtracking/subset_sum_problem/index.html create mode 100644 en/chapter_backtracking/summary/index.html create mode 100644 en/chapter_divide_and_conquer/binary_search_recur.assets/binary_search_recur.png create mode 100644 en/chapter_divide_and_conquer/binary_search_recur/index.html create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_division_pointers.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_example.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_preorder_inorder_division.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_overall.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step1.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step2.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step3.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step4.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step5.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step6.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step7.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step8.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step9.png create mode 100644 en/chapter_divide_and_conquer/build_binary_tree_problem/index.html create mode 100644 en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_bubble_sort.png create mode 100644 en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_merge_sort.png create mode 100644 en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_parallel_computing.png create mode 100644 en/chapter_divide_and_conquer/divide_and_conquer/index.html create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_divide_and_conquer.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_example.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f1_step1.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f1_step2.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step1.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step2.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step3.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step4.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step1.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step2.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step3.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step4.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem.assets/hanota_recursive_tree.png create mode 100644 en/chapter_divide_and_conquer/hanota_problem/index.html create mode 100644 en/chapter_divide_and_conquer/index.html create mode 100644 en/chapter_divide_and_conquer/summary/index.html create mode 100644 en/chapter_dynamic_programming/dp_problem_features.assets/climbing_stairs_constraint_example.png create mode 100644 en/chapter_dynamic_programming/dp_problem_features.assets/climbing_stairs_constraint_state_transfer.png create mode 100644 en/chapter_dynamic_programming/dp_problem_features.assets/min_cost_cs_dp.png create mode 100644 en/chapter_dynamic_programming/dp_problem_features.assets/min_cost_cs_example.png create mode 100644 en/chapter_dynamic_programming/dp_problem_features/index.html create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dfs.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dfs_mem.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step1.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step10.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step11.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step12.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step2.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step3.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step4.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step5.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step6.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step7.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step8.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step9.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_example.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_initial_state.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_state_definition.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_state_transition.png create mode 100644 en/chapter_dynamic_programming/dp_solution_pipeline/index.html create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_decision_tree.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step1.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step10.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step11.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step12.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step13.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step14.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step15.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step2.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step3.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step4.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step5.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step6.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step7.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step8.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step9.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_example.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_state_transfer.png create mode 100644 en/chapter_dynamic_programming/edit_distance_problem/index.html create mode 100644 en/chapter_dynamic_programming/index.html create mode 100644 en/chapter_dynamic_programming/intro_to_dynamic_programming.assets/climbing_stairs_dfs_memo_tree.png create mode 100644 en/chapter_dynamic_programming/intro_to_dynamic_programming.assets/climbing_stairs_dfs_tree.png create mode 100644 en/chapter_dynamic_programming/intro_to_dynamic_programming.assets/climbing_stairs_dp.png create mode 100644 en/chapter_dynamic_programming/intro_to_dynamic_programming.assets/climbing_stairs_example.png create mode 100644 en/chapter_dynamic_programming/intro_to_dynamic_programming.assets/climbing_stairs_state_transfer.png create mode 100644 en/chapter_dynamic_programming/intro_to_dynamic_programming/index.html create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dfs.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dfs_mem.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_comp_step1.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_comp_step2.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_comp_step3.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_comp_step4.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_comp_step5.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_comp_step6.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step1.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step10.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step11.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step12.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step13.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step14.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step2.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step3.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step4.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step5.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step6.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step7.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step8.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_dp_step9.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem.assets/knapsack_example.png create mode 100644 en/chapter_dynamic_programming/knapsack_problem/index.html create mode 100644 en/chapter_dynamic_programming/summary/index.html create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step1.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step10.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step11.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step12.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step13.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step14.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step15.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step2.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step3.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step4.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step5.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step6.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step7.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step8.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_dp_step9.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_example.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/coin_change_ii_example.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_dp_comp_step1.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_dp_comp_step2.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_dp_comp_step3.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_dp_comp_step4.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_dp_comp_step5.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_dp_comp_step6.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem.assets/unbounded_knapsack_example.png create mode 100644 en/chapter_dynamic_programming/unbounded_knapsack_problem/index.html create mode 100644 en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_area_chart.png create mode 100644 en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_example.png create mode 100644 en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_greedy_strategy.png create mode 100644 en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_unit_value.png create mode 100644 en/chapter_greedy/fractional_knapsack_problem/index.html create mode 100644 en/chapter_greedy/greedy_algorithm.assets/coin_change_greedy_strategy.png create mode 100644 en/chapter_greedy/greedy_algorithm.assets/coin_change_greedy_vs_dp.png create mode 100644 en/chapter_greedy/greedy_algorithm/index.html create mode 100644 en/chapter_greedy/index.html create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_example.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step1.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step2.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step3.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step4.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step5.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step6.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step7.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step8.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step9.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_initial_state.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_moving_long_board.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_moving_short_board.png create mode 100644 en/chapter_greedy/max_capacity_problem.assets/max_capacity_skipped_states.png create mode 100644 en/chapter_greedy/max_capacity_problem/index.html create mode 100644 en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_definition.png create mode 100644 en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_greedy_calculation.png create mode 100644 en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_greedy_infer1.png create mode 100644 en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_greedy_infer2.png create mode 100644 en/chapter_greedy/max_product_cutting_problem/index.html create mode 100644 en/chapter_greedy/summary/index.html create mode 100644 en/chapter_reference/index.html create mode 100644 en/chapter_searching/binary_search.assets/binary_search_example.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_ranges.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step1.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step2.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step3.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step4.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step5.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step6.png create mode 100644 en/chapter_searching/binary_search.assets/binary_search_step7.png create mode 100644 en/chapter_searching/binary_search/index.html create mode 100644 en/chapter_searching/binary_search_edge.assets/binary_search_edge_by_element.png create mode 100644 en/chapter_searching/binary_search_edge.assets/binary_search_right_edge_by_left_edge.png create mode 100644 en/chapter_searching/binary_search_edge/index.html create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_example.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_naive.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step1.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step2.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step3.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step4.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step5.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step6.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step7.png create mode 100644 en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step8.png create mode 100644 en/chapter_searching/binary_search_insertion/index.html create mode 100644 en/chapter_searching/index.html create mode 100644 en/chapter_searching/replace_linear_by_hashing.assets/two_sum_brute_force.png create mode 100644 en/chapter_searching/replace_linear_by_hashing.assets/two_sum_hashtable_step1.png create mode 100644 en/chapter_searching/replace_linear_by_hashing.assets/two_sum_hashtable_step2.png create mode 100644 en/chapter_searching/replace_linear_by_hashing.assets/two_sum_hashtable_step3.png create mode 100644 en/chapter_searching/replace_linear_by_hashing/index.html create mode 100644 en/chapter_searching/searching_algorithm_revisited.assets/searching_algorithms.png create mode 100644 en/chapter_searching/searching_algorithm_revisited/index.html create mode 100644 en/chapter_searching/summary/index.html create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step1.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step2.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step3.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step4.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step5.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step6.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_operation_step7.png create mode 100644 en/chapter_sorting/bubble_sort.assets/bubble_sort_overview.png create mode 100644 en/chapter_sorting/bubble_sort/index.html create mode 100644 en/chapter_sorting/bucket_sort.assets/bucket_sort_overview.png create mode 100644 en/chapter_sorting/bucket_sort.assets/scatter_in_buckets_distribution.png create mode 100644 en/chapter_sorting/bucket_sort.assets/scatter_in_buckets_recursively.png create mode 100644 en/chapter_sorting/bucket_sort/index.html create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_overview.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step1.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step2.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step3.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step4.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step5.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step6.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step7.png create mode 100644 en/chapter_sorting/counting_sort.assets/counting_sort_step8.png create mode 100644 en/chapter_sorting/counting_sort/index.html create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step1.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step10.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step11.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step12.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step2.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step3.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step4.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step5.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step6.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step7.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step8.png create mode 100644 en/chapter_sorting/heap_sort.assets/heap_sort_step9.png create mode 100644 en/chapter_sorting/heap_sort/index.html create mode 100644 en/chapter_sorting/index.html create mode 100644 en/chapter_sorting/insertion_sort.assets/insertion_operation.png create mode 100644 en/chapter_sorting/insertion_sort.assets/insertion_sort_overview.png create mode 100644 en/chapter_sorting/insertion_sort/index.html create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_overview.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step1.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step10.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step2.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step3.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step4.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step5.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step6.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step7.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step8.png create mode 100644 en/chapter_sorting/merge_sort.assets/merge_sort_step9.png create mode 100644 en/chapter_sorting/merge_sort/index.html create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step1.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step2.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step3.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step4.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step5.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step6.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step7.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step8.png create mode 100644 en/chapter_sorting/quick_sort.assets/pivot_division_step9.png create mode 100644 en/chapter_sorting/quick_sort.assets/quick_sort_overview.png create mode 100644 en/chapter_sorting/quick_sort/index.html create mode 100644 en/chapter_sorting/radix_sort.assets/radix_sort_overview.png create mode 100644 en/chapter_sorting/radix_sort/index.html create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_instability.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step1.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step10.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step11.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step2.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step3.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step4.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step5.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step6.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step7.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step8.png create mode 100644 en/chapter_sorting/selection_sort.assets/selection_sort_step9.png create mode 100644 en/chapter_sorting/selection_sort/index.html create mode 100644 en/chapter_sorting/sorting_algorithm.assets/sorting_examples.png create mode 100644 en/chapter_sorting/sorting_algorithm/index.html create mode 100644 en/chapter_sorting/summary.assets/sorting_algorithms_comparison.png create mode 100644 en/chapter_sorting/summary/index.html diff --git a/chapter_backtracking/permutations_problem/index.html b/chapter_backtracking/permutations_problem/index.html index 2089cc991..0336c491d 100644 --- a/chapter_backtracking/permutations_problem/index.html +++ b/chapter_backtracking/permutations_problem/index.html @@ -4455,7 +4455,7 @@ (*selected)[i] = true *state = append(*state, choice) // 进行下一轮选择 - backtrackI(state, choices, selected, res) + backtrackII(state, choices, selected, res) // 回退:撤销选择,恢复到之前的状态 (*selected)[i] = false *state = (*state)[:len(*state)-1] diff --git a/chapter_sorting/bucket_sort/index.html b/chapter_sorting/bucket_sort/index.html index 181cf00d9..6bedea265 100644 --- a/chapter_sorting/bucket_sort/index.html +++ b/chapter_sorting/bucket_sort/index.html @@ -4055,7 +4055,35 @@
-
bucket_sort.rb
[class]{}-[func]{bucket_sort}
+
bucket_sort.rb
### 桶排序 ###
+def bucket_sort(nums)
+  # 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
+  k = nums.length / 2
+  buckets = Array.new(k) { [] }
+
+  # 1. 将数组元素分配到各个桶中
+  nums.each do |num|
+    # 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
+    i = (num * k).to_i
+    # 将 num 添加进桶 i
+    buckets[i] << num
+  end
+
+  # 2. 对各个桶执行排序
+  buckets.each do |bucket|
+    # 使用内置排序函数,也可以替换成其他排序算法
+    bucket.sort!
+  end
+
+  # 3. 遍历桶合并结果
+  i = 0
+  buckets.each do |bucket|
+    bucket.each do |num|
+      nums[i] = num
+      i += 1
+    end
+  end
+end
 
diff --git a/chapter_sorting/heap_sort/index.html b/chapter_sorting/heap_sort/index.html index dd356a5d8..003d12fea 100644 --- a/chapter_sorting/heap_sort/index.html +++ b/chapter_sorting/heap_sort/index.html @@ -4219,9 +4219,38 @@
-
heap_sort.rb
[class]{}-[func]{sift_down}
-
-[class]{}-[func]{heap_sort}
+
heap_sort.rb
### 堆的长度为 n ,从节点 i 开始,从顶至底堆化 ###
+def sift_down(nums, n, i)
+  while true
+    # 判断节点 i, l, r 中值最大的节点,记为 ma
+    l = 2 * i + 1
+    r = 2 * i + 2
+    ma = i
+    ma = l if l < n && nums[l] > nums[ma]
+    ma = r if r < n && nums[r] > nums[ma]
+    # 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
+    break if ma == i
+    # 交换两节点
+    nums[i], nums[ma] = nums[ma], nums[i]
+    # 循环向下堆化
+    i = ma
+  end
+end
+
+### 堆排序 ###
+def heap_sort(nums)
+  # 建堆操作:堆化除叶节点以外的其他所有节点
+  (nums.length / 2 - 1).downto(0) do |i|
+    sift_down(nums, nums.length, i)
+  end
+  # 从堆中提取最大元素,循环 n-1 轮
+  (nums.length - 1).downto(1) do |i|
+    # 交换根节点与最右叶节点(交换首元素与尾元素)
+    nums[0], nums[i] = nums[i], nums[0]
+    # 以根节点为起点,从顶至底进行堆化
+    sift_down(nums, i, 0)
+  end
+end
 
diff --git a/chapter_sorting/merge_sort/index.html b/chapter_sorting/merge_sort/index.html index 0e516a562..fc12f91bc 100644 --- a/chapter_sorting/merge_sort/index.html +++ b/chapter_sorting/merge_sort/index.html @@ -4284,9 +4284,53 @@
-
merge_sort.rb
[class]{}-[func]{merge}
-
-[class]{}-[func]{merge_sort}
+
merge_sort.rb
### 合并左子数组和右子数组 ###
+def merge(nums, left, mid, right)
+  # 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
+  # 创建一个临时数组 tmp,用于存放合并后的结果
+  tmp = Array.new(right - left + 1, 0)
+  # 初始化左子数组和右子数组的起始索引
+  i, j, k = left, mid + 1, 0
+  # 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
+  while i <= mid && j <= right
+    if nums[i] <= nums[j]
+      tmp[k] = nums[i]
+      i += 1
+    else
+      tmp[k] = nums[j]
+      j += 1
+    end
+    k += 1
+  end
+  # 将左子数组和右子数组的剩余元素复制到临时数组中
+  while i <= mid
+    tmp[k] = nums[i]
+    i += 1
+    k += 1
+  end
+  while j <= right
+    tmp[k] = nums[j]
+    j += 1
+    k += 1
+  end
+  # 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
+  (0...tmp.length).each do |k|
+    nums[left + k] = tmp[k]
+  end
+end
+
+### 归并排序 ###
+def merge_sort(nums, left, right)
+  # 终止条件
+  # 当子数组长度为 1 时终止递归
+  return if left >= right
+  # 划分阶段
+  mid = (left + right) / 2 # 计算中点
+  merge_sort(nums, left, mid) # 递归左子数组
+  merge_sort(nums, mid + 1, right) # 递归右子数组
+  # 合并阶段
+  merge(nums, left, mid, right)
+end
 
diff --git a/en/404.html b/en/404.html index ada0b7695..deb9efd1a 100644 --- a/en/404.html +++ b/en/404.html @@ -1117,7 +1117,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1562,7 +1562,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1971,6 +1971,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + +
    diff --git a/en/chapter_appendix/contribution.assets/edit_markdown.png b/en/chapter_appendix/contribution.assets/edit_markdown.png new file mode 100644 index 0000000000000000000000000000000000000000..c11dce4fbecb4ba8d00443c13937a187d4c596b7 GIT binary patch literal 87838 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 DZRH|3 literal 0 HcmV?d00001 diff --git a/en/chapter_appendix/contribution/index.html b/en/chapter_appendix/contribution/index.html new file mode 100644 index 000000000..b71079a6a --- /dev/null +++ b/en/chapter_appendix/contribution/index.html @@ -0,0 +1,3899 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16.2 Contributing - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    16.2   Contributing

    +

    Due to the limited abilities of the author, some omissions and errors are inevitable in this book. Please understand. If you discover any typos, broken links, missing content, textual ambiguities, unclear explanations, or unreasonable text structures, please assist us in making corrections to provide readers with better quality learning resources.

    +

    The GitHub IDs of all contributors will be displayed on the repository, web, and PDF versions of the homepage of this book to thank them for their selfless contributions to the open-source community.

    +
    +

    The charm of open source

    +

    The interval between two printings of a paper book is often long, making content updates very inconvenient.

    +

    In this open-source book, however, the content update cycle is shortened to just a few days or even hours.

    +
    +

    1.   Content fine-tuning

    +

    As shown in the Figure 16-3 , there is an "edit icon" in the upper right corner of each page. You can follow these steps to modify text or code.

    +
      +
    1. Click the "edit icon". If prompted to "fork this repository", please agree to do so.
    2. +
    3. Modify the Markdown source file content, check the accuracy of the content, and try to keep the formatting consistent.
    4. +
    5. Fill in the modification description at the bottom of the page, then click the "Propose file change" button. After the page redirects, click the "Create pull request" button to initiate the pull request.
    6. +
    +

    Edit page button

    +

    Figure 16-3   Edit page button

    + +

    Images cannot be directly modified and require the creation of a new Issue or a comment to describe the problem. We will redraw and replace the images as soon as possible.

    +

    2.   Content creation

    +

    If you are interested in participating in this open-source project, including translating code into other programming languages or expanding article content, then the following Pull Request workflow needs to be implemented.

    +
      +
    1. Log in to GitHub and Fork the code repository of this book to your personal account.
    2. +
    3. Go to your Forked repository web page and use the git clone command to clone the repository to your local machine.
    4. +
    5. Create content locally and perform complete tests to verify the correctness of the code.
    6. +
    7. Commit the changes made locally, then push them to the remote repository.
    8. +
    9. Refresh the repository webpage and click the "Create pull request" button to initiate the pull request.
    10. +
    +

    3.   Docker deployment

    +

    In the hello-algo root directory, execute the following Docker script to access the project at http://localhost:8000:

    +
    docker-compose up -d
    +
    +

    Use the following command to remove the deployment:

    +
    docker-compose down
    +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_appendix/index.html b/en/chapter_appendix/index.html new file mode 100644 index 000000000..018410c49 --- /dev/null +++ b/en/chapter_appendix/index.html @@ -0,0 +1,3787 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Chapter 16.   Appendix - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    Chapter 16.   Appendix

    +

    Appendix

    +

    Chapter contents

    + + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_appendix/installation.assets/vscode_extension_installation.png b/en/chapter_appendix/installation.assets/vscode_extension_installation.png new file mode 100644 index 0000000000000000000000000000000000000000..3eabc83d05dd54bbc14b0f7ba16e8ef2f1f77d3b GIT binary patch literal 126853 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

    a0f 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%0A;D*3rd&}TvmR-2ou{qN0A)qw2 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

    T@!Z|#&b_|-$@aM^04Gl#0H+q<_>6t-l`* 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 literal 0 HcmV?d00001 diff --git a/en/chapter_appendix/installation/index.html b/en/chapter_appendix/installation/index.html new file mode 100644 index 000000000..b1ada803a --- /dev/null +++ b/en/chapter_appendix/installation/index.html @@ -0,0 +1,4104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16.1 Installation - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    16.1   Installation

    +

    16.1.1   Install IDE

    +

    We recommend using the open-source, lightweight VS Code as your local Integrated Development Environment (IDE). Visit the VS Code official website and choose the version of VS Code appropriate for your operating system to download and install.

    +

    Download VS Code from the official website

    +

    Figure 16-1   Download VS Code from the official website

    + +

    VS Code has a powerful extension ecosystem, supporting the execution and debugging of most programming languages. For example, after installing the "Python Extension Pack," you can debug Python code. The installation steps are shown in the following figure.

    +

    Install VS Code Extension Pack

    +

    Figure 16-2   Install VS Code Extension Pack

    + +

    16.1.2   Install language environments

    +

    1.   Python environment

    +
      +
    1. Download and install Miniconda3, requiring Python 3.10 or newer.
    2. +
    3. In the VS Code extension marketplace, search for python and install the Python Extension Pack.
    4. +
    5. (Optional) Enter pip install black in the command line to install the code formatting tool.
    6. +
    +

    2.   C/C++ environment

    +
      +
    1. Windows systems need to install MinGW (Configuration tutorial); MacOS comes with Clang, so no installation is necessary.
    2. +
    3. In the VS Code extension marketplace, search for c++ and install the C/C++ Extension Pack.
    4. +
    5. (Optional) Open the Settings page, search for the Clang_format_fallback Style code formatting option, and set it to { BasedOnStyle: Microsoft, BreakBeforeBraces: Attach }.
    6. +
    +

    3.   Java environment

    +
      +
    1. Download and install OpenJDK (version must be > JDK 9).
    2. +
    3. In the VS Code extension marketplace, search for java and install the Extension Pack for Java.
    4. +
    +

    4.   C# environment

    +
      +
    1. Download and install .Net 8.0.
    2. +
    3. In the VS Code extension marketplace, search for C# Dev Kit and install the C# Dev Kit (Configuration tutorial).
    4. +
    5. You can also use Visual Studio (Installation tutorial).
    6. +
    +

    5.   Go environment

    +
      +
    1. Download and install go.
    2. +
    3. In the VS Code extension marketplace, search for go and install Go.
    4. +
    5. Press Ctrl + Shift + P to call up the command bar, enter go, choose Go: Install/Update Tools, select all and install.
    6. +
    +

    6.   Swift environment

    +
      +
    1. Download and install Swift.
    2. +
    3. In the VS Code extension marketplace, search for swift and install Swift for Visual Studio Code.
    4. +
    +

    7.   JavaScript environment

    +
      +
    1. Download and install Node.js.
    2. +
    3. (Optional) In the VS Code extension marketplace, search for Prettier and install the code formatting tool.
    4. +
    +

    8.   TypeScript environment

    +
      +
    1. Follow the same installation steps as the JavaScript environment.
    2. +
    3. Install TypeScript Execute (tsx).
    4. +
    5. In the VS Code extension marketplace, search for typescript and install Pretty TypeScript Errors.
    6. +
    +

    9.   Dart environment

    +
      +
    1. Download and install Dart.
    2. +
    3. In the VS Code extension marketplace, search for dart and install Dart.
    4. +
    +

    10.   Rust environment

    +
      +
    1. Download and install Rust.
    2. +
    3. In the VS Code extension marketplace, search for rust and install rust-analyzer.
    4. +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_appendix/terminology/index.html b/en/chapter_appendix/terminology/index.html new file mode 100644 index 000000000..2f420187f --- /dev/null +++ b/en/chapter_appendix/terminology/index.html @@ -0,0 +1,4423 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16.3 Terminology - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    16.3   Glossary

    +

    The Table 16-1 lists the important terms that appear in the book, and it is worth noting the following points.

    +
      +
    • It is recommended to remember the English names of the terms to facilitate reading English literature.
    • +
    • Some terms have different names in Simplified and Traditional Chinese.
    • +
    +

    Table 16-1   Important Terms in Data Structures and Algorithms

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    English简体中文繁体中文
    algorithm算法演算法
    data structure数据结构資料結構
    code代码程式碼
    file文件檔案
    function函数函式
    method方法方法
    variable变量變數
    asymptotic complexity analysis渐近复杂度分析漸近複雜度分析
    time complexity时间复杂度時間複雜度
    space complexity空间复杂度空間複雜度
    loop循环迴圈
    iteration迭代迭代
    recursion递归遞迴
    tail recursion尾递归尾遞迴
    recursion tree递归树遞迴樹
    big-\(O\) notation\(O\) 记号\(O\) 記號
    asymptotic upper bound渐近上界漸近上界
    sign-magnitude原码原碼
    1’s complement反码一補數
    2’s complement补码二補數
    array数组陣列
    index索引索引
    linked list链表鏈結串列
    linked list node, list node链表节点鏈結串列節點
    head node头节点頭節點
    tail node尾节点尾節點
    list列表串列
    dynamic array动态数组動態陣列
    hard disk硬盘硬碟
    random-access memory (RAM)内存記憶體
    cache memory缓存快取
    cache miss缓存未命中快取未命中
    cache hit rate缓存命中率快取命中率
    stack堆疊
    top of the stack栈顶堆疊頂
    bottom of the stack栈底堆疊底
    queue队列佇列
    double-ended queue双向队列雙向佇列
    front of the queue队首佇列首
    rear of the queue队尾佇列尾
    hash table哈希表雜湊表
    hash set哈希集合雜湊集合
    bucket
    hash function哈希函数雜湊函式
    hash collision哈希冲突雜湊衝突
    load factor负载因子負載因子
    separate chaining链式地址鏈結位址
    open addressing开放寻址開放定址
    linear probing线性探测線性探查
    lazy deletion懒删除懶刪除
    binary tree二叉树二元樹
    tree node树节点樹節點
    left-child node左子节点左子節點
    right-child node右子节点右子節點
    parent node父节点父節點
    left subtree左子树左子樹
    right subtree右子树右子樹
    root node根节点根節點
    leaf node叶节点葉節點
    edge
    level
    degree
    height高度高度
    depth深度深度
    perfect binary tree完美二叉树完美二元樹
    complete binary tree完全二叉树完全二元樹
    full binary tree完满二叉树完滿二元樹
    balanced binary tree平衡二叉树平衡二元樹
    binary search tree二叉搜索树二元搜尋樹
    AVL treeAVL 树AVL 樹
    red-black tree红黑树紅黑樹
    level-order traversal层序遍历層序走訪
    breadth-first traversal广度优先遍历廣度優先走訪
    depth-first traversal深度优先遍历深度優先走訪
    binary search tree二叉搜索树二元搜尋樹
    balanced binary search tree平衡二叉搜索树平衡二元搜尋樹
    balance factor平衡因子平衡因子
    heap堆積
    max heap大顶堆大頂堆積
    min heap小顶堆小頂堆積
    priority queue优先队列優先佇列
    heapify堆化堆積化
    top-\(k\) problemTop-\(k\) 问题Top-\(k\) 問題
    graph
    vertex顶点頂點
    undirected graph无向图無向圖
    directed graph有向图有向圖
    connected graph连通图連通圖
    disconnected graph非连通图非連通圖
    weighted graph有权图有權圖
    adjacency邻接鄰接
    path路径路徑
    in-degree入度入度
    out-degree出度出度
    adjacency matrix邻接矩阵鄰接矩陣
    adjacency list邻接表鄰接表
    breadth-first search广度优先搜索廣度優先搜尋
    depth-first search深度优先搜索深度優先搜尋
    binary search二分查找二分搜尋
    searching algorithm搜索算法搜尋演算法
    sorting algorithm排序算法排序演算法
    selection sort选择排序選擇排序
    bubble sort冒泡排序泡沫排序
    insertion sort插入排序插入排序
    quick sort快速排序快速排序
    merge sort归并排序合併排序
    heap sort堆排序堆積排序
    bucket sort桶排序桶排序
    counting sort计数排序計數排序
    radix sort基数排序基數排序
    divide and conquer分治分治
    hanota problem汉诺塔问题河內塔問題
    backtracking algorithm回溯算法回溯演算法
    constraint约束約束
    solution
    state状态狀態
    pruning剪枝剪枝
    permutations problem全排列问题全排列問題
    subset-sum problem子集和问题子集合問題
    \(n\)-queens problem\(n\) 皇后问题\(n\) 皇后問題
    dynamic programming动态规划動態規劃
    initial state初始状态初始狀態
    state-transition equation状态转移方程狀態轉移方程
    knapsack problem背包问题背包問題
    edit distance problem编辑距离问题編輯距離問題
    greedy algorithm贪心算法貪婪演算法
    +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_array_and_linkedlist/array/index.html b/en/chapter_array_and_linkedlist/array/index.html index e4828a91e..b7a5d17a0 100644 --- a/en/chapter_array_and_linkedlist/array/index.html +++ b/en/chapter_array_and_linkedlist/array/index.html @@ -1277,7 +1277,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1722,7 +1722,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2131,6 +2131,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + +
    diff --git a/en/chapter_array_and_linkedlist/index.html b/en/chapter_array_and_linkedlist/index.html index b033846c5..ae7351cb4 100644 --- a/en/chapter_array_and_linkedlist/index.html +++ b/en/chapter_array_and_linkedlist/index.html @@ -1141,7 +1141,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + @@ -2078,7 +3535,7 @@
  • 4.1   Array
  • 4.2   Linked list
  • 4.3   List
  • -
  • 4.4   Memory and cache
  • +
  • 4.4   Memory and cache *
  • 4.5   Summary
  • diff --git a/en/chapter_array_and_linkedlist/linked_list/index.html b/en/chapter_array_and_linkedlist/linked_list/index.html index 318de1a47..6bc60fa56 100644 --- a/en/chapter_array_and_linkedlist/linked_list/index.html +++ b/en/chapter_array_and_linkedlist/linked_list/index.html @@ -1268,7 +1268,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1713,7 +1713,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2122,6 +2122,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_array_and_linkedlist/list/index.html b/en/chapter_array_and_linkedlist/list/index.html index 1270eba58..333ea6af0 100644 --- a/en/chapter_array_and_linkedlist/list/index.html +++ b/en/chapter_array_and_linkedlist/list/index.html @@ -1259,7 +1259,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1704,7 +1704,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2113,6 +2113,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + @@ -4483,7 +5940,7 @@ aria-label="Footer" @@ -2210,7 +3667,7 @@ aria-label="Footer" @@ -2335,7 +3792,7 @@ aria-label="Footer" diff --git a/en/chapter_computational_complexity/iteration_and_recursion/index.html b/en/chapter_computational_complexity/iteration_and_recursion/index.html index bae9c7c9c..40f725777 100644 --- a/en/chapter_computational_complexity/iteration_and_recursion/index.html +++ b/en/chapter_computational_complexity/iteration_and_recursion/index.html @@ -1274,7 +1274,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1719,7 +1719,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2128,6 +2128,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_computational_complexity/performance_evaluation/index.html b/en/chapter_computational_complexity/performance_evaluation/index.html index 8bfd79729..449a0b7f6 100644 --- a/en/chapter_computational_complexity/performance_evaluation/index.html +++ b/en/chapter_computational_complexity/performance_evaluation/index.html @@ -1199,7 +1199,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_computational_complexity/space_complexity/index.html b/en/chapter_computational_complexity/space_complexity/index.html index a4e48321d..e11ba3f1f 100644 --- a/en/chapter_computational_complexity/space_complexity/index.html +++ b/en/chapter_computational_complexity/space_complexity/index.html @@ -1268,7 +1268,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1713,7 +1713,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2122,6 +2122,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_computational_complexity/summary/index.html b/en/chapter_computational_complexity/summary/index.html index c83da9e31..e394bebde 100644 --- a/en/chapter_computational_complexity/summary/index.html +++ b/en/chapter_computational_complexity/summary/index.html @@ -1199,7 +1199,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_computational_complexity/time_complexity/index.html b/en/chapter_computational_complexity/time_complexity/index.html index 5e8512dca..fcf6840cb 100644 --- a/en/chapter_computational_complexity/time_complexity/index.html +++ b/en/chapter_computational_complexity/time_complexity/index.html @@ -1319,7 +1319,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1764,7 +1764,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2173,6 +2173,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_data_structure/basic_data_types/index.html b/en/chapter_data_structure/basic_data_types/index.html index bc68c9b97..d2385396b 100644 --- a/en/chapter_data_structure/basic_data_types/index.html +++ b/en/chapter_data_structure/basic_data_types/index.html @@ -1151,7 +1151,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1596,7 +1596,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2005,6 +2005,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_data_structure/character_encoding/index.html b/en/chapter_data_structure/character_encoding/index.html index 75ba9dc66..bf77f44fa 100644 --- a/en/chapter_data_structure/character_encoding/index.html +++ b/en/chapter_data_structure/character_encoding/index.html @@ -1226,7 +1226,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1671,7 +1671,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2080,6 +2080,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_data_structure/classification_of_data_structure/index.html b/en/chapter_data_structure/classification_of_data_structure/index.html index 8cac00f07..f26f17e1b 100644 --- a/en/chapter_data_structure/classification_of_data_structure/index.html +++ b/en/chapter_data_structure/classification_of_data_structure/index.html @@ -1199,7 +1199,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_data_structure/index.html b/en/chapter_data_structure/index.html index 28eb7c55c..cbca70a2c 100644 --- a/en/chapter_data_structure/index.html +++ b/en/chapter_data_structure/index.html @@ -1141,7 +1141,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_data_structure/number_encoding/index.html b/en/chapter_data_structure/number_encoding/index.html index 93a90a3a9..e3d16c835 100644 --- a/en/chapter_data_structure/number_encoding/index.html +++ b/en/chapter_data_structure/number_encoding/index.html @@ -1199,7 +1199,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_data_structure/summary/index.html b/en/chapter_data_structure/summary/index.html index c80a628f0..b60155b8c 100644 --- a/en/chapter_data_structure/summary/index.html +++ b/en/chapter_data_structure/summary/index.html @@ -1199,7 +1199,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_divide_and_conquer/binary_search_recur.assets/binary_search_recur.png b/en/chapter_divide_and_conquer/binary_search_recur.assets/binary_search_recur.png new file mode 100644 index 0000000000000000000000000000000000000000..7811a4ce83ac728524f08d842016697606eb42ad GIT binary patch literal 16844 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/binary_search_recur/index.html b/en/chapter_divide_and_conquer/binary_search_recur/index.html new file mode 100644 index 000000000..59558bd48 --- /dev/null +++ b/en/chapter_divide_and_conquer/binary_search_recur/index.html @@ -0,0 +1,4234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12.2 Divide and conquer search strategy - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    12.2   Divide and conquer search strategy

    +

    We have learned that search algorithms fall into two main categories.

    +
      +
    • Brute-force search: It is implemented by traversing the data structure, with a time complexity of \(O(n)\).
    • +
    • Adaptive search: It utilizes a unique data organization form or prior information, and its time complexity can reach \(O(\log n)\) or even \(O(1)\).
    • +
    +

    In fact, search algorithms with a time complexity of \(O(\log n)\) are usually based on the divide-and-conquer strategy, such as binary search and trees.

    +
      +
    • Each step of binary search divides the problem (searching for a target element in an array) into a smaller problem (searching for the target element in half of the array), continuing until the array is empty or the target element is found.
    • +
    • Trees represent the divide-and-conquer idea, where in data structures like binary search trees, AVL trees, and heaps, the time complexity of various operations is \(O(\log n)\).
    • +
    +

    The divide-and-conquer strategy of binary search is as follows.

    +
      +
    • The problem can be divided: Binary search recursively divides the original problem (searching in an array) into subproblems (searching in half of the array), achieved by comparing the middle element with the target element.
    • +
    • Subproblems are independent: In binary search, each round handles one subproblem, unaffected by other subproblems.
    • +
    • The solutions of subproblems do not need to be merged: Binary search aims to find a specific element, so there is no need to merge the solutions of subproblems. When a subproblem is solved, the original problem is also solved.
    • +
    +

    Divide-and-conquer can enhance search efficiency because brute-force search can only eliminate one option per round, whereas divide-and-conquer can eliminate half of the options.

    +

    1.   Implementing binary search based on divide-and-conquer

    +

    In previous chapters, binary search was implemented based on iteration. Now, we implement it based on divide-and-conquer (recursion).

    +
    +

    Question

    +

    Given an ordered array nums of length \(n\), where all elements are unique, please find the element target.

    +
    +

    From a divide-and-conquer perspective, we denote the subproblem corresponding to the search interval \([i, j]\) as \(f(i, j)\).

    +

    Starting from the original problem \(f(0, n-1)\), perform the binary search through the following steps.

    +
      +
    1. Calculate the midpoint \(m\) of the search interval \([i, j]\), and use it to eliminate half of the search interval.
    2. +
    3. Recursively solve the subproblem reduced by half in size, which could be \(f(i, m-1)\) or \(f(m+1, j)\).
    4. +
    5. Repeat steps 1. and 2., until target is found or the interval is empty and returns.
    6. +
    +

    The diagram below shows the divide-and-conquer process of binary search for element \(6\) in an array.

    +

    The divide-and-conquer process of binary search

    +

    Figure 12-4   The divide-and-conquer process of binary search

    + +

    In the implementation code, we declare a recursive function dfs() to solve the problem \(f(i, j)\):

    +
    +
    +
    +
    binary_search_recur.py
    def dfs(nums: list[int], target: int, i: int, j: int) -> int:
    +    """二分查找:问题 f(i, j)"""
    +    # 若区间为空,代表无目标元素,则返回 -1
    +    if i > j:
    +        return -1
    +    # 计算中点索引 m
    +    m = (i + j) // 2
    +    if nums[m] < target:
    +        # 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j)
    +    elif nums[m] > target:
    +        # 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1)
    +    else:
    +        # 找到目标元素,返回其索引
    +        return m
    +
    +def binary_search(nums: list[int], target: int) -> int:
    +    """二分查找"""
    +    n = len(nums)
    +    # 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1)
    +
    +
    +
    +
    binary_search_recur.cpp
    /* 二分查找:问题 f(i, j) */
    +int dfs(vector<int> &nums, int target, int i, int j) {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1;
    +    }
    +    // 计算中点索引 m
    +    int m = (i + j) / 2;
    +    if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j);
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +int binarySearch(vector<int> &nums, int target) {
    +    int n = nums.size();
    +    // 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.java
    /* 二分查找:问题 f(i, j) */
    +int dfs(int[] nums, int target, int i, int j) {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1;
    +    }
    +    // 计算中点索引 m
    +    int m = (i + j) / 2;
    +    if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j);
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +int binarySearch(int[] nums, int target) {
    +    int n = nums.length;
    +    // 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.cs
    /* 二分查找:问题 f(i, j) */
    +int DFS(int[] nums, int target, int i, int j) {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1;
    +    }
    +    // 计算中点索引 m
    +    int m = (i + j) / 2;
    +    if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        return DFS(nums, target, m + 1, j);
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        return DFS(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +int BinarySearch(int[] nums, int target) {
    +    int n = nums.Length;
    +    // 求解问题 f(0, n-1)
    +    return DFS(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.go
    /* 二分查找:问题 f(i, j) */
    +func dfs(nums []int, target, i, j int) int {
    +    // 如果区间为空,代表没有目标元素,则返回 -1
    +    if i > j {
    +        return -1
    +    }
    +    //    计算索引中点
    +    m := i + ((j - i) >> 1)
    +    //判断中点与目标元素大小
    +    if nums[m] < target {
    +        // 小于则递归右半数组
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m+1, j)
    +    } else if nums[m] > target {
    +        // 小于则递归左半数组
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m-1)
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m
    +    }
    +}
    +
    +/* 二分查找 */
    +func binarySearch(nums []int, target int) int {
    +    n := len(nums)
    +    return dfs(nums, target, 0, n-1)
    +}
    +
    +
    +
    +
    binary_search_recur.swift
    /* 二分查找:问题 f(i, j) */
    +func dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if i > j {
    +        return -1
    +    }
    +    // 计算中点索引 m
    +    let m = (i + j) / 2
    +    if nums[m] < target {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums: nums, target: target, i: m + 1, j: j)
    +    } else if nums[m] > target {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums: nums, target: target, i: i, j: m - 1)
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m
    +    }
    +}
    +
    +/* 二分查找 */
    +func binarySearch(nums: [Int], target: Int) -> Int {
    +    // 求解问题 f(0, n-1)
    +    dfs(nums: nums, target: target, i: nums.startIndex, j: nums.endIndex - 1)
    +}
    +
    +
    +
    +
    binary_search_recur.js
    /* 二分查找:问题 f(i, j) */
    +function dfs(nums, target, i, j) {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1;
    +    }
    +    // 计算中点索引 m
    +    const m = i + ((j - i) >> 1);
    +    if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j);
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +function binarySearch(nums, target) {
    +    const n = nums.length;
    +    // 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.ts
    /* 二分查找:问题 f(i, j) */
    +function dfs(nums: number[], target: number, i: number, j: number): number {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1;
    +    }
    +    // 计算中点索引 m
    +    const m = i + ((j - i) >> 1);
    +    if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j);
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +function binarySearch(nums: number[], target: number): number {
    +    const n = nums.length;
    +    // 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.dart
    /* 二分查找:问题 f(i, j) */
    +int dfs(List<int> nums, int target, int i, int j) {
    +  // 若区间为空,代表无目标元素,则返回 -1
    +  if (i > j) {
    +    return -1;
    +  }
    +  // 计算中点索引 m
    +  int m = (i + j) ~/ 2;
    +  if (nums[m] < target) {
    +    // 递归子问题 f(m+1, j)
    +    return dfs(nums, target, m + 1, j);
    +  } else if (nums[m] > target) {
    +    // 递归子问题 f(i, m-1)
    +    return dfs(nums, target, i, m - 1);
    +  } else {
    +    // 找到目标元素,返回其索引
    +    return m;
    +  }
    +}
    +
    +/* 二分查找 */
    +int binarySearch(List<int> nums, int target) {
    +  int n = nums.length;
    +  // 求解问题 f(0, n-1)
    +  return dfs(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.rs
    /* 二分查找:问题 f(i, j) */
    +fn dfs(nums: &[i32], target: i32, i: i32, j: i32) -> i32 {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if i > j {
    +        return -1;
    +    }
    +    let m: i32 = (i + j) / 2;
    +    if nums[m as usize] < target {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j);
    +    } else if nums[m as usize] > target {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +fn binary_search(nums: &[i32], target: i32) -> i32 {
    +    let n = nums.len() as i32;
    +    // 求解问题 f(0, n-1)
    +    dfs(nums, target, 0, n - 1)
    +}
    +
    +
    +
    +
    binary_search_recur.c
    /* 二分查找:问题 f(i, j) */
    +int dfs(int nums[], int target, int i, int j) {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1;
    +    }
    +    // 计算中点索引 m
    +    int m = (i + j) / 2;
    +    if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        return dfs(nums, target, m + 1, j);
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        return dfs(nums, target, i, m - 1);
    +    } else {
    +        // 找到目标元素,返回其索引
    +        return m;
    +    }
    +}
    +
    +/* 二分查找 */
    +int binarySearch(int nums[], int target, int numsSize) {
    +    int n = numsSize;
    +    // 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1);
    +}
    +
    +
    +
    +
    binary_search_recur.kt
    /* 二分查找:问题 f(i, j) */
    +fun dfs(
    +    nums: IntArray,
    +    target: Int,
    +    i: Int,
    +    j: Int
    +): Int {
    +    // 若区间为空,代表无目标元素,则返回 -1
    +    if (i > j) {
    +        return -1
    +    }
    +    // 计算中点索引 m
    +    val m = (i + j) / 2
    +    return if (nums[m] < target) {
    +        // 递归子问题 f(m+1, j)
    +        dfs(nums, target, m + 1, j)
    +    } else if (nums[m] > target) {
    +        // 递归子问题 f(i, m-1)
    +        dfs(nums, target, i, m - 1)
    +    } else {
    +        // 找到目标元素,返回其索引
    +        m
    +    }
    +}
    +
    +/* 二分查找 */
    +fun binarySearch(nums: IntArray, target: Int): Int {
    +    val n = nums.size
    +    // 求解问题 f(0, n-1)
    +    return dfs(nums, target, 0, n - 1)
    +}
    +
    +
    +
    +
    binary_search_recur.rb
    [class]{}-[func]{dfs}
    +
    +[class]{}-[func]{binary_search}
    +
    +
    +
    +
    binary_search_recur.zig
    [class]{}-[func]{dfs}
    +
    +[class]{}-[func]{binarySearch}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_division_pointers.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_division_pointers.png new file mode 100644 index 0000000000000000000000000000000000000000..51f02fa6109869d475ad6469f9c71688d8085021 GIT binary patch literal 15362 zcmd73Ra6~K@Gm-B*toj|2?PlNf?I+I2p$L?*d$mW5Ih9kNN|_n?m>e)8+Q%C-Q8U; z`TpnWtn+Z!xi7b0W_qTpx~jUSde*PH0#uY_urVkw006+2la+c004R^Q;9)e#c_&n`rl&NJ6?630RaKR!opRp2T@rYGm96^&CP-l{;8v9d2^F{ z@)+*@9o7wpx3_o1o_#}`*N!$eclY;W`#Z8qRJGVDCJv}|EtE*E} zQ`gtmOG`^*V`Ia^!*OwOFO&u@FE7*6(>ppk!o$MG$H$YBl4N9LT3cKH{P~lTk}@+h z)78}#6dW8K6;)AQ9upH&Q&ZF5-(Oc(cW`ikoJCeuRu&W%X7r~Q7Z>N|=BB2m#wR3* zi;M5=?PX+SEbcE%PEKZKW|owcWM^mp@bQ_Oo2#v@O)uR}N=&@Ex~gp1pP!!(4GsP9 z;lug)d1KdMdwcuu-@iY8{CIJ3(a_LfVPWz5_3N#zt)Zczqobp~zP_BC94RTOxV)|W z{QSts$j!~ojg5_?lUrwJ=lAd5zkBy?Wo4!G&rnNC%jwnC{L1C}`nq4j>gedGj*iaN z?X9b;Ye-0llcS@&y!^@4UDfP`va+&`-$Hs{S42d_&i>8l)R}MRv0LQw!R5ufjH#xk zCQnb#BP*ftovW_JLAd&;>i>J=t74J2y zE#0n6x%9Pt?QFX0EW4q5{T^(6lF>b5VM^>E#=y$DMwXa+@EL^&_9@TXm zT68ps#RUJ^+sPW-ncCj+2u++hIw%?2t65pF^qz|8Kz=FCJurG6KXj^7wx8C&t!X0qyPaYn*mlp}1!siOD_nQzy47~a0#vow#Kof6O-qV*lj9qhIL z(R)4A_}#bR*hka4V&!&oNiKOJF~8h6KT|g=`83+{&8I)%$wR+}`t=gp9m@;fLg~c; zK%h-dN?hG(dbh>%@yh@ZX?OXg`QU%I|91_3z9{w|W%olRzWSqo{9m>ouLSV^<8$m` z3H`t1@sG@KDAb11-;f!DeUh+wNra8V6Qu~v( zOB(E{xW?qcePw|<`d$z?=c+xP$dA2#3DrS^=*IujqZYY~MLNMCx?8{8R}U1yx**Sx z!knT^BD|WI0<-*!vi%!WDBsHh54BWs6dw-9eX`03T8!31<+ZR*&+CLxd+$bH@KdbT z-}ImS63J0bPEb)YN^pfg1j%9DTqke zMFHfnl~84LF;Z!bAEOS${8{gnwg_M_lXg0g^}{gd)A-J^j~aNkJ}M{L%UF=TrbQN9hjpY~)N$bF}-;Z`cj zc7R+vu#SW|yaHxIFUSy)>voL5%%79cn~54P*#u?zT;ma%ChAYX+l1j5z_l6mTn3^t z>O;_-@KCw2{{j;*kdEQWgO=@MDZ|pTt_n35gGimK!14)0*dQk#Wr)i4#{+%G1hh8J zP*L^Nw9Xz`1>LtrVsz(3n6Fe=U;KonlTrG&4~x;irMLOS<4gAQO9TE&rxW^{Z|orf zu}dhM(+7!4KYn^Ar$1S4Xog~ZUQm>KxNB1K3w#(t2i;z-JM1Xnsm-HKc8coM;LN=F zd_*y=r_H7=V}tygKF%9;HcgC1caP81fP2VzICy({Pkg8_2>m=kD+uco>0zm;jb-e+ zWSN8;13$aQ_4-EJ4Xf#Vtcx!|t~X#s4$09s;B~HZePe<{x)iw;lWjO-BS-gpIeD|6N*jygrVEqUqNB&91=&fYfUVH z_HC91#ik3u8lr~2euj9i0bE!)jAjRg$M~&Md?^rxI8p0(x zm=^=FcncS&Tf|y0R$;QIf>xhofRik$TfF73!yum_>MOtDpNE5k3~#nA*Lk)(v&W6Gq|7lD02<^UJuv?_~;}0(}B+J+}+{Q z5@s5lMWDyLBlfg@D2r>%aD4|PuXsL2PS6Bo}nu5XsiyYKo7 zMF{<$uz{$pywWclYJm!{03XSt1*mET_=?{5jGdmc*4`l5lioc&Q7i1wdZ7ivigX1p zvhKw!Qjkl2BiT(hxERufo#$UWY`{V9qw7X-`6c&FNsI{Dl=|#-kccP8v)a~7Up*a$ zpR~QB?bDd#n#6@~Zdf2xpCh~(Hb4(gxqg3Cp4)W>2|$on3kvnFot}MWLJJd(C)V7n z&L$dsEz1@C>)#vaxI`L2ulW#dMvjmB)rrx-wVPQITa3jw9njdQSk`x!I~RPNkityi zBDd5bbe?1zsG^$^av*#s9tAy3pa|inFLPmm-d4}lVi}PRKlH_cb3UQ5K(Y32_yGa6 z&n2Fy?0-?qmtyKU?X-2Z%XnNAPZ&8QgCW;9t?(c+q8QgxjN4TyZkRpAW|g4g{x#EJ z%Ru-Hxtl54ND#Pn_uR(F=?n#F0%RfsacDVhzc!koSQ~}SimAz=4*%>gW2yg8AFi+P zhX3jBqoRPzURG@_7S-=wMos#9&jh!b5xzt5h(GtAW2sH#gda_4Wx{~S;QwXNMET)W z4we@GO^O>%*eFP$)4s$P0jo?z;`E3E9kXLZJ&cpwcwk`w+k1!pgP_Wr`(#yT4$j}Sq#&wb)>i?3B^pm?Nv_Z#wcGb|ISsdI8_Y8}AVmZP-C| zxj3GdBI>ZY)m(+M;@E`8U+2-&dj(?d;sp z>{M8O$!&p6Aqy}fmT5RA@GVn>r^!$BIM8OQQbjM)Chfe;UP#F^APB@pK!e|7H4JZU zO_7|z)-@?j){~`{msckbEhZTb&wNZ?7KYm?MF=fV5xT zGWGf`bes%EF=^K&UcWTSJoazK3~t_r!4p5)HzAggDoaYc5@?&%y=&uskYr1mC<6Bv zcWUa8`tt^WUHf)vMeA2L2KliQA=FC|jyT-}El*`(IgMIe?gz9Ke31`M{c+xa|uxyA#pi0_!?&iynl8-Bn zHFJLwi~3EHa}x)S#jGe22GV@K4N3yTa&q1vDx3jK#FW7%DxM+Kx&p9<2+SP>f~y%2 z65ef!2HOG>6??Q$?{(mHK;th_R8jD+UXUxS!Kn(~a>-dLC5X^|uH!-PhBo^S7tV|u z*AHAPf$-7O(B^sR>&9EnRnVT@Nrub8-v}aD7K<*(H9eq%v*%A#PJ#jO+{6JdF|z)< z6d{2aeuJBo-$>TqeH@jROi_d~ASsCWg#2@Dilfz=0%kH~9Ha5PG54!k2gjjY8)2|{ zeVd(=pDk>AI8uWCJVzOJfu^YAz-O`H1Au-h#Eia&!i$Fz$LznS)#x0E zk<1?T(CsfXh;UnNu^O3sy>W>Ls{sWA7t{D+sLb6Lfb`)w!Q7_!iR1l-Fn-M`YH4tS z4DJ}@l89{ZuL&Io@-^sLq*xv`XcxvsAl8DM@*4I^p_HPeBjZ6m>`7ZAQ4vIR@Ng0s zn0r0o9A*nc$7zsVV%4)y{Fa%&#|~A}Qm95uVDI~Hh?rm43e3>qC`w!$IMpBK}iDp0Eq^o$o~ss}h3 zfAFxbA(to`KS+^!6miRJl4u?9H~$9Kf5!@W^yfuKLd!}ot=wjDM|w^(Eco}iKb&>8JUcRB?Qre!TQR-_G)@+1_LCb zZl#EbufYylbcD=OdIw_=GFz%#n!G!~UNks?6BCHYQ&`geb(%qbttBqhI|pd0UWzv? zY@?tNALyborQ4RcwKjN#kh>)Lg*pt_{?5 z{5Uz+IlPuoIkTQ1tuAx^LYzc#Wx&kf>M%17@b3hFcJbS}U&1#IxZSti$ElkzdCqMJz3|u@10(m3B2(&S!mj_oYev|gNR;Su;r^8sOd(aEh_l1VNP*X7Fn6eMgBPwsbmw8 zXRmBDRzKbS6BQuoB0kz;<+=K-Vjrt=?;|f_#CFYwW}E-#zcAPLN^@HSI>3{oZVR+T zGE%QEScX3z);Fz)pj7`UmypmFVfGBT1pZiGv^$CvAdAFJ88a1ogjuCt9)-d$Y zJznWeOty6BLlT2@P8mI9Oxs6$}fueyxjrxMIGboLCs&ObyHB-sl3(f?HNOEf?`C(#)CD}le8GA~;2Fv5rt>uSSF#Rh`48dn zTUV?h9y=hVcAYnH%^c{XqvgBHBIt7)gC4SA&K(MfXjcDL1cccjlOXPsvCi)&iS>Nb zOJ5`IDA3bN`P0Xq@_gX2=Ena8^68WQli$h}{KS@brKcRAHD}-Ee9Qk4ED-n$+iDzk zh&iVq?HTq@$VF)yP{SemGYnzh8+W;6<1q zmfdUw7f8hK7x=v;5G2CmT=Uxv82LOSTGUtPF-^Y1HpOvV`KV!G(Q{sJlFPhk=N~{m zj8kHe&z^Oki~Kbngi|53g}cj=2g=#?=nU(;hAWLFK+X&a+zrbMl3TQhWT8AP@4iUr zsp9b|P4XJX`14lrsn{>jE|VXHaLfvQXjV75(|O!iEOZmcR*a0G_*pOs(+f}xW3bs)#vg(ZVbhNxP=1C8PF2J zSX}~M0yp2Msj1$bK2I~XdJeS=q(WKNwSUbA;}jmc<#KKc53N;5N(JK$UQD5u?l+ZW zW}d8GJLpLjoov**r@L=(q-nU^#7AY0xsx=JTp2|D#1u1pg_15k-Wd}}&sjF+_%_Rq zeA+uwzFJ+!^C-#QjfqSkYeN>)l^0vCcD0|t0*j3T8{xHeA zU3LAKb**4NboM$)uV8NS_?f_qYIn>nzVA=*NMMm~L(+|Z629%gBZ`p>$Ng4(%d?e! zf7m8~<8aYjOVFZR_@U8x_tUEp;RBD8(Ok>phx=s%*}i&2DYsD$ZAEX~yeKC(J}chz7fEn`;w*O`qsjP zewUt%Jwln*2Mw*B1?}FHzK{;Djss;)M+5CBxl!2c^Hcve&im$u*m*GFN5ViW9CSIe z->R6564)=^zJhLNPfC8K8Z!@+HnNM{)EvS+-glHp1i6TqKOoL~415fgdxT_|F*oCNSczKgyXn3e*< z8^XUbdqh1On39rJ{Q1MI_m|vGm{~=d=~!LJw3O_?o~3`zF9gGvs(0bN>)`Pn{SOY3 zJnvB$;N`?V>KfID2+9pBiT@s~WREg9YW~*W8LR#C(_lsQNR#8^gnO%o8$sWV6LNB` z(>+8JrM>XX@VeT!gg7L-Z}7^f-L4f$!d`u7(ZEV;LOLpky-@H4H+!n;^e^7Kp%`cP z5SfnOU!^Q{g$h^f_kU)^j+#o!-dNRC^V{G2<0iFRUlDG9WHJHXzP+qr;}GG8R@iNn zwb0sq6Mm%q8>fs+i_kA9y=Ae~7LXCTDQbdn>SMrTjfzj=^^|Qac z*`9PsJ5#;31yhvAwkw(cm$xEKQ}VWGAh(;9xFsOEz*UZAXvSo^8!1bbxx4Dh0;@C6C0Bo(Ul zEx+PTV*L36UstoD);H?daF;B-@hJI#%1 zlf+x{La!%(n9^S4xmQ^Vh7uNg{Up8*qU!o+Da)wEHkc0|p(=amz(JB6m$y|;9r{^|FL42QVF1hIrH z8e_6p*FB3zi+uQ@{$!ber={(dkl{(ZLc0Qa@CvXddsg(^6uVJQ_tNeC;am;^E z{w7OzFqLzMASQ}{z%cfYM!rFXXS5tVAgvLb4t^)ciUEgGgsg~PgX9M>!H ziR1c*lGtB!se1vIn^$rL9|S$Np>;j8FyZ@anJcw2v(d#NlxM58r1>0EqKP_Hup_jw zksXvnZ01!Gl2TN4rIlY)?Krek2$Xvr-W-W3!V1*;(7gUCvOR}rQQkfb-zz?Wmwr`^ zTi2QS`>GcBHoRkM&MxRg&(3L=l~m#au8h-GS{hxH=|Q{m0YQl0zIU0om9>ay9w9y? z%5A;kyq8k~IPWVQ<9F$Ma^!xI0Ezux5EQSI_E_^#-@B;dsc`ud0-c`pw2|vvRk0>a zC9y4d9>@Mz-g81kmi0lfUL)`tyW|>!II4ITR`xV3abh4Bcr(~a&~76(pDJ{=ecjdd zZLqQK`f^*b5m-Mz#^{b_I2#(HCuD}l@pkdqPvVerk}Lm7x3tL}UzDINe{<$n>=jemEecx1;k=;UPFlA*RA*HYPi_-!$OXeqLQ&I z25kpkuRIKZSHB^$W1!h!84IwMgBk~-+(v{`BbKsVAz_-~!x-yNL%+Kfu;cj7W3s3| zns0#R4sh0dWzL6qB~a-I5n2E0agTGU&w+@-zk0=~_6mT8kxRxYj+EW24p;nWSxsDI zNXn}CtgwX|{>6d|@!`9k79mo1f;-+~L+Q$63&omw8GtK%hwLW29PXSPMMdbtR!G7% z#YTGoCEYcaMbHE1J7I*NhbvQthky_mH1ECPT16p z231Tj=(vn@R61|p`M&f2!7>$&BHRI!XTzeDV}1ZIe}^}^99-$w?z;^Ry-KlDOr2;| z-fzStIY>D;5!uKPvW=Avz>-H!_Cj}swPO)Uo^}|Ei8=F??&IeEs@(E=6Ul;hwJ#B2 zDkE;=Z0dU)ZswL(YTQg2_wVgzHgRsZfRsp}$!~L~j!A6H2^^{zfJq}-`)#+3%byW( zrHITO(yMbho!+WoOdA4pPN(sZCi9hJMbiNXd%w`($#+(Njd-|5lWUji0eALS*zeF6 znRpIwCA%VV4+_p^mx@8Ejj}&-&@XK%S(WDbQHDFQc5`Pvwckl;A7PlnbzJ-AYEVTj zX7V>Ul&K{?j_Q9iRmLM9L_Gc5t+qJ)Cs)%miiO*n#k*D!8H;G$m#+u0tzs!O;?}h} z(|Icu%u?%$kByNZDlVQYX73vS8Mh{jV)WzP@yk^^*)$V~%+N;^@$hBbZ+*&d zg%DLp`gibam`Hf4Whd}fy!>P|1uW<`%QEA8!opqJ)wOg_I_LK^3jg*AnYj?+0zvs} zweTvOp>?MVC#aHv8(W`i&Gb}#x5g}~_-7JaQulrC`R z#>{5_?y><@R%%MN`5oBl1gzpzVB3ghiL;pFHp#Rjs_*lRKH@~$%;suph2HusnV`s> zpq&GVCD9Nu0s^|L1g5$yHt*j@iwG7RW2WscqIA~1|L_te+`v~%Y6_AU3~F%2@!OYv zyK0B|=KfQkBV_Z01Pec4Jjsj7#Zepmgj^Q7ddH@BO^$}^8PI)?#de&C_+tuh;l`sU z@K6UnrQHVoAQyOraK-WQmwL@@O;YwF?gXpfVpu9VmU*g|yW0*-;=Ya5j~?fLOjuCC z2v0FZ(p&e-izy+cq6@lfFykJ;oNnmdD75%@i^|&IUhptj8*H*gLyC|(m2Z6{xW^Q$ z?IpDa$x6Lo`lj8Ab*F~MhvW5%{n1z*M(C5PcvPS~b(M;Hs&>fYzfl^4;%N!AGz5>= z1XlR5`+1oE7b4Ct=9HX#SjZw_beu~fPW&nSz8rluO2o@umdYWE90Z8}(O6cX6_arf zI(Rdp>4f|C?Zf4($7S~;dhu>AknKX*se}qw^bvMvI;e-y(^2|m9DC$ijL9jKVVHk|BU~YL!kN$C z{|h>!oxjHyI8jHWC~<33D}9kLAP0KIW1dFCa253k5|I_Tc=~r+fmgCT4aua}PNmat z16Dau?<$@&P~^$ciVU6H*t7$g^MKY33 zp**D;c$c;?HVv$CXQ;n_A(P4vMjNbl8!BH_2dqIE+@h{?-@MS~rj74Cla$bu)LT`= z0oG`p2S`dvqr*_$1N7{TKJ3d#9j3XHe&*9~ogjIdM1Y=tr#0afl1z|d-kODUY!?K} z;}_rg9V9Mwda+%nu+yYnjf1*W!s~ppE{^@6W7j#f>3wjztK()o=2bf_ZPWgG-$Aa-XnqTW7h5R&9r~KNYZ+29tN^nz<3)@|Q z(l(o~d67%cL47Q$+Z<@FE;{BupTvRXrgwhsj)Az#hU&q{ZM^N{It6{WZ~OA+$YTa{ zjAA@pqBV>hU7f@+MGK1$P9r}G*mqL%g2o*zEG!)sQvc!(s^XPjCNm3Mxy`9(9wg~E zTnHz%O<*9HFM=e|44Jgcph1ICHl$yEaU*gs2`R1hp9)?DyVN|ww70ko3`~aa!xh@} z-*Dv+#rMXsqN3ta8rqI1`l{t<08yW)pV9i1MxfXd{tSs|0P7wdF^RkZs!JSgL1auP z7d@;B&+9=+5|RnCK6tI}DUq&dJIAYBU)D51dT;X9dZO&iD0)QOP$EHu!r(ZDk`}M! z+uPr5U)+n)=&o6n$L~eb9G9Qg#;X$;(dLVo;nL0!>rMV1{5c4)>k5OO>|c|w(@No< z9uPQASxtDnj*Qyl7ayb{L*}8zvGL3{DYFM3*oMV{`lDljcxFnCk)n?)X!bSAVjY5V zX`3aq@%tT$M3h$!K;wMZ$g0nUbDYuVzfSK16e0r5`Xb4ZFZS1@W7l!q?j7B+j@9to z%B8GoosY;uLa4})yk#&a_K4>_oIQoOy%qRKt_v+x>!?CU*zgbb{7mH?yM<=EoKM2T zd7qq|HosAYs#XZ+JL=tr>L5S`lGofOAUY|7I2VtaubXIlhkA;Z@gb zp0{so)r+5zVRIfK(H7|ixz&m^lq2*sJjP}9rM|5@UgvI4#GHeLeCt-lf&$-ZhPL&F zpT%E&I>F1}U_V{W{9H=FPn2L;I9?t#%d&OUL5s7+~wfqYy9c=8w279MIy7P^V3q`M;*1P8j; zEo3@qs8vk|JHr9*RYJ$S7ALxDQN&Y*p+t_2ffM_*9VU2S=e91jY5$JF3mm(?>QKT` zE+dDWM|9CmH9u;9{)KuaCQXl?j$F8BMcHQ(Ymt;W?^vY%ENM#@*Ybku$Uz9KSkSicFuMS$;J7 zt)FVvjBd-J#au`s?&6cf6K~;b2`d8XzAZpbqju`URD}3@tUHo)E(<^+MQ(sP6-k{v z)wu7eDFdQ4!P9wXFeOoS0I2#}MgAER9?8c0u!kN#rMGph1W4Yy2@00@u9Jm(~SrT$V7RcN|#1Kk$(2)|2Zr zM?b6nAQplJc8_GijsE+>R_{4N#sNfDMu2=;2e*{ALnO}+wdGpiI> z+FYn=3`&v>`a;CIftM3q-kzwj5;4SFA9~(>50))Us+F^~Jp>CdfQUXe7uqb6r-emt zZn^=f5mbuV4a3f=;F)s27yU5S4daikZ4L-`-@JCqp2lXzy4S8H8myR=ySTN(P3ad?I zkj3lWIJpl#%R$k0*%B3aY-@IvU(jljlpz-<>^%KH|HQ|;{12^&`Kyzcv_U8jjqk%Y z=%;4|{a~?uw?RF%o~d@%!{Yz2=c?fw=|Mt<1Mz<;v5&(c5vLi|B;8c)G_b?IzKw=%BqrPj8;`kwx7qO}c+#VX0O)-T*_iuRQZbhs8XSx|SP@cyd_zJS~9|X^jo0Lr)v_d^wY|1s<}>h{r=m zJ>(rWbvwa`Lt-z=KxsN?kjqtpsvQkL=Ox133MlYQwk6gwGh`fzr!H*+XPo7i2lp<^ z0*RkE-0D4TO@KeMWUC)glz0%rAR2x|Hs>@WLIPFTHb4nUGFAQVGkHu;Kr9m5iA)$m zwG8Dfs{9iY^fehBPWtdlOjPCh1qkCsKch~H=fbT=Umn{aw3NenogcbRzGxYj@J5&b z>5S}X#Ggh{e^eIdd>!ut2=a~G0bMEsbh`+fkL3aSF91{yFdCmAJ~D-(rXUXV1*&(< z;6E(EIN}ItzDkW%CEsnrucO3=O=^0IhT*o7m5L(vvXNx_nbwsEWiYcn=hS@IOaAfP zMJ`sqxvD}{xFSCR3~C~+`YyIx2j*cye_-<>Aa<@4X#U~N-I-YY!UEYh-~+Jj zMxq4Bdp`L$&sOtZTIi{F=VS=D4hqW!5y-iHmj>z0YVQ`=dmU#%eu=OS+$ARnnOJZT zKJuF4^54=Y28<&eWdfKnb*6L1Sf0jLJuhhlQ9YqhG9vJxEz(?&yH&|lSjME5a#RUx zbMN!7l2EQLw(=YVMGryoy*%r^ozc$Af2vj+GW?eo`;{OUz2ZrzfnP)!(UUT+-16Mec$)Ds)r3KRF-l zlj)Ml(bN3f7f~}P{R8XB&v-wYMghe&Adx~ohi)4;Efh|_s&BXRG|2bG3y!>(KQZ7d zhKFG-r@PoWsA45bKu9qhYZGhh-)Wl3cXNMG=Ui0O{73OKw(<0541|@0V24;IEO{%T z4H$6#X$pmVfc^NZATg30io5ta1i;xvHvia6CE6Fy1r(p$=V+T) zpNEJDP|)xbB&8VXDZUH&qcO_tFW5I9LYK2X0VAh_g1!_Y)h`iUaWb<)&LBNF`<)u_ zJV1(ZQ}XcjB=|M-0vkZP7O@aFm38U7(s*Q~yc*Xe_E#i>TW*6R^0|g6(X1dstzVG# zB%-{J5^|Z=U+G7tXFT}J^5b_5q~|nU5%B8;Jls3nomo7^%OxEukjk0PoyGfcSxfye`!g{H^AN3(2AO|&1*3HUO_xm zOseK>mO?gO@~NC{`kc~Q6moK3?dEia;Tk0QJ*zyE zBXYc`H*maP#TLV_60}Vc@$)yBdIiT>1}(Mq=<%S&_n&+rpHYV z1WHfc2b5w*7MNW!O0{Y=#q&poF^>{;|M$?$g+b5KUPz0OzW!H-QMM?sCk zZnM6zi-?x+}n{(&$S{A@YNI(3o^NWv=ivC;2PUV_CB zbJ+D}L)XoLUcc|RCkiLdi@<6cK^|}W~Gty z>d7pvlmqzmZJGcqx5z-h*u^*DYOdp`!<(44pP-LP(&(u9@wEc288XWc?}@AAp1H`A z;M7w$PKzQ~^n6&9G-SPy+RwUSozndM$`SnbWBMi{S6}xEfDoX~qv~04^zU8y>il&Q zA$zr>(-D265`>~IghW8ikkNlQzis~y)oIF2*p0K5*b6E+9Ndy?_;V618GAt`ks=H= zGqg(>i#6uOx7YRe9YP6w>AWn{d6@=UQzWmIVi7z#Y=vx{1n$ z7A`K&MJ%sp#o@vXT1Tj5R~C& z@HMGeAp%%@{IM3WEksCz?a@oYU?kHgJ_3^ij67*@4Ivo@9xxjmFFVx?)(HUap@H0- zfVvP!nJH@Lw)$n^Jo=?o8E5@l1~CvAky;jR-8!&}IWkda3Rg6cc*r6BCIEqm+0+sq z_K>R<1C@!@xTvy>m!=CsQap;!kgpzj34k7Gdr9Dh>;-P9w--N~?7;I-D8S#7gb1-R z{qqH+a{;at^?mj9I$nwPQiuwO=0FCCPPj(A5W5NnHwa}K@b^HO#QAEDYgqpi=Ue6Y24+!dGNFV(~10zvfH2ikoMe8|4R&t* z(ZqqKp`1U;7amHvsrfos=PRTd$>LoG^AjHr z;gi_qsMA3|uA1_T0<0<&S-E6(Hsmd7deIWWX?y@?4O((J@NmuAc#;bk_)fqz5zIHz zn>|h<^CVMbVX4L2$+VfTS9P}v?~LW70ZBbz!Y;9yYu zgn`%3Tq5{6I4QJ=q~qz-mNBSz&31otPgUCrJv{Pj4eBS`UB?t%&X;1AUNbJX9fDRZ ztL(^);~Zv_3 zjx8{RL-iY^h5(Vm@y>FA6;z3mQs7E#(}4xK1D1L<eV~&=4ZlZvV^Lj0(o#v>`dw6D6qs zH7EE9E@JA97!1j7rH*oGY(a~1nO=C9i{nw`4jmH!imjmPFl1Ci9>w9xhtF%bgAITO zNyl>xJPWzx0D~!j4B~GJC>T|IKfK@00n9oCIi|B8^jZOG0%iy;f`Ks3K?}iah`>Ro zdhDu|Gg5M%$1q}-+Jjd;}L> zIjl#iah95cTPg)!1MtLHDQI@tO^$Nypk|4Pdq`;@Yz*Ztwiy(24+)Rc$c$mv^XOPU z(hUWQ2*@@(fYD={Ivo{{`Ckv-B9G3g4%!q20<_s^Eeb_VBW19LlW3uf_cREsvA?|G zS6Uw0$_pP6*HAj3%LB+@!(L@nd0&2*9RFB>RM4ydQj!(B19dBYNMn6Cd{6rQYG@G* zXnopV=eaC*a4s=tFHJZn*9QQL{(@S<&_#1>4ggV^IC{fRrVmi{{O8! z2^R>CCqX%<#Yen_29Y(egNgyRZC=b5F z>Uf}GtuNBAeJ68q(nP!Dvq5VtME0*B@_%m#1KPN1$FKD|MI`LOA$`Chf8c4$zGYA* zn6$Ig7`UXY1=+ttVZWWNS!w3<1@6(lmsKmpvB}U;U@aCFCJcQDjD4@h_6+qfdsj)= zZk~9+BI{`rTgo~VfxyIIk$o%@JquQc*O$WN{sJF(fMER;W%fbG)a0`?;N zq~}LWuwh|yZ9U~itJd*=d04X8-#V4`+Onu$QyS(sYHXI-?_*@vQ)fwI_fk`8go!kD8|^x}<-aX0fkU#Cai*>4 zzemiMZ3jSes8+FkvnUG>z{_V`$EblC*>Qx3pJwGYK60rqg*gN zWE)RM-RJQ&6Z&9O>w?6M0FWLFA7+ep+}!T&ho_7iOTZh}8TCH#+SqL)>Te$bkjU(s z6EnMU8I@lEC}~S=2Av6Jo&RG>W}vY8FI&}sHLyp|f}YzO@s9g~>NN;_iITG8T;=|1 zq$8>Lp*#Hpq(3*+GIVvLn z&KEVh1a$U%zoE1E$ceQ;o_r>S&)7r^S2JYEW?hyB{VTc5*Y5LNnz=I1=h|iNi^A(&qEesqLpTl2T*N zjV~}x0(DsD>_pb8w5Jjt1xRd9xkF+$9#mUU_)34dn14}6GvqK@&A!L`ZEflKt;O05 zI&l9|+6`k`K^}s5P*llRI|kt*J-RWc!-W4&PWZn&<-dMY1*+eF-;39M^Z5_-{~2Ne XDq+2m5^@h(`PY||R+1`~fP4Kv_x^Kg literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_example.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/build_tree_example.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac06bb5a13214b1af418807e6d236a94f1bb58b GIT binary patch literal 13759 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

    Ks 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_overall.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_overall.png new file mode 100644 index 0000000000000000000000000000000000000000..d68b38b075ce20b2b4c9b3ef802e59a792504109 GIT binary patch literal 25815 zcmbTcWn5HW*fzRnn4!D7Q;|kOx`-K9i^qAjE7B)4FCY1s)~X(0Kgv}p%a*B54Ve=Csq$H zs#?!qDc;}T&&|yRw+3mq)i{Q&$b8<3ii)bKsX;Cx3r7l2`zwF{{=L1u?ds|}IXzij zUH!5&cYSkRS6A29*Vp*%;OEbu-@bioX=#a#jU5^qN=ZqntgM`vn3$cNO-xK28ylON znrdih7#SHE7#PT#I$d91Z)gec*kB|TO@nd&)_rHJt3JVKMN=gDp z`eI^Ya&mI^_V)7f@=}U7zkK;}d3A|Gp?>b~PESwI&(DAQ^y%XAVt9D?>h^YHW23jX zx2&wJxw+Z7{jj2ipt-VPU~3Y{etycY1odQD;L@QPINh^MIt) zrlzKjfy3qH<%{dPvzu$RvfY#O+wtA)<+Y26*;52+aqH})v|(4Tqb{ufU(Dcf|Ms8k zitV1w^@4(ep{Zlk@zMVNetPNF!RgJ!_SM?j+S1aJU2og=?p1B){@K~tr@5)5=~0Ki zj?B!=^?x^Oo0k^#`wffd@%bBh^V1)Hj_+TbyF{Y0va-Co4mB%w3v2$$m+t(#x=I~6 znLphB{&%xzVdmTF#nRECfA>*L&Y$|#rQL(;qoX4;WK%{)MrG@s^FUWbNBG>{^~};) z)%;n{=s)Ay{h^J^zvri&8>>;1-{ZUE-nATrW~{fZ|DM_U={5ANX{NFIN7cg4Lg`p( z${Tl)@8yBatDZH}#v1=j_) zuUt%QOpL4zM`VO&mTi?Zl$atL!%9N&0$!2>z#COn1=&~LzjnKW9s&&j^KZ*2%Ao%} z{@-2ZXDFHf@f^HwAbO?ye|?25i9dx>h6hn@=&;@1p_RVS_6BGugO&e(Rhd7|EIWR2 z4!ziFjetR&bcBb*&05I_FK$=xPW|TUERDk~7^4eW=98pe@wCI77++vtr3%eMaLn)b zX2H-GvM21Ri#pPAsT<#eX9sd|0aH~(guwV)eXgg?O&&RC^)^MV+&=o1Pv`ur$4`&j zA&_Q%%=F?dEQgf*(_CxCJxP+yqvK68-$Ur!>G`giYF6R-c*AmCc{XQ&Swglnkqlr7 zsB4?}-k(5cDt^7W_C?)fnn55Lr{`KznV+n@@@#YZ&WsKvAg~F^J1Cc`{s~6DeF4QU zVf_{5&4P{(0st)*iWUd;3y1CXn`<`TTmb4#V2+LM91Z8gz#+>akpax$TAL8uLpep* z`Q$N-5P-k{C??7_03Wrd1l-RzwXLLm69w1IM5HO`$*ipjBjUISLK$>E7q-Su4ex@%ijF=X>;A@YwB12 z(Z?csbjZB)GpPfWuDh#I5s*axN?B<}>JZPoAj2=O!{kf8T}WRe)5-!x(?`i^;E`|} zZQ9SD=+5~e$tR#0Fd!(pT^O?6()@)ZoxRWIU8dF2l^ z5V{POTnewypY*gwUSJ?9@WO>awNV~j^a-&QG0$cCXCQ?Xq+Rpw_4WvFo<2&h{8{c$ z;t>v`@lA525NIp7jv)-H{S0kI*<3GLeU%EXdxVLPupMggmYf-CwX5|~4V_5Cdvb)c zbAYPHkR^<&Sneo1N^N^@O{ginn~RHTm+u%#`*R~=%(h@Ig~lrhy&#neqgeTE2QNo9 z@r4AIQ+u-Oy8tl=1O1?nU-9_oIW(|29C`J=2Zry;9I4D7(E|gJT}?!C-6v@<_&XMh)u|# zT1ANu^J6`3BWC+=d8;C$@upb759V{?4Re7TD>;=CZ7)?ArpfTWAHRTo})&0P7vVl$ANG2|73X}U6 zVc<`R22A2XYUd`ijQ;=!oS$!+=&Pb3`;QQey9N$bEQf6`CXqCuw&)c zVlcq3oEeYs6ZbEYvVo}9f$y5ECD4piul>y8-co{18svL4rw`^P$G2Hy*|VnfzNk=ryx*I91k9zHk=4sb(ZcnD+(4 zJG2ny@}xLlDBdV5z#qS9A?(T;Vr|9ns5_`=ds91puu3aI<#uVyZk-H6q-3wN^*wr7 zk&xP9c^jp~>ZQs)Y@rGa=u{ZZHNOJ}?k+UfzW9m<0+r>Yt)sqV`!3E0rib2=J`@>{ z#qG%}`>-^)bEUFK8Vd-#PJ%fnX5ZS^*v!2)F4S~wuQonY2hvsMi>Q%NKZgVGFc2yQ z5wU>YW{`fyC#Ky`>dQ@XJJ5@yEfo?Gc|Iks$_7Hi$Da=^EI@L&bB*zheNEc0hWBqW zQ%NH2>QhC^A+d2OlI0?@N`rxM7>5%jmeO5-z72+RoANT29`OF&liZL3Nk;SbHrfV0 zLHQ)GfJ~|qYhn?IH&GC>Or||Cs$u_LW^uA{lC7-p*`>Bz`SYc#z%4bh%5@R;&sUWO zsi+;#S{TwnjfpzCR%nZ-TaYb?S=>YL82^jZaD6I|xc$^tJ@E}#W^P@`-b2LBxE!VO z_iMoAnS*^8WdzYU|4c`vtScnQ?dYkCxfl}EwpOQFZfep{@&;n4`!t$eL~xOci&j<} zi@jG7sHon3=8_$YrqWZKz2sDziYA^NPlYUhbqZ1-o4NzBubYC%kl&39B{wTMDhhSa z_7<8lId59h_!p&MFEq1=WS*V>_%*?sDhGvR(IA)FKGU{&zjBS@or-$1L{5o+6JB;tUv9`2jHH4i4vL?+K1ia`#p9}Dgx*MTcs`Rz{cF1;O ztGxM9{LbF{y#J~Eoae2OVk2oLO(D7h22ak;Dm@bWF=)RPkx&6RE~#8oLe@79&SOBs zmzY>EI~%|#{sYCuXq(O-&D|$QE2h5JX78guZ2VerimFbz(cL-sL({$Z1TZ>59L^J% zsdBQU)%#Lp775X105>ujmQan+yw9Xb{Q{Jz1H1#V5K%(p2SOP#{TEU0o~d#WNG&#` zVoCZ53>!1i7Sp`)j_QeMJyX~Y2+W59cm2J$B*vVKGJ5mWsdQ+~$R{A#fSj%&e>Q{6 zz}-A_^(`gH?TT+c`2-BIEbwnS>fG7h!O+5a|KZ_k{=8*0&c{R2} zUG^-YeF=^HAWlvwA_vqe3Fl?#O7jp!OqQylg~aV8?sxQ(yjgSn!h zpb0z3qk{w&qc?PVHwnC?JJfQ@xi;@!qwC0kxM~~nih=hP;F5IUWZHtv>&|26yNeT` zl^1;S0^KVZA~1kyaRJX(m4@Bi9c{YXFZN&Wmo~YqX#$tH`yqhU#5g1Aju66_M_XCe z7mb1&6JHA>Fh@oAkyOpV!f$(O@s2Oj5L~}-E=CzYyYi;XICB$7FDYTZ$rnEC_eV(# zmh~zLsX4uGCsCw?5ZE9i+pma1Qug=o8(GPKJLBzoF2)%o@VYpa{IaxxUm>m%Jm5^I z(8pv1)|1G;&R}0qO(t)enJItlrKSX2Ij!OT1O9h}cfP+T?O&o1?W3W|=(+4eq&a*; zh53MWd=4fH=2om4jk|F7TQG1g~7m^Ne}uE zQ?&vLZ>&br4-^+NOl$Wtk`BVU{ykarKO;U7y}ZcowNJM@9w+MAwnUGW&)DP?>$Z zem%^Cs7@3$qf9Pk(ZZ^U`R6-vkT=rwfkiBM$^0+I;p7hr>1EiYHz75nbUop(`krUT zN@d01K7pJU$5o;97UF~3Av>l_;1^HdFte~4O@e%)4<`;-eXU&-n2a)}p{k6J4G{V2 zUm5f9qyM;WzUpK4Sl53P_NwzhyuILv%T0#G{d?dS8`adV(gcMkp#aqC1#u{vMqW#C z=1qc~xPR-c7yZ7}GNy&LNa##q8o^c4mltbXlwgG_`;(yIh_NMUmR;q%Kh}pi5p4;x z4bTi)fkOUhQb#D7l{%%&f^-$y?%iv_6d9LF7rOs&a%$15Xk;ot$Ul}`0*~KCTDDTr zq!-2!&*E)ih{@`27V>uB2+=nU;1c=_V)a;jbRvzyfA;tOT39}LMGzU4F%&jPxe4$% zbf4NM^oEi8k9(#ja`` zgG>zD_Cv{);~lZpprUt&UtR+Y{J7>pL7_*kq!$!2&l0yW?S_QSnaCN6fJaCc_E!bC z89X9p44BAsqKRaPR-~c|w0Q!P6D^;R0FH%{Z1=n5rUJseDKE&89exavfbV%NEbf}) zAzkVnwRj_O=2qqFqyWI_;FG9V)t%)iuObNg1o88!A*0w|0+|^91NzENlN5F8|7ZtTrc~5kp)rI=w2*KGaCo3)h~kR2 zLbyE=*LNpzQ1m0B7W6U);*oR{wrH|G*czD9bapXKcV>|G8WPGpN(_W73&@c)Q$>bM zx&;G)rM|KK+crr1XENlc1+T{d4<&{c*@VEO{3jSlxph1SsAy8Fh%YwfEGBB%1X;Et zZ5pyur~!}^fkh0+$72QpR?49Mi!q2)7h1&VIOOZeXKYH`EzDm8^J&p?>%t7s3!?t9 zlFqfNex^g5wyG{v;1U+ftrCDPICXygfa!0cAUW_f`eh1052>QWn0SoJOWQAp2A6p> zF@_$FPJJn-jwUhrTVcYm&5grS*5JY@uy_bbepfWvV4y2SS{7=LV5g4K_ws{q8=h-8 zpj25qcJHhUCUll`bBx@f7hKM|0T)zr`5$OTgaI=2LcGtV7&GZCM)#Zd1~S&o(kU zfe~G%_j9$xa+rCcas|I$Lw3L55>##40AoOcu-GlX((k`q%;jHmIc@2{fuV-q6K-Wd zqf)aFsUzzrAk+_=%EDdj*$IBoz~QH>J37A46i72oG3S6z5if{@r6>NOX!a*6bVSg4 z-mOg! zb$Me`nO$|n!6#N>#K+K!dPm?R&8dF%%*q^Ov*Jz{b?h9F@(JktV;-?zrt`?q1?IvXf&h;yjcG%22qF| zo}!SYrW}0=Uek&)?7$9hO&G@7AyrG~fbXr}u$4##3-W+!4_)V#EKi?<9^;Vf{8RIV z#*gAGl(@f|m8s?@378b{(J13_9qLX0_P@JHqpLvuP7z|ZG@rwLHw z_~2xKFHIqR0L70^Z`sFS1b^i#7VvXMjWRDd5JZv*LnN)&4bG*o=7EIFrH1JQZ!8#2 zB5d#9`f&E#0y{xRWttvdq04?pq{*hdlZ%8N&q{6`$&sOY07rtQ7yC20bN$3WgK}c? zwODeIeQ$mP%Q>y~jcj*0W}1!nNzz8E39(j$$S3JTReZI4%~`w2%B!IULhGMZ1PiT( zv8_IK8TR{o(co8%nh=IhdmNDaqJ8X1dLb$_pN^#DmsQgq?S=ne}W@=`M}Tc zg%cd>R^!TX9&n703a4A7gO!FUbkMIGeD6t2$P)rEm&xR9yB?o10Sc?7PpqcI-FP6C(?yc4?bS{MC0$PgO@4jzX(%_+OIp@huiKF3-ep7*K5DR*T> zukaRL<&UJ%RO>^sn__-~XlC!fGMfEoH6H|4nju|~#o##58l~Mx!z*Iu1cx4*1`E~0 zrOKJ+ahMcxKViw;22eL!$V=LAwP>O(EU5DtZ3i%aR7uU^8Mg~C9|JCo9X)GTp6i(e zKVX)fuSjw4w%pGRsOt56un!-!@L|=6Y`1NBiExm(a5zxhsB?HX^z-T2u&NXulR{@5 zlz_m#Af54#0^N}AL*tYj#zv?2@Alz!Gs^0rIm>nwID!0GE5qqAbjuysGxm7Ri=+o-UpS1?R*I#9| zwjyed6`;j6mty6j@MGioyNt0M!TQI-{&VlyzYV5}dbwoR34dWnSzdK}IDP;gCl}5! z+h%<`#*AF@)HB{&i7bXv4Rvk9F7?Fk(~IHdFIBV+_hMlD0pq?1!sOH$0o<7)2X*8- z6>T+j#2YQ@K)z4DFU zP`*Gt*wj`Mn2Ql#&xEBU7HbFW^(bD+t~Vij5{rq26Y@XFKU)xRkC#vWUY9XU`fr;s zeA}ro*=B%#{#D(mhk!Q)*IUn6^+Z=H*+ATOJk>1oN9u{}VnL2lT}s*w9k4TI8r$30 z{i5Wrdjd^(^}NWA#NuxOJ2v{mZJ3LAs*eo(Xs#*;)sD$d#^sWu8z3ROP|U{GLq^sz zttRj~DaXxRkoBR#_+^?lJk1xRNPd-ZMp#ullK1WadG}Ujis6w~@CgAtCr>UJyEe=1 zV*1e`Cu4*P4pu_05aPq#d|Y= z7Gi@O*Rep?=vujNpcg6pnU{;zHZEy!=<{3J8>Y8Ha5i?*lp}kD_K`1mi6@OIn#W*6* zQUul#P}k7yd3!BGpj0&Ky)k=!(@+0iisrH5_EzL>XrYYY(9uyNoho~`T)W@9F~{+P zf@y$%_?m>jqTkaI{}Ooaj^r@6pFKND7{_jwd%b%*ykzwPQ0kAeht zCsUlLKl=y;52pntmQd}sG}9l}1Cl}_1l%CAc)TJlQ&RW3Q`m{R^sUI2L=vO#=LVLO$axOCvPyrOWvQ;0an#@eYcUFappJ( z6D<%!4iX*;Z3p7l`Cky|rXusUhT7Iaz@#%bxUSp;M$DM^fHEKkaYQ!((^=xV)(N|` z6?$Dcky;>A8y2Edh}7)wxU20}&ydm6r&Slf<6h(fF`q}YBy@POxiehZ1qY1H!(vq% zwu%9_NZ|yA;Ch;!$exG?Rw(ZLOYl#Y0{8fl%~p$MH%dYsbQ6pEV%>sMk};WOn}JiI zT+1oSh4kqq>UD(Q3=1De>Toe&JG%*znqwv?+WpW`$ZKa=exbzuGCmh2szT2;?43U{{#<6P(!nStB@mzvpYMiQ}yP7*gmW}MH z9uJfR)YTlCA^jq4IL?l*sh_+v6Cy}^jbrmF`2t!$Sn}DL;{cNO(zcnvh5AOFj;Okg z+U1uRguFai_M=b0cd~c6`?gqz)wA6)0ojj{A2}eessIL9N&*$s-7_bgFqgzUB$(BM z-)1Z89c$ML*l!t2Dr!{7`>S=^;z>qU>R75GTxIDQ7g8w83OR7Xyg@i4*r6Cj5P$?yRnIps(L%&zccWWcUPwRRk5BTghEDjQH|%`t&{;|t~f z?3@R{@e5s4;NM&l{@5|aP`E*b%63HxlvXx`;wGm>LOfXX46^!qlNo8Kk+8m#HDfSa zs@|2lKFSmhNc)lj%i>)Sp%zN0aSN4$3}V%_qnKo(Z*nI)TNr@- zP3%NHBvjvS6}nq`_)`o*FZZT-;26VVf3Q1#n9v1U^VgfmN+r2Ad#7%(xuMeKJ;O?k*&!k3Qi%!|(h=?TGOWe;b*3WXn9osx4~ zwbS589lq0$|okR)G zkytf=(O{%1}hqgzrY(OFh!hT~g@d#~%Gcq6`j8+e#og(U^)WPk9 z>p-!=piQt8(=jncrwQV`?E$l?vO?eQTVN+fBjM*TmF>0==&NgIR-C)iUvYToIi%(m z1?tID)-$JNLi=PktYzQHQG)p{ZT8T18kAI90GMk~+O4d}O*1gclchMI3yh%2pmXQ~ zU(CY-rSYhBGSG8E-2a{ur)}k9!vXrjAl3zXS45QYyWwepAbxK|HRUU+j06b$f zX>ySmMZ1*bB?H!Ea4Q#0#sv2HyvF~gT4P(K5E94%SD`UdYu^!MRrUDJ4`W8U(fFd@ zblO8Dunrq@{!h7h4@L?x$0coP09JqN-3s1G#P~u1_8Nd%H(Ln96EojZ6|&V`w)d$# zB#zb=Tl1lEs-d=zwZnwvMN*u~{t_S;FjPnzbO{rh*<`*7o$Z=DNb!JPRCi?!SYO|f zZ6^^;zxL1u#Uw3M(jVGMRVlfNm}(J{6qQgKC-=z+>Q93z-b-QpuT)C;5qt@faY>1d zBIf?iW&M~N5N(ov6>FC{+PU)X{NRoSG$Uk`x(A{9lcgiLiihMz-d01yxGo?%>Pw!1 zJVvHZojVe-Fp7aCzg74~AX?LzpRM_1l9u~R; z)MgDW?8s|izmY7TW9IE4KZYln;kK@9rB??Jr2VL4bH3t2vhLh8!9Hv_g&$#l#SX8{nvxiR&AnNJ`U1Rd zjm4HI`!T+N`To*rR1$IrJ&e2^CX{$+0-BcQWD1`>Sl`Xzkn1!%+)$O(<2yhis%spp zOk+ejd1M|dzTVFpK6}+{-Fp0pFz?7Tf^0Sqt#T*T0EgX(la!p5t194keQ5((0v~K} z((HM4ke1NgE3~5qD2+#s^nGyx>oay_GV7BXxQZ8axZ-`u3HPDNr}sQqiBDx$+&en{ zPr%K63ZB*#O@2ogRTSv~h%Q(=kWrf!n<*M%=*dnS($W?Lh4E*%!cZzUFO5Mr;WAnM zBsQ6>!o$CoBNT;dXaS2oP}9qB2)yBM~k5NpPGJ2RCDlsEwaAvX4joQK~o=@A1%7_ zEQ<71=|+v8uLIOAzb+8!;?Rl~$q6W4aE812sdcRc*@yeyeo&W6aC#B* zVq4IDQADnkErr^?I~4{uFivw#!XY>3e)o4=yRVB*1^r|xb3VH@z8RQp7_3fw(#tlM z!l=;LTA?58bFiRm@hMLfYV32=N6`e--*@&BGQJNE=k+4|KPqS2h&Xm$5SYG@3;8N# z%5uv!AzCXQbkR!~K;SbS1tfj{Lu4iz<1_J6@0yUKO53n?O$uB8k@dV&#m&}@AcN1} z=ZUVD!Enl=i7~woFIpq7xbZfAdi28QEc=c};`Ve^Szh=7aJY9o3zDPT3S>jJZ7Uj_ z{cm7ib%af$WD&n7V@S-CsU<9Dhfsd^7pkgZ5zJ9oTI^(r+@3ONWtG*qgI{+daVC6& zynVlnv`bM*whSuu!oN7W!kXdiD|ImMfzd;x#{Xj4ctj-(;45N>0z+?4tSN46kT$ne ziit`l95!aNzbRy+|M+Hp2>6~^TRH~wx!a>Ni#mw%p!S!8_{xA*LTZkg=qJMgGGBKx z&LQ`7V}>4d)wx)!Ir2$z5W`R?ZWds<-at9w-JA4=;ckU2@!6PQSZVy19`j#l%5%#>TG?ctXfPXLQt|!uLHlmgIo4iIh0P~H z?shLT+a&K09^Zt;xGX75;WSQ>-@&P3=U-U-B7s6~@NG5$xv)_L6c^s?L`as;%!w>E zKc8M~IKvKja}CRYG1?(Bn$j_;;;81byoBW+W_^pi6Q{b&4y3-@TzUUv+kNH_`5t`7 zVpSah^6z)j%PseTLZ17IC#zWKKm{iDp))5k@qOWygQmh97(anab|Cdl8Q~`&H|^*W zbDdyJbnMDzF!;e{jZ+@vQGA&HKF7v(mU#~56aZ)hScIf^u%DS^nFXs$$8jZ*o|-}Q zEPxfssV80UMd?r>)B9;ta9{aEl^=qSiH$f$);!E>dp%`}5t|%Iq(^!GW#;2qG@JM} zz-Pdee-^YwjicXay&#?b;8geK5?+4{iA#~Aavo{>uqa21G;GH<6ZJ+B!iG9d;cHh)*5@|k!l zOeks5Ix9YbqZ?e3>=J9}%HQX$#RDu!foPIr#|*{=iMav3R);*^W`_S+xj;Ja=g=ie zu6apOfk-DOk6-pLruRS0Wdw8JI&C1YB8X>O9nz;ib$Lk_YW}+&5J8axD`3g}HzTlH zd4+4^zK1@OS3W-28=dxJ*Y#C`)1JIcHMSPHCWy6AyiEMxqDr8}D3BlL1@7)D^5aK{ zU5T452EEjx53&2%OJ_tv67MgO!A1*&!!z72G@|QoPGX1`z#tyvJfQPX#LqTiK@>N1 zlD7^|mC6;Hfr&zegj>5U3ry4-65n39_9l$gOO~4# z8GxbLHTF(1x=^7zdF|1|V7@d9H9Hi3Y;s6-xR3Q^1%J&pZ~lK=lVHtgS2ibR5$((} zJq!n3`}`9ws?SD)$Ub{V0&lj09Gzn(3ZPu{)WqD7UuNBV?B%s3g`Byf(Dl{NBt6D3 z??QMiw${t&fn+onp*>Xi8B2bOm5#aKX{ymD9ldJKXut2#dV9F$M^clPcRCVe>aUv1-CBcR-D5pWU%@Z2w+?6n;iLLTv z`~>L^7FP#+TIM=j(G%MI^OeR-(-d~x?WMU?`}-HnrnbrHaw*e?Yku=Ay6>9yBSn zOc&o<+gF@ltx3>di4gsIqxbD;x>vgAq;bvyx#XlN#`jakH`NSx0$*X@%R+nBG&OrK zRtpLFCM8j2CW&svj#Ln($8TT#Q`-C|^>_Kh%9v1oCxM_>FSMP4`W+W7{Rdy>NI9eg znhZMz`IBgM%11+Z$^xClm*X^Au9wRKM+^gMa8bW@yiQEGH;eiIIvDfAgv!vt(k>o& z;=v9fmOZ}IJURaT(6Y~oI3C=>T`qIyl{c1#iV9Of1ikmkvfqL333C>qqTI>yGh)VQ zpc^`efJDJpOI;-6@hG2fpmP%+&L3h%_0_GVT-s#socVi(6jvHzw9(}$;`uoTNDwj- zD9Xc0^Y%|SmR2US)UoD@;iv;E^U?QJ@&vwfQ-5e9fpiW5&7y8 zRSv_>_DfzP>XVbRXsCla0zNlJkx!rw(%gwa>*33zY8PRp?c|{D_$aH+REv4&g!q zazI?CDdzTTepraf%s+U>9{EQs#sSiNI?4;E#J{Uksw%+DleXbaUz9qj86|YLetMNt zA1v#9`9&oA^2?zY%o~f9;#n2Oka{?ve&qPCqk32zK{2d#8>U5w+TtqwpmE0}Ij8#> zBZKfwdm-?o=xv2u+0m^sTmBU5oIptlE3%mJyYx%LI3$t;^&Nu<+Yn;6tDKpbY9ivX--v>PTBy-3z!ElEX*$&U;{r@`~TNSG@bk;X~b z+PT0_yf4Bb_dsykmlnI3m^moxeP7Wev+knCMNqd1I6L_Afg%R%Q%nO^s+k<26@T== zsGhfGAU(+eGZ#?cHNRl{Juxul8mOt*oa+%B0AB7+Sxdw|A001#>qt!Z>}i$$`9E&S zWhbLYHk}HN+~kk(#tAY_jKByPSK~Vb6v#b<8!(pg8-vW%lr))DD@25`OtAHGP z{bkrWj<9zuMMCW!e<;Ac?2BGX;tafI~U~@HpKQ?3N0nM`?p~ z*pf02@_taUaWN*({i3>NrbiDkRXM>3!ClP<)V>3R`?0XSKPnVLTO#%1THV`~oK!E3 zz*m=aDbkb&g>(*(jY2unxo~X?bCKwJ2gvsyFZC%H;r)h+jN81dJH`Fy458d*Wf#1~ ztVrz!A%^=p7!n_MAG(M)%uD-Q8HGmTx#+myNf!`(3>S4G+ZEr&LAX4et@Twyd*54R z#8W=?d;?Em>HkPnMo&wmG_qO8wTnI>0E^g-jU6#x_J3*PWVQ8l7n+<#1Qne7jG@;| zbfKgRI(b8<{XEpMCZ$mYfR36Z5_;>D3Ri)Zvt!<=eHg7ZaNe?{iCe(H&Aju2t3jXZ z5j@|wwS4qHg_MNhv>*sq*)@`xl~9jAf_qcslQ>~Zl*V*7n}rJ6Zn@&vj^S<|OO{nb zY3)fJr)ffzkYm4bh2C%n_ zc2ctzc|)J$s0wWs00VWUNQL>C&#i!L(VIc{{2zfOcUha^Vl4miq}~;K^czG3o{r~~ zKE^_HHI&D^QAJ|0@bQ%()u62S;5wZV=;rh-v`+%!DIYRd{VkKly(L^wIsDj#EFTzR ze4c_{w_!o~1`B~ZVWCaQ7*}bwvnw?x@+R8#wJw-r2}GIFLOesO9sXcB`!5RR>qCo~ zob|e^i`DfZ|41nd^MvB|p;Wl&aTr<8KLFOfYCks`)_5-oj+|qnfge9@a_K3KKoTYM zLpcyf13-o@I6xdBb7SrJ&I;U5dr0&BMBPGpnw&QVou#_SQ9|Eh*xZ7&K31+t=mqOVhLW=#?h8h29!X2Xkp-ZChtcxxq)>7_{713i0 zIAjC&m~Ggldmr*EsQWR*6n$t7?f@~xFqqbO0XFnx(zP!3%%4+@MKH;1#fa4{O|y9mFmFQE$NNWJ*iCfiF@=DAxFEJk zth3Ss@e`z8_M0?6#ZsVd&MVEtc3f%q_!)H3Ia4F3^bvG-I|&&2;0y91jbHY9gacxB z(=Z`F(9mt3z+A?xx3|fSj`?J%8YV6Dw1=#h+X%F(vwM`KakHB^gNd7qnJCrDfxGd6 z!rKMrIHpT#KI*JgO3RWxNwwQUZVtKDfEDdgJ7e?3W~36F^t8YJ*n|&Ire_!=08R{M z1n8OuF-);}#YP>B1k8v%=}zE>r_1kk>1)sH=e;#g;#=a;BJLvZA}=YG!7LBOa8_Wa9S(DEH5*o)jZ{SSCxzs9*ncJX{Y-1gZ0_4vK7+#fqcZnj>5BEYS zYvUMIzV>sFI?IueNU)Txwe?2dB;a+0dvig1N%~z4ia&9Ep7d>1X-To*l>9UrPr;lu zTB||1-Q``D4mlUMry6R#f(m^D$k@KS<-GPHT#JTIm%S)wM&>SKCf+o?;qw!wY{m4w zl+cCD;M%gvJj6c^0-ax|Kr=qHBYh}N@Ns0s@P@{4zAO-#_6q%II`=Qeb8j2^8i6Oc zubxul{>DCJrp%T`8WDQ9YrbR~YQrsIbr9uIxUe?O`B{OYZ(J2-Xu%HO;>9v(?aPe7varB+{~NPu;!0! z$S3uLlqzcz$l=$UnUDJmiv z3o)sST>gB|!BR3oIG39tdoRMm_@Qs7_)2rQngs7xt~Q9LKH2WSJy<+G5E^DYPioTB zK}Su`JZ7Br+ijtP%U1)&HFRS@tPUJCKyWrs1imJ-o$g>_1aNj@-EBP(B-3xzQ97HY zk0eicD8FrE{ad5ZUri^27`!4;C3-gZ%-vSGkpuHZk_?b04iI=Py+wH{ymKN3*@6s{ik3*|Vx(C_2Qe`GYSM zVRVo_f5SUP1ctA=Vwmqf|1u~hvAL~YTd1G1gIn9I_L~c0$6596^xlO_8BqFo!n}DX zRmuUJe_cslo~dhjZeL{IvffrCQb(oC%JXHtY%z95@4m5=NkGpRk-jr6ysR$O` zowiO*SKq1nqA-y`UMER{z_U&uHU~1t3dHQ20b?y`iSwbBir3+r(zkP4^~aR!n5fec zp6L&ZWZ)fLhm-dJ6m6)vCo^XpH;D_FLmo8ok+m-pR|1hV_6JC!Ms;r%Craiog?$~qX7cWo{g7PtZ+1k3Pbunv$3Y)PaeY) zBxN39!4P=k5>??vzj8&Xli8SB>$}%qSJKnCC;^yL-4nVRhbOAy8r=Y+`)09-eOisW zwqH^(L}reit)sT$$(RZU9w0YkkZ5Xnw!vm11Ypkb4-mLSzt64X3P!dk)@i zKX@SMRr3C(#pn!K$N-qrmJe3dS0>vn5Sfgbg(>0TVMSFkG?1|)-G<)KQA15I1|5L3 za=u;uS2wr8#|ZKX@2izQ(bP#!!v%ufWV7zxw-~1FyHOI#I9Jsdb8P&%rzyn+pg%0V zp1QU@2M)!TcdlEAu5*citIM#n$1 z&-Pb{3?ol*TN&F0jV*xO`F_Heu=&2e_!u3KRq--%yJ*rt1NE&3Z^fx`XwhMW;nQ>r z&;tn!AmD8G1>4qg4}fZ5efvG!Ua-ZN8o<}P?W}j`@l5Lh0sLi%uzefb()vRt&^*?_ zU#H9J)P!gk!^=yjLPVi2fk2$0`NoBV5-oKjwWz`;da`(Ch0r(#l|uG@8j`rE?p_>z zroW$mb8t%cNpA^Y3ZswWnt0i^ZMJNW?)27j*e(b>=Tgu?`o5Gy42^;cq*V)mlnP}u z29kw|8GHDj#6-Gt1u#d#T$tz%{<6eU#S&e&kzvLjA_K^<)T^+p!Xi0wGrf?>p`~!{ zRyhUI;HO#vyuXKxF>+l58HvL3XW`$8OCn;B^@K$5{iI(|%CA`YnGbN_9x$lh9Bl?D zM@9xW+`=-F5R$;5Ok^bVBmCVpaVzoRXHEqLNGmj-?f0;75Y~eljSXsN69+8}at3Uo zm*yowU+EfBe9(FIe-YfekkP@8T&J@hTpN2(l;j(lcSW$mjCS@+XuWy7g1l}%T=YJDS8l1~qWdQbf1hPh;>uSb=hS?fknV;`X5yJAkGJ$b5PZH$ z(?IXxq;x>e{i_O~l?%MG(h+DU2NoKEyCcax+;AU0&hYlf)%0$TQh65?vmaN=T$X%} z|KQ-@tlhuj%y#mTc06riPbBku4}7^G#QpJ@ZkzE)*j(bab>C4g*sutXQhV@#m$5+Vq~w?D?aCr-KecB^wFx89aEm+}i`i_q}K?r>$>UQSPl znL!X7PmOXhu4K{WZyi|Zi%D_#!sFfc*@arJ_+Po&99IQ8eEjLgokxGxle;Q@sIu!x zgX{xB3aZ?DLsBR_EUk~Yp#xi+K;<;t;WsA@W~vo`5<)nwigr7om+% z?C|6S{|8Ebt86!6N92Pjl9FM9kH@itfp}Xgqz-@`j1-scpX?h*KOv6R!kw?1q78Uy z9TlpY?`eB&;uQfOgtC&O9`;6{S3bZqVmz;npoc#iqW<5{5cZiMuBd1jh^=J_sRb-q zXP2p@Hr+nu?Ao*y=JZ@S%zSdP8xtuR&T;UmD#%+Xt@iZtqBy}um`d?49M%C%ppi_I z?QgLQ+ebG0Xd>i618@2zD5E1U$Z$iT4j+f@ec=}YUMOV*+`G-=H76s*B<<79O7-|D zvmYbBLyO!W86MlG#JiRi8i9G8(VLZ~5L0K3pSRpdAKJ`}Z^a7TF@G(}qgg2WVtx2X ziH>+Fv%2k5JC15iA%Uqu)!pPM@?UZvtW6+kw3|MSYl`+I1vJOnPoJ&9O*opKI60T3 zJn@m8eT*D0XGVt`JpA2(d%uu42$7Sj1TpfYk(7{}QP&*-639LSs)vRH88VU_R_-hBMyuf@!@ ztvLKb`#H{`yN@&uBFwUZf*7xZjdp=paHCsGp?AQ1YvkVQz#-5Wb4~Q_JzJNp>947$ z0ZvW7l*$|R8mOyxJnHPzVNsC^a>ke#tidF!%uGCyEcmPIC={bh;$eEGl;F~~6jyG9 z^7G8`p!Z&9L%ek>E2V2Em7OSwL9W`vdcw6pSr$FDy=bRrHHc8A2JLOYb5ny9 zhw=?W=i=)M6E&>FdfaQFOhUp`Sl2wmRh zI?m`^DHVQ!iR`x3hK{6G&$-cSF8SmT+VtU83re~e7KNZ5m#Z$=5OVgJOt$F~r@%+_Cx)%`Q3 z(5{n4{j4(a7~K-1*tPBV(wWERE4aa?G95L%Sq1+xUkdB3z@86vErZ$@j1V*#OFq^n zeR5O`B`D%LY+k#*-&HkX|Hg0cgN%Hx=2in~%XFXAS;VJgkJIm8a1gWNPiIRpRDm{! z!vCkTuMCUojpDpB%+L%aFmy_n(o&-gC6Y?lfHX>X4oFF=l$3&ql+v9;HxeRU64KoQ z?)cw*_QURe+4*+gd(OG%{@!@bJvC`*Zt--$dUVob4rAm?Aj2T8cqC6TXR>=X=CA)yAlnVBd{SfdK0}SR>Bh?8@}oLn zex4>HC#n`3`rRg-1s?B(%*s80W@}nYiWcneb_IY{YJod;OPZlo_TuZ&N3p`0Cc~tk z=duS@%kC5Vc&SD6m~1V(2d>F;A%arAJVn3U;d1?HoNtG-o;bu8B*jbg}gn;b$*}>T_Z6A+~OYuk;RfyGhF{22Z z=H}id?c8@lnER(SB&BTa34E^?3t6~eu*a~AnDb7$a(fx2L1 z+9Menq0f0XaZz3K2Dah!{rcp;3e+;vRl%(^M4jiiqM}5)= ze4zOs^a-}0xz+-14DV3srdWA1;lg>0hsj1Y)u+=I;6@Gxy)XsMAZzTtaweDcqp9aQ zn$zoO21FYx9uT<27TnB&UlidBi(FRHV^-h)Vc(`fDeMq>f{s?W#;aIR@HYMIh?$Ad zHc++%{0dqJf+bAy5W1wL{I>~uUatdHuRlaL|IDe9Aoz9W%8g+rC`&@Ry?vnSDkMl= z4VVlxFe_I^UKo?R3e6x5QSOmMWTte3pg-f0*@76HNReDsnalSQX+O50^6O*ZCjZ;( zOCo^jgZy8E$JpcSxqq-Gx?78tn$wcDO%JOH)hnzfVpvUlj#$x^=64{HjgXx^ZBO-o zGrdC=!|EG$Mdlx;Z3`>s*A8q-PylIAvkWmvJ*X-FHc|bqI6=2$E2f}jVaSzhM>(^lbpG%XMH$^Ak{JU@eEy=4;R*4=R z!BkRVYVX^`KOEs5k)DKL4m!!^pK%1uoK=%bpYZPfj${v%FXy?7ZEzJs$Lp(% z9dZ$u{I=q1dU>9#$r2&#v5*)_jwSgR5NNE3UVhxne5gs}63w)heV)b=;fSjp%oYK{ z;J*i1J2Jndm!sskgF@j$;rJlB7UrNw2gH&^5!;&m=o|o>U>V`zC~t)iEzm@7!N^JA z+1qHd-4x_5XVVNeHBtqgG1f?a9x2b+S+9CK;@@6ICY z7~Q?l3OXAP72e3&a%}F$ouy!PZp^*Gg2GjKCxi$b_gTrjTQK*3IVH5WYUa#uBb`go zR|m6H?u}-t0Li(u%`+xSG;P>xveL5xFqwlsNks1tJRYo^D2L&f7Vbl{v(feQ*)mP< z-A@x$M$vj?bUokZpYdVgP(z<#De+r-$Ox*4M)ZhMzP&R(U6$Zp|M`;xp)e85z)lv4 zZq;ebf1;o%%=VA=pH$jvG!jWi{JIyXfVA|DaRI5b;t+FH6S;0z=;^s_Xz({LqDQ-r zgzp58KV|ytypvV#G>afZ;u-G>l1yLT@eUyhMjQnf>B8R`s)R3bB95F1?6?Jg8C%=G zXRAIY6r+H#y9v)p3ns`VbeY`e;rviv<<(1Dj&sx@&rvdaxvVS7|EXdMTfE)mz|7kG zZN9V8)^Ay9Y=Gv-%FTp-`75l{gO+(cvQ=$LT(&7XLh%QM8V2!aiejXz;vb>Tvp?xdMjy|pLT=aPitXN1e1Ev6dpD|5NSV_O^s)(HXyq&J%@u+@a)LLX2{jCfS!E{^;KRQ)i0(}#0_ z7RvbIAqP=Y@qEHiW{taKxGQ_007r+ti3V+8-hx!{38Yo6Jb-@TN1;5`%qv+(_2f*f z6ZPvr0N4+gg_R>+DTo^ol7psjX3#Tmpr4|!;=3Ht{wTh7F~p-@TPW&Ns*~mJwsL^6 z^4K(c~I{86H zNI}$^gsxZS)W9E;s>Dvk8BpC#v>97OtLXwfRk?RT5P!g%2))Ycc>L>DzYFBiE>uhF`^SeJZ(|Ndnf)DzsdW3s}?K2FjVv^ z-`2mV=&EeN!y1co*24a~R>Obsm9FJHm@M{Ausyj5;us03B@BO339;?2j(+(uk3~&$R?r^bJi=)e1pi2$2ww)&z}pXfx832y#=N+pjbJ0`9K!+ zk__9>Wrc9mKn07_V^X2gAdBT`jof$l;8Np1HS$;9g_1YUnFdKXz>%y7i!zG#vzQ7N zPBw0AEJ{Vrn(j2<2|!z|#)TfmWA~~b2WKjCNO2X^1B7hMo6F(5T-|ejl|IK>$$WsH zIi~(`Uat5j&K@+(ZiLRUzw_CO;&opF*%NJl!U8V=gaAfLiRgfVr(97-CIL344B*% zxEeaa3xtg)-kaR9Ch0*pxoY!La#@0Kai1LS1&@>EpZC7r$-*r%g~vwZJo8;L+jsa{ zU*}Iwm-z-{s3elLdI;SR7qm5f?v+cyk^{Xkxz`A&_elB=4{pCtJ5Cw(8npF#|8Q^- z+yWHFhU{K{KSU{1h(3F^h2Y1OQ@vyO`|#_vx1M@*u2XCEb-%$$=TB^h0%_~ofrj{e z16h4X-q*lvk>T-!2LpZc(v8lPO9wU7OMg?Qp;J2jk0lwnbt&Na>!QCQhXN>~H^SR1 zn_+j!vgeJ8)mHss7WErId6Pe7?pI4zM zSM^}q{leqI^2ABPB zq{Zu+mKpd{9d}J=n+enV=87BUAgOspB?3UWMuLP8J8k!RfOV6I&3BoBmn!45 zRcn_fRik>qnWS5!RUyv-4Dw2{sPrqbyG!wpLk|oJf&#TID+Df3#(qSSi$8RdjQQ2T zkkH7Q{|s9R3ygAO#67MyG>i*Vys%$!8$sAo6$hI{h@^=(tjd7cV6KituB0XnD#W*e zk4aAKd}olUK?RYLQp|4vd+BAQ@S58@V_WFGzq9MVj4eSmn<*)VusFh}{0O#YVP7^y zSWbBRv%%}0B3XimyN^J7Z-JW@vUxg>3t29j>>P~?@U;a25M&{Tn>etR9s(RT6E}su zcU7Kb3}|ZbXiU&`sY`JU@Xpig7DrfwgIGA$aGW_x~`fq(g4q=Lu54)Tf8Od z7Czg_SqI;MS$;*YTe|&*7`QhsO6TG3p*zIsmY@19imc++H09el`7oZgQ_6PsN|~0= zo02F?^$fBY^|LxEb7OGM1cgV5Ja}kWI8>=xa5~P|Z@SJEqHU}56PL#r-SMgipenZ2 zYRy9*L1QgSvgBF7%bDVp^*#1UWpe?Iy9g*up$b^SJ+rqfv1n&DlSQv}5TnCqe~UjX zn!#%R;p zL^TbW3rDoI1g#RbH3ju%OJ+u+e4B+kE@*)jloF5|7?L92WQLo-srQ|rEMd`E@}&G% zf*v%T2kMgnF_=1vwfSYVk@O&|j1Ipn!kAt#>NGpDPD&ynIVR@^nh`n9%cmQyf)=G0 zAnfi!6#jeyKG|nYRKSN*XJOkC_bj@?8qr8 ziEl5Y9H~?v>{P=m3)9I7M)oeZWt!YJRF(WWLAV2Us(1~%>iLNaB(A*cSCl^l|I+qZ z=0E*P`JghHGJmt=ttivvulyeVIRZcjOZfZO36a8qQR29f&3OFN$lmtChag0Z$D>ZMAmC2=Ny zkzJdMq_cAPi_oU%x(6A6db+2o+rn!V^s2l_8x8j0jOZg{iCMk$toq#*bUm{M{+x`7 z;DCGP!E(u1E=!Y_h=fUD=0d}Qm`BVL6nElX?l76rcD_5t3)Dml`R?mnWPgTUe1#bF zRL^=?QZ7F&Dr<$Q-Q@talhsawoT!~Oc@UMkb>FiX7}8gUp6ijx%gV|I(gQ6rvN!3h zh{a$q$f(W13jgM3?KIRUJBhB$ubtsXk4CXF3nKWohh}Np9E`~bu7vuG8zM_l*3VZs z_z`w2LE3>NlN&tm6aPeYWUZBRAKso#zZ!Yjd9#H->Lph9v~AKWJ-Z(6`20D&tN-&A z2Lp6?pvg3?lLc*izUc3hiL!(iz+GdXVb`SXMvL^&&CJ`fAU!jmMn$6Mo9ws)?}QEX zFi>*kWdx9=6RS5F-k9pMQ(#OaOaV%N>HUh|vBK{cvaloF&|P|DopvZEH|f|sadhs~ zyiiTl0DOIi;dZr^R5(&j0pP|3d(@9An@Bb6l|mXg(A-IU@eJ}9Lb8|o5jT1v>w<#p zBPLI1150rDUoO{%0L$xq#!(6W(2Gf)K>Mh=vF(fPk~IAi7N_~XFu$m3qJUqm#4&d< z&GAP()7to2S);22WqX3!_8=uzOpTjxozPC@@Pm@>?fU0pUwZA#p4l4kV?S?6ABsSF zEpN6=eR$Q17u%)eTGDZbDnFN9k$o8MsU_0%Kz!i8Mjhaj00r3Re}T>x$rqd*#kXjq)9u|Gj)movjp1iKL7~b@F*XpgoSl zUK43y%R@)OKkPsbpkV;J(;%|7$W*7J^*U9^(tROUc4uXy! zZOxs#r>!p&I&2*aMedj{S^XE3L2H7{m!$lR<-thfn z|GlmiN0Qd8+J!; zydp3CCy1v|YU}cZ;l|ig*yFzFpjzPl%YeWgTi&tFAE65y<832-BVn)PBsPkhU=bSK z@;mdaPB{0-BDB@c(Dz@-h6d>*DxS zm4$zz)yTj7Rx!5tc7B$Wn`QOq_6u2yzidh^H~HuTC(jmRU-DzwftVCbF0f6E!P0`@ z_wK_mjRg2HP!~;FjL37qSemeG1Zr{~OXHHsBZLBlb%70@;tIRrmQgKX8`btL%%6NF zhXC-P#OdbUwpa3P@*`@bAFz(=M~?@=go^g`boa_3^kjF~k63>uz~e$|l;UU{b?BeV z`q*84Z)m(@p*G;Cn;t-#K z`BSzTE`l~+oHVV!gRwTy%L2P*{$dX#MS;cd;C*lQKGnh1dUuQS7miV9a$6%tb=0Y0 zn~FAVd8jt#*Z@ML>i&_wsW=zWO9j7{awkf71-gEyAy|{oR4&1EZ&(t=sF2+P=7h|>M1d{pKhk0Tn zMHi=+V+E`2%pH)0Woxd047--ss3F@#OL0adW)ne5Y;Wmy-YdlVSQ%lJeBl2DC>cB1 z$zbvA0B)o!Fzoao|23w9z- z<2D2h1#xcOE=_BJ7AJzGAxC5Kk=^M(FH^lj)Lcdm(_n{%jq~pY1t2274_T}G2WL)C z#Wp4n2RGgiB-8GpapLNA8VzyLVNQ1{g#GRy|Wj@31d*OObG} zWpJJU5@d2rY|{O9uZ&f?q4LkBfnn?Ipe}e9BW#~M8ag}% z`Ex;KA`d`UW3Rj8|AC+CgAA9x)kU3}!b1$-QpX~l86*IhstSETO6v` z22>~je=g-Q3ZXRYUs&PgrUecb&8&)BPI9G1wTQkbJVM;=@bt-P_q*s8Net>!4ihG? zmc;nQ{E)<*ySN;&*|vR%a~`?4s(*SWZ#Yp79BfSk0o3~diHck>kh(ng;mO10a`iV& zAY^39#OW1tnB!7E*F!l3T}n~}%WJ_57CFW!;@f8nmiw7uh<|(Ou}Af{hp>q7G8~_< z-5-B;K>VMDk2GORQiWI6_>pL@Y^G9c6a1wC7UGsbKcHvoF=gR?xPdX(wAPdV$$m~C zJ4d{rXh5-*&lho5#tUdWSEaCUNsrEZxA)lqiWKg3_M|9sV*`T{bp4UzO;=B;%LyZV zKM{uNeFk80bFT<$Byn3Ur9yjc3E|B(sPUhV*OA-un(Sh%DEP<=eo2buKq z>H)jC<1L*9|DZbTYtoPrOQAy%J2N+cU2O<4po|1V&RIv>ZSUqDP zFx=S;e1LzQI^HyT8S`&Jcpl4u<|cqZAC%rR4@oz{kPOb4>_8gJx!XWk|EZX30*-;O zf)}EZXTmF1z+DKv)$5!45z$=@+`?bj5um7zcg%p~)aTLPY~)k1`$>)>;mQfB6>u0V zbwoHYJ;^u9gKjtO3m;lO*{+icTjY=@EWhOOU1@)~(f+WpJF#QCIc+uvz2)NHTq4d; z`px<=$Qvx#TrFQDy3=Z8KRmwqTB|)*vUAKiIpPKPo!P@);IR(#>zIGp#{baY-!;`IAd9ob2dc{=q_OL3?MUi77F1>aXr83e|k z(`f+9?t8U|Zb#`o1AXqiESO|Ylp3K1=0l}5-7pZQMpbqfN;H+|1`XI?UNwTgP;CRB zeMW&!Nn5f>9F`ht{1>)f(betWB-f^Blg!nu(f*&d$Av`?Oz%fTJ9m6=$LrC&3xp>r^*A>t8Vr1^=?k%S&ct`+lXz~nVd`*L;p`%|6N}oiq^WB z)GPRPbBFTAKn*lCKuDV7!8+Rk5Z#P@{ymGCaf zl2qK$(~LQp{`1IDP*ZjC<rQaB1~}tqk~Zs}QN$9XTz&-Ht`tym#Bh!lP8Qw~bDwC-4k%qsRLR)u zRi)&Kp};}^zWBnH)SmX`l?(RKY-LJ0&2~;_B?G-c%1qkC?&vFtyyoG{9#;xHcI*5( zL$WLXOu7Mm@z*54hmJy?yo&fpR-X&lft;lX)udzLvMhbQY+PO9@U&|<=2Hj7o2!$@1(;# ze8UbiG8$mMhXy{BBz@u9yiYMWtTW1tNd3xXoh2<&oTP3WLK=CxT^L1ao0YaTV6t7j zU+2@@zy5T)|CT(({`B*~U4Vc=r%*;^wXAs^sY;o<4p?9cz_68yghTWawlA^(O$ jZ(Gm83H~PmiaLY$u6Om;Hug^?06Z@E{UT$x1+Xu|(Ru!N#){c&j{3?Cly?a+zSNCPO&%LcauWI@H z;-YEGsK(V`F1&Z7nr5_2lfLVz^>qVWGOZdVG9*cXxMhZ!a`7 zbZKd6XJ_Zfj~~vVvyrLularI9qoc#~Lv3ws85tROve)A}H{V3hWlxWFb#=vNEw8Mf z^p5V8Hf%LFH@oIftcZ1xSWzv*lmSwC4= zK3-W_SzKJKudlaks2H9)uqfW_-&l2Mt@|~9m>HDp=&3nY`uMTv2gNma%XE}`!uP4uduN2 z+wei>;BL?QN*;C+>TYRX{=K??R@uDWG`;n#e59b*fFaNt{et<>)BiVLYLaBfMzit7hvP~8Y_*|HR&fDPH)gqu!Ko zhQS(wj_IGWK)W|a+yNDCW{Ro03YsXlUkZNigd9m1D!YtPb}H9yi}sUX9Jo>KA$HuT zdJ>EqH>v_pG?`HC=fqgj^P1$B`(|Y_sG%Nsex2i9WjJ%32{VC%>EzQMkJ|Cm&xpP2 z;uQy^SlR&plbZ3ex70xvD56F=bslZd^Tt9d3@@8Qq8w>Jqn4RiGFnyJluWNAn0EL% z2z=!2?|&(O5cYPNN@wE!#!JlMRdd}+VS9drz^EL_GmRd@qFVCAuKa78-HA8Ll4aoh z5N8T2W(GBtcDtUFCn&6$L5_s@N=wB)&no6S5c1~FmF>}~Ix4RYpUXIy@wS-#uVf=1 zc|phnKgRltt`nfKR|&?Qw9@qXjka|&AMIy0+Jm&{XLS4$DM4xM-dD>6HvQPkkE2cV zfROd)+|VGk+B8 zxN-o$P-ndy#;Yr>A3|o17lj01Zi)PMja%r@F<9F}rX>TO&T0UlXWV;&y4ce58fE#1x92L*hCc|4`#KyDBw`>P7li_73z}7WXm=B8c+aS7ibKF z(W$Cb)$J3=XUQJd+wUk){x%t@)<~Z^eA$^8DsOGySxCi|CeG{)$iC0rAJsDW>J6~p z4Eoc>2?>1qv4!uD_6}(2e_~p^2p@avhV#@vd^z`SU$I!!(oJ*f`ucUN^f>C+mY~w;Z@Zb{fv3B~TSJvOtJ=QAyPJSB9sh+&2Ko~zt#>r$^ zt8ARGPwo~H{5XmGy8ro#qpjgwM#4(Y5INTA=?qUU+grXW#<-j1fIY~C zvvxf?{OZ{oQm2^WsPUhrT#LbrZt}P9#9UYYupUhnf8*W|c=uZ{l||Z=968l}GDQ=g zf*WlG|I*5c+w5m+0xzY|$7kBS2D$JfGZBDX5aKe|xFF z4#u7Cz3}drJmz@zOzVS)WogwXz#}P=&;20h+xL44kn79H6kkW{hDF8Y8+|NepJB|1 z)G=oVa0(2(id%gX`@!b^jX>V8`6G9k!Y4hOeM45!6bV0#^>sS$3}-m65rr$8grd~^ z@i@Y%_z35`!*vwTGJB*4zjSVPxlg>fR<(Ot{gl~DMx^>^F)4nWF@zF-JF4moh~^uC z5v{+P{_Sg^oHz{*;CB;g6FBf8wBlO=z$xa7d+hgFe;V)I$C4{mu+yXGmohbC<--N( zDnetxsd#GHpJm;~!02Mr?KgA`C_Y|Q28^aPvB~{h7uPtYoWNc+X35j(Y|v!6azohy zAjr`=)D(f%{QnH_LoJkEvSFrxr@nyagtZ7X6Cm{q1Dw<@sq?YkzN7smfdUQ1|A8Ov19rR1R}0+e|$IsPQ9nD@RS6_&mUG7 zy(on}wfFl~kaG{*^IAE(r` z(#~lop^YpuN4jOpZrk-U7a!uJ`@Di2-$cL>#AmH-)clvN>tHx^9t5 z)_pfUG-?%d%`*aAoXM+ND|@vgNUIv*UbEqSPQ$Y@_@=I2!?U@tBc(G5`(vrx^Ao1+ zS&0XrT!mrqbDpr<4^(8w2M2f2$bIJ@roav4P8KC7{#=32>m=xzc^n##A{7LOM%}gZ zl5SLd9wxhoUB2U``E{P=SgqGIx_8M|L{6@f|LSCnU+GfvJR_5DUY%X0`w&Qg6Mgw|l3|Mb7%56mJQ{OK`T)?Z}e=Sj&>-+e4VuI9fA@qQTt z1$SVEmUR4`iM@{G?Cj_jwMCzIBp1ANFl4q0p_Q%9WBmL!V)GcIEJ3I0FW?>v&ryd^ z>g`t)Xf>fbS&rW@vV>|Kw%XtqdQZU@|zc7d-;%O(H1rpNM+()>uQNDnNk z2v3kI@2Sy1Vc4sK+1+@#;iZC8nDOT+AlF%7x zK1X|G9aR{hWP4AE_FBB37wB^@>*=_{gEad;i$&{=i5FH3#OM(!9bNIiH1AinDej1o zek@ehqy5S(bxrq7QP1)T=kRzuS4%Zho%D}Jn>l)j3~oah{Fn0aCugdGv?z-t&~A_F zACoS0eCJ&t9y%ckaOB>k%4c^bHqW4{z*7dm1Q93)T8Yj?dN+}|y?&bOIx|NfYc)jG zm&yCrk6gy`k9vx09V>KDZ|mURmD+f83Mv3-EC89SwSF&x*K%A`N=)Ar{cG2#H~X%b zPhuP%ts;lSR&CirQUMGg&Y_%Y)mhImRkdMTx{vl%k8Yj+g+qWOUudHF9@TcJUZM>d z#eaZfK!iM9$E{4scK{3pX?E^u$n4+UTl6oixi&2eQsUg>*Yu&kOi_VuVl?FKUyM*I zUSIZelcyC0r&_E?6aX75ew^&@u-4LN|7HEB@)W@>%D-OqYYHVx-BIK{q(lRF`NPU7 zaPbks-&{Q)tXKyi4shg`Cr;|smW94PF<`N}%Ug!q_eKa&$@tXF|M%wOa77&5iKnA* zH7_b;30&M&1dneh)lv9_&woGxLeyy50P!J_D1(AXveZYOi1LU2zc!R`*5ZQr2`y=G z*`Ul%_blZ7N3C?-ci%c(TuN0stSjaR6Cw@a_?g>D3H-Nel-3?C4c)@!a}mPf8dAY9 zuOj`?fk?k)b>)pt)}`LWQLKtQMWy}dZJuN;6X(_U1+Mk~X2@}>k4j5uk8~d8Vr_Zs z&7Kqy8=`0f#Wz7hQ{cRB7SPRrnPYjVz;LeTEe6Y&UWnLTB93=#VvD0hACUc%p8iB5 zx183a8`}LwtRrQ6lFE=M^&kP9^k)>%O^dl3SO5%#gdtLOALsTJ3%VvLq_p=5uKV6R zccmfxCvP7U;4%{3E~wArnk3Cmjc%ces)MTnK1EJT3YvKLfYzC;cBdN;pL$T(4t!I6 zOiFY|g5ifvD1FwjVS$^@7PS~#FsE25=P#aLOqzS-&eo+GwBM@(><7jU&%aED>-n5n zTH6@@w5GnFFk+r83uJRk0X?s-e4L#1-+2vqIoZe{#F3sD5|lyFJN|AkDj7d2S%~Il zS>tqsE0DWR)0cV|U_}3wXM(H6!5%z?wE>P2iCF^-n3?N~2`3-ey#CJ!Kfbxmk`HLU zBN)0eq0oRA1uoc1&Xy)mxqXgP-w0i^CdUTc7dbuUv8MuAro@UJH5$L_akFB6ZJraf z0SC@?RRz^mkw|RvxmN5HJS!90#2Zr3AzEcXM|=mM7r`$cb93c;j{x2^#5sY}SAngU zU{&C$KCt@(prggSq|3@(5(ml}Ej>-(%j<8C76*2v6?DZQ76TAiYnWA4Y$FEh*kI*< z{@?-YR{%H4JEq*=*cll_hIQv#+dj4c#?UZ_y_I}2;KT%;g%CF(Tt0mPb^(q_nY};_ zfdf6}fjc8yN)gC+LYn_>%ic##DuSXSUM0(b%R?Jl%UB>r4|r`{PG&qU;w#}*3UR+U ze}1||J=pr!V%w-*K#m|Ka?+q2Z3uh$MxpSYcTT{z02KsipT-QvV!XOf9O=mV!69>b z9+;sS+Ct~7sFl%=0^T-k*I>E>% zALM(i00(zO=qm|yY@!h2cfK;>j7%22w#nM;KSb7-6Xb)&rdh1Ycw8-q3f3`CS0jFt7PaHeT@`HKk;slXZPyCmKD%oVfd zvYMI%Nip7@i-)Xj*DR?a6I;R+)uo zPUK`^M5d<#%-fSGDHPv?cL?Wi{%K}SM3-g{UID7W9?3zFr3Aa0G!AAN)U_;xTf}`! z>lG&rPg(3`#QxPc6W|sT(q~M1q%Xp|?ok{-2C)X;`wTbtCraI1YkEgb9mI^0(V9Vc zBMKk>0?Ovg@T#KZ|5*s>m zdR2;q6_bJTTqlHt-p|F<`98Ry*c&&4L3l8$z@1EQ4@s$ERs5*=YD7M3L4We*uqLRJ zE~-0$r~cTy6!=+)sZ<9Y9F~hKNqpA}2>|{}CdqPl<}NNsqCTSx^il|ry4nl8w}uiiE6u7@&<|{}AAlu_vy&yo zm0UcLzyood{xhPm?O_EZg(&-VOzq)pD!r=#v}60G*YCWDFvZ%Bhf1Xkd# z#IV3REUyg)GYSiJQ1O%fd@rb8SX%Td{nq7hX2EeqEjJoP6cWk#A_(9VLZ|>`w}9vv zKTc?p15(paq{M7cpwlx_kysZbYCu;9&p{TC;u&9-4XLmhpluBVy{%7vj)Kq*L>*+< zWrV|fgREblt2|*y!46tXKQY!4Ki`$es&|+gjgmr0#B#4u>J+kp`{pzqpHEL8SZ}=j zJLx_Vwp$v=sB#AGj5ZqA$Q~Y+=>O-ACwaKmWqSK+$`G?};o?Cu0PCbeG;j=RDvKL z#S#4@B@f)n30Iua52D$@0+0-C+2VuUL!zkW@w$G(|IFc?SLNodzFFf_X=i&eV%{<<$MdBp> zuUOO()a`> zt&(6_pg>`4`H&l!ncYEb2z)63TKM5{t0d<1&?PZ;)c%mUw{p@>l3lEGCev;G`lV;J zGmui3`T9%H;n&QU3iBHFNPgLQ&O7MiBN3y;0<(Fs zUQ=SMoZvGpYWW~YTOdCD(f9sdFIu$9vyM}sRFAuH#F;TgWNxi?EuJOk&$s|KA}5+6u1Z1!>wfhwPx8}s=z5CpjTnOr z!2ZCn0poiUP&_T4CBe3V)5CenM<_o_objJenCFZ*Pp?x?^us(+rZt znV73Nxw#k`0lk-Jgj+r?dxwYg7Nd@L9m{SZbnYc=%R`>}=lhybhHdz9Uzj3*2oabb zpXr3E%==95uSxN?uYl_&mcMpBX<@xoKLkeC8b9&bue(t#kCH=aH>b#8@QD z^H>6hjEg`@uxxz9e-0xs}l&F!P@hKoT??mTx;d=jtyjK|=&{ro3NkZ= zn^=nPH~m2-tMQpeYR7(dG>(6?>Opfv*>OD2(e;t-x{(VPVG2An zRgS=JQjA%kD1u@BWbE-!03ff?a2RAjj@2X65V@rWS5;+RP15^U39_fM+4v5kByk9i zBv8=K&c3+b#^Rx-;OpCWDv67tOMKaG*!z3qxu17{T?In$xNB`e!IiJsu^ewky{|y( zfmXnE{AP;QRr!B%JQve$Edk95Q6&E$H>X%p9;3o^DUO{Du?8xEM`I^|7PH*pqnpre z={gcDr?udgF(4bpwc!doavtJ=kG*5$9mvLQYRS}^Zz4Xzq<|Lz9}Msv@{Q>+c)E&) z4>XZIFy?6aWyW;`oiQs$>_dO-$uOMZ^4lc1?w6H(Lg~r@>7q}609qu^T!7o=TEryZ zc@$|f5L52#sU(aJ1NeJZ1gxM55cVrKzXn#wi6k6vE}_TY>n@doq{E)w+}D-yi{&c7 z*Y+C&!+tYpR-7vh1?68evKB|CS|UWFEXB879|e1?^?Y8t44y2z_tCnV++3FH`b%)) z0V^2x+BHu#r>dnsSPC+j&EV`#>-d%mumoelmpVC|KMi`pss9dP7O;NDw z`~k@5!x(t!Qs_S1O(r(yZVFD44Qamhpqd=zx;b6rxxxNwKAAst;Nu}^@*Fk?wyvdds?;#7OoVM`Q>dlc1vGnB%U{yQf^|MFbo5nz$Jnwfx zEXBZ71z_8oY&)QRTyY3id(BVOEwr%GG+$54_N&H^Th^fAY;d`rL=lV7Q7){fUW;1x zvSQUbklcv9&2CrfMkv_ay0&6NR~8fdRpG4i*6Zh$*CK_4Rm;vd@$%iPT^E z)IR!IL%w^~?YD&$+a1>)(o;Ed?1ty)h0vk>7hW^U?(QCAFjTn-fqx}h@fG8K73Swr zoi>nXTJ>EE{3M{O5OxuI^K?{`1vw`rf0dDx){r9o?R<)|j2=bhat>rgq@@I-_YdUM zhVXhFNcr4nCM8fXYo|&U8STEULBq8Y6K{#{UIgG7jfE8j`Urq6`vGRR0V5;^0lroQ zDA7<|aru2nOLLPZRd0})6jwC-PL!H=4f@gpxZpaWJ1+-gNzC11Yb^oU8$>7wh~0gi zD1XPTMuVNJdYTulj6`Af!yx(S21?PZ15z-TV4Tz%U#fO`KEx5-0-LztfB*wMbc&h< zc#AU}5q25`z)U`-=)&oVFW)6Kd}NY}_s?4xQvdEd_-rXW_mT-`#Jh`tjje{_v`-BZfM^Q>C!aib>N3e4z45Agb>AbptmT(e z*{KO*QAyYh$2CoN!{67hapD-B&JmeE44a7ikwiLSLI#T{;e2;)TzHQvTGQn;t)GSdd&j@#8!3W@A{DdyJgxpM>Ea6Sdp_+#PIZihr6VT*N?#NzCJ3u$atNIx4 zYk6?^JP^`qQyln26#&tsv;H5jD#swRbno+!=zTenR@G{cDbw&=SCAy|$B_|s7q|4j zTVou0?`w<#K9pg?6O2BtU*%PetSFxJqWl^Oz#xwX;oJA=2=(-#1aWT!(BRO$O8Q3(BtSJeJ#0+S zGP5-Fv@vI6CQ_C*FG#z(Z*G*F=;BB}=J4SUZ&K`&2W1wPVipDCcD1$xz1`LU01TsP zN@ku$n%n&D$|Uz^h07&-iQo0l;aPI3j~gDWDFPsNL^y!gef_r(bItBr=W}oR;vW(u z=7Ko0$JK;#glyKO%$H8QEBf}UcIx#OlJ9J9o2u>6Y9vSXnORbZ`lI3=I$Xd$9Bfhv zzxSU+=#G3zs}=f7U#w>H+Q-VGr(ZtV2udGJG#sU4%~3VR`aYi zMgz=U5>UUc8ZHMtt6%)en%jhwt(V4xDg+I=ozH0|09aY$z{hh`2W;VB^?$=sN zI+sj68M3Y^8$KWVL!e$Gb7;+k=D_9b;buH*4e#sN^Zq_^ltDp!XZAwnoPG*2)vUg$&kglIqCB2-(T zQf%YO32|%%zi}5wl`n6sYqe%)YYR@kDOM*}V;yJFOSo5v3x4b!OBcymHrlgi*J&5@8Ir`1pLbD+{hijAkns(C&teG~Z?FR<3ZA3DTDP7O{K z%&OHZ1JrcNlv`@*ZZ>)&}c7WSGB!u zsr%n+jP_M2vUK%5?7Y%!K2vhk_gePgB_Y{v~9w5xs=dJ$}teSV9ygi1N1}t>ko6MS>=5-mL@$9P#dDP!m=P4Gvj9E)f0q wga3c=g^Gh>T|FJt{)(WMFP}e(`&SrJA#+i@;_rB1^tZ3BqNV&($=vUM0F`hZg#Z8m literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step2.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..23dfb8b8813e4be4797bde13be664a9c13d8a8a7 GIT binary patch literal 10758 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step3.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..73f650aa6c98d8057c506b555039a0ffa9fcd969 GIT binary patch literal 12042 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 XT@x7o)h1pkdu!yA literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step4.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5db20506753d81c44e969407b69bd27729dc97 GIT binary patch literal 12462 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⋘T^#*!5tLg6KF1cArHMraKQjUcIupdrEGOTzL8JY)43toUpxC4C&N?p4O z*Y_M-5~@Tg=_?nzhLFX}$ikwN6~zHXpyV{Ueu--3HW5@G zX!>nJ!^4sTJb7^&4=9g$*Clt&-qMxk2oMrEvaSn&n9x7ZzC9^-D{Z=9q+|B0coGcV z^1d2K{T)CD!^G{^A9Y8Pg4X_65kN&pz2z-_dLWi)WuFTd=4X|O1UZ{8ea_so zUu+M9GyRidQ+#eE>)wEE{S$%y^p0Zpgbt0q&EYt!wk*NC@A_%7?9s2^_LbI)LG~_= zV#!uOdFj{_q9>)C5U>0BfNBwA+Pj7~nCAHg>SsZD;C z@8OeC9!;VCL|XW$)jQO(1#sV2&T=|%RJ0{AyQa+t2(Mkhw=Y+KQAX&It}P6!1=`6$ z4-US&fcGgY%@ytw{#An)GCO?W5Y`@l&_3cu^7LvI&=|{@emZ?Gp+^1q{;4U-2Ky1&Hl4LvPZ8?UYZYgJRy?A%8{j8$dbV zvZgFX-tzxri>k8wVt4>*+1wUu=jAU?3HL|3sEF$7M7v;x*sicw?ek`+-sW zc-_ujJPLC@b2b>O5t-){`4ga1;+`1d3Aaub*zbP-{cRbbTx7`aOl37Dw(-4HnB@s6 z_5&fHt>ss2A`r?OY6dPA)FIeid)os!9#Ub~V1@vO_&pvcvHNW@?~F+KVPIX=QaNfO zg_e=|QW@Pxh(Jtlciwx?b4t8@RRm6|5uNHC$`t$om-ozRoJokW(pp|??2K5WSc@4H z14Pvzd?PQ=fr7i@2h#0+?8kz|*TO&xhZ+m_Qdb!ybxDN^aM7lAx z;^N`;D_HO84moGTq34A&wrmyn&NLb`sNmi2*ai$9|2ajlV*kWim`OvZaN4U2@exuC zVGk?dXdLzwx6Ey4gA5tLlbjQHZWa@@nHV+{*G)+9m&vFui0bxpBmgw7bY`=2V7x*K zuCtf)KrcJ~eOf1qyc8tb!Wf?j^yZtk{Mw~R z#SZYKt+qG|Ey!ZGVr8dx=z)x`5U?WFcn#@>Y<$Ge4~CiaI>97##s9^`G$i=b748jX zBA#qMF3g8O?=~;c?{4{BaAJ8cqd*<7G%+#p>zOP_Ng+l6e=2my9|PCyHbq&n?VC=> z+al7AUT}$@?TYnZqx>jDzpM17N+NXMAE%PfSCxpne3utku8LanfE%jA3(vb}SxZz& zRooexulkhpIBE>G5UNuKKCGh(guQ!)8F7DtpRW`5%29ab z+&Mt}XJAIUbbSjOjl!J%eCX@TTguOZf*$_TZq9BABznCaScA6{P!2Su&%sBep(-9AiggjX%!0wj`2g~@?r7f-q#Pj&V$P;pP6aa?iaZr!7#IE znl-vDQS;y=W)P&>7?Enc9m{2CTLja7@Tvaf9ZyER^Q_?1mY@oCbUI zoerykpkTPAB371nQZ;-q*D!di&}}s`!V$>P7iM zdSlH&I8!JULmu@~o&V0VTb(1g22!DY^XpPW5=tMNW<9!Vnq>E3sV^Ftl_mDbH0f_+ zaC-V$YN`Q0Q(d!F=7yqh2$%r07VA~kaWz)8ZyI4I& zAX}rui0gT*_227|o8$Ydcf3=!mo?6^aSA?EK=xC_F#-Dw)eLT)=g+gi*)MF!H?M(V z4?{e`9Y@Z(PJm#-muS@tkonD*<46Lz#c5YOJRsk$Bzzk4c^(jJalr#<28%KQ$f81% z`w}ie=pMaK4#A{4PVf`ZrRmg^87&iB2KgfA)d@kJ|-?oDA`= z4qaF=EBrrf4o`-{!GAdHR}-qb|8pGL|6hCFmr||64G{^R_=2K--M&E_l52DE!UrM%K=OYhv)UK{i? zpLqAuT?^aTSD&AY(8cG=B_TDjenlFi@y`u7_gzvOaw^$y*G6$z&zPb zXrn3Eo(J_A;dYket(_1Nidh22>n0T&X{j6ydfNg<9|_R7Fdj>d9tY)x=-~ zGQQ6AtNAxmZ5=nzskd*eGZEm~!b{{)De zr?S?x50lWP=px5%#O`!6W0NPe@v>nOgvk*`c~M60H+Fz!YpY{|tE1u%1_136+slA!t#`>!p^K#=_+RNUr1;3H&p4@GK7t zV~nb|ICQRd6N;viDg8|9vI)+G_1FXYxvhj1Lkz%fr~4Q)w)cs?#~|4I){Am2YH@Rm zbf>|btluL!GBT2kg-9|wG8s;WY0ZmC*rxobSb6&6c|MFdrReb;)8Imkeyq;FP+GO% z52ggJswb3;0mfT0pt%Wt|C0!>&0FPJ*ZW=;gZLFX;^$fVPMCLPntpj~HVocD57hB= z@56ErIm-{A-Ju~@Sy*9aHJ+Q({b+b9OXIbD2f7mm!&qsSx4Ic(E?Udu9GRXUCnDN@ zoUN_#85i{DxCT>`(qnk0R-ND9pb7CpIJx$C?uMedv5) zRb_K6oh4!3Mg$sX6o!pqrS`$J+`gvr@|3D}fWG4LhsSo$tLUA8svA1-!1K)vl)a?h z;>Yjqwl1^HfF)Eq*J1zOvxUU9O-19u-mk}M{~G(@a6cttl%T8$WI3Jrv|M958+C-K<9B=W ztiKLYV#juo)V=QA)L5Qv^Qa(DrekBL%sGSgzAEvr$rFO{{^;&XD=-%3I;DKrAXZ^Y zWv6w0@sJQDzH!6ve*>kN{k94&pId0JPMz2>Ok~u|3*Gbb zbd~Xs0Q^Dg+Iq%TdaU{F}P;7 zLD+chje1bVRJ-(TDR7PEX>#R<#Uo=Uev$Pq#Z_y!*Z};BZC3QE{(^n24}Lo$n9%{5X-**ohW=w;#4* z9#;Sv{dHkz!`LL!8@H6$k*x($VcFIyNOE4L6cz$EzrzR5CSye5Ctz=GuMhR4#3}&> zTvMYa6Nriji!0q3ETqBbWKz&R-I`D5CA>~V$R{){BICaF(Ux{X*x$S03`zG-%;NBx zvSlOTdtUhbz;lSxR<9G$+2fdn`$({?ZbChNEBF&#WXR^iI1iHoiyIJA;WRp{PWILD z`%}cA5&~t$Ww9TiH2N9k-m^)GR!5)`Z)EyTlHRxa8gzBSwtFENJ$!EmWO=vdNz@{< zgFvNfU2DI?2XB8kg*1P1528$K>4o5{D5ud9=~}r`NySP{z)0Z3lJBs)z2qT3v^4|V zxS5i#fg^7?+*gqAR>3_{9J{6n{JIz&t2sLchI!3VeHl3nI%c!OGn@$mlM>~jFBmS5~0u2<~uS>FBUvk9G z^;t$GU>64VazM_AK|fFufroEs)y>AaR*5`O8^S z>VmG-sNO0mJA{^;D3g<|Cplc}E)qxML><6nTQ@M*)*Xa{2-BOGBoaE51|2a27mT1< zAIrrkfO#cAhf?E&&?ZHC@D)jm6k2{!x3>!_ChrX4UAHs5j(-AKMrDPEX#lLEwV`C} z*U8GI{qfcB=+mFqjvZkHGm}+8S%xjValiR+yUCL?(#FF%m56OxUe@ZZ_lV*An60VT zt*bG|GS$&b@i8~#+Wv@8eDhm&g_H~-k~CG{*RdUS4bObZ3iep>fu0PIi<23RocT>X zKrb5VvB>;EH=qfmN~C4Kyh+~aL95WW_y|@P>A`^J`~=I(hCeLzX+WsoT6kna;+<`m zCd6~P%N=KxVIFHC>$bA%^o;wmQ#bM-DF1x1(EJ_xHo-$-g|>zZO5}w~>NKPCz1!bakC*Xq!A@ub`IU`NLp#z{wWM#j6TA1H``w!Ah=zDz5 zS8fAi3nazeHFr|l73RZl0M$@=s8@9e{m(e%dX>t^Gku!y^U6Wv45RD&o3c1cFG^1aNdl+HrN1q z<=iO$&a&SR3V7RO>90k<6Z7c%k2h_q`vA{q`Gy9>Ao)R!s5`i-Ote@QI=nnZ^27DouFYCSE$JHC-H$IuRF=|%nX4bQ$ z!KFv`@p`t&V?&2nT-(E0CQU@j@tr*&c5jSeUyo}#(VCLrLTVzr?&~m*~C+k7K)Zhsg8^Th;I3@f(Dz^q$Y#9ueeSr zH;l#Mk3H!mzB&jPv3L^a$|(Zi{DMK!mI0l7ElxhpkAk5s4sbE1V%4g-8PX-k?G2E2 z^zK$T{;-dX{Y@zc!m#r5;lCz{5Azx8zULx)@ zJ+UPaDP<1L{G>B(kgVZ(XI$qYk8x4BeSvA2tHQQRPX=l6_1E~Xc=uYbq#-FTV3lt! z->OdO*w_9;vcg&OUq=T^m&V_{y|4D)o60q+RO+!>bS_#R^~mCSUUjp!$AR5fX`*W4 z6E3$?%=f)1aN^A_0ZCOny343HFbo haAkGgiuf;{0L-48M7i+MFX?}Ebrl`uGDS?t{{lVNXDt8# literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step5.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step5.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f55b54a78db43f98c5a360a8d73e091541c5bb GIT binary patch literal 12587 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 dF`;p`^a&f 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step6.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..f69ede0a6ad000283d1be45443c31c6990a1efab GIT binary patch literal 13876 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 X+-*?pK6sh=udJ=Er}j?OD&+qF0O}kw literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step7.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..ee72272ae309144a6dc95e1f35d3a39c21ae7c43 GIT binary patch literal 13985 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

    M+3wbc3FLYse)q|NjK546`llmn?) zhe_gzpQEWuc>Ri+#HrBcLA!ssErkqf{UUi@)a4~T$G^aP(GG8SE@aEA*qNh8-xH0+ z+Ig1z1G_J6gbH;b<8DrZ+IS3u7dIos#N5+l8PJZ-*E!rk!cKJZgdWuv&pX zzCi37d4IL6D#6?QVU%sb(E8y@U%F1;YYs+4*wd~{5I^m6Qz3>3+%Hu$D;H;kR}U(F z$6t!`IndortNjaP=0w9QABF+FK$tGrNBoLCEzHIEZ<)4qTrm$D;ZRZe7<=arIeLRX z3U}6ga60ZmEn0onbJb1;Aw^+^6=H$llksStliq4Oe9f>kM3-O+%ObkV{H2nV_jOxs zFus6l4n@j$MoH|y(6DxmF^=~lEeZ3lnh*I=htM9+1lFm#db&prx9T^3$JGELXGIB? z55nD2&fF-E_Mk2b7SXyi9s;*kLCgA(w6a?CbL9u-A1N}7&~K67Z=bM`4u=hN-OmwB0lM*Z-nhg`G*fa)g4+nV9{^<6Jpvnw0egL6MyzCX}MEV=E0?Ogd z-_R69v-VWkw-Hg)aLU}&pO_%>v)Nfn3$}l(0jBLZ_z{+EROntyRcC&b`>1G)blYj% zSM8*W7RuRGrt?0x+bC%^8!Bn@UC3Z*I*>4znI4j{AgMuPaJE?O%I~rz(|wufVN?5l zgpzJvD1h|%v&O@)1%q3`z1?`6S}Uwu+0)#ina*(A!8jn(S-f8suw`fKuLbM#qs41_ zLOYUj^zW(kEh~%}AIU%)OL~YLPr)bTh{wLTqXD@}IfA6m-PZ4}5DJx@8d3ZL@uf?f zT@miu$A3FNgYQzjuLF44P(w|6xQSzrs5^N8w&4vtq5C#0n?K3^MJ_o12uucRbR_Cu-34Y`e2s%}3hDLij z@MfU}@yDOP^sqC_)>C`N=%LwNwi(fHaZ0b2z%-j{Kzo;IkQ?vAUy8UengMX#Gyy+B z^(>g<>7z#_@jvPO8=SXGjcz1m+(J+C1I>VLKEFHEyEkS;P-6ItB2vyq9WMl;__&DW z1O49Y{)UG7ETJI|5ladNN!(FrbIJ@$>wzD(6L%^nTWc@m@@>7{mXdw`1yG?sh)g6& zA>dRY#0RQ&Bm3tIRM~of@E#L7<$dV!CglC6ju&OoK8@2xj9tur8qkQJVs@h#gw3jq z{F^)&B19|8qJRv9Ih@H1Sx@zftcc!7DnaICXrq{rQ;Z&s)11aH;B}BQ zZ9OR_V$6rN^Q4U>;oYZm!Zi)-zD~l~VuLr?HsVHjvsw>Be`gvMyxWt)+F3q!oT-!v zDw^?vYAPm4W;01pj=swu%2)MDd|@JsdWf_l;?d)MM9Aa`>H-Je-WS1OVcPOa{zo+_ z;_lh~O)h;mUewhsHShqba|5D~CxPi&6xA}J1L;ayvSO(5ZB7JT#El*eGgXg z&@Fu7bldK4tDWNdczE}6_L}U8KRwJbMIVBkUJJH(xW&RvHy0f_a;+ z`HO{7*QfB=KYzro$Rf^vPEQqlCwp&BpDgOwtXm;H&T7t4XlPI2e;1j?!uZ}+o*1j& zSbmiOYn#Pm%ESF#{BPwu1Gg4V8So?-ue}1t!W&zt(~Hc32W*!RuKZLGb&qh?97_us zWKV;j!)#l!pDFFLk;H~`axtDPU^~hn!AIiTs0RXY@grdrW>3)C@q^OVB4$U=S%3+B zRf3Dz@4NJpaOqvBORTnXF%6eSVqo16Y_okdBueO#yE0+_q*fvbvM=|GQRA{qH?lFG zD?buvVd^B9`hE$@=K3E9t)%U&w~Y5)0}CahZ;#p>+j6&a{ldd9AE#eAf_FI^VGuiO zkzD@w<8;XBt-E1Fz4g}-1wv-B8k~}vTeBwfMmn;0JgPQxH*!CTQsP7e8NYjCj8rEN zk$iU>v#H|7Y!4BVXY>@|XjzqRgCrr$Hb1RB9Wvtu>s}vXzDk+?gJ^b$AfbifZAHzP z7)`Msxr|gdT3>A18$|ZDjHoeWV_d^JQv4Fv*z9}3=y14@K_qV^1FzfLkG4?ulz?wg zYatMw;}Im2u)2YKug4b=KmysTt=Ykllyy`Fw9h=S^`C=}?GjG`Q?Zt#LZ&xRN}D6r zb0Hokz6TFdw$Ig)HpNv|*plPzYyDtI#P?-w<2U{CZHoUF%vV>cnNcEpva7$LFW!ZEE7T`}%w*zlq zK8?gK&by;B{;0$nq3?Nzp3Dn8qZWDkgmwXb0;l_t2P#u}m(eUku4q918JGEKz!=R5 z2Q^yP9?t;Ucv*w-ocpgpmJ9RkE2D%D&EjFQM9Zw|-Ee%HDPBZj=wOTD~u0!eu=Z9Kp*b1qrbTPkL@u9Y{B7cJ1Y1Eq9>6nbpG_G@00!PbB zO#GTa7$1fQE|I|wZBl%W`s+PK&QELzJio{gA~}DwWSRLt#3*EXZ#C%h+6_Hce2<6ZIm$Q zoixhtGY(8X{8%Y0NzeZ?#bWG}ZH&L7D`Sjs?j50fc+9{!Xd|?DLqKekrOy|~GdQ-j z=k0dcFc~`ZWm-|G>EQ3rN)!}5lKd5k93(-U{dI;0I3C;C5BQ669$EiW-8$rDFk-0V zPPhqZy`$Z+1g&D)U%a!QSMGcHTl>~3^vy*_{Qlrq%0M61%lrS-P3Dd-=4CvZc%TH7 z>?tFs$k4Y!2Hn3s+iA~KC1EazttqelnzcbHy4*y`3@)$@X~IecjXVeyLR?r60P&bD z{}>L*2hsCDu?IS@c)7XlUMeXF_YxmGKcw*YP&o4t2t*iZ{ zGT(%C&r`JA{{^Y`id4b?N9)|8$fEVkMs-5AQD(9-pO~hc#N$8Q2Sce{SWXEalQ6@c zvESco`|bn-T$}7=odpOC1pGl8DlMP?Mq0Mpq!JCrrrXL9l>}EaDuz|+W_-Nwm;N;& zi&<<&kgHO1p;S>{qig4y7)e164x-m9WuEm8FUZih^mbLr%S^ubwYylptWuUQtH}I# z$cx|7hwp5W7Q*sm-TSmniPO8XYtPotRSmE_h3aB6TQZd>OpiJJ3}4lA0MFY?rgupX zs+;>ZK5o8J|G$2D{(t&+(xt`O|ItYgt}6r{{V!(-(0Y3F4N>tS=09fus3>YE6v`w0 F{|6$$nY{o2 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step8.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..8a180a23dd01e75cefb157e52bf701443dd486d2 GIT binary patch literal 15233 zcmbVzWmr^E*Y-Ix!_bX%3=PuKNDN3LDXqdtiqay|3>|`$64D_J0wPGsASfv*U85-7 zAr0U7Jnzr%{qvsdntk?Jaqn7t?Y+-g6JwyKK}y6(1ONc3mZqu^0N~-WkYNHS?sifr zWCsA?k-=SKwd?Ea-QC@(sVU^U4cCZ8qn6r}larX3n9$~sjg5_8zkVGZ9o5#>wzs!8 zeA&qzJ^J(KPyYC@d+YAye(#z_~77Rb93|M%a`Zp=ex z5)xKcR)&U#Fc{3(*x2~^cxh>AS6A1UFJG#wt4Bvi-@JLVwzig;nOR?7pOcgG?c2Ae z@uq=+ft{V5#l=OfvdzZE#=^qF^z`)j`1roQzUME09v&Xf%*_1!`Ln#d{Ot1beaq_j z(vSR!k>up$guFj_d3ovm+jT$ZCnqO+dwWmLuiAQcCw8`ye+;&^w&wI?m(*{@_8ctk z?-^8WmCjG~^z^)F-_5F63rPBvIW@YlbbNeq9`SAe=;ZQI{kBtAt2L(ae*4FF@7^UP zCH>yN*xug0U$@=y>*VX;zH`%-S=)zSE2qcD$Lq&`13LC5=Kt2VZ5Pc>+Q?GGKLN-o3`8{7poR$dj6ay4;;%%1e7hV?jS zUjUHR&{9=4_LCl>cYs=~JZ2>B zg$n>&36Cjo3~*d%0=x9LI)e!GL8J%6NbE{RQ(UNq_ZMb@yn6e;FEuZ*dJyo(vV(WE zwV!H5eoLd0CIVe&c~z|lBblTmgc%q=*r)T>_0d5Q08e^X|GeLmf_WlH@?J~4Ol@a< z!EYW0zW!D9#I^C$ZyE|D`$};H10HPG+;ZfW^Gi+HArPcVstRtnfd@1ArhVOv_gjht zP4va)bY8e94-I@sb3MI~Yu~br3Q~t*sXd##M;} zf4Nr>0NksLji>|p70C)OIsXgFcr9(v=ewR zxZw`KKeD66_+8W}kU;0YH@xoVLJrTCqbmeb%Io?dY+++HqGA{zvV=U|*f+-TJClMi z(aKqCm6KhqF=qj;&#^=(10i%E{#rZ$;VZc&sX0x~@qrWMWeI^KYj6J1=rE^ifA)Da z-6uei?cW0q2V&J+u)E)FWbdj4^$9qG;0}b%LnZE~=8xtU{r~(U!|* z6MI6(!GjPAr1-W&q4n&I;WajNF$vG;kE$iB1*$h!;N$+VA~$a5j_VX9;=jSbj3L+e zrxxVitZu*Gs}r8#=iSi1vt}bZ(=@$78rM9?HgpX>?#8OW{X1dS?kcd&TB~UtZuY_C z${a`UHD71D@0g8w!qmftmde(as|{}Tnsd1m&lj zMmEBMQ+e%QErY-H!eB&$M#?Nv3$Y0*ON-ZC>AS9iS3L zy|y0(A{EJ#PwEuVaY5RC5;#wQQW@G|>k1bJf0TvH6J9%+Z%gmuLL|Oah{JgfYA$|AHkGIo< zi$X=cMCD}cZ^~w{X+0?li7xT|LCTl?9DgBz(hI!Tu`qZpKUw2zvBT(aIU$|$o-{9K zk&=rJjZ|Km|DFF7INFRsfNI%1)2_hLUDsrPw>$`5{7y;}k(|MZWpV}FV8}kX5N@E) z8w#V5Y|~v9zySzRa^;m~bMfM`@fieE24hS4xb!vdHy)IHiBoBL`8yC=>gbiotSE){ zGfkORhnB8z_3Ghhf#TCofTPNRl>0c4yuCC#o=}*v*X!SP;E!kA|H{aCi2x;WHDJQ= z3%0mQaD}94{bfWd%-^ZofKc!~_QPq=NahiYdP!v5l}jDByR|%Lk31Kyk5>=P?q26IU+jxb2aMCMoJ0}!+&kv!-DnW)R=Rql z#5&TVteRNN!tEQ7928F$X`sBr*9R*ytLRnRq2xMuvuHqFeeqOFytpzn-2C4G4n$rD$v?Gc=1RCMF}jLjUrkHEz@O))wlPaxF^lyy`1Euz`k>E$EYO5 zrysS3HeO-+%qMB;gPFKni2Z$0{cCsBnwk4$Awi~_%E zd3fTz8i^OR&r*1dE5z&@Nhz$FH6$br+VkaOM08FK819@is$?SZ#q*=pae@&hp4vf* z;BpMFwFk6wro*QcArL@*@&cB~${u@k8^;eTImM4EtwnC<`hsQ&n1{#?b00m6eTpJV zn8DB;vZ}|gWOvo#F7ZYQpJAEA|MKD|)+(@u9=@%Ch6~C-Vs3x?^+eX?(z0ucaTOd6 zpl-e8;LLp@GOH&_3zzXv5F%HWy9wSc|MU8&2q;F=Vm6ROSYIq~Yrf!mKpgCmL2Bv^`S}};nRQhB>dqyb4CF607hsM1n3ShZ1k`%SNaf8 z;U_|;zJhi?OF2y`(;hq`C%Az>tQT7Q^L9*M#@vnD3$VaS$fpmT;AR-KN5xRpS~0<# zwgGK$M2hn8e-iM-e?kWRF2bql^J98UwqyI{(I|AM^*G-b*ty*6U(tp7baT#}8bD=a z6^Nrka0nyFDt>41Cp|OfyMy4c1PRvpj*y!mJ>KqqA&2N*x)ZPyU{Nhaik(&Q=llW4 zrAKvQK)d`>o4g#F3A8&28MYyAdcs)e#xMe19^6!x^}t$`0Q<)}LTc}$A&`5aMxX)& z2kZG}LVL`Eos9SCoX;*(L<8W|DB+czAUeB=IEajp4ujXTIRx6eRV3VJrBO%aY=R5@ z;xl5ykrlZ`$sY6z*R2|0VAXkqF5*ELxpIR|ZL$_{zjmVdY|b&zt}%Bp!^e~?l$?Ow zN}4E-;zipDktF)K4Y6>QgDaIyJbJ2O*%9kZf)bvXk|027=?C3t!k3bRopN%VzJQ1@ zxP&MruCVYSthM{X)mf-`yF_`}zW<*W-a{VJQpa%~W+BGrg4RK?seK;JPHjtN0 z9vb_3eQlvX;}=lJ9;^Ov@<874_E@^t!^{PkiwQvNSp27UyK+PUqb^v&i*Z>3K64jE zMbctQB2FF;NT4&cg{->2N&rRk_N}q@_~HPCb$3Ru7oHeHmwSKJ$51*f59PtB1GF0) zeO{T{V%p3I6OG#VFgf`B5rdzwV=T0XAo}Pa>y<-?q5Nd*Vuag$;J#QHmLAVtp7wrX zu5cFtHI^;yf@Sv)&dy!g6(z~Ac)*mZJn?6SE_>hsK3b?U*T_1!hW z`-4blEyM-gv@=K2K3hwsHaFL57&9hxZkiEha9`Aq)2lJ~b|*1*N2OI(odjzlct~3j zf8&!AAsw5*HI+iGGD>;9^lB1l`U7Rj1NXKzJji?QjkLNS`+vjTxBeRiyzm`(D_r;&M&~YqfW3{L7ZN#u{vfmz7OUCW#e(~^G|ts*##-K`N>ufF#+s9!*5S5 z7jg)!-+5Rlts%d467h;SzViqSR~bfuoW)4TXf!l{ZW1Dpxsd z6jJ(q*?8pJ%U2%2vsvyaR!j^_3b4RkFA@(qIU)Y_&4k@*%Kk+gF@ABDQJiNoM zRdiA%>lPKIlL6!&w6TL3x!OwlO*pi+6D!M_A8ceCJXVU12`_(pCa+o0(m+m@=hkWj zZ6WwZwgS&1dMhi^Q!Jp4N3vS{j^kYOx!F!U^f7P8)FT)4!>BLBuFSE9A%SZJ_MGs# zjx)i{|1vw8nuBS!A8R0|%%oPWIc&JVFrpr?J_WUjWsaIs3S<&3S9}HAeECDEO$N_@ zR8muJ`QIW;BZQue0p*84yUImC^H2OCGwg4Qk(iEZ9QUF0Rs<{Nlck=8J`t9281e}$ z0;&Q0L>B5cC^m^6e1tGj+->ZDS?p53Mk}l`b~!1(q=tS{C&t3X&;qzM|1UGZ(k*Mr zi6AMG#!x~Y-klozit|%>%k&Lu+G} zfp@*U>$&(>r6KEpO4hC6G8EMWwK_&}cRr5b3H zNQ%{qRKxke#I0vkl`Hu&`Hug#F^u`aqwsgZqp=>>GU!bo`cKfmb1A&ekhiu^4+~?aU3hl$nKz|fH z1_cx)pyv@?_!>ePaT_@df@T{(O`l%Zyy&iWff_P*2k%&Bm|M|=vZ1q3XnlF&8rzrs+x4 zT0Yz{Ou>TTd@c}I$fWMOW=Sm49*Q*+MGvvh{!OKz{Fnh4RTfh4)?X#t)&Ie8qLP8w zFY6aDW}ro+Jti|`OvD_t$!HT~-3S^07ZIp^4-cTaU;}b`-p!C1*io3TZgFmQ6 zTY$Lj;J9vSa=MiUhEKY2GOR9D?IV01cKO8Y+Qf(qpuxSW?o_~^NQIV?4YNd1wx+Q` zBA5lR$L^Wj3BI)j2^oFMu2KT&(Z{5*$MMr)4rvSA!Einyv_GcA;`#~l`#Zq3q{X5x z0Ng$L2@`KWVK9fR5)c>$(8by39z1tcg4MjIUz4r`JT@BveRBQ7O@G){`ZQ5`P{=UMXkBh|{mXJn;m-imO*r)08r6{QP zN2`x%(p^Sf%Bd3q2S{5pfJ!LZ>Rh zNB5fQDQ7lAe?CB-2P}(?x={$DDeRrYr9!hQ9-ltRhWL=UT+F8c&A8&n3_f4kJ#EO_ z@_KV0tWUr+vZFf%hEgb}0x1g8BVE|;Mw_l6o!-pieXs*`ueV#@LDIPj<4>%yQ}Jf( znt)o9zOpye{txtMy^UfVmbkTe(r3GO4*YQu9fz`OXNJVz)Whg(LtBaSbrT$158wtO zS6RNg+U#1)w~delwO;^;!T4?JE-DQ1h2(bzBuj*Dsr60orT9{cf&qr9L47y&YFO>) zeV?re@M78ii6eYC=}xFsd=?>x6mAOyF?|kcz#rx;cx(vl9BhS(Df_TVWcJ-8=)qR6 zh+HdV-CZyzjgnX?V^hn~ZP$Os>L1o|zrrdZhg(?Chh5c>)E)B@%U|DfhzUP_m zLfGK5oWjAw1Oe19-0_B>wwxQ))&r@z0FoPNY^(^ftE19$YPE>>AK+w!5MxT!=)2eH z5N!ZALml7i!aRWP6*^KSZ}B9-WD`aymtWsb=OjLxp5~R!mPk^FVXh!6GaLR=T*@pzunvTdDhka|u(uMbj|B%VZp!ZN4OB5s+ zaS8$?Qz-a}QUcw4%`0AtEFm4KF@9=wGSuF!_nPX(OZjt{i)ha5$)l10nVik`-T^_-k`Lh&#jV z*@b8zacl6UUhVPxfa>fTP%Yb4-TDJq_u{xi7LrXO!Rc}p8FZn6H%x#1>!kyAPH@sy zpq^cx?L%Ook++>^r3wY4Y5}aDTb@$lA;*(!e|75eG~dPF#k19U+=z*&oYYPtZlXO@FK(8!EWj*>bEvXoJWhq~;=Ajdiw+6xb5J51 z>u&e@%1MX<3G~;pV0KKrZ2tExd%dfqKRp{`_qci5uK`jDr~4xuCAr`rO%vY?GYvW|eRWRk z7W$a}{^w6h0Jpc~T^)EoLVL-W2@`HU-dCnyrjsZmRje#LR1f0bt5nI9;=IU6FGWUi zF#K`c>mV3lyA&-XdBzXvs1@vQP&jk$_eAcM(DpzpZh^=*_y1TyK1!UD3};h1FXO|o z-aK+AqIcoDw6^}&Fia&r*8B@yRcO2v`U7I$+Myl#iHVw9q|1{Dle^+Vny1$&3JjJL zld9!GvyCpwlB1WXk)VN7s$Q|9XI5G-(8t-ijsjZSf7}LI8F-+d-1u8A_Y=SeF{`0` z5iw5IZNHD(qo#L&WlHKGB8=FH*gr@FKwEREP)0ywF|l(ty=99WpW^yOgn*WMf9b-{ zHxU|~R|ZzkkGXIYK*5%d?ph2zjEN22Gzhf@Ds8rIqlI(O-i*j>R{-$#zB?ac&e09J zGk4cHKPNk}W#HyzL7Mr{lH!4)vH9!n8e*Y{ zeiAoD!{9YDk9arC|L&M!^wQeIS&+W?1L9nOqi1!qJS&Fwq}Pb2xp{g+krYE0mu=Mw z0LwMCrdLZzXE!h=t8G%e+-QT&vUGRR=6{}*6o!1BR*NTRcj-m=3z;^X!o`9yo@s$; zMeqTG?p9THa~T{*yvp8N(;po1ZQmbn%H9EXsm>Qn7}1Rk{z!aLp&gN~sNwg(t8p>I z3ho+$0tXi|-lxnouRoO)v4+3WwOR6UVctOe%A|Puk*5b|3T~V8ZLZYH^btR0`2#|= zif)W>OxHqq2$ejp*t;|-rpe6nJ0zmvj0UlD0O<|98!QU$6K zg>zX2Zd}TzzJ`37z08fc{%C*fD8B%i?XO9Ox%)b85471m72S#Zu-hYowx-70t!l&P z@c^WK9Pls!!GPgybFSm#zP4aY_4C8m(qz4toU8>KKRbjxJtV)C-SIX_LPPkHMbW~K z7S5zgso}eiZC#i2B=_QnHSSBL>$p)_Mf-KqcZ;JJanMKp2mDn``Tcw1B#lgT*C+QL zMDpSpaCrdp(lb|PcboB7b=X3zx0z2L#dq+SIWVrRV=c_&Jw0t$yo-rV5Dc zjs8t7ygO{=C|X{s_xXz~p6Fe5u3XW%ZCn5R@zPCu%OOAmBuSy{~lmYMw?`Ppj!!@w0KGo1Uh#LpoLEGYCv3L9?-8V zHkqp5{M(ZtDbvQNnghmNylPZ{PVEz;?tnB+9HIk6z4)3D58+wRtU+h$((hdOKH1%6 zY^-2cnYEQZ=46c$34EU>Q*l(?Ck)#p!h)kl+_KPaI7QN=D!yt^_pB8(ubW^>#jNuw zFqbp0z8a^g_$cuq7?=3g#Ir4qRhnGQN*T)0zU1=$idz^(tPubE@*bcDi3Gjzc7;c& z$9sLv=YbhYiX^jPbkB~@Y(+33@l@#8?&=~<0IU?ywt6&d>-mh1zga_=_R$d@dvlSK z2lF_p>A<&G)azA2@1?CTdzXV27fP$%xsC_liM0l{pT#i*sgvpHh(sFeF{v#FS0nz*G(-R;q*+f(D*du>LB*p-Tv={WwlD#{^|B zU+}N2I5@Jm3DVq`5vysU_gMN@p4kgQBa4czV!UoleA|mO?MEw*oRcTzaC=ro4m3Ty zlOZ1;%;Ct9EMANrn6}3#^mI90P|JR((PEwA{kh5X>CUallhH%omh5!^&&1>lY*@0JD#}I{og`?pt5SH=$%`)mhM^b?l4g% z^$Jub={RJ?a@lfn-15-*ZP^hw&f0W69UXnwTy?)EZu01k=K}6w;tTOUCT{jt?^{aB zj8a~^z{$Azo2Nb<~o@>UQz*7c;pbsxZ1Y9Bv=_AcpeybHCVEAG-@@&8I&11Co zLa=m=jZJ!vDzxf|nk`F~BS#R$YPKo9fy>sF{+iP9L z_-c+OSEeNZdMucyp)2%Sxt*rvyS;XR8M{`n;dxBTQ&yewk6zbVWmi4i4$auy*Zm}$&x+NSys%4q@;{~5mwU_p&N*0tZ$>gasy}@XK zgtfRjQ1TaDm{^4ODYS!&%0F`CzUJth0_1*@MWG{3giTQy=Kch4ibU(}2kO-Z&L;6s zdgphA%E}vVyHigGGBCnlOT6e7t;RHtzn~8y)_Pmm`GXQuHX$h=!S!8Bpg=Y>zBE)9 ztD!k6FCo&BFcM|OdGisSUwp662}QC*;j`8Epa}zCJnN=n^9^1nvYelXRD%UKP0^gI zIQ><^Z^JHT@1DAq9Kj}8-1+rJEB%11oLVN68cAkmvW_S_C#52bEI2u&JXqLD$`^3N(S$lIy|}iJ&(&?xh`MR#x^Y8 zNYk9ZlJ6Z?pSFde-6PJuU^&Nc9+y5VbNg3a7M_ay>z@o;6&prnSHi`Sq&7j0B#( zn;vRHwAVIV!HTDc&iUHKB4H5oA@5V-2&tK7>c`C&Usae$31Kz9SE0{^6T&LEHNO&G z$Oiio7Q9VG7~Y~HK%qDG&89+S&N)N$ZvMV^b>@$;&N$%=u>w%tvr2Sli(6gOK?Ieq z?973=N`<#?DP1K-h@zFk8{F@l-rov&_`Dlix^8yLq@A}yPl77hP-^M3Hf$!Xe{*B_ zcljTo-M27CB7(eOrP<1R*5G;Z^V33HJWgH3*p>rcA#%V>67URp;+3hWWc!{jHJU@U!^-OQw5BGu*egSc@O= zU$@x|kwAva+pLcGcYm80Y1!3HEag=CcwSNfTJ4kco$q1{dD4dJt)wUQ;~;>I#$S;S zCUNNE0MOil9s~m>CCY+r@d(GntH*LA>58Jq0h!ba6nQc}lBNFxKDgTt$aGWI zu>A`Ma#jKw6f%DjOp&AG&_KifrOAO*Xt)zJJyNFdz9>f$0MSWXto!7!K`Gi}SMa19 z+rWu%M4^68WTEvx`v+F=6OF-#e=EE4E_?2TZu8+nhpKC#yr>sucKRP3QSXbrAVGp{ zQ4xSA94_hw`Fy5qhucJ1v+JpSJYi2vkWT4-2NeIU#fPW5tim>38;^8A!M9i{_a9^@ zbv^!nNJ#RSk@v4Y?PU9h;bMS@?{@vB-bITy{@I)L1W4JUptMyKm`$gaYkIQ0s@rHc z_|+T*615f!4ou(;>(<~gP-5sjuOexE8W5P#cLMU#L%>-;f|>Wj-%Yrh>X4vle6;|O ze*Ly5jjU&KyV1g}tR^`P>TJn6* z`G8{PVT-p=bbY&3l@z-8g22)Ww+n)*T!HPkTLjwlCE=pQ{;m6*t5MpxY7yMoL4_V# znVk?7Ked)co4NK=n^<)Ki&HHv0I2i>6?$pU^(3RG}ndzjo+w@Pr!JO&fV;`1EFe3VV0H&cHL;s+AphsAkCE#2&vu_My<6=pl8Aw?x-5S4}}Wj4V(|659o>A zMNl)(;m))u>`cHa-rRV*Y~=8uM%xxXQX~|*O>9nf|F!Hs1wLj2(y(=qi-X^KP~WoiY#@uMOWNmz`gbg{} z^&}8HSTit(Z&<5lT9Jh~oz}{kTtZp-+t5kXZwtIK`4z>`U z+O*&u!b49r2JVY0-C>Ki5!qS7aFBOY6nDWlR|HMxIe-n(--wkZ|BYJ{@ zQdFB6aU47UO%0Q!^?S(O?|Evz@1uuE{=aJfJ8_pyajDreR&1uqOzBm6!Lj#7TkeWf z_h)IW6Q^Ud4k{sIo9dI>JuQUbc>921O)zDf%{2`L?S}O--&A|FRc$a4!BF3+;+Dq1 z@e`#6$O5UkBjE5V6e?O^#*F4cRMKK9?0|%~pgdE}Fm$lu7xY!(Zz%3-u^`&w7TQo8 zeINRHb6!`UQ5iu0l%Agd>pj;ej0m?&g2mS68NFkVX1oE5km7i35{rwR zt%~}aOADu@eK+GU@zx=yYZKuUDBijG>IEGJ7Y_W&qbm20&E6+5KH8T-ooml7+r%27 z>F*DpHcH6-JXy8-ljM*4Dt&S|D=QaR`C|9oxiN4<4H5%}gPlE=F1A}QC~WgkGI(Gk zls<&qk}lz1SD|DT<%C?gRx>T;M$f9=eXFQaGdD(_q89{vT6hMAT!}0gWlPnmZx_$) z^M>gGH^#}_K_I8i>ECZI75VG&$3{d-VYhO;|` z!?%rw9W~%wgDL0HD{l&MOn!qQQ>A-1)d`DAUlm{)82Yv5{r6dOP^5un8Wky*iV+~V ziH_w6nFEB~AF)hT%{swFr3_xc1ts9fCXehF@ZF7ov8GKx{ciQowOG4-Pw+xGH_Gue z-(BWGNaxv~a7!OePoR)za(9g^Ax(r1Bd{hRuP+j*k}t72DZ=fUuXY2emW1>MX0J|p zG`m~@!Im&ibQvMmqWq&NZBTTXbrvyxGSvK!oWQGuEXYtrbE5KzaB+}_@IV=GGZsb# z;dAiA^k6XCI}o1sPkn=y%rNVt60)9_7Gn8$i*bKV z+u}CAO!DPJ#m#kQ?vKQkd{jMTC<+u3CThCU&S#k_FtH=RdYbj|o@n)XWz^ zA8?ZLq;rOHqLt!P^ZdaFU)O57#RhG19!o3L!c%$e>sCyG}`{vX^5YY3py~6 zzOt%ZOZ|Uv1k=<%gNxq%Tyd$=yWc2cvq6#|*It~_2UWw}6E=Q-73buN@#k?8j2Gx4 zpC`n|#^1{|U$x?`+IWe%<*`E)|IXv>$!DBxYa)cuF}GBF=^Tn`^j7)-8&Lnu&EDES-*dK^_cRdq#1<%d(5i6}ipl|z>xuL?7TUC%!J}OP(yxho;qmnRD+f4`$#rZMF9Li=RN+j(Xs_Klmc%+%> zqDR1sdBdxmiXv<{OqB_2pN7R)B1_#2gI`X`%HrY7wCSGoBJ>{Z5acD`ilDi=BpFWW zdNn79&g9CBVrK>%v@^4MS|~8x9;^QT=K$P1hsUdy&c^ilqSJrp`w3U{(MJ|c83SfU zl*AE`Uba0j6+m}KV9g7hoNp(cY_hp8sjre7jJUF382vfW{3)^DV|0$eSlmGJ`j2M@TT5lkpUNmKu3`O~~V#ENDqIIZDSaGbWB@IYn!&u<{r|}oO zFg%C`^iUc%tMPVgr%SH2fcEY-4s?n62vCBX+MX+MOqINE!NahopNnE45lhtoErnDU zY&djZMpQ`>0=?&mH1Gy^U4HG<&*Be@^Xr8%M6}XQKikquEWOeI=k{a9P_GbG8sgUf zJR;fY3K*LR22s=Z>d8XrVFS_@g^%!i814C@g>$YY@@0f&(UJoeLi>7C;V*QPSV5Wz z0*xnKoUUxqXSBs48EsHL2?%{Wb;8vw)X=&;;B+^~=ZFaBAv^(mC!%jarL6`~GT8m9 zWTxfY*YH~4_BVZ$f!(l(Ec%AxW6GB9k&-fP`wvF8TiU=qsX`lh<1#Lb=K|>L88EIG z8shcprvO+v!yL0`BUdwUs6>G6Ki1EY|HNz6YKCY0&m#}VQ{{J0zU=|(;A$2<3ROsc`{sn#Rg2d62qZLHvYhr zl$>Te8rS{66c&!gI2zZFW0sbFm6cq%0hgbhr+&qOTpZHKxHJ3|o?Z9(-rmSK#+7?0 z`bh>PhbPcwH`n!2Cb8@IWruHzU@q-I;(8oClB15y#{H$)mx$7v#(IhsN?+Ni;fc|e z;&{X4N$FP7`Q>#XKu`qZLidf*J2=MXEqwPl)rYEW9QgF!10RS#(ypipwZ1EE8y#UX?fM6iQjC+h^evK ze%sLM_^@>qPJ*Dcz!%#!YiefD@h09hOHPdGfvj6X({qIGe6){Oqbs|`7S6+Qj^HT_ zV=B7YbyL9IV2Pw3fk8M2>YPRP02`CvS zp!xe>*OKn%&s>sHS>FOTf072@z-*u4XSW+CC&Sl>J;dR=(*7?#%<@n~JUU7LipXRo zB&-I?ty0RdanimV*9+roKFpdZ&QwL7Js)g(r5dPt)KMp9_uS5&8u{9U$z(R z*gFcYw#r1H0eAamdOP`vM(>rzpVe!ND_ZB>Ew0ql7O-wOJ(p(s`Vsx2f(Ex4@74&hwtFkm4lKw&K^$j_>nxNI0${TE<)fKE zUN^O!!S|-`OCbwiOThZC=w3YqoA5~xf*D`?MY8g@|Jj_PaMy=BzQ;>ujn#=4-I;8% z{F7OOPzxqqx0HjekF~1AY^TQ|rD?wZmltTTH+ZLY(6tP1b|!|h@#a~oo$u-?!D%{|9xZolXCK{l2l7m2YaI#t8*Evk7W%G z8R?v)c@zW)O#7hSBoX9kU&R8}8`9HpQ};KG2ZOskDQx(r?5mB!R1??D4GBmK z{&@c2&QgR%1X12=v1j%qLM_fzW!)V&a6^IT{Z@FB>j625YJVNYJfP=WEIiG_+xhnL zZ1%M!NL*L$;;0eM)LkRjzs?WC=PKj;SEWJ6oIa5kD1@bG<~-nMQmRndz)C5brR$i= zsG5G_VCnng?OtEJtb8ep2VpPebDhp3J&Lx zzMIX19+N}saBvdH{*X_WkQKTemg#OTs6}bf)5P*NJ3BB7k3Dm%&W~un;I*vi3}=F) zvFddo&>0S(isauPGj%@U-SMJO5>X;N{Zqy=mNpgw{Wup$RAFVPL07vF<1x*S21Ha} zpS`Nsi>!8JjTP&_LttM1{4HqD`p~eBNf+YcFU<@1@C!OBQF=YpDoE%G_{{UapKAYC o&dCBRGu1yX!P)f;-Txq<)tqaZ`zjK6+y8O2)bv!VRZyY-4_FeaC;$Ke literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step9.png b/en/chapter_divide_and_conquer/build_binary_tree_problem.assets/built_tree_step9.png new file mode 100644 index 0000000000000000000000000000000000000000..923dd9036d3f7c6c602eb4c069aae8b797ef3481 GIT binary patch literal 15889 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 b7%o3ecNEl*!}0I0-hh(4s$7LEEa3kF3-&)O literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/build_binary_tree_problem/index.html b/en/chapter_divide_and_conquer/build_binary_tree_problem/index.html new file mode 100644 index 000000000..0726ef1c2 --- /dev/null +++ b/en/chapter_divide_and_conquer/build_binary_tree_problem/index.html @@ -0,0 +1,4405 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12.3 Building binary tree problem - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    12.3   Building binary tree problem

    +
    +

    Question

    +

    Given the preorder traversal preorder and inorder traversal inorder of a binary tree, construct the binary tree and return the root node of the binary tree. Assume that there are no duplicate values in the nodes of the binary tree (as shown in the diagram below).

    +
    +

    Example data for building a binary tree

    +

    Figure 12-5   Example data for building a binary tree

    + +

    1.   Determining if it is a divide and conquer problem

    +

    The original problem of constructing a binary tree from preorder and inorder is a typical divide and conquer problem.

    +
      +
    • The problem can be decomposed: From the perspective of divide and conquer, we can divide the original problem into two subproblems: building the left subtree and building the right subtree, plus one operation: initializing the root node. For each subtree (subproblem), we can still use the above division method, dividing it into smaller subtrees (subproblems), until the smallest subproblem (empty subtree) is reached.
    • +
    • The subproblems are independent: The left and right subtrees are independent of each other, with no overlap. When building the left subtree, we only need to focus on the parts of the inorder and preorder traversals that correspond to the left subtree. The same applies to the right subtree.
    • +
    • Solutions to subproblems can be combined: Once the solutions for the left and right subtrees (solutions to subproblems) are obtained, we can link them to the root node to obtain the solution to the original problem.
    • +
    +

    2.   How to divide the subtrees

    +

    Based on the above analysis, this problem can be solved using divide and conquer, but how do we use the preorder traversal preorder and inorder traversal inorder to divide the left and right subtrees?

    +

    By definition, preorder and inorder can be divided into three parts.

    +
      +
    • Preorder traversal: [ Root | Left Subtree | Right Subtree ], for example, the tree in the diagram corresponds to [ 3 | 9 | 2 1 7 ].
    • +
    • Inorder traversal: [ Left Subtree | Root | Right Subtree ], for example, the tree in the diagram corresponds to [ 9 | 3 | 1 2 7 ].
    • +
    +

    Using the data in the diagram above, we can obtain the division results as shown in the steps below.

    +
      +
    1. The first element 3 in the preorder traversal is the value of the root node.
    2. +
    3. Find the index of the root node 3 in inorder, and use this index to divide inorder into [ 9 | 3 | 1 2 7 ].
    4. +
    5. Based on the division results of inorder, it is easy to determine the number of nodes in the left and right subtrees as 1 and 3, respectively, thus dividing preorder into [ 3 | 9 | 2 1 7 ].
    6. +
    +

    Dividing the subtrees in preorder and inorder traversals

    +

    Figure 12-6   Dividing the subtrees in preorder and inorder traversals

    + +

    3.   Describing subtree intervals based on variables

    +

    Based on the above division method, we have now obtained the index intervals of the root, left subtree, and right subtree in preorder and inorder. To describe these index intervals, we need the help of several pointer variables.

    +
      +
    • Let the index of the current tree's root node in preorder be denoted as \(i\).
    • +
    • Let the index of the current tree's root node in inorder be denoted as \(m\).
    • +
    • Let the index interval of the current tree in inorder be denoted as \([l, r]\).
    • +
    +

    As shown in the Table 12-1 , the above variables can represent the index of the root node in preorder as well as the index intervals of the subtrees in inorder.

    +

    Table 12-1   Indexes of the root node and subtrees in preorder and inorder traversals

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Root node index in preorderSubtree index interval in inorder
    Current tree\(i\)\([l, r]\)
    Left subtree\(i + 1\)\([l, m-1]\)
    Right subtree\(i + 1 + (m - l)\)\([m+1, r]\)
    +
    +

    Please note, the meaning of \((m-l)\) in the right subtree root index is "the number of nodes in the left subtree", which is suggested to be understood in conjunction with the diagram below.

    +

    Indexes of the root node and left and right subtrees

    +

    Figure 12-7   Indexes of the root node and left and right subtrees

    + +

    4.   Code implementation

    +

    To improve the efficiency of querying \(m\), we use a hash table hmap to store the mapping of elements in inorder to their indexes:

    +
    +
    +
    +
    build_tree.py
    def dfs(
    +    preorder: list[int],
    +    inorder_map: dict[int, int],
    +    i: int,
    +    l: int,
    +    r: int,
    +) -> TreeNode | None:
    +    """构建二叉树:分治"""
    +    # 子树区间为空时终止
    +    if r - l < 0:
    +        return None
    +    # 初始化根节点
    +    root = TreeNode(preorder[i])
    +    # 查询 m ,从而划分左右子树
    +    m = inorder_map[preorder[i]]
    +    # 子问题:构建左子树
    +    root.left = dfs(preorder, inorder_map, i + 1, l, m - 1)
    +    # 子问题:构建右子树
    +    root.right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r)
    +    # 返回根节点
    +    return root
    +
    +def build_tree(preorder: list[int], inorder: list[int]) -> TreeNode | None:
    +    """构建二叉树"""
    +    # 初始化哈希表,存储 inorder 元素到索引的映射
    +    inorder_map = {val: i for i, val in enumerate(inorder)}
    +    root = dfs(preorder, inorder_map, 0, 0, len(inorder) - 1)
    +    return root
    +
    +
    +
    +
    build_tree.cpp
    /* 构建二叉树:分治 */
    +TreeNode *dfs(vector<int> &preorder, unordered_map<int, int> &inorderMap, int i, int l, int r) {
    +    // 子树区间为空时终止
    +    if (r - l < 0)
    +        return NULL;
    +    // 初始化根节点
    +    TreeNode *root = new TreeNode(preorder[i]);
    +    // 查询 m ,从而划分左右子树
    +    int m = inorderMap[preorder[i]];
    +    // 子问题:构建左子树
    +    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1);
    +    // 子问题:构建右子树
    +    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
    +    // 返回根节点
    +    return root;
    +}
    +
    +/* 构建二叉树 */
    +TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    unordered_map<int, int> inorderMap;
    +    for (int i = 0; i < inorder.size(); i++) {
    +        inorderMap[inorder[i]] = i;
    +    }
    +    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorder.size() - 1);
    +    return root;
    +}
    +
    +
    +
    +
    build_tree.java
    /* 构建二叉树:分治 */
    +TreeNode dfs(int[] preorder, Map<Integer, Integer> inorderMap, int i, int l, int r) {
    +    // 子树区间为空时终止
    +    if (r - l < 0)
    +        return null;
    +    // 初始化根节点
    +    TreeNode root = new TreeNode(preorder[i]);
    +    // 查询 m ,从而划分左右子树
    +    int m = inorderMap.get(preorder[i]);
    +    // 子问题:构建左子树
    +    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);
    +    // 子问题:构建右子树
    +    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
    +    // 返回根节点
    +    return root;
    +}
    +
    +/* 构建二叉树 */
    +TreeNode buildTree(int[] preorder, int[] inorder) {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    Map<Integer, Integer> inorderMap = new HashMap<>();
    +    for (int i = 0; i < inorder.length; i++) {
    +        inorderMap.put(inorder[i], i);
    +    }
    +    TreeNode root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);
    +    return root;
    +}
    +
    +
    +
    +
    build_tree.cs
    /* 构建二叉树:分治 */
    +TreeNode? DFS(int[] preorder, Dictionary<int, int> inorderMap, int i, int l, int r) {
    +    // 子树区间为空时终止
    +    if (r - l < 0)
    +        return null;
    +    // 初始化根节点
    +    TreeNode root = new(preorder[i]);
    +    // 查询 m ,从而划分左右子树
    +    int m = inorderMap[preorder[i]];
    +    // 子问题:构建左子树
    +    root.left = DFS(preorder, inorderMap, i + 1, l, m - 1);
    +    // 子问题:构建右子树
    +    root.right = DFS(preorder, inorderMap, i + 1 + m - l, m + 1, r);
    +    // 返回根节点
    +    return root;
    +}
    +
    +/* 构建二叉树 */
    +TreeNode? BuildTree(int[] preorder, int[] inorder) {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    Dictionary<int, int> inorderMap = [];
    +    for (int i = 0; i < inorder.Length; i++) {
    +        inorderMap.TryAdd(inorder[i], i);
    +    }
    +    TreeNode? root = DFS(preorder, inorderMap, 0, 0, inorder.Length - 1);
    +    return root;
    +}
    +
    +
    +
    +
    build_tree.go
    /* 构建二叉树:分治 */
    +func dfsBuildTree(preorder []int, inorderMap map[int]int, i, l, r int) *TreeNode {
    +    // 子树区间为空时终止
    +    if r-l < 0 {
    +        return nil
    +    }
    +    // 初始化根节点
    +    root := NewTreeNode(preorder[i])
    +    // 查询 m ,从而划分左右子树
    +    m := inorderMap[preorder[i]]
    +    // 子问题:构建左子树
    +    root.Left = dfsBuildTree(preorder, inorderMap, i+1, l, m-1)
    +    // 子问题:构建右子树
    +    root.Right = dfsBuildTree(preorder, inorderMap, i+1+m-l, m+1, r)
    +    // 返回根节点
    +    return root
    +}
    +
    +/* 构建二叉树 */
    +func buildTree(preorder, inorder []int) *TreeNode {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    inorderMap := make(map[int]int, len(inorder))
    +    for i := 0; i < len(inorder); i++ {
    +        inorderMap[inorder[i]] = i
    +    }
    +
    +    root := dfsBuildTree(preorder, inorderMap, 0, 0, len(inorder)-1)
    +    return root
    +}
    +
    +
    +
    +
    build_tree.swift
    /* 构建二叉树:分治 */
    +func dfs(preorder: [Int], inorderMap: [Int: Int], i: Int, l: Int, r: Int) -> TreeNode? {
    +    // 子树区间为空时终止
    +    if r - l < 0 {
    +        return nil
    +    }
    +    // 初始化根节点
    +    let root = TreeNode(x: preorder[i])
    +    // 查询 m ,从而划分左右子树
    +    let m = inorderMap[preorder[i]]!
    +    // 子问题:构建左子树
    +    root.left = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1, l: l, r: m - 1)
    +    // 子问题:构建右子树
    +    root.right = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1 + m - l, l: m + 1, r: r)
    +    // 返回根节点
    +    return root
    +}
    +
    +/* 构建二叉树 */
    +func buildTree(preorder: [Int], inorder: [Int]) -> TreeNode? {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    let inorderMap = inorder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
    +    return dfs(preorder: preorder, inorderMap: inorderMap, i: inorder.startIndex, l: inorder.startIndex, r: inorder.endIndex - 1)
    +}
    +
    +
    +
    +
    build_tree.js
    /* 构建二叉树:分治 */
    +function dfs(preorder, inorderMap, i, l, r) {
    +    // 子树区间为空时终止
    +    if (r - l < 0) return null;
    +    // 初始化根节点
    +    const root = new TreeNode(preorder[i]);
    +    // 查询 m ,从而划分左右子树
    +    const m = inorderMap.get(preorder[i]);
    +    // 子问题:构建左子树
    +    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);
    +    // 子问题:构建右子树
    +    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
    +    // 返回根节点
    +    return root;
    +}
    +
    +/* 构建二叉树 */
    +function buildTree(preorder, inorder) {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    let inorderMap = new Map();
    +    for (let i = 0; i < inorder.length; i++) {
    +        inorderMap.set(inorder[i], i);
    +    }
    +    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);
    +    return root;
    +}
    +
    +
    +
    +
    build_tree.ts
    /* 构建二叉树:分治 */
    +function dfs(
    +    preorder: number[],
    +    inorderMap: Map<number, number>,
    +    i: number,
    +    l: number,
    +    r: number
    +): TreeNode | null {
    +    // 子树区间为空时终止
    +    if (r - l < 0) return null;
    +    // 初始化根节点
    +    const root: TreeNode = new TreeNode(preorder[i]);
    +    // 查询 m ,从而划分左右子树
    +    const m = inorderMap.get(preorder[i]);
    +    // 子问题:构建左子树
    +    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);
    +    // 子问题:构建右子树
    +    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
    +    // 返回根节点
    +    return root;
    +}
    +
    +/* 构建二叉树 */
    +function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    let inorderMap = new Map<number, number>();
    +    for (let i = 0; i < inorder.length; i++) {
    +        inorderMap.set(inorder[i], i);
    +    }
    +    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);
    +    return root;
    +}
    +
    +
    +
    +
    build_tree.dart
    /* 构建二叉树:分治 */
    +TreeNode? dfs(
    +  List<int> preorder,
    +  Map<int, int> inorderMap,
    +  int i,
    +  int l,
    +  int r,
    +) {
    +  // 子树区间为空时终止
    +  if (r - l < 0) {
    +    return null;
    +  }
    +  // 初始化根节点
    +  TreeNode? root = TreeNode(preorder[i]);
    +  // 查询 m ,从而划分左右子树
    +  int m = inorderMap[preorder[i]]!;
    +  // 子问题:构建左子树
    +  root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);
    +  // 子问题:构建右子树
    +  root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
    +  // 返回根节点
    +  return root;
    +}
    +
    +/* 构建二叉树 */
    +TreeNode? buildTree(List<int> preorder, List<int> inorder) {
    +  // 初始化哈希表,存储 inorder 元素到索引的映射
    +  Map<int, int> inorderMap = {};
    +  for (int i = 0; i < inorder.length; i++) {
    +    inorderMap[inorder[i]] = i;
    +  }
    +  TreeNode? root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);
    +  return root;
    +}
    +
    +
    +
    +
    build_tree.rs
    /* 构建二叉树:分治 */
    +fn dfs(
    +    preorder: &[i32],
    +    inorder_map: &HashMap<i32, i32>,
    +    i: i32,
    +    l: i32,
    +    r: i32,
    +) -> Option<Rc<RefCell<TreeNode>>> {
    +    // 子树区间为空时终止
    +    if r - l < 0 {
    +        return None;
    +    }
    +    // 初始化根节点
    +    let root = TreeNode::new(preorder[i as usize]);
    +    // 查询 m ,从而划分左右子树
    +    let m = inorder_map.get(&preorder[i as usize]).unwrap();
    +    // 子问题:构建左子树
    +    root.borrow_mut().left = dfs(preorder, inorder_map, i + 1, l, m - 1);
    +    // 子问题:构建右子树
    +    root.borrow_mut().right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r);
    +    // 返回根节点
    +    Some(root)
    +}
    +
    +/* 构建二叉树 */
    +fn build_tree(preorder: &[i32], inorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    let mut inorder_map: HashMap<i32, i32> = HashMap::new();
    +    for i in 0..inorder.len() {
    +        inorder_map.insert(inorder[i], i as i32);
    +    }
    +    let root = dfs(preorder, &inorder_map, 0, 0, inorder.len() as i32 - 1);
    +    root
    +}
    +
    +
    +
    +
    build_tree.c
    /* 构建二叉树:分治 */
    +TreeNode *dfs(int *preorder, int *inorderMap, int i, int l, int r, int size) {
    +    // 子树区间为空时终止
    +    if (r - l < 0)
    +        return NULL;
    +    // 初始化根节点
    +    TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));
    +    root->val = preorder[i];
    +    root->left = NULL;
    +    root->right = NULL;
    +    // 查询 m ,从而划分左右子树
    +    int m = inorderMap[preorder[i]];
    +    // 子问题:构建左子树
    +    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1, size);
    +    // 子问题:构建右子树
    +    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r, size);
    +    // 返回根节点
    +    return root;
    +}
    +
    +/* 构建二叉树 */
    +TreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    int *inorderMap = (int *)malloc(sizeof(int) * MAX_SIZE);
    +    for (int i = 0; i < inorderSize; i++) {
    +        inorderMap[inorder[i]] = i;
    +    }
    +    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorderSize - 1, inorderSize);
    +    free(inorderMap);
    +    return root;
    +}
    +
    +
    +
    +
    build_tree.kt
    /* 构建二叉树:分治 */
    +fun dfs(
    +    preorder: IntArray,
    +    inorderMap: Map<Int?, Int?>,
    +    i: Int,
    +    l: Int,
    +    r: Int
    +): TreeNode? {
    +    // 子树区间为空时终止
    +    if (r - l < 0) return null
    +    // 初始化根节点
    +    val root = TreeNode(preorder[i])
    +    // 查询 m ,从而划分左右子树
    +    val m = inorderMap[preorder[i]]!!
    +    // 子问题:构建左子树
    +    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1)
    +    // 子问题:构建右子树
    +    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r)
    +    // 返回根节点
    +    return root
    +}
    +
    +/* 构建二叉树 */
    +fun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {
    +    // 初始化哈希表,存储 inorder 元素到索引的映射
    +    val inorderMap = HashMap<Int?, Int?>()
    +    for (i in inorder.indices) {
    +        inorderMap[inorder[i]] = i
    +    }
    +    val root = dfs(preorder, inorderMap, 0, 0, inorder.size - 1)
    +    return root
    +}
    +
    +
    +
    +
    build_tree.rb
    [class]{}-[func]{dfs}
    +
    +[class]{}-[func]{build_tree}
    +
    +
    +
    +
    build_tree.zig
    [class]{}-[func]{dfs}
    +
    +[class]{}-[func]{buildTree}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    The diagram below shows the recursive process of building the binary tree, where each node is established during the "descending" process, and each edge (reference) is established during the "ascending" process.

    +
    +
    +
    +

    Recursive process of building a binary tree

    +
    +
    +

    built_tree_step2

    +
    +
    +

    built_tree_step3

    +
    +
    +

    built_tree_step4

    +
    +
    +

    built_tree_step5

    +
    +
    +

    built_tree_step6

    +
    +
    +

    built_tree_step7

    +
    +
    +

    built_tree_step8

    +
    +
    +

    built_tree_step9

    +
    +
    +
    +

    Figure 12-8   Recursive process of building a binary tree

    + +

    Each recursive function's division results of preorder and inorder are shown in the diagram below.

    +

    Division results in each recursive function

    +

    Figure 12-9   Division results in each recursive function

    + +

    Assuming the number of nodes in the tree is \(n\), initializing each node (executing a recursive function dfs()) takes \(O(1)\) time. Thus, the overall time complexity is \(O(n)\).

    +

    The hash table stores the mapping of inorder elements to their indexes, with a space complexity of \(O(n)\). In the worst case, when the binary tree degenerates into a linked list, the recursive depth reaches \(n\), using \(O(n)\) stack frame space. Therefore, the overall space complexity is \(O(n)\).

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_bubble_sort.png b/en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_bubble_sort.png new file mode 100644 index 0000000000000000000000000000000000000000..261ccf21bccb4e76bb9341f8dd7e19593ad7d0c1 GIT binary patch literal 24306 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 OU8^Z+DVEDy2mc>TSUddy literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_parallel_computing.png b/en/chapter_divide_and_conquer/divide_and_conquer.assets/divide_and_conquer_parallel_computing.png new file mode 100644 index 0000000000000000000000000000000000000000..4abbb183d457e50874eb657b090afebb1f730980 GIT binary patch literal 15428 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + 12.1 Divide and conquer algorithms - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    12.1   Divide and conquer algorithms

    +

    Divide and conquer, fully referred to as "divide and rule", is an extremely important and common algorithm strategy. Divide and conquer is usually based on recursion and includes two steps: "divide" and "conquer".

    +
      +
    1. Divide (partition phase): Recursively decompose the original problem into two or more sub-problems until the smallest sub-problem is reached and the process terminates.
    2. +
    3. Conquer (merge phase): Starting from the smallest sub-problem with a known solution, merge the solutions of the sub-problems from bottom to top to construct the solution to the original problem.
    4. +
    +

    As shown in the Figure 12-1 , "merge sort" is one of the typical applications of the divide and conquer strategy.

    +
      +
    1. Divide: Recursively divide the original array (original problem) into two sub-arrays (sub-problems), until the sub-array has only one element (smallest sub-problem).
    2. +
    3. Conquer: Merge the ordered sub-arrays (solutions to the sub-problems) from bottom to top to obtain an ordered original array (solution to the original problem).
    4. +
    +

    Merge sort's divide and conquer strategy

    +

    Figure 12-1   Merge sort's divide and conquer strategy

    + +

    12.1.1   How to identify divide and conquer problems

    +

    Whether a problem is suitable for a divide and conquer solution can usually be judged based on the following criteria.

    +
      +
    1. The problem can be decomposed: The original problem can be decomposed into smaller, similar sub-problems and can be recursively divided in the same manner.
    2. +
    3. Sub-problems are independent: There is no overlap between sub-problems, and they are independent and can be solved separately.
    4. +
    5. Solutions to sub-problems can be merged: The solution to the original problem is obtained by merging the solutions of the sub-problems.
    6. +
    +

    Clearly, merge sort meets these three criteria.

    +
      +
    1. The problem can be decomposed: Recursively divide the array (original problem) into two sub-arrays (sub-problems).
    2. +
    3. Sub-problems are independent: Each sub-array can be sorted independently (sub-problems can be solved independently).
    4. +
    5. Solutions to sub-problems can be merged: Two ordered sub-arrays (solutions to the sub-problems) can be merged into one ordered array (solution to the original problem).
    6. +
    +

    12.1.2   Improving efficiency through divide and conquer

    +

    Divide and conquer can not only effectively solve algorithm problems but often also improve algorithm efficiency. In sorting algorithms, quicksort, merge sort, and heap sort are faster than selection, bubble, and insertion sorts because they apply the divide and conquer strategy.

    +

    Then, we may ask: Why can divide and conquer improve algorithm efficiency, and what is the underlying logic? In other words, why are the steps of decomposing a large problem into multiple sub-problems, solving the sub-problems, and merging the solutions of the sub-problems into the solution of the original problem more efficient than directly solving the original problem? This question can be discussed from the aspects of the number of operations and parallel computation.

    +

    1.   Optimization of operation count

    +

    Taking "bubble sort" as an example, it requires \(O(n^2)\) time to process an array of length \(n\). Suppose we divide the array from the midpoint into two sub-arrays as shown in the Figure 12-2 , then the division requires \(O(n)\) time, sorting each sub-array requires \(O((n / 2)^2)\) time, and merging the two sub-arrays requires \(O(n)\) time, with the total time complexity being:

    +
    \[ +O(n + (\frac{n}{2})^2 \times 2 + n) = O(\frac{n^2}{2} + 2n) +\]
    +

    Bubble sort before and after array partition

    +

    Figure 12-2   Bubble sort before and after array partition

    + +

    Next, we calculate the following inequality, where the left and right sides are the total number of operations before and after the partition, respectively:

    +
    \[ +\begin{aligned} +n^2 & > \frac{n^2}{2} + 2n \newline +n^2 - \frac{n^2}{2} - 2n & > 0 \newline +n(n - 4) & > 0 +\end{aligned} +\]
    +

    This means that when \(n > 4\), the number of operations after partitioning is fewer, and the sorting efficiency should be higher. Please note that the time complexity after partitioning is still quadratic \(O(n^2)\), but the constant factor in the complexity has decreased.

    +

    Further, what if we keep dividing the sub-arrays from their midpoints into two sub-arrays until the sub-arrays have only one element left? This idea is actually "merge sort," with a time complexity of \(O(n \log n)\).

    +

    Furthermore, what if we set several more partition points and evenly divide the original array into \(k\) sub-arrays? This situation is very similar to "bucket sort," which is very suitable for sorting massive data, and theoretically, the time complexity can reach \(O(n + k)\).

    +

    2.   Optimization through parallel computation

    +

    We know that the sub-problems generated by divide and conquer are independent of each other, thus they can usually be solved in parallel. This means that divide and conquer can not only reduce the algorithm's time complexity, but also facilitate parallel optimization by the operating system.

    +

    Parallel optimization is especially effective in environments with multiple cores or processors, as the system can process multiple sub-problems simultaneously, making fuller use of computing resources and significantly reducing the overall runtime.

    +

    For example, in the "bucket sort" shown in the Figure 12-3 , we distribute massive data evenly across various buckets, then the sorting tasks of all buckets can be distributed to different computing units, and the results are merged after completion.

    +

    Bucket sort's parallel computation

    +

    Figure 12-3   Bucket sort's parallel computation

    + +

    12.1.3   Common applications of divide and conquer

    +

    On one hand, divide and conquer can be used to solve many classic algorithm problems.

    +
      +
    • Finding the closest point pair: This algorithm first divides the set of points into two parts, then finds the closest point pair in each part, and finally finds the closest point pair that spans the two parts.
    • +
    • Large integer multiplication: For example, the Karatsuba algorithm, which breaks down large integer multiplication into several smaller integer multiplications and additions.
    • +
    • Matrix multiplication: For example, the Strassen algorithm, which decomposes large matrix multiplication into multiple small matrix multiplications and additions.
    • +
    • Tower of Hanoi problem: The Tower of Hanoi problem can be solved recursively, a typical application of the divide and conquer strategy.
    • +
    • Solving inverse pairs: In a sequence, if a number in front is greater than a number behind, these two numbers form an inverse pair. Solving the inverse pair problem can utilize the idea of divide and conquer, with the aid of merge sort.
    • +
    +

    On the other hand, divide and conquer is very widely applied in the design of algorithms and data structures.

    +
      +
    • Binary search: Binary search divides an ordered array from the midpoint index into two parts, then decides which half to exclude based on the comparison result between the target value and the middle element value, and performs the same binary operation in the remaining interval.
    • +
    • Merge sort: Already introduced at the beginning of this section, no further elaboration is needed.
    • +
    • Quicksort: Quicksort selects a pivot value, then divides the array into two sub-arrays, one with elements smaller than the pivot and the other with elements larger than the pivot, and then performs the same partitioning operation on these two parts until the sub-array has only one element.
    • +
    • Bucket sort: The basic idea of bucket sort is to distribute data to multiple buckets, then sort the elements within each bucket, and finally retrieve the elements from the buckets in order to obtain an ordered array.
    • +
    • Trees: For example, binary search trees, AVL trees, red-black trees, B-trees, B+ trees, etc., their operations such as search, insertion, and deletion can all be considered applications of the divide and conquer strategy.
    • +
    • Heap: A heap is a special type of complete binary tree, whose various operations, such as insertion, deletion, and heapification, actually imply the idea of divide and conquer.
    • +
    • Hash table: Although hash tables do not directly apply divide and conquer, some hash collision resolution solutions indirectly apply the divide and conquer strategy, for example, long lists in chained addressing being converted to red-black trees to improve query efficiency.
    • +
    +

    It can be seen that divide and conquer is a subtly pervasive algorithmic idea, embedded within various algorithms and data structures.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_divide_and_conquer.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_divide_and_conquer.png new file mode 100644 index 0000000000000000000000000000000000000000..aeab11a0657c71ffd29f51464f20f3fb01c01382 GIT binary patch literal 32200 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_example.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_example.png new file mode 100644 index 0000000000000000000000000000000000000000..c45d0e5c5c24f184b5971dbc9d8156d6deea1f66 GIT binary patch literal 12261 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f1_step2.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f1_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..852c897d72d7c676a22ae19d19350a26f14d1eae GIT binary patch literal 9103 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 Vce!MlM86yvU(?XV6kfsx{TJ~&0A~OI literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step2.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..390eeca8be8b778acd80490a098d889093122048 GIT binary patch literal 9400 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 K%2vuiL;ep4(adiE literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step4.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f2_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..ec75fde61a7df64a788f2b522730dbd7175830c5 GIT binary patch literal 14501 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 Ah5!Hn literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step1.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..e0fd3f5201640ee9584f000e565f685403d74c12 GIT binary patch literal 9571 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 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step3.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..d3b2e1dfc0f25279f277e91e363c9aa37555376c GIT binary patch literal 13132 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 K=?Y1s&;J7?F)^k9 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step4.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_f3_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..95af9ff43a50d38f4484f0b15614b367edec64bb GIT binary patch literal 15960 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 TX^XUI|0^rXs>xJInTGsdKE^N5 literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_recursive_tree.png b/en/chapter_divide_and_conquer/hanota_problem.assets/hanota_recursive_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..cebed6b1ce97616c4c80551953650c9f0ef81ad4 GIT binary patch literal 18093 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 VY0Jr~sSf=h0Z&&ymvv4FO#qHUnTr4b literal 0 HcmV?d00001 diff --git a/en/chapter_divide_and_conquer/hanota_problem/index.html b/en/chapter_divide_and_conquer/hanota_problem/index.html new file mode 100644 index 000000000..7dde6e8dd --- /dev/null +++ b/en/chapter_divide_and_conquer/hanota_problem/index.html @@ -0,0 +1,4378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12.4 Tower of Hanoi Problem - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    12.4   Tower of Hanoi Problem

    +

    In both merge sorting and building binary trees, we decompose the original problem into two subproblems, each half the size of the original problem. However, for the Tower of Hanoi, we adopt a different decomposition strategy.

    +
    +

    Question

    +

    Given three pillars, denoted as A, B, and C. Initially, pillar A is stacked with \(n\) discs, arranged in order from top to bottom from smallest to largest. Our task is to move these \(n\) discs to pillar C, maintaining their original order (as shown below). The following rules must be followed during the disc movement process:

    +
      +
    1. A disc can only be picked up from the top of a pillar and placed on top of another pillar.
    2. +
    3. Only one disc can be moved at a time.
    4. +
    5. A smaller disc must always be on top of a larger disc.
    6. +
    +
    +

    Example of the Tower of Hanoi

    +

    Figure 12-10   Example of the Tower of Hanoi

    + +

    We denote the Tower of Hanoi of size \(i\) as \(f(i)\). For example, \(f(3)\) represents the Tower of Hanoi of moving \(3\) discs from A to C.

    +

    1.   Consider the base case

    +

    As shown below, for the problem \(f(1)\), i.e., when there is only one disc, we can directly move it from A to C.

    +
    +
    +
    +

    Solution for a problem of size 1

    +
    +
    +

    hanota_f1_step2

    +
    +
    +
    +

    Figure 12-11   Solution for a problem of size 1

    + +

    As shown below, for the problem \(f(2)\), i.e., when there are two discs, since the smaller disc must always be above the larger disc, B is needed to assist in the movement.

    +
      +
    1. First, move the smaller disc from A to B.
    2. +
    3. Then move the larger disc from A to C.
    4. +
    5. Finally, move the smaller disc from B to C.
    6. +
    +
    +
    +
    +

    Solution for a problem of size 2

    +
    +
    +

    hanota_f2_step2

    +
    +
    +

    hanota_f2_step3

    +
    +
    +

    hanota_f2_step4

    +
    +
    +
    +

    Figure 12-12   Solution for a problem of size 2

    + +

    The process of solving the problem \(f(2)\) can be summarized as: moving two discs from A to C with the help of B. Here, C is called the target pillar, and B is called the buffer pillar.

    +

    2.   Decomposition of subproblems

    +

    For the problem \(f(3)\), i.e., when there are three discs, the situation becomes slightly more complicated.

    +

    Since we already know the solutions to \(f(1)\) and \(f(2)\), we can think from a divide-and-conquer perspective and consider the two top discs on A as a unit, performing the steps shown below. This way, the three discs are successfully moved from A to C.

    +
      +
    1. Let B be the target pillar and C the buffer pillar, and move the two discs from A to B.
    2. +
    3. Move the remaining disc from A directly to C.
    4. +
    5. Let C be the target pillar and A the buffer pillar, and move the two discs from B to C.
    6. +
    +
    +
    +
    +

    Solution for a problem of size 3

    +
    +
    +

    hanota_f3_step2

    +
    +
    +

    hanota_f3_step3

    +
    +
    +

    hanota_f3_step4

    +
    +
    +
    +

    Figure 12-13   Solution for a problem of size 3

    + +

    Essentially, we divide the problem \(f(3)\) into two subproblems \(f(2)\) and one subproblem \(f(1)\). By solving these three subproblems in order, the original problem is resolved. This indicates that the subproblems are independent, and their solutions can be merged.

    +

    From this, we can summarize the divide-and-conquer strategy for solving the Tower of Hanoi shown in the following image: divide the original problem \(f(n)\) into two subproblems \(f(n-1)\) and one subproblem \(f(1)\), and solve these three subproblems in the following order.

    +
      +
    1. Move \(n-1\) discs with the help of C from A to B.
    2. +
    3. Move the remaining one disc directly from A to C.
    4. +
    5. Move \(n-1\) discs with the help of A from B to C.
    6. +
    +

    For these two subproblems \(f(n-1)\), they can be recursively divided in the same manner until the smallest subproblem \(f(1)\) is reached. The solution to \(f(1)\) is already known and requires only one move.

    +

    Divide and conquer strategy for solving the Tower of Hanoi

    +

    Figure 12-14   Divide and conquer strategy for solving the Tower of Hanoi

    + +

    3.   Code implementation

    +

    In the code, we declare a recursive function dfs(i, src, buf, tar) whose role is to move the \(i\) discs on top of pillar src with the help of buffer pillar buf to the target pillar tar:

    +
    +
    +
    +
    hanota.py
    def move(src: list[int], tar: list[int]):
    +    """移动一个圆盘"""
    +    # 从 src 顶部拿出一个圆盘
    +    pan = src.pop()
    +    # 将圆盘放入 tar 顶部
    +    tar.append(pan)
    +
    +def dfs(i: int, src: list[int], buf: list[int], tar: list[int]):
    +    """求解汉诺塔问题 f(i)"""
    +    # 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if i == 1:
    +        move(src, tar)
    +        return
    +    # 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf)
    +    # 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar)
    +    # 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar)
    +
    +def solve_hanota(A: list[int], B: list[int], C: list[int]):
    +    """求解汉诺塔问题"""
    +    n = len(A)
    +    # 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C)
    +
    +
    +
    +
    hanota.cpp
    /* 移动一个圆盘 */
    +void move(vector<int> &src, vector<int> &tar) {
    +    // 从 src 顶部拿出一个圆盘
    +    int pan = src.back();
    +    src.pop_back();
    +    // 将圆盘放入 tar 顶部
    +    tar.push_back(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +void dfs(int i, vector<int> &src, vector<int> &buf, vector<int> &tar) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i == 1) {
    +        move(src, tar);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +void solveHanota(vector<int> &A, vector<int> &B, vector<int> &C) {
    +    int n = A.size();
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.java
    /* 移动一个圆盘 */
    +void move(List<Integer> src, List<Integer> tar) {
    +    // 从 src 顶部拿出一个圆盘
    +    Integer pan = src.remove(src.size() - 1);
    +    // 将圆盘放入 tar 顶部
    +    tar.add(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +void dfs(int i, List<Integer> src, List<Integer> buf, List<Integer> tar) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i == 1) {
    +        move(src, tar);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +void solveHanota(List<Integer> A, List<Integer> B, List<Integer> C) {
    +    int n = A.size();
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.cs
    /* 移动一个圆盘 */
    +void Move(List<int> src, List<int> tar) {
    +    // 从 src 顶部拿出一个圆盘
    +    int pan = src[^1];
    +    src.RemoveAt(src.Count - 1);
    +    // 将圆盘放入 tar 顶部
    +    tar.Add(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +void DFS(int i, List<int> src, List<int> buf, List<int> tar) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i == 1) {
    +        Move(src, tar);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    DFS(i - 1, src, tar, buf);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    Move(src, tar);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    DFS(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +void SolveHanota(List<int> A, List<int> B, List<int> C) {
    +    int n = A.Count;
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    DFS(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.go
    /* 移动一个圆盘 */
    +func move(src, tar *list.List) {
    +    // 从 src 顶部拿出一个圆盘
    +    pan := src.Back()
    +    // 将圆盘放入 tar 顶部
    +    tar.PushBack(pan.Value)
    +    // 移除 src 顶部圆盘
    +    src.Remove(pan)
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +func dfsHanota(i int, src, buf, tar *list.List) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if i == 1 {
    +        move(src, tar)
    +        return
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfsHanota(i-1, src, tar, buf)
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar)
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfsHanota(i-1, buf, src, tar)
    +}
    +
    +/* 求解汉诺塔问题 */
    +func solveHanota(A, B, C *list.List) {
    +    n := A.Len()
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfsHanota(n, A, B, C)
    +}
    +
    +
    +
    +
    hanota.swift
    /* 移动一个圆盘 */
    +func move(src: inout [Int], tar: inout [Int]) {
    +    // 从 src 顶部拿出一个圆盘
    +    let pan = src.popLast()!
    +    // 将圆盘放入 tar 顶部
    +    tar.append(pan)
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +func dfs(i: Int, src: inout [Int], buf: inout [Int], tar: inout [Int]) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if i == 1 {
    +        move(src: &src, tar: &tar)
    +        return
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i: i - 1, src: &src, buf: &tar, tar: &buf)
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src: &src, tar: &tar)
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i: i - 1, src: &buf, buf: &src, tar: &tar)
    +}
    +
    +/* 求解汉诺塔问题 */
    +func solveHanota(A: inout [Int], B: inout [Int], C: inout [Int]) {
    +    let n = A.count
    +    // 列表尾部是柱子顶部
    +    // 将 src 顶部 n 个圆盘借助 B 移到 C
    +    dfs(i: n, src: &A, buf: &B, tar: &C)
    +}
    +
    +
    +
    +
    hanota.js
    /* 移动一个圆盘 */
    +function move(src, tar) {
    +    // 从 src 顶部拿出一个圆盘
    +    const pan = src.pop();
    +    // 将圆盘放入 tar 顶部
    +    tar.push(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +function dfs(i, src, buf, tar) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i === 1) {
    +        move(src, tar);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +function solveHanota(A, B, C) {
    +    const n = A.length;
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.ts
    /* 移动一个圆盘 */
    +function move(src: number[], tar: number[]): void {
    +    // 从 src 顶部拿出一个圆盘
    +    const pan = src.pop();
    +    // 将圆盘放入 tar 顶部
    +    tar.push(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +function dfs(i: number, src: number[], buf: number[], tar: number[]): void {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i === 1) {
    +        move(src, tar);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +function solveHanota(A: number[], B: number[], C: number[]): void {
    +    const n = A.length;
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.dart
    /* 移动一个圆盘 */
    +void move(List<int> src, List<int> tar) {
    +  // 从 src 顶部拿出一个圆盘
    +  int pan = src.removeLast();
    +  // 将圆盘放入 tar 顶部
    +  tar.add(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +void dfs(int i, List<int> src, List<int> buf, List<int> tar) {
    +  // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +  if (i == 1) {
    +    move(src, tar);
    +    return;
    +  }
    +  // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +  dfs(i - 1, src, tar, buf);
    +  // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +  move(src, tar);
    +  // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +  dfs(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +void solveHanota(List<int> A, List<int> B, List<int> C) {
    +  int n = A.length;
    +  // 将 A 顶部 n 个圆盘借助 B 移到 C
    +  dfs(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.rs
    /* 移动一个圆盘 */
    +fn move_pan(src: &mut Vec<i32>, tar: &mut Vec<i32>) {
    +    // 从 src 顶部拿出一个圆盘
    +    let pan = src.remove(src.len() - 1);
    +    // 将圆盘放入 tar 顶部
    +    tar.push(pan);
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +fn dfs(i: i32, src: &mut Vec<i32>, buf: &mut Vec<i32>, tar: &mut Vec<i32>) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if i == 1 {
    +        move_pan(src, tar);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move_pan(src, tar);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar);
    +}
    +
    +/* 求解汉诺塔问题 */
    +fn solve_hanota(A: &mut Vec<i32>, B: &mut Vec<i32>, C: &mut Vec<i32>) {
    +    let n = A.len() as i32;
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C);
    +}
    +
    +
    +
    +
    hanota.c
    /* 移动一个圆盘 */
    +void move(int *src, int *srcSize, int *tar, int *tarSize) {
    +    // 从 src 顶部拿出一个圆盘
    +    int pan = src[*srcSize - 1];
    +    src[*srcSize - 1] = 0;
    +    (*srcSize)--;
    +    // 将圆盘放入 tar 顶部
    +    tar[*tarSize] = pan;
    +    (*tarSize)++;
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +void dfs(int i, int *src, int *srcSize, int *buf, int *bufSize, int *tar, int *tarSize) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i == 1) {
    +        move(src, srcSize, tar, tarSize);
    +        return;
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, srcSize, tar, tarSize, buf, bufSize);
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, srcSize, tar, tarSize);
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, bufSize, src, srcSize, tar, tarSize);
    +}
    +
    +/* 求解汉诺塔问题 */
    +void solveHanota(int *A, int *ASize, int *B, int *BSize, int *C, int *CSize) {
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(*ASize, A, ASize, B, BSize, C, CSize);
    +}
    +
    +
    +
    +
    hanota.kt
    /* 移动一个圆盘 */
    +fun move(src: MutableList<Int>, tar: MutableList<Int>) {
    +    // 从 src 顶部拿出一个圆盘
    +    val pan = src.removeAt(src.size - 1)
    +    // 将圆盘放入 tar 顶部
    +    tar.add(pan)
    +}
    +
    +/* 求解汉诺塔问题 f(i) */
    +fun dfs(i: Int, src: MutableList<Int>, buf: MutableList<Int>, tar: MutableList<Int>) {
    +    // 若 src 只剩下一个圆盘,则直接将其移到 tar
    +    if (i == 1) {
    +        move(src, tar)
    +        return
    +    }
    +    // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
    +    dfs(i - 1, src, tar, buf)
    +    // 子问题 f(1) :将 src 剩余一个圆盘移到 tar
    +    move(src, tar)
    +    // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
    +    dfs(i - 1, buf, src, tar)
    +}
    +
    +/* 求解汉诺塔问题 */
    +fun solveHanota(A: MutableList<Int>, B: MutableList<Int>, C: MutableList<Int>) {
    +    val n = A.size
    +    // 将 A 顶部 n 个圆盘借助 B 移到 C
    +    dfs(n, A, B, C)
    +}
    +
    +
    +
    +
    hanota.rb
    [class]{}-[func]{move}
    +
    +[class]{}-[func]{dfs}
    +
    +[class]{}-[func]{solve_hanota}
    +
    +
    +
    +
    hanota.zig
    [class]{}-[func]{move}
    +
    +[class]{}-[func]{dfs}
    +
    +[class]{}-[func]{solveHanota}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    As shown below, the Tower of Hanoi forms a recursive tree with a height of \(n\), each node representing a subproblem, corresponding to an open dfs() function, thus the time complexity is \(O(2^n)\), and the space complexity is \(O(n)\).

    +

    Recursive tree of the Tower of Hanoi

    +

    Figure 12-15   Recursive tree of the Tower of Hanoi

    + +
    +

    Quote

    +

    The Tower of Hanoi originates from an ancient legend. In a temple in ancient India, monks had three tall diamond pillars and \(64\) differently sized golden discs. The monks continuously moved the discs, believing that when the last disc is correctly placed, the world would end.

    +

    However, even if the monks moved a disc every second, it would take about \(2^{64} \approx 1.84×10^{19}\) seconds, approximately 585 billion years, far exceeding current estimates of the age of the universe. Thus, if the legend is true, we probably do not need to worry about the world ending.

    +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_divide_and_conquer/index.html b/en/chapter_divide_and_conquer/index.html new file mode 100644 index 000000000..1556d9359 --- /dev/null +++ b/en/chapter_divide_and_conquer/index.html @@ -0,0 +1,3794 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Chapter 12.   Divide and conquer - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    Chapter 12.   Divide and conquer

    +

    Divide and Conquer

    +
    +

    Abstract

    +

    Difficult problems are decomposed layer by layer, each decomposition making them simpler.

    +

    Divide and conquer reveals an important truth: start with simplicity, and nothing is complex anymore.

    +
    +

    Chapter contents

    + + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_divide_and_conquer/summary/index.html b/en/chapter_divide_and_conquer/summary/index.html new file mode 100644 index 000000000..b0f21e1dc --- /dev/null +++ b/en/chapter_divide_and_conquer/summary/index.html @@ -0,0 +1,3784 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12.5 Summary - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    12.5   Summary

    +
      +
    • Divide and conquer is a common algorithm design strategy, which includes dividing (partitioning) and conquering (merging) two stages, usually implemented based on recursion.
    • +
    • The basis for judging whether it is a divide and conquer algorithm problem includes: whether the problem can be decomposed, whether the subproblems are independent, and whether the subproblems can be merged.
    • +
    • Merge sort is a typical application of the divide and conquer strategy, which recursively divides the array into two equal-length subarrays until only one element remains, and then starts merging layer by layer to complete the sorting.
    • +
    • Introducing the divide and conquer strategy can often improve algorithm efficiency. On one hand, the divide and conquer strategy reduces the number of operations; on the other hand, it is conducive to parallel optimization of the system after division.
    • +
    • Divide and conquer can solve many algorithm problems and is widely used in data structure and algorithm design, where its presence is ubiquitous.
    • +
    • Compared to brute force search, adaptive search is more efficient. Search algorithms with a time complexity of \(O(\log n)\) are usually based on the divide and conquer strategy.
    • +
    • Binary search is another typical application of the divide and conquer strategy, which does not include the step of merging the solutions of subproblems. We can implement binary search through recursive divide and conquer.
    • +
    • In the problem of constructing binary trees, building the tree (original problem) can be divided into building the left and right subtree (subproblems), which can be achieved by partitioning the index intervals of the preorder and inorder traversals.
    • +
    • In the Tower of Hanoi problem, a problem of size \(n\) can be divided into two subproblems of size \(n-1\) and one subproblem of size \(1\). By solving these three subproblems in sequence, the original problem is consequently resolved.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_dynamic_programming/dp_problem_features.assets/climbing_stairs_constraint_example.png b/en/chapter_dynamic_programming/dp_problem_features.assets/climbing_stairs_constraint_example.png new file mode 100644 index 0000000000000000000000000000000000000000..28e050093e218bec384fae4671a4cb518bbd8918 GIT binary patch literal 21575 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_problem_features.assets/climbing_stairs_constraint_state_transfer.png b/en/chapter_dynamic_programming/dp_problem_features.assets/climbing_stairs_constraint_state_transfer.png new file mode 100644 index 0000000000000000000000000000000000000000..ed1bf07380901010bb5ecc29eac8df2b798e8165 GIT binary patch literal 19318 zcmbTdWmKEb6E=J&!5xabyIX+*O)2hB+`UkWv`Ensq!foD#oda#6)3^o-J!TswD_C; z{_pek`S9fAoZMt*XRn#LW_Hi82~}5>!^R-T00016L0(!D0FV)n;4w4^;^S{FmlfiV zKkCX_GEYxWH#aw@r>CKzp+x?Jg@uLC{Db!PcF}Jkn$1<~>+AXX`OC}8b8~ZTZEX*a zkCJ%@-QC?)RaFNE2Zx7;LqkI^au3vhR+f~Mh~^yB*4AEJT=ezz{r&rQU|=9SJ6j^} z;QROQU0q$9o10-_Vb8Po6XN4le^%Vx-HnZnt*oplHkKzDkIYPma;9 zI6gl=-`Lw@2^-1l?=CAV3+z7g={R$1`;*++rrTO`c6)17ecaU4G(SJzxpA|1bo@Ma z%&s_Bz3gaqc2=&T^keyt+}zyls|%@u!?T-5yQb60gS&(4D~r05iS+}=o?lT>QFBLk z&C@%Rlao#@r!s|yr6ZfRUCrk0jhAx|o`pYHe*D*}ZL8`CB%3oilkgy1MLCv7ntj6WCbOvUa0fa? zmaTR7>c!Zpk)YAOwcVY%iS5qa&D_NqwTvl;vcmb(xnbt)uTfZ6N6#R^{Q#{Q^$uX-RtGUgZ>T676qB>7iS}fd#{rwo2JI=$48gX zPOXdP+GeNZQYR}$w-i&S(!1MD$_ra(b`0`n%nE0X@@G9tMp~wK42qV-6UGIu#*^sBTBwbLe+rldLB4e#k40V6Nna^C`;Q6)kdjsO3>rKT++CI?sY z`Ws4y?#F7IWO2Mlx}fB=rn%F<gePNV$`WU>hVe)LaMM8c z$FL8zRl$TbHtPjdzMq6my(NrWz?p<@DzvZHH!=f^0|I&~XvkN7ie>5WF}HY&HYOOG z;-e@`W&(y-T->1L2eNtS($rwY9zV>pv#?b#)Mk8KS5Q8q319=aC3iZb0 zjBe9S)EdXm*dT!d>)#HeWp#J2Nia}H^t!!@()p*_na_&BeiXi)^6AQ!at8WIg8Y}3mQ+%6-oDdF{(_omIr-P z9+5=WIWYP8N1UzRa?9(5Q^VA#EF%0h-6UP zCG^?Y${omOkaeSi7k8(Gx+jae(8H=2)2YayJiQJPOsIJ;7+}*N3V6z}NY?cH_~}<` z_qw)a$L#?uCerYndo`s=~X6e-=MiBcg+->GG0(O9eP@4cn08b z-qm6yqC|zIc3beJaudI({$bd{iVLj}P(w{76&>2A-iv2e^~cskiFxw^HZ1ULnhfOX zQBV=LWsIaK`VrMnTK2BD)FeGSq>6RG&-8^%wm7XfK9(mXU!_7DMX9X=_j-iX{#$(k ze<~D%X1J`x&#HE@3(8q5;Am@WOU(QCK0kLk7a1Joj+u%w?$4AMICT>nN}pUir*xeC zjeQVs&q)#%fax#DB=U_4fHuz!;=lf7sP!8oA`e56xfw0#kPVoDF`NZp6J4CrSqqpMR+orw`bKJ&GOZ<(3Qrw}6oeCT$NRjQku%ZP@@{ z_?*qXkPzV9XnF_=IjsL=CCc&(RYVS`8ut3tK%OwEkc#emv?>OgsvVjp3o}6Cc=9#m z_AKqSgSJIoVCDip@pSZF(KqSM5k}FYF(!j+g@YvHNW%q+Uq>4nDs1b0)wiX^S}W%1 z+&tyP%If`wVg-~WjPsphBz6GDyy#zb+{%G^;{yK=z@Og3cTZW%B?5$e#4IaTrSQQH5WE~~?TYvrPEPs9L2@ZKCTL}JJVGOcgK)BEV!tvygFS%EUkAjDu zsGP2*Jl+9FlDMUq1D9LbINoOhkWJqiBYyvY(Sz{X0W5ev5k|wobEL|?D2%LvB7lA19>-xqkrpe`Vc-z8WGFS^wj|D1=~kizRbS76~(8TyCP!JsZ_;7dH^Yf`xE3$~{f7w5U% zG07AL*kUaZj!Xn4g32VnsW~omQ%1r2rpL)&hnmEUnn!hwhr;`Y`phm7*`5S7&n>WU zBO;EP2Bi|(#=b)TT=<zrCDriF2bimw=l-&}^-nLD#(W zgbM!K?d!i&SJhzJYMMH_b2jb$R0~Lc2zRX^UiiBv;UGD>Lcjb2{Np~_1KmsvHn!OA zQq6!B46@=Z0ku`5>KTs%rNUve=)Tn?K8~4#0JDK$meXwDwJO`Dzi;OmS!Im1^4Bp( zHOc_Oy9IJ8Bv4S(n^sO33uBqKRo~8|Kd|Divc}DI@w3rWJ9SXtZ2ARa{gp;qU&56( z&)$xXh6N*PgBTMHkk(_gEC|bU6Iy8va6Rkj`GrI0%Lj}7Rr_Xx0H*wPJpC7nUHIV` zU$$W>aFztZ0|jLw8&^MXzD!i1hjpQ4h-hqkf5AysAb-K z0ah-Ln@^(ruFukQ>~PqxqK6%XZWbJc5+v!{S_;t_a&sW}$^~YU?V~P{2=W<`-xd_8(1h zZ6{MP)+F~r;^J}i0k2ZGIP|RbN@mG5elO#&gi!M@1|(n)-^k1J5_nRTO^(Ae-c5L1d_ibw4iMm@=!p<^DrBV<3@QQ@c+yN7w{K&67gX$TXr8zLf zVK77I<%da&nd92hO#r6=O(FZ7rE(C(Tuqz3W|NosQ4BVm0oc1qu{x{K%)~lhOKtMP zu7>9EAGhB;ORU!f`u#>dOOav)QN#gM4Dk^aVCzAqn4@)Hh~LXF-o^2)pZ8tD=eOBy z<&%dhP7b74={Pj7k~$(~3Pby7B4c2A0aEg+vzUXa09G{64t2|&Jh%*|t4Z%ZfEJf0 zU?yyk4t@k)$Gv%-$nqORnVMlWTUc1oW9$y{@l$t6o=?KlM>Ff43EydUJOGJPkeRE| zUmwd@xPz9ewXfsnJnqcDJo^J{9|PhV^Ch%NX+5P)RjaBT9%-| zG*{QI6omAEI?~uw6L^v0@i6Lb+Jq0?8@_f*%QRI7R8BVUXxLyuF|N~|TwSk8EFs>{ zKua!hRX;e_q~8IB!NF0apxU}x;MeB8q-A!yG;q+y>wd+%LsbN7c_|_?7cUB|Px zmPb?2O=qJ+Npj`IhucXQS&X<7Slyo>SAIPoRn~Sw;_b*YPWv>k7H~L13Qyu>S*6Ma z2&5*ocS3e;W`LClHM^EkH$cr<(gJ%e^zZ82F(*ANJKBgm`v5?vvn#35rL4jji6O6bHnK9xVOY$JR+-R&)|4F6~xr=bE8}Q zoPSH{?j%3puO;E-HsP$f=!>TU8C&<=QefMwlSv0zgy*cpQ2%mTJ%gu8DUWc#Ad{B! z7;C5_nTts3zr^_~0LKvVs*4kg5Df$#vSNWe5*}g8bmZ?mxOqstgpsn>C7=k|ugQ)E zq%>CJ{r&w9QVTCdMeCD*jL0Xa4X%bEuxb3V61G`sVWAxMT6#vtqVlu#mPZZErv>^H zQbgb_bg5cBmY=;}%jT_sP_Ayr(xsy3BRMN~B~QPg*OiNO;%_xk2IhrE8ZyYDrc!4? zvcXO#zweD%gjIPFyety#E|YICXzAvw`VX`>a|R4Cm~G0N9!}qul3-1*V4gPD zJ>;A1NSTY=f#PMSUyEh)bJWX8GVApKD}pN{7C>h0hZU{SVLSoiILJL+Ii zW&`=K>o(*eRYs102>AVEk_O_~V7hqAS?5B9(#14!mmnAce0mSE>q2Ys%JLY@Dx;Pe z#mB~n&i}^?-c0~XOHNHqwYD2V|C5x@$NS>Ni`p!pS|Iv()tcRsAaCO_cyS18Exo+F zym`okWXDvWyo$Rh6k!?-WOvSdtB(?D&44nPz^($MPIr$J|1c;!zgD20ua%tEj#0$t z-~wq8@@natshHwDPuyXLF$=)1p377}XX^5paSF3S8G9^{zdHUvot;XLU)=@#eC6_k zo|^L0HqfzP@ZMHB++|JL*!aHiL+&4JME9pXWkk_=R{j-M@#t`Rmd5_ON(+kk=L}-c zG)m8Q2P%hhIfkr(!k^l>`sC5wE2K&rz76k~?LmhkrJjR_t(y*ZUng9Y7KNlhj8>mP zuDP8A@Si!a5k+tjO7hP6{h54SNEx+?(8cWo4(It@2}kF;Gw}SYwnAIwd3sVFrPg#W zo`fVYHxs63m=7z!^K0Ns1P#5{O9l6H+W+sNDu*KXS#=-qeGQ}pgjaSEKvzMfkaQ)G z!iTkOAv5;zkxMFQ9C!^&KDCN&H1sH*kP;ELqFG`53wb@3kGEUv#GO@?bBFUwG57esEUSv z@cL9rMGW@h2Y9o%&%CKZjwz9Nd%usXBhbwuonkQ8U}sIG;F_WEIvGPO(%Y;UP`v4w zU_^}_SY}Eb-{bG zao1~mE&DPAk&vx`aJBu`pL8$Rq0j%0S5iOXL3w7hoO*y1RWM*kqZ{7cQ;caAw}=Oa zEvjQHtywNYg3rhM>UJ7rfCOPDx0kvBZGy4do|NXwH!sBRftin%-!zmn6$`N zdQ5dap|IN!tvVmis}jJZaT8WTge*rIbF1TZ8L(%vP-?lfcbW(R=;KY_F;QChmvb{I^6l>QD}$lt&Ha%Y%8 zb5z;W8Q%New}gD*j0!xc>Icr__Mu>%M?si-liFvj#}pT7kZYJD3)Wh|;O>I(9ZgZa zsKfbSSaC3UndVf0&F=T3(}T$1^x$qvn7;PVDKopk*5x~;Eg_o(Ki;r2F@dH>g^54F z?K=4^DW5eBt{GDsuGu7GI$ewvsfum%Eb|v$7}G}r<5Xk8U)6KfvA)|cn>lw#T6$zN zzEW2SIo2#J4#AmKx#MJ%t@vXY_aY%4({$Pn=L?b#9so_z2{GvB81uqt9KmfD4 zQFbk=lnQ$-W<(fY8ubx9e;MvFAB5X^eqYN|D&$3wx>Uje5m8gNPH_)%9~ zfqZCd<{D2XmDV;tz76rO@ra;PI0->p^Yzo9w(NY)@)gw5l(w3m6f|ay0ZQnQAm9jh zwVS3D0Z81I%WVx%& z!ch@Hz1S6sblKw=GL#rA?N-NaAt0R_S&Uy+zp%^AoCJq zt;;QyxXcb0I?MRL3fo`dhIRfDYdy4)+*Be5s~GUQ-j6jz5%AiGpL4Rzc2|vLgM8-*K z09u~G3@?b*IVT%47ldupU@F5lFAn<69Rc9&)_6wDv`9jvCwCu`F?oNZ5d&aLPLk?g zRBm|8sD`iqY0al69+j>Sl)V+#6i$^l){_pk)2=hbDq~-mx!SX6h(&TTbzM?W z6r`uS%bz^B6;nrz){brql!z(V5LS|sb63cE|e;L&HCt_`7LQI;uj)4Ry zF;Lwa5Dn+^)Oz%zRp}&uy{d+9{m=uDDg`I9zY@vW%{HUqX3|5_tmlyz2Jdl;%t3hY z1$mjbv)W~Vdy`SQw^j_f*)}sjwD6*+lL#dEAcWiq2El*J%W%}_0I5ZJFFS_f^4PYW zMN$-AXI`kN1t^Lm#O^qWbZG%SV=9oAO}XU6nrjuKd@(@=CgPyfl>1I5n+lVjz`#JqZAshX|o6CCfu8AZ6s_67;O5hIiV}p^f+{ zNPsQY0>gUq)aTN-&tbmll42{KdlMQJ1^`uA*rdVY&jpaHY%yk55s#dM9SI&3D9Qb} zBET7%#)?$=MN}9bYf_;Ipz3{ynz}GH!=au@0h_)(mNak!hHs!Dw_w^ADcCzw0Eqm{ z0CKW74;A&=OHjNka&vOU0XD7Yh0B5oys!y<(m;}bLKIp2aZ5_x5RX7cRh!;dAlHxMmFN&wm4L`$HZYnQ zs+LWX@jK83KWZ5@)Q;f&?prz-;0|R{OTsNd=56=6gtMJ?=P@C9!E?R$vJ$ZG^GM%}J`CB=R9F@COg@Xf7+TsLx$0OX39K6`KrHV)*NoypuYnKU zGBtewUEq{4Kk5Q;lP}&FuKsH3bo{~^b`0iAq&762X$C?7@ElSCI&s*}(Lyuk(umJ5 zdRV9y`j)@d-~apPu$Sb)_FSny-x-IH=PTm)r-omjq^((G1z&{flE{2hc?#7 zzud)W;*n|*j@&G6X)sv;^gdufJleS-&MT$S6{oVM^T7OAQ46UuS}CO{AUyo1?RBTf z#H;2f9({-Rz*`cQu1Z5KAE#@%+&_iLe>?>7h(9$gH}pI|o8|`S5w3Z)wZePO>yme< z5F;Pt30Js7smu=pB;#HV-Z?@3?)^~~XCLVBhcya4p3nBUyWbw2O`H|Ze;Mw5kzC}; zO?ld!kQwr|xBBMYe<57V`nXbqzb${4YXMYbT5dn%E5g9}o);4mQ!?;^xQw7JOc%$7yQ|I60|yLq1M{A47+(&VEslo?~(dGh_`REu&c_N1JemB^pxM@ReLl_d-iwbahGI85O2yt0hM>564g<{1 zbNJJnylC~*FRps=NJ|_%3$CrK9*j-AJKJDsZB6M%lxY*U z9kj;&N$K`knG9)VfLIOsZ(WzzA+|iH^H0p|qxy2Dq@P6hZOo;cMD+9kX#jNCmln4c z7eJkQ=FF95$a^8veop53a_(gnqgo0gc~UWw9auKy<;NJBSg(09`e)rsTI+|)U`x{# zM_@1-aA~`TN6zrFob$;6L(HT2&T_kOvrzHZ!~53&DC;qCkKD;YYTwjsyKE%<=u2^} zZww}B(jWqqS<0t#V(SDc>)5&{J_ZM5hJD}R{=yuVGc;OY>PAwbvy8P+yWakD)5-8C zjp>S~^U*>b>b2?T8=p5nY6Y1dF#Nc~0WjR@>i9Unh!->4@w)i>crwr!w?GqR46qC=M84nrflnpKEJ~JbV;-#M;l%2W5Aiqyq&jl}^506ZuT{WmPWIO6_<|(<5RYp*Tea00z1FP;v_2QR+BFqhd-+#IuL!G z*1BwW4GoGK#ZiIrwgCP^l0O+4ddP4Ua2f zd9(ClHB{bc zXRZifhpSxg{_X6uto-R?Rg)A%S(FVB{FW*oG@a?$A`hyys`$KuN|5qfa_K>~uzke} z%dfl*9X9RAqiTfn20;Hn^~uBzKKFf#%}mMtiDSC$IAk~V+aV5=?$Q0tvnQr?)bJEz z!*24^q)Y^gMc%}PO3uKT@9g7kujSgC;82Fox3e0!e*9#;4$duPrS3YRLTgc-2*Z}T z%P^rm^_;IkG{0|8x-?>V->seI`tH5vkJN)RSDx1XCO-{9G%-R-8qXl`QtW)1AS2PB z2Yb-YJ=M?Rlzuxsg9>IvGP`QeGph%_mxyl6bMs^5eD1X^Dv_s{g(vsFr!}oMtUVjD z8t{8#XWC|zB^3~3mr9a%!fkS6r^iFWM@ZT^3zqgJlel`CJ2s{su1+)ipW|r&q3YTU zp^D3F*d$Fl4U9g2x%z`9Y&yywesALC{@W9-gJ{?sw=ZEHD&R4iiN5SpT%#WSIZt99y9^;9YbA#g4*XB1yk z#w`ckksNjWNsggFIMXO#-gfs+ofg*q>(?(;;Txjr5Y|XQ-@3JcI?&k8JEPMRIP8I?sM* zQz1sVDHSsB(et*I%AF8;qv0G*qDD6hb9rnmO8I6Jb4vca-HCRTO&q83n(<%gVz6m3 zz7&oKco(6MU?QFRusm^z9MZzhkh?f;T3+1Kt|PCUoRQ~Y?G`W0;d&nH{x&B?0C!vy zgvofuZ?~8MAKW`w-US-XZP3Cda@WXxo^G-^XtM|LuxL|czDCtCDKO=*tfwV=iF|O{gYLNY|TK%vH(Z-dn^}wpo|~eC#VX8(=5;m zsDi1N>f8gTDDtG&Ma31ErNU(`^SiSVyn^&lyc+NGpLsJg zX8=fA3F#D_L{bzjYl(LA)L7=v@f9qnw-NLi7lCqsco02wjZcsUUXQUu(<(~MjkzsNb1F~ z=MBFB>081~F$Bf)()8sT5RR7I^6@AFB&kxavqJ#M4Jn7ZKtK^&>J&X@xQy14QjHH6 z<^arc|4XDNV32I{KGYbPOw*l19oxg}T4=-AriJk%m(G{4t}xIxfO?+8{nJ(KbsuOD zJs^=gEax$1mT`ez%B2!8LbCHm^W{UYz`cmhA~=3oVU06u*Jr4objZ`G=o7x$;JBzs0h{8qY6Op zf;vqcUsvFrJ}5g|SkRUP+OKiSUGaPQ0K}$|`OXzlSYyt1XkmUE_)$YRFHilOkK}RoOz$c_Ls-3)rxu2K`PNncE5j;+8bmB zNgNzTEOGE_gz_)W2L#Rxgj1QkK6AnhV!Tv+e(ZnASNtn+0h8;Vs@RlA3xcpq>S(wi zg2DQH!u%u)mB<)qf-J7uyuMVE?$`8`=j__e5;4;mUFz>-y@9YeM7J0dkrwwBCo7f< z#lL~5ClTss(O-@N*t%&V#r`98E;^I?GNc%(-GAp|$@q<+3_rTW-n1v9|3&*I;yMot z(f4VFrHD`xKt70rQv=EH5-T~Qq-)6Beii8F^gN00fb&Tly}doBgdcn#1K%e;{Sv)y zaU@WPZkSy=y$PJ)osoj zSK2h{C*;0dIR-I&nN6QGfxV6pUHbhpJ|a*wUuSFNH4G$;)*ayUwvKj;=eqI7J8z(4 z?!$3n1QkY*7`V9Q|P47pqS7(65cUJ61ViaK)jh_60*DDHGh^Zi;$9XLi+u2oOW{nUy9kn6mEX} zU8${?HsCi_PsY!|HUA9u1Q$6Mfc{jlWN97^p-KJFh(H^3NBQxut^f|cPh)V^&~t2_ zkgJIPP`E)`KbBb}qDZ49hq!?tLfj+E`=rvG;giIG!H~Vi*Cu5U!$oR>hS?KiN&?_DM?GX}~ax1_jL& zDvE;j9Cx>9+6Lf5hzL}1W=&LFR=n{KnR%Jet{H9~wtkMX#oR%TOG-BNpA6HFi#r7$ z{fu9v$ed-9%qPL^U7chRt&K0v7Csir7Y%wa>a$Q_B1|LD^fB3w{j~EH)Bem` zb)-+>ZJjwkJ3*12ceHcA7|g*$vfEiS74YLi&hGq z%>)(k4+mT7%EADb=T1m2Y6aD`Wj3ZtiSg{(;{1TuLr&Ncf)uQD-HW%q5nH@ZVE5u2 zzjAZl>krJ9YVQLpk+o=l)Jmt<5FRFmGkiv<3=Qq#N%{ne*6H*0mV>8>LoDt@4*53X zxvr+42Pt!WJSGiPf8ajehx{K|C(t5QdmM$$RUu#fJOl+9X)l}7TW4mAmhCzFn11`E zcgBMeYd1h2pCx}Ea6?pC*(!C#Q_OiZjFkZz*H4ygB5a`_bR6{}3fkfjp5yViq%X@Z z48Sc~S~d+qAb*9ANq#1D&?k7Zi>HrOc%JW-gL=-fmPGk9Ej|6x+8(7w0&p?<`*%6< z9d0vAujA-EdPlWU^RlX%YXSz=9DS{W19^6 z@F*er=psG)a?a86Ftn9-@qyl*!V&pZ)5pu&&>E;&v()M!YAnID_mZ_ zG~u`02!OC+&e@sYqn=clALd^2_8MCtC3)lSvO1ME?iw5g+kQG_^3Y3|r8NWa74%iz%ZJdo@h+xGe$&{%VBNbovqj|6k=@hT0Z(^7pn z+v714E?ROUL?jPW=@+D!TFQ!JdX%46V|FqLR^{X9iiz|v2_hQlmydzIc0={^BHve< zX(QspAKhF`2mqk1g(jO25~BXQni}e|u#YC;Rsh4ev8soZ#d9kFTO38r!V8Q?D%OVy zpXlO0E+fC7t6r=*eA(EPiw;CJHQHnSTbDaWH@WStt{dX^8-)**RoCp|0fzvFnaN|G zhK1RtvpXuCwM_g(r&ayHVLtj=SVspIsbh7;<2B8Po~Qsf7QuDZdov$eMq;cvLNfu%_K^aOO8FLu?Pd z-!*Df9*#b?C2-DnrGKwd_JN}UsvA4t{nwIR39c@ zf_DKEAgPwJcEILIQU0}Peu4``WNcx<08bS5QZqZ1)Zh>x)@kBOANb1~$9F}!yBwS9 zHpxC_MB1PDQu+3`loG;a-DCtgUnVj`<0Yt|t5zwtb${sl3d{hxE2K*lRIja%G|KwQ z;2#%*O!KlK-_Hmw>wS3#2TG{De2e{dxR4Ph{rM8)5j=t83uMwsG377YfJ*aT$ymi+ zv#`6yBq3F*O-KEZIa(L&$?(O-GDDP2R!=Yh0ugiv4=UWsZ@xu@> zarX}Zbpbh6ucatSx)I@l}L&h|}KA?i=XP(Qc3b*z}v)8(Bd~#hR}LkE(KVy|V06pIjq2 z#bGM!J3f>-4U0W@^))wtL4okXi1yVPf`U7JZDc1eJD@TV1GVuJ2Ot^iHWt=fY?zV%w#^0 zEBO*^cl`5UHJ#UsuP8VKc3${-AI%&{lF`jRxw&1w;-{I8e^l+zW64+$s{l|^w2yyq zA!Dv6TXMSb{EIDK%&8U7=}XxE(?roX{7EBEtbAGZolI3^l?7V%e;iTJM>n%>+7?WX zMmNxs?bzi`WG+RmR8s|T0<5;kOQ(+LiVUl~=09T5qTn$x)d1YzAs^AZ$a#f!E9(LJ zBY8_ZLpu5Xf$AN{_J2S%>DMDQZ#ncixhS3skMpV6l4mTaOu8v`cxBh%E+b;%6XVV7q z2lk=YCzySzH3@uvfQS+5zs)c@)1R*OA(hdt4f&%dBm|K<^n`W(n=FB#tVW2{hJK%F zVLG2R1_9c?Q0dg)`=G4=cIoxj-bfMZxxNsO(HcW)u5N@|#|P?#S8b$bN|Cu{$Nj59 z`<$(8d8cN%b%0;B3hcL}A3Y#_V7!Kh`i{#lpZ<9WZCM?;gzjxQ^heuxg{vqP#?J1? zzKs2<2jTv!8E(9ftH?fsfd@C_@K1aQUk5qnO@AVRI--b?8xnQ1*D$(oeX0VV(xd59 zBb5nu<{a^ypY*TdFk==7-P+3J=$j;>xQU#_qB5>Wc6=5mLr(SJU+M_{1O9sO&oHtZ9!!z#ny^19zb|A` zAX%5@Rg6cXe1{*3+we1jhLG+fL<9b1ywrT-4RYE$yxf=bD+bS|nvwNl!@7tY7i8TC zcTWXhGmB9!q(V6t|7U*6bO}FuR!K@|GVWWEiR69awOuCK1YZ*twXAeEJ-9mVBsJt5 z?%S{&{x62E=T@3G{?y&CgF+zo9*ilwwur%6)NkrMmHZF3Fn5TJ*Z@FGHJ1-|jj z0MSuYbC_9wC4FRjqK(YH0HU)1?&GEODS~a~RNu9G0w#Yxyx12GD-(GNupd$|Z%rO-Zs8qElt{#QX z>h>3Qy8Kq*{(9ZQXn%54wL%s*kgs^mYxuet!uR~CKB-UgdJr-aUiz6weTpdPyUfFN z2)yEz+Si1q4;~m7)9!qtM*sE_dI9+s0%URFEVPlYG&It|)NZGlEZuG@bT83w5r=OSyktm! zk4>?dnuY37-o=YEp1;8uMA8s`RVuha(6=`?EZ%J|AsuYkYiMl)%ORqhbH0%eh+F1bUVRDDX4i!wdAi z^tm`6?1Fr!Mh$m&(e(RFf^xF`@b4e=%!l^sV6rSvK7P22ddG9s)`JxP_|K1;QxYLr zK?8L-wqa|C-d(uAeNJO^JM9~_E9#zqw_kTMAmsP+H46*{8LL0X&oXAEydgFbiYv&k zZ}Z`|{b*$hTmjYciiwNrd$Lh(=J{9Y7eQIY zCRFuZiB(}0S7n-l585hLMGo46j>5e_7&y2z0y6+~Nw`~+MQ-u#jPSFDyqnzD+1@l9 z=Dr~c*nsS#|0A0`sXKo&?tkppX+j!HN}|e6Y^%sJ64l=i*!_*0$g0biZV6M^!_nRmba*isLE@3kG&SAWQ6<-)=}&l~&?v zy|ECV!$JQG62`Qbuj_w6veEWV-cF>nl6C%BnMq_vJdXTFR8ypfu8sd# ziyd2&K99Y3MQY*2+7rds&U8^Df&&?3&1hMc%qwtEa-hs zc(J_J-lv5`AA{AfhVV9(9Rj%Ghu|Vh0tDFKpXlA0?XO8+ z);bObo~$wOB2ph!p+0cJK@3!y>&o~Qh_X!-vme$CSrwQ0h;G&vJ6BUBW(;ck4S_D| zuZg?cIB|j?62J672N1wK*=;%?c&q5s2VznL&#d;qt;1p<&io6CT!8x4Y}|IjB<7`3 zXgTwrL~BgOM4(u$Mu?b~bFDn_z2+aecl_zf)GxuoMpQV=dUxjZztG4N+s%M)cHgXa zJpZ_YJwhfhWkFM`nAZ=kDUaIs(g-+X<)RH=NGbtW?aw1LFw^i%J6cq_XO`~FBCjQ@ z1`!}Y(gpRdGgmFDz)f^C1(JH3-&diHw&7!!{)Z9++9t$xfc~LWXMQF1vplQ_iw;JQ-~fH2l+T@e(n7l-zR+ws;s-Y3mnCY z@7%a+XvP;1{dX)Xdh(oi2T>AsED<&&P^EB!Kn8#Xu7)qHtw)Ax}dQIN$e**>F5 zF<6$8L6X2IcxATw$dz^t`xyP*Odrl(VF)yTQ9=Qg;=h0f0Az%xf;7MaH+Yui3Z};k zd#e2Oyi5fNaoOr=`!w*?cV!}BPWnS8X?e4LI-cyWOX5>X^z~z}SuZpcvt4KG>#1wiY2c|L0Rd_x_|jtySuE|%%*;ZmDd}t>WPK;+^uHLN=9B$MuxKxZEPskg< zI>lW;G*Ur~)h>>J+oM8MK&FK8>?88$XpABp zSZ2BitaWj0y6K1aVBRDW%naQO?c%>sa&}M-6H4U^l$cw?0qqILfzPk=uemG2c7pRA z@!>JNuw?}NRn`0@SIq_SP~fRvkF4$X_15#ebrYnAAdoT~(9A^a)u(KBHJgxes;YBN zm+Rgz!T1t#FT}+v#OUgay#5{P$R1Caf~g$oEH6Fn-q?OMLYgPf3IZ`! zPv)+|^2xJGEcOC4n-b~UFdIv%II+wKP-1?NwD@mWY`q7ROT*I}EQi(1_L0-VVeF8k z5D?=&`bpB;=0biwf|?nowfk@#b6wwE2NYg>i2M|!J`g^^oyB3X_e!HE;pLYH6p3Dd z*#ZdlvWC~(KuSrNyGN8&i|#4x$XmdiJp8awQfN-b9~8#m|F;E8j;HS=h)L5R(W7BOKiW5L^a(;)#HFYb@;k8fk3N4F1|f`@suC!J^fO z_Uw%sTzzlt?`+H|QO+a9-v28d@cIf8G(#Y77e{L;!u^1%r??Y8@G`-7D=gSA^?yUh ze^*ib&&j>ssdM`Fl?)-@F!)j@A;^SH3Z+N&$Z(x&#zJzj*mKb+8sfOIbSC@x-R8eB z5?37XY@+|#uesY8jpSihpGeJmcC0KAM1C_U>eZSK8Wwg~zOHBfSw-Hk3Gp}%#I^$< zXrj9k>2M_uk?q#>63)dK%`+B)Uc`U|&4Ey(KX38$$kEqzyJr%WH>h^qg(APaLK#B@ z`D4!`N0B#OrH{({VPfs|)>=bc|MLz2af?m**cJ!OLgIRl)a8S&imhaPNR0-u?E(ly zH?L_c_ZcV&3_D2@*x$!Fz`;o_3-4c7JoRvJg??dlAf$;!n-x9TYwPy-v?vH%P7Aq|~-rAM1*&YE%=(&m0Z8{J~& z{^Pdk?*5D2C2ngMOoI&5ebDkml(!mfPUINT_Dej{fZO-N1{`*52Kj?HTvF9F?S+w@swMyvs#A${&`2|!ZoZeCe zDWl?jNgbNd5ei6ksmskCFQ`~wi^F~>Y%9B#t*}jt>#8}vncDhua(tKqMDdZLS3;{& zj4&g?FfQoq&WZ&K=#>!$+n^^->bD2K()oU9@HxwoC-Z{o$cNV%Y-=JVIe`_!5dxOe(;fu=mW5wFllPc|8+f zMMNxd6nq@^*BeUEThwfNRme#MGYdm-l!x2<5O_cogFSOwa4iHg`vnB+Y5mkyCqp@i zYUO!3^S^*%(g3E}7=Z^QFpukQI#K0Ton&iKKjO4oI*Cspq~4tumLT#9{FRuQVM) z2?!5IDH|>F*uW!OC>o3@i!@W;hMk#t*3*SDloZtU1<@Hjq8RiCPuJ?Qcs zy6T8TK6viIcah_M4P%o|k5>ysASowgV6~0eVu6ix#H2Gf-8mZ*u!%ZkGb~^lp`Il$ z)}nH_dTu}4S`?RH$?}X#gruC2fqD zT^hS&g~MZYt^;eN4z29Y*+;?oYC$v*Ac}*PTo63l3zN?2RVe)rHW+#=`(LL2k1p>Y zQPpk$2@H_XlGmJ7+UIm|1Ks%}D;r zg$>R=+`J0yLYHpZ30V=*XJ6V}Z-T{?+fu1MwEC~gn_~IG35Bj<-$jT0V=#Fu1#cO( zi^|Hxf9@;a%c*udGPKFX-D6kkE+~U7`vTtd=rhLb;9tX7P~(wjv@y{n=b-^1R!9VC z?zflbVlIK;{-vN;@2>2DiQz&auZu8}9s0^ZY}wpvK3slpAZWZR?N>~ue;Y!}f+S?Mv$uk9>NAH1zkg!N^7Ee6Rw@=` zpGe;+=}Zb zI#XC~`j%lST-T=YB8=*Kudn{R;SyQ5R{4q2_4 zg^sw2SdyWUlocpz5{7UYs+Ua7w{TGR; zy41j@j66^7w~K_QC!K%arHcTc^R+D#RrYe$XYSBjgi4en>V7Rfa+sRny`Cx=8d2}k z#tY&uXp@HSglX_wIgRlewxgCd9e_T@z^*wT%QNXedBI03jR(Grb?e3}T?O8$mr xPvG{o`dmK#8+SQaT1xaI2XCeQpg literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_problem_features.assets/min_cost_cs_dp.png b/en/chapter_dynamic_programming/dp_problem_features.assets/min_cost_cs_dp.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef66958b176d061cde41672d68fd065ae2242ef GIT binary patch literal 20674 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 K#VUDt@IL@k%YVoK literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_problem_features.assets/min_cost_cs_example.png b/en/chapter_dynamic_programming/dp_problem_features.assets/min_cost_cs_example.png new file mode 100644 index 0000000000000000000000000000000000000000..033caa8e801722a9073645ca03e5690d4396ce09 GIT binary patch literal 19703 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + 14.2 Characteristics of DP problems - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    14.2   Characteristics of dynamic programming problems

    +

    In the previous section, we learned how dynamic programming solves the original problem by decomposing it into subproblems. In fact, subproblem decomposition is a general algorithmic approach, with different emphases in divide and conquer, dynamic programming, and backtracking.

    +
      +
    • Divide and conquer algorithms recursively divide the original problem into multiple independent subproblems until the smallest subproblems are reached, and combine the solutions of the subproblems during backtracking to ultimately obtain the solution to the original problem.
    • +
    • Dynamic programming also decomposes the problem recursively, but the main difference from divide and conquer algorithms is that the subproblems in dynamic programming are interdependent, and many overlapping subproblems will appear during the decomposition process.
    • +
    • Backtracking algorithms exhaust all possible solutions through trial and error and avoid unnecessary search branches by pruning. The solution to the original problem consists of a series of decision steps, and we can consider each sub-sequence before each decision step as a subproblem.
    • +
    +

    In fact, dynamic programming is commonly used to solve optimization problems, which not only include overlapping subproblems but also have two other major characteristics: optimal substructure and statelessness.

    +

    14.2.1   Optimal substructure

    +

    We make a slight modification to the stair climbing problem to make it more suitable to demonstrate the concept of optimal substructure.

    +
    +

    Minimum cost of climbing stairs

    +

    Given a staircase, you can step up 1 or 2 steps at a time, and each step on the staircase has a non-negative integer representing the cost you need to pay at that step. Given a non-negative integer array \(cost\), where \(cost[i]\) represents the cost you need to pay at the \(i\)-th step, \(cost[0]\) is the ground (starting point). What is the minimum cost required to reach the top?

    +
    +

    As shown in the Figure 14-6 , if the costs of the 1st, 2nd, and 3rd steps are \(1\), \(10\), and \(1\) respectively, then the minimum cost to climb to the 3rd step from the ground is \(2\).

    +

    Minimum cost to climb to the 3rd step

    +

    Figure 14-6   Minimum cost to climb to the 3rd step

    + +

    Let \(dp[i]\) be the cumulative cost of climbing to the \(i\)-th step. Since the \(i\)-th step can only come from the \(i-1\) or \(i-2\) step, \(dp[i]\) can only be either \(dp[i-1] + cost[i]\) or \(dp[i-2] + cost[i]\). To minimize the cost, we should choose the smaller of the two:

    +
    \[ +dp[i] = \min(dp[i-1], dp[i-2]) + cost[i] +\]
    +

    This leads us to the meaning of optimal substructure: The optimal solution to the original problem is constructed from the optimal solutions of subproblems.

    +

    This problem obviously has optimal substructure: we select the better one from the optimal solutions of the two subproblems, \(dp[i-1]\) and \(dp[i-2]\), and use it to construct the optimal solution for the original problem \(dp[i]\).

    +

    So, does the stair climbing problem from the previous section have optimal substructure? Its goal is to solve for the number of solutions, which seems to be a counting problem, but if we ask in another way: "Solve for the maximum number of solutions". We surprisingly find that although the problem has changed, the optimal substructure has emerged: the maximum number of solutions at the \(n\)-th step equals the sum of the maximum number of solutions at the \(n-1\) and \(n-2\) steps. Thus, the interpretation of optimal substructure is quite flexible and will have different meanings in different problems.

    +

    According to the state transition equation, and the initial states \(dp[1] = cost[1]\) and \(dp[2] = cost[2]\), we can obtain the dynamic programming code:

    +
    +
    +
    +
    min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp(cost: list[int]) -> int:
    +    """爬楼梯最小代价:动态规划"""
    +    n = len(cost) - 1
    +    if n == 1 or n == 2:
    +        return cost[n]
    +    # 初始化 dp 表,用于存储子问题的解
    +    dp = [0] * (n + 1)
    +    # 初始状态:预设最小子问题的解
    +    dp[1], dp[2] = cost[1], cost[2]
    +    # 状态转移:从较小子问题逐步求解较大子问题
    +    for i in range(3, n + 1):
    +        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
    +    return dp[n]
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.cpp
    /* 爬楼梯最小代价:动态规划 */
    +int minCostClimbingStairsDP(vector<int> &cost) {
    +    int n = cost.size() - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    // 初始化 dp 表,用于存储子问题的解
    +    vector<int> dp(n + 1);
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    return dp[n];
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.java
    /* 爬楼梯最小代价:动态规划 */
    +int minCostClimbingStairsDP(int[] cost) {
    +    int n = cost.length - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    // 初始化 dp 表,用于存储子问题的解
    +    int[] dp = new int[n + 1];
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    return dp[n];
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.cs
    /* 爬楼梯最小代价:动态规划 */
    +int MinCostClimbingStairsDP(int[] cost) {
    +    int n = cost.Length - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    // 初始化 dp 表,用于存储子问题的解
    +    int[] dp = new int[n + 1];
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i] = Math.Min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    return dp[n];
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.go
    /* 爬楼梯最小代价:动态规划 */
    +func minCostClimbingStairsDP(cost []int) int {
    +    n := len(cost) - 1
    +    if n == 1 || n == 2 {
    +        return cost[n]
    +    }
    +    min := func(a, b int) int {
    +        if a < b {
    +            return a
    +        }
    +        return b
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    dp := make([]int, n+1)
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1]
    +    dp[2] = cost[2]
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i := 3; i <= n; i++ {
    +        dp[i] = min(dp[i-1], dp[i-2]) + cost[i]
    +    }
    +    return dp[n]
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.swift
    /* 爬楼梯最小代价:动态规划 */
    +func minCostClimbingStairsDP(cost: [Int]) -> Int {
    +    let n = cost.count - 1
    +    if n == 1 || n == 2 {
    +        return cost[n]
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    var dp = Array(repeating: 0, count: n + 1)
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1]
    +    dp[2] = cost[2]
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i in 3 ... n {
    +        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
    +    }
    +    return dp[n]
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.js
    /* 爬楼梯最小代价:动态规划 */
    +function minCostClimbingStairsDP(cost) {
    +    const n = cost.length - 1;
    +    if (n === 1 || n === 2) {
    +        return cost[n];
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    const dp = new Array(n + 1);
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (let i = 3; i <= n; i++) {
    +        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    return dp[n];
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.ts
    /* 爬楼梯最小代价:动态规划 */
    +function minCostClimbingStairsDP(cost: Array<number>): number {
    +    const n = cost.length - 1;
    +    if (n === 1 || n === 2) {
    +        return cost[n];
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    const dp = new Array(n + 1);
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (let i = 3; i <= n; i++) {
    +        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    return dp[n];
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.dart
    /* 爬楼梯最小代价:动态规划 */
    +int minCostClimbingStairsDP(List<int> cost) {
    +  int n = cost.length - 1;
    +  if (n == 1 || n == 2) return cost[n];
    +  // 初始化 dp 表,用于存储子问题的解
    +  List<int> dp = List.filled(n + 1, 0);
    +  // 初始状态:预设最小子问题的解
    +  dp[1] = cost[1];
    +  dp[2] = cost[2];
    +  // 状态转移:从较小子问题逐步求解较大子问题
    +  for (int i = 3; i <= n; i++) {
    +    dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
    +  }
    +  return dp[n];
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.rs
    /* 爬楼梯最小代价:动态规划 */
    +fn min_cost_climbing_stairs_dp(cost: &[i32]) -> i32 {
    +    let n = cost.len() - 1;
    +    if n == 1 || n == 2 {
    +        return cost[n];
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    let mut dp = vec![-1; n + 1];
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i in 3..=n {
    +        dp[i] = cmp::min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    dp[n]
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.c
    /* 爬楼梯最小代价:动态规划 */
    +int minCostClimbingStairsDP(int cost[], int costSize) {
    +    int n = costSize - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    // 初始化 dp 表,用于存储子问题的解
    +    int *dp = calloc(n + 1, sizeof(int));
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i] = myMin(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    int res = dp[n];
    +    // 释放内存
    +    free(dp);
    +    return res;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.kt
    /* 爬楼梯最小代价:动态规划 */
    +fun minCostClimbingStairsDP(cost: IntArray): Int {
    +    val n = cost.size - 1
    +    if (n == 1 || n == 2) return cost[n]
    +    // 初始化 dp 表,用于存储子问题的解
    +    val dp = IntArray(n + 1)
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1]
    +    dp[2] = cost[2]
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (i in 3..n) {
    +        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
    +    }
    +    return dp[n]
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.zig
    // 爬楼梯最小代价:动态规划
    +fn minCostClimbingStairsDP(comptime cost: []i32) i32 {
    +    comptime var n = cost.len - 1;
    +    if (n == 1 or n == 2) {
    +        return cost[n];
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    var dp = [_]i32{-1} ** (n + 1);
    +    // 初始状态:预设最小子问题的解
    +    dp[1] = cost[1];
    +    dp[2] = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (3..n + 1) |i| {
    +        dp[i] = @min(dp[i - 1], dp[i - 2]) + cost[i];
    +    }
    +    return dp[n];
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    The Figure 14-7 shows the dynamic programming process for the above code.

    +

    Dynamic programming process for minimum cost of climbing stairs

    +

    Figure 14-7   Dynamic programming process for minimum cost of climbing stairs

    + +

    This problem can also be space-optimized, compressing one dimension to zero, reducing the space complexity from \(O(n)\) to \(O(1)\):

    +
    +
    +
    +
    min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp_comp(cost: list[int]) -> int:
    +    """爬楼梯最小代价:空间优化后的动态规划"""
    +    n = len(cost) - 1
    +    if n == 1 or n == 2:
    +        return cost[n]
    +    a, b = cost[1], cost[2]
    +    for i in range(3, n + 1):
    +        a, b = b, min(a, b) + cost[i]
    +    return b
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.cpp
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +int minCostClimbingStairsDPComp(vector<int> &cost) {
    +    int n = cost.size() - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    int a = cost[1], b = cost[2];
    +    for (int i = 3; i <= n; i++) {
    +        int tmp = b;
    +        b = min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.java
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +int minCostClimbingStairsDPComp(int[] cost) {
    +    int n = cost.length - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    int a = cost[1], b = cost[2];
    +    for (int i = 3; i <= n; i++) {
    +        int tmp = b;
    +        b = Math.min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.cs
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +int MinCostClimbingStairsDPComp(int[] cost) {
    +    int n = cost.Length - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    int a = cost[1], b = cost[2];
    +    for (int i = 3; i <= n; i++) {
    +        int tmp = b;
    +        b = Math.Min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.go
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +func minCostClimbingStairsDPComp(cost []int) int {
    +    n := len(cost) - 1
    +    if n == 1 || n == 2 {
    +        return cost[n]
    +    }
    +    min := func(a, b int) int {
    +        if a < b {
    +            return a
    +        }
    +        return b
    +    }
    +    // 初始状态:预设最小子问题的解
    +    a, b := cost[1], cost[2]
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i := 3; i <= n; i++ {
    +        tmp := b
    +        b = min(a, tmp) + cost[i]
    +        a = tmp
    +    }
    +    return b
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.swift
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +func minCostClimbingStairsDPComp(cost: [Int]) -> Int {
    +    let n = cost.count - 1
    +    if n == 1 || n == 2 {
    +        return cost[n]
    +    }
    +    var (a, b) = (cost[1], cost[2])
    +    for i in 3 ... n {
    +        (a, b) = (b, min(a, b) + cost[i])
    +    }
    +    return b
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.js
    /* 爬楼梯最小代价:状态压缩后的动态规划 */
    +function minCostClimbingStairsDPComp(cost) {
    +    const n = cost.length - 1;
    +    if (n === 1 || n === 2) {
    +        return cost[n];
    +    }
    +    let a = cost[1],
    +        b = cost[2];
    +    for (let i = 3; i <= n; i++) {
    +        const tmp = b;
    +        b = Math.min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.ts
    /* 爬楼梯最小代价:状态压缩后的动态规划 */
    +function minCostClimbingStairsDPComp(cost: Array<number>): number {
    +    const n = cost.length - 1;
    +    if (n === 1 || n === 2) {
    +        return cost[n];
    +    }
    +    let a = cost[1],
    +        b = cost[2];
    +    for (let i = 3; i <= n; i++) {
    +        const tmp = b;
    +        b = Math.min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.dart
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +int minCostClimbingStairsDPComp(List<int> cost) {
    +  int n = cost.length - 1;
    +  if (n == 1 || n == 2) return cost[n];
    +  int a = cost[1], b = cost[2];
    +  for (int i = 3; i <= n; i++) {
    +    int tmp = b;
    +    b = min(a, tmp) + cost[i];
    +    a = tmp;
    +  }
    +  return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.rs
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +fn min_cost_climbing_stairs_dp_comp(cost: &[i32]) -> i32 {
    +    let n = cost.len() - 1;
    +    if n == 1 || n == 2 {
    +        return cost[n];
    +    };
    +    let (mut a, mut b) = (cost[1], cost[2]);
    +    for i in 3..=n {
    +        let tmp = b;
    +        b = cmp::min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    b
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.c
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +int minCostClimbingStairsDPComp(int cost[], int costSize) {
    +    int n = costSize - 1;
    +    if (n == 1 || n == 2)
    +        return cost[n];
    +    int a = cost[1], b = cost[2];
    +    for (int i = 3; i <= n; i++) {
    +        int tmp = b;
    +        b = myMin(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.kt
    /* 爬楼梯最小代价:空间优化后的动态规划 */
    +fun minCostClimbingStairsDPComp(cost: IntArray): Int {
    +    val n = cost.size - 1
    +    if (n == 1 || n == 2) return cost[n]
    +    var a = cost[1]
    +    var b = cost[2]
    +    for (i in 3..n) {
    +        val tmp = b
    +        b = min(a, tmp) + cost[i]
    +        a = tmp
    +    }
    +    return b
    +}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp_comp}
    +
    +
    +
    +
    min_cost_climbing_stairs_dp.zig
    // 爬楼梯最小代价:空间优化后的动态规划
    +fn minCostClimbingStairsDPComp(cost: []i32) i32 {
    +    var n = cost.len - 1;
    +    if (n == 1 or n == 2) {
    +        return cost[n];
    +    }
    +    var a = cost[1];
    +    var b = cost[2];
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (3..n + 1) |i| {
    +        var tmp = b;
    +        b = @min(a, tmp) + cost[i];
    +        a = tmp;
    +    }
    +    return b;
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    14.2.2   Statelessness

    +

    Statelessness is one of the important characteristics that make dynamic programming effective in solving problems. Its definition is: Given a certain state, its future development is only related to the current state and unrelated to all past states experienced.

    +

    Taking the stair climbing problem as an example, given state \(i\), it will develop into states \(i+1\) and \(i+2\), corresponding to jumping 1 step and 2 steps respectively. When making these two choices, we do not need to consider the states before state \(i\), as they do not affect the future of state \(i\).

    +

    However, if we add a constraint to the stair climbing problem, the situation changes.

    +
    +

    Stair climbing with constraints

    +

    Given a staircase with \(n\) steps, you can go up 1 or 2 steps each time, but you cannot jump 1 step twice in a row. How many ways are there to climb to the top?

    +
    +

    As shown in the Figure 14-8 , there are only 2 feasible options for climbing to the 3rd step, among which the option of jumping 1 step three times in a row does not meet the constraint condition and is therefore discarded.

    +

    Number of feasible options for climbing to the 3rd step with constraints

    +

    Figure 14-8   Number of feasible options for climbing to the 3rd step with constraints

    + +

    In this problem, if the last round was a jump of 1 step, then the next round must be a jump of 2 steps. This means that the next step choice cannot be independently determined by the current state (current stair step), but also depends on the previous state (last round's stair step).

    +

    It is not difficult to find that this problem no longer satisfies statelessness, and the state transition equation \(dp[i] = dp[i-1] + dp[i-2]\) also fails, because \(dp[i-1]\) represents this round's jump of 1 step, but it includes many "last round was a jump of 1 step" options, which, to meet the constraint, cannot be directly included in \(dp[i]\).

    +

    For this, we need to expand the state definition: State \([i, j]\) represents being on the \(i\)-th step and the last round was a jump of \(j\) steps, where \(j \in \{1, 2\}\). This state definition effectively distinguishes whether the last round was a jump of 1 step or 2 steps, and we can judge accordingly where the current state came from.

    +
      +
    • When the last round was a jump of 1 step, the round before last could only choose to jump 2 steps, that is, \(dp[i, 1]\) can only be transferred from \(dp[i-1, 2]\).
    • +
    • When the last round was a jump of 2 steps, the round before last could choose to jump 1 step or 2 steps, that is, \(dp[i, 2]\) can be transferred from \(dp[i-2, 1]\) or \(dp[i-2, 2]\).
    • +
    +

    As shown in the Figure 14-9 , \(dp[i, j]\) represents the number of solutions for state \([i, j]\). At this point, the state transition equation is:

    +
    \[ +\begin{cases} +dp[i, 1] = dp[i-1, 2] \\ +dp[i, 2] = dp[i-2, 1] + dp[i-2, 2] +\end{cases} +\]
    +

    Recursive relationship considering constraints

    +

    Figure 14-9   Recursive relationship considering constraints

    + +

    In the end, returning \(dp[n, 1] + dp[n, 2]\) will do, the sum of the two representing the total number of solutions for climbing to the \(n\)-th step:

    +
    +
    +
    +
    climbing_stairs_constraint_dp.py
    def climbing_stairs_constraint_dp(n: int) -> int:
    +    """带约束爬楼梯:动态规划"""
    +    if n == 1 or n == 2:
    +        return 1
    +    # 初始化 dp 表,用于存储子问题的解
    +    dp = [[0] * 3 for _ in range(n + 1)]
    +    # 初始状态:预设最小子问题的解
    +    dp[1][1], dp[1][2] = 1, 0
    +    dp[2][1], dp[2][2] = 0, 1
    +    # 状态转移:从较小子问题逐步求解较大子问题
    +    for i in range(3, n + 1):
    +        dp[i][1] = dp[i - 1][2]
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]
    +    return dp[n][1] + dp[n][2]
    +
    +
    +
    +
    climbing_stairs_constraint_dp.cpp
    /* 带约束爬楼梯:动态规划 */
    +int climbingStairsConstraintDP(int n) {
    +    if (n == 1 || n == 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    vector<vector<int>> dp(n + 1, vector<int>(3, 0));
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    return dp[n][1] + dp[n][2];
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.java
    /* 带约束爬楼梯:动态规划 */
    +int climbingStairsConstraintDP(int n) {
    +    if (n == 1 || n == 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    int[][] dp = new int[n + 1][3];
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    return dp[n][1] + dp[n][2];
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.cs
    /* 带约束爬楼梯:动态规划 */
    +int ClimbingStairsConstraintDP(int n) {
    +    if (n == 1 || n == 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    int[,] dp = new int[n + 1, 3];
    +    // 初始状态:预设最小子问题的解
    +    dp[1, 1] = 1;
    +    dp[1, 2] = 0;
    +    dp[2, 1] = 0;
    +    dp[2, 2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i, 1] = dp[i - 1, 2];
    +        dp[i, 2] = dp[i - 2, 1] + dp[i - 2, 2];
    +    }
    +    return dp[n, 1] + dp[n, 2];
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.go
    /* 带约束爬楼梯:动态规划 */
    +func climbingStairsConstraintDP(n int) int {
    +    if n == 1 || n == 2 {
    +        return 1
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    dp := make([][3]int, n+1)
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1
    +    dp[1][2] = 0
    +    dp[2][1] = 0
    +    dp[2][2] = 1
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i := 3; i <= n; i++ {
    +        dp[i][1] = dp[i-1][2]
    +        dp[i][2] = dp[i-2][1] + dp[i-2][2]
    +    }
    +    return dp[n][1] + dp[n][2]
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.swift
    /* 带约束爬楼梯:动态规划 */
    +func climbingStairsConstraintDP(n: Int) -> Int {
    +    if n == 1 || n == 2 {
    +        return 1
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    var dp = Array(repeating: Array(repeating: 0, count: 3), count: n + 1)
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1
    +    dp[1][2] = 0
    +    dp[2][1] = 0
    +    dp[2][2] = 1
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i in 3 ... n {
    +        dp[i][1] = dp[i - 1][2]
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]
    +    }
    +    return dp[n][1] + dp[n][2]
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.js
    /* 带约束爬楼梯:动态规划 */
    +function climbingStairsConstraintDP(n) {
    +    if (n === 1 || n === 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    const dp = Array.from(new Array(n + 1), () => new Array(3));
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (let i = 3; i <= n; i++) {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    return dp[n][1] + dp[n][2];
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.ts
    /* 带约束爬楼梯:动态规划 */
    +function climbingStairsConstraintDP(n: number): number {
    +    if (n === 1 || n === 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    const dp = Array.from({ length: n + 1 }, () => new Array(3));
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (let i = 3; i <= n; i++) {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    return dp[n][1] + dp[n][2];
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.dart
    /* 带约束爬楼梯:动态规划 */
    +int climbingStairsConstraintDP(int n) {
    +  if (n == 1 || n == 2) {
    +    return 1;
    +  }
    +  // 初始化 dp 表,用于存储子问题的解
    +  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(3, 0));
    +  // 初始状态:预设最小子问题的解
    +  dp[1][1] = 1;
    +  dp[1][2] = 0;
    +  dp[2][1] = 0;
    +  dp[2][2] = 1;
    +  // 状态转移:从较小子问题逐步求解较大子问题
    +  for (int i = 3; i <= n; i++) {
    +    dp[i][1] = dp[i - 1][2];
    +    dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +  }
    +  return dp[n][1] + dp[n][2];
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.rs
    /* 带约束爬楼梯:动态规划 */
    +fn climbing_stairs_constraint_dp(n: usize) -> i32 {
    +    if n == 1 || n == 2 {
    +        return 1;
    +    };
    +    // 初始化 dp 表,用于存储子问题的解
    +    let mut dp = vec![vec![-1; 3]; n + 1];
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for i in 3..=n {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    dp[n][1] + dp[n][2]
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.c
    /* 带约束爬楼梯:动态规划 */
    +int climbingStairsConstraintDP(int n) {
    +    if (n == 1 || n == 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    int **dp = malloc((n + 1) * sizeof(int *));
    +    for (int i = 0; i <= n; i++) {
    +        dp[i] = calloc(3, sizeof(int));
    +    }
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (int i = 3; i <= n; i++) {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    int res = dp[n][1] + dp[n][2];
    +    // 释放内存
    +    for (int i = 0; i <= n; i++) {
    +        free(dp[i]);
    +    }
    +    free(dp);
    +    return res;
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.kt
    /* 带约束爬楼梯:动态规划 */
    +fun climbingStairsConstraintDP(n: Int): Int {
    +    if (n == 1 || n == 2) {
    +        return 1
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    val dp = Array(n + 1) { IntArray(3) }
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1
    +    dp[1][2] = 0
    +    dp[2][1] = 0
    +    dp[2][2] = 1
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (i in 3..n) {
    +        dp[i][1] = dp[i - 1][2]
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]
    +    }
    +    return dp[n][1] + dp[n][2]
    +}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.rb
    [class]{}-[func]{climbing_stairs_constraint_dp}
    +
    +
    +
    +
    climbing_stairs_constraint_dp.zig
    // 带约束爬楼梯:动态规划
    +fn climbingStairsConstraintDP(comptime n: usize) i32 {
    +    if (n == 1 or n == 2) {
    +        return 1;
    +    }
    +    // 初始化 dp 表,用于存储子问题的解
    +    var dp = [_][3]i32{ [_]i32{ -1, -1, -1 } } ** (n + 1);
    +    // 初始状态:预设最小子问题的解
    +    dp[1][1] = 1;
    +    dp[1][2] = 0;
    +    dp[2][1] = 0;
    +    dp[2][2] = 1;
    +    // 状态转移:从较小子问题逐步求解较大子问题
    +    for (3..n + 1) |i| {
    +        dp[i][1] = dp[i - 1][2];
    +        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];
    +    }
    +    return dp[n][1] + dp[n][2];
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    In the above cases, since we only need to consider the previous state, we can still meet the statelessness by expanding the state definition. However, some problems have very serious "state effects".

    +
    +

    Stair climbing with obstacle generation

    +

    Given a staircase with \(n\) steps, you can go up 1 or 2 steps each time. It is stipulated that when climbing to the \(i\)-th step, the system automatically places an obstacle on the \(2i\)-th step, and thereafter all rounds are not allowed to jump to the \(2i\)-th step. For example, if the first two rounds jump to the 2nd and 3rd steps, then later you cannot jump to the 4th and 6th steps. How many ways are there to climb to the top?

    +
    +

    In this problem, the next jump depends on all past states, as each jump places obstacles on higher steps, affecting future jumps. For such problems, dynamic programming often struggles to solve.

    +

    In fact, many complex combinatorial optimization problems (such as the traveling salesman problem) do not satisfy statelessness. For these kinds of problems, we usually choose to use other methods, such as heuristic search, genetic algorithms, reinforcement learning, etc., to obtain usable local optimal solutions within a limited time.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dfs.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dfs.png new file mode 100644 index 0000000000000000000000000000000000000000..9a9872bdf0d8ff10153451eba319f6bb5014f2d8 GIT binary patch literal 30886 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step1.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..5699358f9e41dc7b35471a489461d9b6ac20c19e GIT binary patch literal 11645 zcmdUVc|28byZ62J-fXjN$dFlyOd({pks&jg6T4CfnWr)=WQtJ6R46G#hL8w5G9}48 zXCq`DicHz>*6(?q_xy3rd(Qiu=kpHtAJ(Ds$O-pr@3IITR zPUoyC0AwT+@r43OI&9~PIgk!5#`Iym@akw}C z{&-ybsiQo8zrXy`kC{HfNkO{oQN;F6LqU@aCS+>u?OQ9D>PLY{qY49mwR^IVx3lGfim)33hlnyndpdSIwrMWW5+qSr^1(F?136d7k6DF&loH3rOsIVoJQh*4*7WBrlZyY3Dg;$&V`cPtJWB|kvQ-SP z(&$KJ3^Inz739cVC!-&Ej3Jizg0>vtbI`!a@B(Be;EKPV|>qO*mIqZ1LI>XB3up4&?C_ID6P zmPd)lefAjx8a=5?H`h$yVSg-if{uqQBN)w$oBEGWWKS%O+Z!DyPw( zf04mh*R;%3t(myF7h13o?mY71^vS5stOt(X-d=)pze+`TLES10d~ECa|3yY4(rVPb zZxDrhz5d(z&1XbgVoS-~T#GPk>I6iNuj|O2J`viq@2muOAM|#nfG-l6;3p$FJ_7Qn zW&tinC+&LK?}3fn^+ow6;qi~FFc*I0V)tND-K7I*ZhQ%)UGGR0aN;%q3b9=H-E#@P z&^E;<{~PCVEr*_va)Bqy&3Cv;kwa*5MQ>c&xJ2ktdP3kGhXJE|GPGbs`(@A$6`C-B z$S9%4?=_FgzX--9qLO&-qCIA3B$L?j-Z;VAHq`AWegAO0@~js#g1-l0FIN<%mw14! zd$!sr_yiVy0%3cd5Nk+iiT|$M>MJCt)R|A&Ey(J0){Rd16X2D!>F=LFt7+@Ys z99MOq#x;-V__u#z7eArt9F5O|uzODCr|gF%;O@Cx&N^dt@Oqu!?d}3%O*uQvk0N;g zJKv=n8LD^DYb?c>R|*lB>Ds?TMBzO!bxG(L+~MF0ReuyOy};{De)hv(T&8#K7ELEz zb^u9i#ZxmP56L`4+QXh*Q~{%c+UV|nE(u2XWkp!Ylf>dPteJmdswC)Gca&~3Uqr$m zoQ{w<{XC7IonhOtm-$^X(;Huo|;9>ddHzU%^j91Zu?+RzNj4TrYxG^ z6K3)|^}Tk^MOiSq9(1&Ep3>t4nD|i~;mKTYu!jAUY`ALVipDmXEytmkosA=O_#fLc zU`lS!9Xw3L&hf=jJ5Yd~?(I#^7W{F&uvZ5RyGHfM4y$wTZoHPVd5eu1DyRDv-2{ro$fI9i_h+k@JSkG$2#^ zWysFQYYmJIU#k;!cT=}3=Wm?PCObGY5hC6GXD>v(M&$AzXpPDy%svUyY@nR_?a24@ zA#Xy5B`W6^7Y6=+-)I;vxxx&>c<($(efdkZEH$!N|H^YI)fx>3xG?y&Z4AB!iD2XAL0I`?LDN6LV_a6= zu6tFpatShR-+Sv<@SFRr#L3|o20_cGrl)7|3Fx3PXgazznyEU3Og`*?0{>fH{~fTQ z-vUfdYSFw_#DVZ?swgO7rU|UlvJtFQXx6^M|GJ;prGak4DI6wh@)P6myCU8y>0&cx zX1-x_-kAG{j#s}z&p*$|>S_z^`|RJtB()=zOr)g4MI^3zf`

    oOp7ciD@AFn^q2{ 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step10.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step10.png new file mode 100644 index 0000000000000000000000000000000000000000..895c38bd446dbdca1ae933d8b5ac5f17b49e8709 GIT binary patch literal 16335 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step12.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step12.png new file mode 100644 index 0000000000000000000000000000000000000000..a2b1b8ca35c2406763067c266530cba51cfa5d96 GIT binary patch literal 12722 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 C#WFGg literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step3.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..49e984e5939e1d2ad9305e21f95cdc0fbfb7cc23 GIT binary patch literal 16575 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

  • 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 U`hD}5_)lM1;gNjlJ>={E2GVqLo&W#< literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step5.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step5.png new file mode 100644 index 0000000000000000000000000000000000000000..090e91764ca44869982e5d2a2b3e3048a04de228 GIT binary patch literal 16419 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 Nn@SprrSfKh{{!R49xng@ literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step6.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..5eb6d2db31b080afdc66d075992bec2bbba7c77f GIT binary patch literal 16429 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step7.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_dp_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe8d4cf1abab7c99dc9fa68b05e96ed410ad647 GIT binary patch literal 16538 zcmd731z1$y_b1{k`#K}u;!kr+TkBm@cR5&@NN$wPM|At@lCq_or^Wl+*33Cf$Ld3pK7#KgI|xq*R! z;Tg=>`1R#qY#Bh%BJ^{a(Q{#+SkYE>2Nr&;ZLXQ-nz%;J zY2}SW5M)(gsrG1;CuS%iA;B>F!Q9H6S;>@g=2%r#ReHzs$jq;S$@4~T6Ax-OQ@SwD zRkPM*)3yOqd3kxW3tQ83n?qwi&>w!RtZx^8SQ3aIt{$u^|5TozpFg&|=~6w*95zs0 zU0q&Yp4^($KDoB|eNpPcaC}Q#%lp;0ZL8fg?}Jjm6=GeT8tKOjSlT*oY;B|zE{Z3Q z^v(3OjmR-K&ROa|*;^6(jUc=~j-;k8W<)2NXO@TFm zK9xSf-FqsfoB356YULY|tqZd&v-*XTFU#Kh#Ah2@*xolZ3(1_%s+~xC+h2{Yt{ncJ zQa)Y$Wuo@OXl_NWqgUvI7Y0wN=ik1YZ5wWjFK_ctDTJE7zOEh0$Zd#}ZaM{iu z4E zVXU^zsZ-S?J+aChm*A41J!1H4^SiVqPv`z7D}^!fE&B{r{+(|>MjADbt$5C~4@o-l z^E0TK>J=DW$(Qq%R|lTd@?G<1!E5;_z>@gS>GKOY4IO4ZF#1ETM6y6_4jD z`3nHQ*^9;C>fKN+X(yN$xqP;|whq*AcXO&h;;ev*)D#+w96qEJ=R-eP>+8fnCREr8 z`$lVduv9k_OonT?Gk+|xPI1BP^`3;<^377+$(3dm*rW;LVzBD*<$En@7g!^!JfX-b zDIXdeKB>TKgf-@m&r(PBbTNNTo$OYH*)GCxGo}5hEe~0=q3Hhy!9|_7LZ#*{9cpxd zP0?O+Y_>*9w5VY`g@ZuyUE+{eYEiSsOiI1f<;!fdDC)4gxV1+3U%i+5JQWnreG?vU z&Uv_RFo|{e4OuJEIkN4z1PO|LB!-R4BXG1`PyS~W;+WCl88h`)KeM}pgKM{hYHZq`bAL=5y8@g zHRbc%rH9Di>%NhW5t(#=Z%3Wf@_RuXgL{fGkq#c+nP5HzJkz`qO#`W;F{7p|(;09+ zix4vC5|KiUTMs3pbF>QegTPBxncOY9I`c8vSqMSt2XDR?m!Jc)9nA3N zFnh-n7YDfMQG>tjJFoyJKNDBO+2!+dgws<&%D>`UV%}o?u-FFk=m^m{pC>;u|Aj0u zrYV@X!wTg;m~yt;XM^CdIJ?M<;71RiB!K#W7K975Q(`J(PmpO9E;-!b_b{Sv)pw%@l%YH70ST^>;;ZU0!vkd zG#_njT^aS95LWRGgbUlZCyy*O7=6~Co(%kgiRX{py$0PVPzT?pmz1aVR>7y!6hw23 z0Wz`B8L*xh%clY$Y{gv;I+SlH{{_vAat#OHzbcH>UdUiZ3xcPrJIIPZ#`0n+z`}-C zIAhWJrYrDD{B9pdl81;pxTm4zLaIHIK?TO-3Pev{?z9W$XR$(G?;F~y5+4TN9tHl? z#P9m%n+aq&AXm6FKllf%iJTUAP7P`(IY)Pnv|Fs$ z1z+ZyEYEeAE>K?XPdz1)&luj#VxMIrS|Wh_dGM710XvKfBF27jlE8KBhY|(woIUSbP*N6N7vXAI}{hZ==K6q~~GZBKsq$ zngelJT;K|9q0+$|5HmRntM12pDDa-$PRdPSCf!SO1{jNFcbmaEGR5&mE(R-?2<6W2lNJlJdyq97QiPe0vQD*LB|G8|lfT^A-$g}4`uWJur&0ll z1%EX#eol-JF*u#gnwF1b+DZ-a-vw2jp$E0Pc*gO+fbA5t zeW*xtjDpv|=Q#kq$qPU~>4llPdlR~Za4hR&H<*?PWsix86C)*Ghw6bB7O>{pa!{sN z2X9_!HW#UYw{E}$#P?jTZ=r`>z*$(HsO~j&Dj@9p&cF$$`>WJ?68L3*3A;dOg<9Es zb0!2*c?c~ECx>g`$;iM1%+y-v`b&*wxZUj763s{nSf81`0x}I>fXsF77Ior`BWhTcouAeN3h1t;MAw7D%5t(m5oQ`T>TQ zC_ROtmvZNF0vQT*%~#FXFGaO;6#c>ySA$wklGI&P^W5Ak>1E*%d+{t z6*ZX&qbG^C2yUI@-PnrScqB4oh6f~R^tvOnbmU?8w}AP_%``haj8U$jG^*E00CC-&$^4 zK&t_^SQ$a%Y?)_vcjVXLA%?c@@|#%?nPhi9Y0_k50_iaU{y7IM9f{HRd^fHDeS0Ex zSPh$&5C;yP#R9lww_iPd9O`|%{OGEJe4f7R8#{nGB~UBU4cJEdNTz;K0D3?GqUBpO=x{xd(LgY^z$VB6G+dIX}skNf!!%b@@`E7Ojq(^1k$A90+{4#DSsUD1d_kTz|iC{$s^vp8yyk z!20nD6?oTy2S%1Y@&b)>o@K+f>cksx2jD|au<5eX${!^E zs4E3Iziw*6|AJ(2Ex+#QAyIG?@E}CTESAF|90-g5ha?0(Tor*~K}75dA>;sFPzT%? zi2o&^Q=-BOS^*E^7bB6T_Y~MlDBz(Cq|fHSBH6KjSRD3D`MOY;pdxwm!N_k30FmC4hZSr-1%M^b|Bo#R*I2|%hoM`t)yMirmnV!-cKc0+lVdBV zR&ttwDIZJo{qgCq3p_q~vaxc#TO;zYvpSd*QjXwm5@>j;elK+=QuIW;pcEZTOW$|Z zWvdkZnQpe>mv?H=<=56zqO%&|pmQ0m;J=Z?UL;HwgP36S=eQ6K1lGx+=OY~%ft%X@ z41otedg`U0^V#H*#9wC$ltBmnSHJZpQelt;$N>v{_d>aIOgRweWMCmTOp>D4mD%oB z@Z2!-lXk8jcZkc1LX4x0=h4>l8TKR8{8i(H%T*FFn_UI#FAI=lG3#BrWpsP&X_>61 zTC}(H+Qwgb(*5R)`D4pi^szkanM&r-DeLt_Je(76d5=HWb#DWL0xb~pfF|6W0R91= z9X3vYo}&qOqC)*`F#s_;G$$QI|7syZd()gOQ2f(k3rd6^NSkT>3ug;r9Kv-C$p2|_ z0^hIYxZxyGpx|XJ(7ur643i>YfN?>8VAGz$A}|~5uIdTC<)2ppO#iMFw3DQ8Lvh&6 zmLNSeho0QGE3O~G1UjG0hb5ocHw{&Uua~BnGcB;tb4-~r;lfO zXmXkn=MAbY-g#{31hzjOK17n06w4x-ec!)$)Ga|T&rgP~Jsxw}0h0r2C|fOkIA$%m zX3k5G0(w5hNv{Sj9nT1+H5sdL&|B`)0rm%YnC*Vp4E56ZK0Bsf?k55IMQ&2o#08r? zKNI?Q-PX|6W*l?)I7tpQ?$9%&$X5oHGAA`e&1M-T2rUJ0!||8W1K;>l(2_L3)>_1b ztpk{QkfDE_+dbG`y`|QYO$QHx4O9}Y%xx2(Zx>i$6bojLy6qkzqzz_vKvP)Lr>QRo zP<$SYdgn^3{2UTf3I}!r2u>@kX1!ZKmxl5Bu7Vnt=r~z_#M@WSaxMG6HlFixgANuh zKd;VXuO?g7HaK*(<;iT&L6Pj%A;8?SEU+5q(z!Xk(`|Q2f>t_*p5SJn?M!l%DM<(c zGt>J|6y5liI-6hCi6w&{5(0-_Ma(bLCJi ztwro&(#0ySKnsqL|M?TGm8XwW4p}Y`ma(R$AENb8jh_%uLnfESFh>|mAe;Q@C0GD> zd@${$d(d^b;jF~1{?FYqmSJ$v$(j5-l9XN7|NLgzNb0g?(%e!0>Y|VDW#syk;m|tk zQ#LUCsaGR;fi5XPqZQ9ZNMueV;swb~*H730JVH!o#zox2(}x+(c*lo7jkpd>IFD6; zA0GN;13rm~JeM`A?pp#%l`^?gZtKR33ou=IF++Y8_?QWietu9&I|UALOJ|T=} zobG0|CU#{`JORu|c8@RGNDNn)JQeCUkcq$Zej9o*46`*yZ>xXI$oC>c*(n#}pyh@R zcS6w}`fht4B%rb2jXv#zuv!M&SHqFRpAa>dHCAJP27j_BdxTN~zkUIBNlgYQmo|_9 zKCKM!y73WZn{RN?3DV0T&n^w-^U+)!37;DN+-o!igm8Em2}GU8ew(%#tO)P~hK%3sHmAm=Te7~(X? z5%aYQW=h1&@N|OVHcbWNUv2Q32RN~5jv;zHwf9LN?;jL5ui;w`gXt-y=N#Gew|(mE zfSAG5wzDMmcI;=(r28OyRcSVZQqwKjodkn#X>^5a{~`GiHdy>1KH0F481+!t`YxFF zAWzm(1b+DF8>p!xRT_~mV$dQqHB`v*;oTX%##P80;q_)zaKAyV8P7#TWZ<>Clm6X5 z0mlO@kd9tC!i9bL8c4g~mcfN>T?L6^xnkcoVR_SgYcq+aLQzwPxv!7t(2tN50Qux4t*>{G~l>G0GzUs z39>rUn|N_ZV#!4Bzt^;+bUjCl?|_AJwGx?CRAW~ArI*zt!>|t^y)=UK$0peTa+;i-hl4Y^UH4v{C-q6eZO#j zY~$wn*{E}~MOVxI2DFwYGDb^R_QY7K^%W=;0;HZl(b>IormSwaF5=(UNuUHyq!jB} zuowS#`Pe&l-2w*epMQq}|ip{W@$k8>}3_Aduc&B4CY-eoZ zz0U#tCc*z-L-u#ZWIkLxe3)>s$87WK@f&AL^NYxzzJsoVpA{}9nV+Z`w4?5IMK1ozqa_{;4SO&%|6 zYKuO6Nx|fFF8m0t-Y0YR&(m+$$JF*HnUHe|MtN~in|dwvH9V#Jz4=%*B%4Uao3u>q zXvQYBcj?CbB4_HnG#CrSV}`Dpcf=w@e%hg7naiuK|ChpBNSBr>JWJ7_SNc2aAoFwL z^%7UvYSNB|{TA_@U+}a3u&R5&B{6NaX_r9-nDO5h-eaLX*67(x*E8?+e^4x!m#J{#nOB~Du~hi&-rfebL11?>dtV6ccg=tL+PW*UK& z2`M_eH4^sU1x^bxgS9<)B2q+t>fJ(Z8W#-52p~oVFR=X4$BO1~(A@5B!-Jk*+pO!> zPhd<3FI3gf_RTmE&D|aAK$@?eGWiYBt|=1zc9K`GSJPI@!dI`KG6*k_4C6y^_|kG6 ztAtP^MtsU}_$p{t{@rnhgmn&X&nmd_**luha%S!MwsI0d=4C%ft5rOH3r8Re1V-dP zDs_#-%R%1dwkku%+EHYf+h{q88xfxy|91Ze>pt8k{!rfxFv*7pk)XevVqPM&o#Zo< z$Wh8tlO)w*Oew3iRBUM49I6{@NbOpj5n1EWj2%h}w8rzRUvPJEhAxUgLboT2-2d_N80#ghnfNm&jRfeQgVjG}1hyq5 zPpESDBq!{QfxNY6H_RSKWQ#|uJ61cH- zj)Q*c^r|VV@m(;~rF^7f|F{2I#z469XT^Iq5d{oP=%Y5WkCcht|7LT-3=dE43(%Gl z#IQ6(vd>7cZos6yl3Qg!V1)N}smpE9?X)c64>O2pqiDJPz#8E*V0Fg;&*{HJ4+lfg zd4CeFZ9X=M&=#sIhGVSJ4%Y(7oMD#Jnr#v8A~e5l4+}5DkD)_&ET^627fRHDy_!Xb zIu|Hax0-yZCsT@t;WASJZw9bwdf!9IO&|`Z_o8ZAlIJjZxXIj)+@%RKY$$LbD0o(1 zEWFtJU8W*r$PQvU+2x+HD+89>r62gUA7Jm>Jbamzz?961z>-^+7?j@TDapx0S^8zs zA2>{`|INljKc)dYX=mjLANsD8^&&+M7FxaaZE93+(y^g8pm444;x~{OVLf&5L*bx*6SPybrdBfPk}1LM0MG=to!VJ8H456syN zFI`lr!MttS*MC&_MC;s*aB_g9olqXD-t*W-y37*LWSd@i>B2&m4CULwyvlKC#7VFSVz??}>SKtkQ8+r3dZRa2X;J z&gWIFPx*QR!tW+^1go=k$5$s$iP_Sg6pb@b=j5FRd=|Rf+?mroh(pOP@7DzN!MBQ{ zU69i~Y#0JEA6P`x@Pc4LEjW!sg+-!F_K@E15$2HSa-AoUJ&OsH+lh#CMNTIulu@zn z!ilN!4H{hiEnyckin{tb+u-IN()}+!dAaW3Mw$Nb+P6+|#!Ka*+{?p7i&_5;!wRjd z1IoKr{cO`FSB?FRzr~ny2H;V4VvgxUmQ_(_A>SV2$FRZnh!XB?))b~jB|<&I((>Cd zIovZ2X{UuS)7lIs1s3+A_l=4Iq{4G25S(;AKkhPs}x{kyC3c!EuKo{*FI;B{y z+O{}QrmcLJ2|7+|)D-9u`O|Qgckn1AMD{e@Jutsf|HRsWn{$0~|Jvp9(-8Q)#ahm= zSETJZ9p`lYRtp%WO2hE2$u@z|ACvp`vogas?wRCMg}EJFJD+S#yqAhguh*Z>Thw4Q z^jU{rk-6#KLXO<7VLv?X^~2Af+jb-sagKhkZmoJ=Y;eh0ROFO=+;EeTdr|z$x^}X7 zvbg14X23H?*oEZ|sqt7uw{(KS;}f==GpE5V})9&&exJ9_oAfNB5Niqowqfe~Mn!!{lzF8Onx zFC0v0R(h1luOtG?<#wCO$XZ4W$wSjHPNI3`0AU40=Elo|qKHa&xems7tyDm207@d& z@kB1)*8S>^PMig^!8RH-{f1F)JK}!;bNHgaihhl#DbLMIUN!Jp`;lBYY@ppE{V~Yk z?AInm+))vY7Wz$EFwX_0V#r)_NHB6h7-MG1R9uIBa!cd-(uu3PMVqBe5^9YlI`ViX zPF^@~g4lgC!~hv5;nWD^`?ecMLNvg=s>_fg?~x=#R7Umet=E@(kCQ&>WB`!am$5eFjLrbmD%aXQX%@UBx^l0U8pO(t@~q(s>9l4nd$A{9-`y z_tXvGxd8oivv_CxXMbijC|(PMeSl|oJp1|4=)p=Q@B*^*6hcaC7S}(21qMf7aju>| z2CIxujA=Rfe+3(V%|vl3(xcg<65~XhK*=AA71AFy&pt|Io~heq;kh^r*zCBQ`(|Fy zhr>Lyt|eycHX}9D4XqwdY(FrS`@wmrFNt?&qSwbXtWm`)U0(8ir^QNmL^1{R+XBS% zmi4EQ8(|ns$R-{je6EaIg32!+@LV>_ulh+#^aN&cNd939<2xECi_he}|COX*hNOU5 z=~)IC3g379JNg8Ai_ZhDMV)oLR5w5BrbnzDg9;`p(<>JGc$an_em|#PSTkV>ebTzGeN(S!y)vH58T@NWV%~4Fbg|K zJN{Axx1HJV=O2CIzTjDT;5g?G;hmWWo8c z0A|r(1~(+#k%(-HCjH$loQDw`OgM$g)gqZ@eih89^sA6Hi%m2Gn%sTP(BmVs#gi^y6V^vXn)+vAa&O%?*qV9}?^H!N44^;h`jP03`@*T~5k zqvd&D`%$p}?qz%SffHA|B9z|OV-Uzh8#ObYDI=qB-FXIEAz0%>#yQS``J{g6pyL#Wzsaz1J3ptg+j8$8Yj=n6Pt7Itb zTdPmfqq_H`+N)9I%-6)AlGHPbh)njsePoiiXk2%)AjwT>=YPQ3LF0xvo_y#@(IMn1 z3=NtO+Z2}eh&a#T={BD8W>uw3ym5kAhu~=AkXny^qc-GKr%%3`Qld||l-ez468h9z zves+hwm2i=hsHOx^x_2A$3EAt0#Z>$I3FCjH_*a{rg=@qJ+@dhVO> zR$D}d9W_Vrnx#bB3}rowELMJF@aE?SA(yy+I=cU8cxM5<`Qmzz=Jn^e9Zip`I48Lu zlZrbyOT>0Qripbw}A4)eH$>r-WVGvMkfEkj1eKMGCAvLvHc@vZ0GY-rV{o1_Yg)-sape3)1C1umaihsj1Mz zf5xDwp2@A3EyT1oj(TTlv#;r39xeNf*mBl}x`R1)RFN>xf^=v&Fu$bH#RUUfU{g!?X?9j(7G{1$Fs=kfbcL4{mG zI`if8u93H6;dCf_P{N$@^HG#2C5l2iO6?ltE{=UdRZKEPa-a>nrKURSXhwzpnRDS4 z!$Pd$&=i5|Luk5 zEa||`8jYJi^fC5`{bQG1O7TZq;=6A?_HexIb;RWMBHJHtE%IP-dcSb&F!x~s^fra2 zNr;ilf7XxBcg>=UQrZ1x9pgx0e`$ReN4D3CpR5m%tSZ&k+C$$Y1U&F~MWZfL{;tfZ z4D4wNPpK^pN4rgueEAg@wA>I(F3b(1t|kfdxk^yr-55Usv5YQib!7v9Zmm)>q!>b_$?j2{ zhnGnOnm-x|F=N_%Y1nrJk8X9>q-nfL!AOhADySfDs}f;wXNye?U<1CgdBmAASuxPJ zYuVPTu0jtUEF#edxmwR0B+lPD zWUg4j#vLuxN{ZZ^xi|XL++YsnJ_nqTQaqzBn0V+c?$SG~pr`^{F}aoA{R}kNd7JXB zGWxu(0sCBd`(usuWSECNIzpSvbPTrg*&n{|Qvh`~WeXQ{hp7gFEBsJaI8Bm2R3@~tqv zqYCNfR?oGb6BF8dI1OH84PYQl&Lojpq4v>lW@-WMRuO^oYsJ63H(|^UPkcSsZr6A6 zJ|bmr?^&@*FBlFwp9khotQY18Ex#L-=CoHJce@*&lI<*{)+yg`2OHcxx{ZZX9_=D6 zNzYfc%)wf+rbwpZcdKG4)tg);o7_WVxB*}MPaocYaK(R61MNagjD6nmi~{v?@@3eM z^q5%)ue_}LDQSU)wLhP7s)u4L%v2?Ppn`WyE7kWc{kW~tAhIsX!BB0I;w`Q~yiH&J z{dt3!cQdUqr8?p7C?%0KYE~(HqGi8|t9Rk_`k6_&AVThXH{3^G=to>8LfXdXis{`{ z&uXhf_3d~MH+XYsMQE4*L%>!~cQoo{p@J$j4*A2$#9h+$A1v#NJLk1#n^VQ9xpG_K z&j9Rfa3Qz1j~e@+e2tgYg_sOaQE5w=D@sJeI$pw>_i$P*DTZ3-riwt8F=fQ;wW86< z>DN}X%jL={bkT<9yUSfv!V9_Xm)_~_YwxsF-;BxR_hd@yQm!pH56!!Ozh=>Pob&B* zP3Gs5^T##5i5n;Z$f4#`+C;{mPjh#&;pvn-E6U4;@7-@3zb?mzsg(QN>Av@FAwHN< zXZ$iZL1aEKGqYtw-J`(Jqhlu~CU~h4h7*bczj^RP*o9_Rv4Ef*^XP|Q$F&hQK#I_U z-Lhz$;(+Wr56TyX7HXI~%a)i#sXPd1);}TR;Cw82_rZj!Ia2#6JSi+6al>p+o)xX( zv6>kB3Z!g$FiIPqosL;jh*c)wy0E%LSB90^StNDs0ii5BOR`oxCy*Uo7T_PyNItv_ ziz~P@ewUE_84D36*RJFyJ2eVPM}y!ioM7<&2CKM!*gBsIzr(5nSmwnL$Ab3nh?eQm zKOGvB0srHo&%_x|bG|6Qc$4dH28m#IzyHB7_99(Ng&F}?^hY#Ppk(vr4QSh(rw2Z5 zVp=ncItq=ELe5p$9$F#NF2qpzxN4N zy!cW7IdHNuA(!wyJKmd{F}P@^T!FEL3t$lOe7G(OL7g|12`#roMquMFBn&IpkegID zp!)1fcR4)m5?1sKHJZkOnD|#$T(uk6@Lg=Zjn5t+@-0#VvQ{fTUc`0bFbOZ~7I=aa zbx-3sud{ROdWtG+D`xGv{8h+jejL1b^|-FdO{%ZQFdts07-;lN7@t2`}-MeX>>wll}RN*3gy;y=7OL z_v}8grD)+B5Pj-YG8!w4giuM5zk}qQA-`)Ns!$)}>m|=(!9uBJ+*c>Fc@NEw~5lKRn$?wZR#_yC0 z^MoF>N-Nkr7k_!@Dzxo5*XU@&)a1yNON|<^(e(?a&P|e1qIz~kT!sG{)7v}!W%yyS z^&3WRs`X<+&{z70ViZ#?p|LD($(#FD?8tw`(Ie94=%h6xXCSv0Bv5twe^Cx99iHNr(dD{vn~A?~ z&#omY=bS#9X{E{{znl{N#es0-0Zxse7z^I6HYq!4-Apd($#LAzp3Q(-5OZ~Da9VXq zi;kK)bGS%0X~GzOJZ@;1?$h(mjf6NnJp7dM{k!KR#<4hE(4DbZL%xph6z)h zqFyI>O;U5{G)6r!YWzx~^Oa}@|Bg&}XSij7N|Km&Y^Bt#hC=qh;9|qJHm+h{Wxdf# z=iz>r`oQx)qaR{`_M8x8-YJ z$YDJTFb7x#AH;qYS!1w3`R$qS>xwH!)Lt;t-f8k_F$DfHGuolUXJ2w}6H`n2-fa9T zbgp{Hj6l{)*M24uxTy-$wx&*9(4#** z>%KYu5r_5W<8x)cH?XU+&SkjIJ|v(dApMgF>(ld4s@30QFIQ+TRx~;|@ReIDV+%wI z*SySKT#dA+!uxg<&*R!i3(|S?;AMY0)s8E5<3HbX`(i26B?^_lX%q-HT{-#854E$* zMV8}^%OMyKV)Bl0<4C>C7wkniaZ<28$m%OP_~%$p&JDp) zbp`tuj4bGq$Cxzv0OQhV1KrUI2umy4m{NM`<8Iub#aoHjc!z(a{`Si$)J60SUE|V> ztDDBfQ~?y)PpN%LR=i*Q#@VGi^{ObmO&#tk%P2oB*r9dPjFU2IfDo@XGhCx6ydaF) znuaS@@s@*Nn7BMdmel9FDgLZIM~9APt%}m?Napj=Q@fIL_n~=)0)L|`>~A?)*J&`D z>_P+KxY}0=d|r}B&t#LaA8!|~)8CRE0qcbzuY}uhRO?*51mr2J*A!=Kp_r-BVr5W@ z(~taExDTykSBmv)P%bsP4l6TeIEOD|k!l2KdY|mi{9@qipH*#sUDr0(<3VT!@$x~O zoYja68c-I~!QpGSiZqU$?6Fv!1}f)3YY?zDr}5;rlRZ zibecLws|T&%Xi``xZ1ZC@Hvh6Ei0r*AHVb227x+2rALa>D7lsrI*fTkkd#<>RZ}9S zP*##B_f%=ALt3%Ik?tCOLdnWm(RvTC+_(xbdE_e-9Qcw=2*TN+t2XddYDuby}zzVozUmi)VuU;39<42}r;v`;~K z=B^4~(x|bD5?wyX?|!L>`lgGSbh!CZ-@XGL`g6iU+*6wPu@fU0yXx$P5OX(~m%@nN2noo#$Gq5R6!xdw1YlIEeMXk4j zpccZ4xt~{__!pVGScYXWw}$-;Ne_yTzl2Vm!r;}b8g_2h~vIeeu(++VoIlCsBt za>QR~{M6H_VEVd9YnNshj?#SlP;=8^K{PeV2{z`=Mh zMqw$&)Po#d^`ZUv_9>2!4lz%qozez71hkR;!Xd;yOC8!F*P)lJeXPRIVfFhT%v_38 zm7c}TS;0_(_)fG6bVu7RtG_)@+B-frEm~Bbt-U)_I^YvPOs};0$-12{U;b4^6vFf< z@j$(`y>x7^%81QdkT~4!eD~`&vu<-*i?qY@QakHCL5Qwvxkx)IyN&7-|2#Pj_@U@h zlr>$q($ew7WU0k>T!!k^rXnl)Q}6mQi!CP(`CmX?UwC>G2J@-<4Qq=&Y*^?BvF@5` zGu1~7!-0Is&+s?D#8$idjeWOx6kE4kUMl$@f-IjV*xzJp^2t&*Rr><~*B8Oo+^K8c)5Y zCEw-d`-`=$A5-kJ(?7pBv3r+u(e905Mznnj%Gs5#j#L`2LcsC;~Or%GJl4NYlsk{PR7AzpI6133yvCsRl~ zEcDT;4CNSuORHz8ingkA=!QDtTSm^twfwLrE4?%Kc&&d(QbIu8SUtUOV)M>^CRI%z zB{tYp$t#{wGTZwucN&0KOw{1xq(>|-nBbX5I=F8Kw^kE;uQwpy^nCFe+8}+{rDyQ@ z)lCbwG}ROX2P#oIEIrjIGOzBi5G}%tSEG0{j{}ld>$7$<+S+#MV<{ZeBP-C<=~NSQ zY#AR|R0?9jj=k29g@>|&n-CdN8O;5fHLz9&c0CMC8*D!q$I}Hy5Fh+G-K@vnYKB_# zCF~NAgA2HGtD|4)#wQUGT4#6_vPR|LM`3SnyVdiZin89jX3GMe%#M*`1E1~(wD=Qg znU(0NVn;E@G_p*B>n#c5p<`hQD{4c7iDfFemH%Df(>w!2zE;HGE17G99~+ck*iIyv zY9TK73C7Z6o3#B2%{%iASHC=lPapUUVi$lEAI~R&-w)~c_XR7zDpblsq7P?iC?vRa z8FdQ{nYP0CqKv{%Z*3llk9hsD@{o8H+-TYs&e_eaqt~8Le1pi}tK+;Aafb>INN}%q ziPett24EJ2-SZTTeiBDK`Lur5WO9LX@WH2|F~j(0?Qz(dV8UtYB{27jq4kE`vS$bx z1ezkACsC?-h4Orx@K{7~?pra%aBnv2M$RHUc zry*w;kSJ*f|L^d4{R{QCHDcxV*gF+uK8<(G3j^Jqta@$H%R`d*zcyV`F0*8ymB; zvr9`$Vq#(u5fM+{XKjK*PEK}objZre z_Vx8`ZEs0QNq_tHZF6f=LqlVDc(}T{`t0m%U|?WwZZ0n`uXTJiHa51qySsK`2Z2De zwY4QCChqU=4-E}Nv-(Ngwz}nhcSw&@KWo2Sw;$^|h;^N}3U%%?=>e~5_wzRZlWMst0 z$45p+T3A>Z8yibXN`_a4jgF4i*473G2fu#(T3%kEv9ZzK-oEZvosyE0YracYS66<1 zzM9&Ti;Iii-rmUS$c2T4z`($@wYB8r)SHjoR*g6;pw5FrLU!}<*D~6i*^=R(xRBM33a+2Ae;qP7xAC?SB^2N9{Mo5)tY5~Y zKd&<{Fe*^r^7)VE<-Cf8^!&NB_L<)4-j4D1rtV#jvdMSlL*?Cr6+`9Lj-IIbE#&BG z&G5>bjA@&K@wWv?zY^bo=3RxnjSod@O8IMU;j>Rajc6L0jV^39|6DB}Sc++!@vEGE z8J=9wziwW>_^NL9TiuMg*GTrja6(EEJSDH7XK8SDFn9Q%rfsKsXgT+5XXuBLl0wC_ABrl`wIkDLofLR#;jyTW1o)5h${_iETLzMJi&W_7(*t)~B>AubJw9pp+x4cv7y% zMwt)49JpPhxN3j*aPU1W_=AW~q4Xa66-OzwGe!D1qIut&)JJlDL$_!&O zI;m^edc{H)N~_1W&{wK%%w>V{9XM2lUXp5Vvx5n5hSZD(&RI($n6XvzTv<+%;2)eP4TG^J8%2`~F@|d0Fq# zjCnfagxd1K>9_F^W9VmJ96ZGQ-i`lLg$Hm#zOq}2p#GqL=twf@lflJ>@fMAG zO6gHC2f;>r2z;-85#%1h=u;Pr9Bw||scl#ilm%LJuxcp!R(}opBUC5{{7m7%by?}< zA;m*1FjVT}@)7{5BX(T=Nn9Ry%I&e|F^a1mwRb+mL#p*a#yM`ap{;y-4vUKd9>T}Y z4Wt{W!Sump56R@O0YNAT!6>;&6o4>;6lU$Uq+UaXRxJq%fH2$QoJ?T*8)x-BiFAz+ zbd^T>NX#J-f8Y@n{2hI+X_r5wRv@)=6pQ5VNS@vc(XPa1D}uCn(0<-%@B^p+oMh5S z&ij@INZV4d-Mg`?K(+#kAS+WwSS)Z?Q!H0}voC>VO4M+F3&>ea z=Bmg;My?YBNkJPhWaGS8;!J^uYOLU2PvRp-R)eXB#{)0?4vm5BsT&>&SKi)`*pMTv zpgy^;`#N$1xEUwP1Ja>la%3vVFng|o6F>#n`l}G0k^+VGbQaE-m^*wS2gXj zp#UiCO}1;u8oWU){ul<{Yu4jXf{>>V{)WnZa3?u_poOIku993Mf!ePK>n?1`~+{ z=v2O7NxQH_98?4*m@;r=$e;tI=AUXeZ;nnv-sjd`g`y{6`z;X>+%aDosLXBW;HwyJ zU|G*3Cp%=?{p!NG?J@`|d^1U;>GQmggLbf_mt-eqF@Bn%XgIVJ&g?gw=cDqkoA(a5 z{9rggS#LB$;lDQY75hV%&9MsER%{3wOIngLm<5g%2PmXNF+b=da0BzhXNEk(V}`I{ z8vZtx`Gf*D3>F;zpTmOxGNz!M4>!he%$dUjZ9{!tLAD#TSfP2guoy2bPuMii0FIq5g&s?E(*dKb;5YV@BiIx&SwY%AH$holL3Ja^Z{Y}U3=jr1G9W|Bt z&WS!x+nDk3fsnxgmYEoUV)AYr>8pGk;9+upIsn1s)-YyFj&uN6m^_sj)0r8R|HE|u ze_%oii@jvN+KibyW?#n4g?os!eq~4h)`djP$OrV%r=jV zkmVS0lekS))5c~=ct~pgo6mlh(!x@I-8Ca!mo)1mgN(gu|4L~T&;voAL~bzq7~vs@ zfOMRw0Gxo0&}KN*zfy_i*?#*Hls0#*nd#xaoZRcnRdO z5bdlCASqBHk88%D76C;vh{%=Ra3Y7KVw5paHgq~UwkC&+O_$l1PYT}bNfc?lR?+qZ7qXNTs0VzIU z5MQ$Vj+|b32@8091FH9~>FhBPc-V2Kw*pZgEh2!ZZVX7UGpK^vEPQk{xiqEJcVKi1 z+*!fnamZ&ZJmnT(7Tldjzav^G&@6%U6w(j-Hh7)$$32(sQsQOR{nF@0EVCJ0S~l?b z9b}chsqnV$(je?JU!3dPE^Y^~P6Uc#IDknNq*zV<2mXh-;H3NsPqi0lLZ=XHn`&@HZrp!GJoZikOYmoq!>v<08;FN~}Fg?mL*#TB;i z-+VN2wF$f?;&8kId$=L#+<(2RN! zMvl6&QWJhL_8ZrThP`j!m5wZ7hlWyE-^!xc>Tkl*HdX zaZ~ip!GIgB_p#LGw302QIZc}@2Z7^3DQ;^}bWE-VcD@2d$`>x~hXbhO>Q;jasw!@- z=f>*l5fB9ziFKJ>R=mfzSRu+ije!!LN?S6IBjbW92sC%q>r!u|D{(INyUs8#dS8UK z@im1V3rJau_Piy(I=pP<OEZ$GT>?_mjBip)ndU{3Jr0Ac3k8G;dw|R|EF?x~BO* z%6{HN-+*YJ(=fvcu2dY3g+M=}|BIw|f?!44>h~kynf?4?FXTWIjBFNV`s$M*&r9vO z>0xTXLDJJ{n}{5IoyGzxIrAeQ7V_ufg9(A5vy|Udd=<~!9OkK^SGw}%He{bCmQ@Rt ziw75EY+5ysCWAX3)mA?O?K*Xg4>w}Mf$i2Z1yWuZ-DDuds`Yx+6td~5{VxBWv;L1} zn;3|Lo^^#9io%nx#PX-UREZiu+C-xnrOJu$hQk33Aq1;`WQhaIpfV(Y5(*|>xkJo+ z_yg(T_)=$`&wg>3v495Oi$5QcioR0y1w!^cckmGe4?E0~L)86ImF@Y3-7;}f0#8>Ppw;-PY`7?r06}R%XzJ{(;{riGQ^<*zD`VQB? zu6t`Jf=C#u?V;z!tFMP9QhE5mc2X4&X_6gHiQE=oXm0!AyIxJ}Eywmm9Qs*a4G0lB zBtu*vz_*+O7e%#Ng@@pQ>r^%IPkjB$Nq}^ELB|RAwbCG>-3Zu)*v^o#zzKw%!0q+* z5yk>j%HYd5JUC?_IdioR5po%?(hjTS5zsk7!Ai1>u%zvUAAq6NI~!5Y$f8)4z&jzh z&Qqit1Vkry8wYe?u>fam@*+;S0@THd+3jb!YdXn}I|Mk^bY?=*IN?^JI9~YOZ*UOp zky{qRGPz-{COAlTb0O71JTq6o6KhtmE82%U%X1YXiBSHC?cPTdJ~l1ms$|g5FVrBv z7|n`l;1hOO3ZT$d`bF+T5Q&9yGb^)xL6W*gEq&?~=n>FEiBv=MHO4lQNe{adA(&Pc zK}H}4K3J(h`b*!0w?fe*P{tlxXi4iG_~CRm@PRNpo{OVI{K?Wl*{&3^b<#;0sop9h zGVM!)cc_aVK)%5d>ivahHUOre^fceP#M=L1j8Y7!-<&p6WC{_qk8ZVK2=!zr)w7=| zlMm~ohv*G_8tomdSdPT&#k@TDw)5K9H?;9L(%=Y;FopTcguDv_)G(yJMsSy4arsN0 zp(&{CtSVHxoGp&ODERIkAF152-n$K}e@XLP6+wi_j*=T?f5&lYHen_cox|37z6~)V zE(n2w%GDo?K)}?W964~PK<+h$f;FW~W90Q2W1e#k}>V(7GDk#XPoN;kh&k208?oV zuyfIeGR%0NnA5hm{o_*HkwB_=XAvDvI#44$WK#01+z=$w2-28+L z`3DD!pN9#mHwy=$OLAa?jtp7igJe2Cq|JKA@M>5qeYgr)uTB-8lNt3j0~IQKmRY@Qe{$^l1d z(E0z{dHoL--L>AiFiwBd#E${d*3~M@P_{#kyLuWEtP#U(t|_Vn#y(IHH)=cL zmgXpMRlgv|C0ERI3cSo-mK9*=_ueL4uUpYCd*SJ2(wi5z_+A7o_~FpQ@0!#{!uYps zkPw=MrJDaK5ewJFSB4mQ-rchl&;DU2Oglze(GB_120e5db z$@IMgw5ke7iwl4V!yTM14}207OYsY!qFn{~$@CPc2zJ&(;m#7Em^Mfdtq5l9q{fzjIBTtVJi*jx=4 zSurA}tz454-r<*`$+~BQIszu#(lEDBr%gyLM36PYd9#Nb=wwO)>I#&ln0x<^BE2&MrT^N?YTUjBR*9n-nRZoF@t@=gPgQ zdh!0wVW>oKKCI&o4h1bzl=wp-TWtwezqrA#lpP8@#l$J#p+4J``H0pdM&7`A1Cm7s zfJ^g&$P&Q3`}Ux$oFkFciI7;IgBU@W3b?cH{L9BhQ*t{O=H#pC{@F8j06brSXPryE-bpL! zR$(YE|4Cc=hif+;d{MiU2-f=OfAmCsol zd{P>4&Fl$(W;XNiD0>1^M)>Gj#!&6eImjk|r_*8|atBfy-(xMooGyV0SA4`&uuN6o ztA{XTibU-;sMP$c%h{gs1r$D1A!gNa-;LWeSgqR>cz@gY1W+uA^a>Y5XN*WO6;1vZ zmV}53LYEouB6lX#@TopmPqsV+vqlH}FPoQkOd?EA_*K@7BW4Y%w~JaXKNPh{89HO? zQm1ojvI`Ga*KA$&>LX88$#4;;s&QkyvrC-b)=^E&WC}9oVqfnNRoX!x1h#ja7gOks zcO=^%_**aI`Fp|&aN_DAFuY{G|F80-x(o*#myE9&n_6mVXHUimaY@WxomhZ1I)1p> z$)F?39JG5SCwl!I24s+mf=CBja_L=c(Ya=+a^W(|%I` zEY+lbzYmcDps7}jXkMA z-V+u+dJ(wkt8LSJZ@36h=wTT>;VFR-fjCw=xzIubTXI>p%77Lj!y2r>`*yy#w|5`- zD2--XTynYMV7I$B6swRYpH8}0ixJW>OBzky(T!8bHPxVwE9gMHgT9S z40c;-fllji%B!+|bYpeV?QO5q(S^^jD+1)|#q)ob;FmumCzS$2x=w19)DyZk&bIXp zgiFbqS4a0)SI)7pz4q^|_{5K7uJpC9MBx4SCf+G^l7IjnqYqY^D~b#*Lhy9%c=IB& zu-M1C9`x}b5kJ07)jVfd$|yF-!YmXCHi97HJX*Pkg<}b6DZ=uNKZfW zTdy4&g&|jYO{xasZLgmXt&E<8k*@8&n6pZw@0K#IdzZcc;>WM-k?aR2o@b7;(6io| z^KuRnTr+xq)@LHIHk0JuVD$a7= z^J|l0$v0YI>$B;qTKdc zkB~+S5HiZjf5{<#BazeSFDWtn$GugbhdLiM(&1ard zmU!_~V*36NlKI=FG?Kcxk`H7yyLjPGX`do>fji&006v10exQU(`c@=w=Uw%W15?=j zk!qb;4&Z}Qz5EYCBdpG3CD0eZ5pDQP?^>2zGy92l{;wxzL6Y)rJ8zzel+h>D*vJH943mF>ED^058m(8;A;{mg878DLV|eNYG!YbN(S>gZ(uYE z;R=kJWvsB`ZYP0{3j_6@335KCyf($%bsUss?7s~ptiT!1@8TtWXeT6(}WH9 zh}LM!!u@yEK@y`ftDicYZn&}goridkII29VmxvShLEJqjiihG=ABg^O2F?Le1ZL)E zoj5KVAEPA-8HMX7EQ^fjW!a84Bf6p=@IS`wSHmT<5n8^JVEL#%r;14Fm7Vzg(kDUo z{+u4+GqyYjbn0%-8pWfIlV#fsw6nYMKbKNCvdI$eR0+!zYHU?U*QE*77Jnc+WsJKQ zzBmofE*B$q$Gw#=0zZzm-^q=YKY!HMoN!h!L?h}~!nU?9Xl%fQqkf6SrLd38MAK{P zuqbWutLhlnd)Z1pUU z*)lrLZ3l}t^qf?~FXw%iq~PJ~bgan?vMmH(Wm+Vofz?w2L?HvVI?n)^`sNUcybk78 zz(hbe`$S;)%Q*I`Eqj%0#?nph(SVOB$LAgOKT_RGqQlcgJy;^Cq)SQ47Q^jS;taW_ z8&UBLG>`_n z@|9V>1-D>m;WsnG>3>pAh-j7ChlG`O!)y-WecBwYHsGCrzSB1YI|0bMJj~!^axtfz z4?%p+0!)Fk?U4^3Y}gF>kbk5Ar;#LGrbUj84x4`k&7Oi)Y0o2DKmI-Cz0fEAsD;iU z)q!?)LPT>o<#T4+4o?}DB#U2d32z?1HRK2tf`=1og@L!Ml{#2_x{7h)WC(;Y;I~`!-uQv zVDhMGQX%{l519|g! zFAUcr5KFz9#3JzMZnye+?oRUNOzPoWHOCOLT~}wpr6S(|Quw0A3+G4jD2|S0DPwu* z*eh{O_5$H8q82QCgbPE<+eR{Zc0!stLjf*ZxdzHR`9!F4f-Oi1J0&cs<-vjcJfYCu z$FY>^-vGV3$WpF~jmI>olN628_-jLaZhKrk+yLmPdA+Skv@*rYHG`7w+B1e_i;Ty@O^G zm?Y>v`t3qq$vrA+gsn5K1)MNi6b?kfDX z3%km)z8zAhfZrv=cAnxG;f|<*FRX~DyaEi*;mZ8ukYBH#AyVTB`!D~Q$=*dy_4Ifn zoI+y`ZB*B#SM-X%Lh~fR|4i7hq%Oow-Jr7$r^R3CD%4sE+29s4(&73_ptUxDtULj{ z@q)2fvqPwUBLX-Kxy!lsq2-I+juw{B@daX(>xuw?!IcByq(vt?Ccl==@ z>@coqp*Xg@XCNmYCt>j|5khDX!DRw_GrDZWtuBywQFEE5A}>I}#V*mrc5xUszbo)w z)5!!!{m+UzRYOy-nWypSE+wmDSXQ5S$MI+WVXh>5N)JTbjyVUh9M7>N@R&cB@OWwY zDD`{H{E0RPc5|^I)0dV;A93_OlF}+}cbx8#pTy0#5l1fjxsHo5w^bCC?(@O8k_ZlS6-O)YYvuY{KB0jMJGO8Y9(QDz9BKY9V-6xEtmZ2Xzq8~+#cQ{u#wl)y9#?o zM~~G{`=uc571gUjiIAc-$)Q(mp*Y`3P~;m!knl5v*37u7RF(n9NhmaYOS$t|b?d8N z;*zGIz}Ok%C2p-|0>sKOj6wEevPm@oVoXxtdMhsf#aTJY`x*ZRbnJw*KP@|n*;)H_ z2H6iLe$bV@s_Zl=xSk?OR4Cz)dp*Xq4c(LBihroN}6-+5r>knRox;qzg} z=LD%5-j$4^rS=DZEIahnURkQoA4+`Xv&BNUW{OownGzozw79_@nOY3`fVBhD5B%`a z9ex=_h>Gv3cA`xb@Y~pyJYEe=qd#uNMym=Z$}+yLnxht$%Kwu238>v%F}oY2B3Fs~ zRh3|9DwO&MV&sk1OXGJ;g?Z0Y!~O=!=CT#Yal?&iFHWU}8?^rVl}?BJycEMo5 zpqKC~r>hbbvZQUwodQ|?#7YnFea`KDSpP)I@Evm2Gm{x|pB&4K zzWBp2B1)rC(o=rk7hzTx%lroSDY?eHuO;@id{$OZAr2jJ`~0VkzkX%iOA6PF*O9;d z<|%i@xA{oNR?gkmdoqo>Hm__FRbDX&-~DEn$)q=#aM(C~UM?nh!~IQU&|nuLHNgl+ zYuQzi6~dNfEZ7kmAh%CfOD^$xKME(Vn=bI8y~A8xuwyyZXJA!A+#De4U9CrZdWJQgv z=eE+IwjTj036x~O9OUhHb3r(dK^B^g7Fj&;IzkrLZ)Ais2f zdu!21$Df0uT*#tupwT-M$-8g|J+xyDR*8cD)HPT~uKfG+8c@WNZZ@Vwbc(RI5cav} z_aTTq7Po}-`G^fZ(Y#wY2Wwze z)Op}nNq`D#AV!S_O&8G%rZ;i1R{OhpMdf4cKaN=1R>RA|Q&m>p=nS&aE)`6zs4f56UE*yJH> zEZZ1|kC_yaVywN5#T$fuTg0XbLjSn(1@2L}+G(f-r;HnU?m}Qy0;$>Ubfr=T!kyWIOnCfTJ_QF})w;#+*}xbFUuN>tnl6vOL54R8%%min;JWRBL(D z(^-Y^W3iD}?3g!Jo?Lt3U z+MgsH#m9}MwZ8kdginI8!IL%|QsKY&6ePXCO_Y=@2xVnY#q-iE%ZwdLzV@ zaQcf$r3z(4FJs$53bJo%M zmgekRjn$~exr8e-@Bh2nDhHkWN*q8*~w{79{)@eX!&Bc@tpCg zo@4mBk=&t7-1y!DqR=OSMz8m}D_FjaKOLIUV;b+;389=IyLOICKS`87T5Re){dDHQ zA&L~*X~*mk{`|6|fLH_L%3G3z4m0Ev-3rB@Y2{T5e)XLl*hYeRv_%;e>rFT+f!ORO z)AoYE#uLeP)!}Atcskwp=uGS@?ffb+6X_Kg3>EQdDpiQ<%JT5zMF@33 zZ4+svPp{%!$s+T0BO%;ULq2FOG=vEoZF@0)WUCI!-YRqbDgqZv4lq! z5*RB}4?1h0l@E;;l!K1$Q#cfbu2j+9czLoi^?*A;qKI5wmX-7v4{aqK(;bf;cazzx zk+NjEfE0o1(U_wR7Ds{ACLkFdW+wV_^8*8{nv^kct-=*Hj|AHR*x5sE7vK5e-gCE7 z)oA(})QC_fdeWl$kW1)%8`zG(&rYOrIXk_M)1Tr&fi`D8*Og(;xOk5Q6y$Y}Kywtm z9u+@a{sld=+PhXWoc)ay8#m^pbp%oO5IyXXydvgR<{isBbrcKBT7LaCDK<6S7CHLn zAfiJoyjk~*JwpB)f_Bg7oxpt@B4%-XF%9kXPI9y z&^)O7lJlsYRikD)n7d+f>k(tr!t>u{6E`9?3}th)1p2;&=r`agBFtB(r+$M?;aZ%f3l^)?j#PR|vOQ!oA1GY>*~HHgYSYv31q zpzGl;ebB->LB-$2Bug3ZPnPm?el!;zJq_+7e#|C$8J11EKC+Nxp+2%IG{#tZk)h=d z&$V5%N;)KzG2a2^xuWN0B;8X}#otRK&HAT#hT)W(SizNEYH5)JsjL`w-;wR0vZZZ; zr2i3-!SzQf>euP@__Z+d3|% ztr#Xp>#$zm&7@h9@2`*7LY$2J)zRyvbP^3;or__|GqZj?jQSbeHAiE_@2O&)cLk+^ zZ8|UQ*8|E@uCcI6A`M~0H;!%2w zHl!-%sjonbuna)>{y5IHQ^VxwDHK@F)eZH;!_rc z3JSqGo~$z$`^NJCW#vfo6xxwYzVrLm{1$tb_*0bIs=SS~;1K3Vy_kY&@c zveBbYcbzEVNtD*4{W2Qw5Vxi!_3(<9jZSNMO`wQ$ZLJSPhI@&3mfi9`0E~Z9aorwe z9W(n2eB(4Rd%w9Keip6Wl{2%;w-o;@_7(3Pa%muv&MeT4bU6?G$cU6=^0CD;Yf0c* zd=T;*CeyU|tSTSJr6t+7apR}kT43H=Ek#TeWMtNSV;vR9{L@c{WND~yHYKt(=5s-lkIH{|+kPcn3IWvJr{bw8(lm2j9wPmx`e^ z?}hg~cO_p@WRFd`87BO0B7V2cBhy=(x1b6Uex9O%C8H0J%?_0(04Xw?=1OD0D&x-cw4kDOBU*?j$H#wZEF`B7XAI>VTRpD|KA6 zSPQE^w&S=RmRg7hL?8d05d5e;w8mU-LjB28b4!K#4 quchNDMtX`X7Q8=~6W2NZ#Y_#c$(FD%JV(@B5tJ0vvO_~dot>S!y1IRReJd*~larGJ0|NyG1@ZCm15*RDv$HBHDossI zr>Ccb!!zye?FtGCSy@>J2M7KA{aq7X-@kuvX=#axiCI`!2nh*k{Misy75V4SpPrr` zO)V`oHMPRR!iCiZFE6hzU%uq$=X-tdTwY%8?(S}FZGByz7#0@hFMc+l&L!zKX2&u zyla1#oSa-XvOm4F>HB+|69UH6|7Mt!9{rK@Y( zhGm-rv+E(R=AXTpsvYfrnKM)VWz3;)O!P(n%a<=*{GR$3`xR8q2Q*G66^*2S9Z<07 zudlCf?%wSmT6^ z7bVScX>l&z9^blGY#tAr`wqj&1v#H`@`nz(21noh82W%7OwFu`eOXY~)}vRv{H13i zw}0qMUw{2roo2?*+>26O0AwlEloamzk8d1?@?VH{B5q5>>=m-iMhnRN`nsu{XwRa={#`l0 z$=u>~Kcmvnu!{(bmSyWnv#y;lrK>Iyy)xwZQVT!6i@IyMO@y=CH)}7B?!@ez%&@*E zd5Q>Z7j57#NczJV{GKpU03Fx7Y%LA_tsnUuAJ9)1T=Tcqy?NPv+7Ja9)*N~gjW&}@ z%+}zJsvd7xhLRJNspA*G0%r--ara=^u)cE=AwINJ-XDE5U2q2>{&h4N7UMk#*LZdO zjI6GiTv&UC?rp$#4-Y!^T;wK!BG zXNbzC^LAbOMb0j7gfa7?4O<+JR6Pq3Mb%;r$iAJB@C;83!c{hq#_Et&2gZub`b?L` zs(#@3O7?s_`Y&6>k@1M`1|*S?*D)`8Lplpk{|_q8?6=)b-$XU@f`Cqyhn~XHifMK) z8RR{2E;TvR<=dzy24=;YevD<}byIkSLVb*?@mg-HpE?yW`(4d)Iy>dPKOk*iw=EgN z7oIddJ$S^|%`JkXb4o&iYF+%_mU#e1+zra(K+#l9`EO4ST%88d6aTlxESH!6kPrax ziWadh^84WX=}Y8sgI-l84!Pm>>!9nIlt}+aI5ZicrpgqRzVnO%buzFpKlV-cEhTD1 z+Et{59)kB8769HoT>jK~(WNL6*=3KD=M?A-cLF0&f(%%GL)o8*;I&L+K@b0VYDbVY z&st@Icby2(99_mQ8^Gs>V`+;-uTcJG_2_c21NI-$9kj4t;r5(uKW+&jlqjf4W~JZd z#6gT{9J7AIcK95itSuh^Y4a?d&)|@vUMQb*@>f-$3Z51Heg>Kl7W05-S3%{SOK=?I z-Pj`bg<|3ZLddB3SnpgA9%)9Nq@iC{FN)j%+ZzqSCC~=g*22v)XM(&*vrbv7zC=Gt zxC(mg+Zc#3R}*3yW%wad%Pxm+^a|<78f2Z{L&`9~6GZv#GCW4`=+$*_@eOfIQhY3- zKzY37a?%|Nk@QaUTX(&qK<8Q9Oj{D9K)(Z%O2=c~7Ki4*@$>-!M*N#gSGcw&p;4ef zrU^ex4iY1HVgXyeJO@k&Nwkcn+~Jjg`VSY$(4?*mB27Njv(HKwMPhJ;M97~!k`4mr zzaLewEXaXJh?H(JL1b5(C<}x|jE|v_eMPL=rc|?uAzIA&R)Ky&*_(AyLm7Rsu85c7nx zHoF*M&F2qh-wK;p4UX)kwjv$fZQmM#7*s0Y`P3p^*4YUqV)f`rUwoadbq2`neGcTo z1;NVKia~=iCkL#yu`|D>UsZ1Pggk-OOCU!F zcvrdz;e6uBn@fac^KK{4Nzf|w7J|_G5r+c2vI?>=b_btR)oVbf5;JpVj`*q1bA&L7l5nNw^X-u7;wpl7MEcw-t2k}!ggi2G zIAvQfh-i-l!>knOons30S0sXgjU8d^hXO70ieR0Lz{)?6z-kJDNaD$%B54kIc9#?O z!N(E$ufXj?Pj0q9N_UB?AK}Q=KK+WkSZ+LybjYlVjSs*llflfBG04lvrK1n7br7=r zPvZX1Gqz(}K<4;&FAhEM5Qr+YV!#;7k?c&vP~2h**e3noSp4>uwJ4ub*_y?{+xAcC zq@+YHbunMgR2b|;C#L*O-Ni|7fa|6rZfE`v6sIv^tETVNF=)`XEL7pLw_g;x!trH! zf@NzN_W{&9jwMCqY-D8aR}?*xFsSrZ~zyw=+bt>~K! z`Sr(n;ci_KxE8s8{2rtwya!sw9Z*Wx5f#XHSt#11%Dagxlu}gj)W|Bi_5e+0D;pa2 zO&|2!Rsu6M3k#qKlXn?x%=Z*k&Co)ggK3Ck-e(VjLM>?#os^+lYZA9;QauAuL78iY_*$`dr368QQ(x9+oc+#)vE1&XvErX0M~XwxWP^^SVJ@ z*&B;Cy^<)o!$DxnI_I|h2RRWG(iV4GZGWec!Zq7zA4ffC8lST|62~I)%-=g}AG}w2 zRe=5xjAW23Ds4&$!UHocE|f29AyP<3ogN+WOz;~XhQK`)iI&p2^3e-=uR;xS!>?QU zBH~1f7WY+OSv|z_OJPCNOP$%s&fo~qfV{hqciIk849q~bbD-=gALXVn7VH&$w$Zrc zk&x9H&6cERItyxCv`j-jTnmwv$OBi!FNt|UqxiuT_^>4Pa+TYW)u`V(OMvJJ&6a&5 z%qj=Oz3c2jf_exUdEpm*8XOd#CiqO@9$N!8m?SvpK)X(>|5paT%FoAa=M7*SeMb&_ zfXQ9ED5^9zh+w^FU{CLP^o$rCa>wq53^*(*ltGtMA^#4>!wC^+htuDB`kx-+Wv3JK4FzibTovM+5tw>Ph+Z_HrS3S=L z(KXX|EmHen?hZL_Svm`v@9qpcGyLKQ4r)lb9oLGr(%Ah*`rSU@pF!mXjKjV#;3v|c z-v9m=q?{^bsye3~(s^B&%-H8yXg+89%!57o{^bU4Km_k)av-v}!MVe~mXIRsz(bQl z3wIeJKw(<}4hO(R0R#n%-~fc!B-kxMT?l~ZcX83D*dp71u1JgBRGK*`@T@DJ zLlYR`x{FP{JfQ=@nm`XSj+l8FGcYU;(4Hp<^lv=CaNQCZ&j8S}NDS7QfmKZ)WEF%2 zB*}uH$OFK$d${lcDG)Mi0A&pji0GpKe*>J{g;y0MR6!oF_2aNr+*A8x*^cduPr#zV zECezAbc`pn%40jVo89ez^ej&PG@{S;dcoeJdrlz_n+ty?VB=kZ%VZfS<0K2Sx+ zyy4jLH3}q!ro5dL3fxUj@y5q2*0Yy$R%IjmFSezB9ed=F_eEAEn=$;y`Qe{41!RYl zAdLc&fhyn&5(m2(h#(w)lTl#zhdzR=Rcs3>o7^Qhe;fSWMV^DShW~#%;UR@yA4z9J zn2zv=uSOgy0sk}$bMOZO%zj{R7%Kw~dhKbrpVLj?cPQo;Fbk!#_FefV_{eQf{W=Le z{qt%2yiA}N1MGAh8;0-cdn4x0#>7>SKe6LX{~BmqzyE?0ZcKg?X>?x+7d=f^Cl^9Y zh#7liH7cJdJz5&H<_Lc4le5L|?~I{=Sm|Q}ZW-9`$!8H-{P(=Tzdp`&z7?-u;3G)! zgAfcW_el?bmlMkjf*nQt!(m^%l?a5;C)as;cu{KYbrRBVjrT7$7Q!ru6k%n$83GSA ze~jWTcw*xZA}biTrE77Y^8tyQq;|wOLj7(M)A7fUjsfsw*7CS0$KMD8LWUstlynC# z{gjIuJ*o?S6|hNAp^(1?!S7=5a285Dy*76((^xIWC6vr_#G{Ys{1-III3ZjS^wPK_{)#lq`J)8g1?T{Lh%+ zHcqCq;i99%vPgoaHZjwyC4A}q z={*t?6*KO{i5(h4wO3zl5-~5gB676i)2g|j^ZTG7L|N!bWj)VJz(#?hV}xHencoD9 zR8m&~PnzfVTi_DHlS<;U1u;re6b?WiW%@n+l#7eG;XGKwM}_ZBg`#7H$>@H8z}PfA z_=Atc{4J1+@PrNtccUSCMPv=(=?;CPT>l7SM;JcL9&$o-{DL%ETi0bgWo6*jI{&<{ zj(i}+F~@=q!N3U9Kk?dq9Ikg&6b`alE(jYI7XZ{`LY!QrqG8~M51?KjHr9Lhn@0#GIJ)^BayEq<59w zk=g_tgZMkT$g;2IS^FxtkP<%hWwm|k=m0`;%vFq^0)%eW`(TGWwPdG8XJ+_WRlmVS z2Yv9QugMJ082boKk#hq6ZS9Uw@%IkXyDx|f&5>I?@xaP+t!dtiRgReemC71GkQIEX zU{5RI%X8AirATFZbPgW8^X3v9yy%0E%Ff%DL1zfyqXZ`RL0@yJr^NGEDoncCcS=B_ zCF?I!(&B)e!Abr4b}&G2r`!K#r|Mi`0eP0?+1&kB)w!eJGehjpGMVJ1yHw{yf_Vs_ z1&2@yl*+#@+Vj7j*=@l1kELyK_{YS?{&x-OnbmTfE^}lKFNt`3lkirr9ik%4Bv0Cn zGovc|y&>8Sl^5WFHcxvYdy9g>(_P2EA^k#7L%n4&ki)fr4vw@HkDJ;BFbx@igd|~) zj1nIYaQg?K01uJ=E21N;AR!du084l~@AEDJJt2UDo&>(8YyYL%^XC8oOhW=73IHWw zq4W_QmxQLYfnyycha)T}2W6e&9Wy=O-6aH5;%NHp*m!NQ((vT5eE1-Ze0c6}C~FsQ z4fw0+pNZgnWCu(h0Q}np0;2yygZ|@V9C(WvpyubP!Poy}2X^r?^U}zk7TgQdYU)3$N7kC8XoEr?UUx`P5 znrpxKW83P^cHwdM*WU)Whmfdw(!0pAjl3WT^^pxL<}5bYVU+~FD-T4cQL#qnd5(V7;HqcTP$@{&<_o}frTl5|ko0QwP z0X{)<8a3k>4p~Rt`aZtOSUI|P5d64DTVy3|ug3%&+nBZ=mdfs|0z zL^}-nTYKm!|67%x$gF&18R6BlZVfq2WL9H&!VMx2baUC|+8=iYWEYN5@*P?&{V!i6 zEnbshcIpF;RJ!*h1ue&M`~7kbI}C3CKk@Au>IVw@%0!?Cj^!>gU2+wc3J@lVQtY~DF^f7f(#j&s! zhJqA^KDxl!zTS?JY`pj5*pU}_JB3924ajt+mVllnVcr&bDT$zM(GV;ViFrX ziu_3cM($HGs;BB>CPSl9?%C&JrX>!)CM>}@zhy_kc8J*C$Yvv`Tf7W;Ru^^A>WsS2GU9tw4d8nP8ji!XOd45b!bjqkG~<=wvq9nw9?V03tf(Mk(z_yt%6OPS zB|NTu8t_=mP0BadOB3;3`6`gk-k<|?_?~pM`i1yti5w{tjV1-`a3BM-!JAC551B_p z)J>4PvSfLr2X(x9>k%oVeZ*^aS?3N8h7a?xhVmx0?h3{VZ;)hw;UI;J(dN6nW?mo?_6jbmAt-+U zBD@r?bRpBLNin`w+VpRQtB5}i{)3`Wh?--9g!4H8E9@%Ln*c_+IX9x0XYYWW!skW4 zl@FM^qY?h3Yigpa>-3sc&@behg_?#+D!;!nghp9@QbVB%QUL!22ab*cJ}$gn6Cwv$ z>4HY}j(noYCYNwiU&OmE?Q=R)BC^otiQ9PFyd zTtRMyPa%Gum_8l&LJzp|KxLN79%&*H#1#CY{#&uA^KS(AE`UZKf}o8%VUi%| z6KTTl-|#m@dv>%O&A`^N@Qw#~NJS3R*5(aJ!k?RrlDULKb)$f<1mO^f1Ijbt@k@#y zyaV@@&zWJFL1CbmzNE5}^hX%HSTR%qR^mjfK4%QZcrdTh;_H(>&U-|#V7>kCk&=2> zLkBm|Atp10&&wPn%A8Y$2Z^$Ho*$6ExTw7xES1^U@Ak~nsL{an+4i`=?jL;LN^FI^ zj`?!LQcP4I4keI6qIOd`xEjYQY-#YG@J8n}i&DByK1~tpx}CH>Jn)XxQPenYYNvOq zd7hmC7wg~?pdbpY|C$A`&Obuuuk#P_{&oJ_=)n}$8*irvgIM>wX`UEf#X9R4YyjXF z);r%hMp*sEy5s(VkkB8j^Dff>Qi8GGIyNw%(Fg&&ctMblb>^S`-@reMy)I^i4|?vq ztc|;}Uy!2f{wqeQDKrv3nCcqt|2!slP7FVqcX0!l1NC`vAt2-zSRA`(M2_ytY-%s* ziQA(sm?I_f66#wy2`h7HjAqb1syh&lxMlI3 zRr~H%?pV65nxoSyZ{=HTBsK2eSxC$CfMn$EOt!- z$xT1I>Hwe)G?%SQyk;^!;Be~)3C+{WF{LV~LA&g-w!RK6VW z+y0$LE-@?uqyd)Fr%f*PyBXL@Mn)WBVc{LSd>u(4 z-cuCU_-C0IF9wcF@zd=Lea#=|x*nAhyvs7_8a$5d0*p0l?F{7GWIboJdONlE*Kz%6 zIPe36+n(X3ytfxPYWtkaFkf>hjMBUQHlp$I>5_FBpdKn)43->;@iHAoytCcG99W;R zY}rEjAFaEr&6XpD20RT&8)diKEe~5>ZFMU!uxJRjXT~Y||HxntAK$GV+@C%wrNd|+ zZrR_AF<-p`8oh@QZ=J`=@h zhPTtyFyj2h4jeuCRMKR3t8UR0s7k0-^}5WHoRNukGq)TMDCunnC5LBL5nx8SIziQw zBt#0~kEC^o#A_|dyK$!VgsJgCARh?#;CUH*q;Kz|Mekb` zl3i1hvR|5^9Ai(tjmH9I=q>vF*eC|W%i8MRlv01F?p;UJRIhS&DDE(!YTLe?I&!6Y z;)Wv|SxouUL5om&X5dUIGGx-BLNz_3Ou_)@3x2r|Dgzr4iToehrjqSxP}`1;q>0|- zrZ;lBG<3eEElhprn0(fA_mPiPFuudbn105D$s18|KiUPWmdac;F^hB(b*)Z~;x9-T z%KNAOcmR)XvV&xf)W15Lt#W1d$6eC;gC}AX!1MBPaK$&Xc2~cf@VWP8xJm@~Z8WNd zd&;ny1pZF5vh4OM$VQtUpRNIe^O%(PgZTHw2Mybgjx^Je0bRB0rqkTihE*i6tVgvk z)ws%|^xakb7#5OjdoCwGoHMayIkGI*54`Xpd;Rj`A&W)%)jwt2e;!B_FIkP^s{c-# zHub>MxnMFVUrEYCH4aT%Kv{q8ulp<747NS%9M%K(@5Hi&WMo=quJp)Onb!Ni8r1&6 z^?#;|(Wgl0?{eq37*WyrA3lQl&-b(*iPHjj*1XX?w}!ngcBK?njcgMhM${~11By@A z9yZ0_aKZ1^pHqz|O1a;~Udo+NI~3|i)X|e3BH9IW{)!hQ>L}i@95-nq$qr$el_#O* zUva<@2}LGcdTzzDgJ`DILPyF<+pF;swMekV-#P5}6wm&tbbC(yeazAIwmdE_(w4g< zt(Q$naFZz_>6RN{OR-Jgp4^xT!bibfkNQr)#cbUkJL=m@BxToiPMh#y4x7vdaNme1 zYl9V6hyTZwtkDA2s10=}u^vfzrxKTPo#WotSC83*kG2y5AIMuc4v&ONC5&H1MXFw1 zMv3vkHmr7c;>J8V;yv{vnl7IT{gjMu6U=9)R7gY?_U?7c+&dv*F`vV9K) z>73KAlhaGgHkV;Q@3jzF#o@n%zX@4e;q~`Dz{^r}XNFoGd(*x0Kw$n2KJ0Ppv0cUB zs$D08T?T@8Sb^kn{xuaK?C=A>#j58fcvCO!sK)(#UV^Og`l81X#*JIm&0It++wRjI=DA~Kwm|2WsPQ{oYXuY4S5fue z#5n;|Pp6gIgYK<&i@4=(HBG>0@qDTCp%W)rd1C@IIV!_I8t z80+Ee!!~07;FC)Qh|$GQnl4_uFO42jD00JGo)j(PJnI_QMe%Ixie~*=r8gr2CKia~ zl*Xcl;aK0=pw3rS*PhpEO^-=WEgvvM+O+5in^Z~L{UQOG8?(vZk!$-R$UKy@~;eXAAB9D|2lE={%V3!)A7too-m7mw>HXh24nNkd34W8_j+TpOuFQ68ORcXyY`N|52>V#= z?-bd&7bQYYiHYU0!n6_ye3vqtaf+A%Hg9)tU#(_vAnP|=b@ZWYHdZSO))onU zLRvvC4)=rZ6mAbOj)>bp8N;FS0rZOKBKkS@J-toBh&Y^u-08JWWM{mncd5Axl0(K# z_8u_XJjc<&A+ym)(Mu(vEbiH5|)yPqocu0 zAk0UYl_ExAqeq1jcH{W=jvKZaM@6Zrf!4|=6tA$W$_dGNUasFRirpy)V6oH4s?h4E z6h$~4Z_w&+9pV2}CQ(-UksB8Y*0RWJ|NgGAltmIX{4{z(*%PAu$t(GDlcV)&$?F`2 zpSmusdY@IEi817esWB@zkv_l2Odon1C*ZvjZeb2C`J95s+zjT;(NIdK#+>)1(ys@J1qmmUDZ&|1)4s{RhX08%1{mM?O z%yL?xAq|P#y8p}B-2zYN_p%OUW-~Wh`3;u{CzaILV^vkHiso*`&y#N}@E6Yrgz#!M zUKQX?K07*^95_zEhGt*8=%$L++~uLB!{49p|13^HT-c2(w7)*Q&Ojz;nKHx`{_L*p z{tZ~K2Sr$#CbeC6ofa)(bxT-z*M&kt%|mWU4jyC@>kh4_^`WMxsmhsOEY{|&YH4Ax znnSYnk<|=px7R85N|0C3aW(y6FA2YcyCaj*@b07BAji&&=`%JPK7CLimar*hHcwpZ zA&Ykcu9rCerB|#-XtbJITup4%y}W-J{oIIG5QlELKq;`Hf)?MCkyF~*CGks$kmD<< z4aD)z-eMPCiuSL!D3+?{uEQ{T_3VtFm4TNYyVNB(&IyqraqpJ{z#^`C+bc!8h=+Zt4XS>FSLJMXG67rd-&OVk_K&+c@y3W_xSjc7k1=e*6lq=J$n2n zywCHukGUs_*>!C^osW;o)Ro2)5AB2Z0+^ZCw=)gK@8u=|U$Gm6iCH%vXlfzfvzzz^ z7_?+hiI8P7lRA%3u2H4vsxGn1`~2GZ?$lwTddTUqvx@9P;ge&!YW*^UXDAs~I_V;# z&tnL4QWP>T@WP-vujEH_SVur3Ijs(jJkG8?#f-dhe!zR55L4~W6H8U;e%&@T^X|}f zT~P3|n>Qw74fX;a+h;B=3-v@k-?bGucyt zH!cANENH_)X6tL3vu9e!nh5?3Gu1W2SDkj8@AJaaAp1*W!EiUvf{-y&C(c=Z@xj?Z z)3kvMiU0eU_!vbW?3^w0UtMLa<0Y~}x5#)>p~Wj7Oe!4GJzXcl#=$y%sf=DNdC=!N zP3jP89twK7sI70bu%M-hmPK*Le3RVI%$TZ>jvE^qa?8-R8A=ngv2U_1QhHd}+nJ;$jpY|N-ef4d_YIk?ZoWt$gi z+%<-`#PMKMR~hW9ALm&%BsU%_k+#MyZF}BlFtV`FfD*}&d~n=R9a+{eD~E!l z{H5Nk>r7~ThIY%YJn*vBn~9g^;#_pJNrSo=^g@Oee4eCT5F;}wW@{0UmA}SBl+i}j zw6#0P&-seN)^$stzuHrObT9;sQ({3#UEBmQPX@GUuJh&(;LEUY?u^A5M1u-96@fED z^94D+19uy0T1eDyV|-%+7xR6^v{MVU zZR#QrM?qfX3n{uGYH%iHq>`7*r-g7GwJfYfVQpCTEJueHrK`D@`wBU#qP=`w3F-fx z;3tgw4!z6lRK5bqbXQ%n8LE4Kg!p+y(WLf_Fqr;b>qO1vXNm%|wTl>NsJRB8OVzH)N zRxoYFo%tgbJW)&c0>ria`D(@odo!#6XIa)cgE8FxHxWR~!Z|I&8#t632nAITV>ET8 z3_#1x{3I|fb+eCP;HZ5${})M_-vBh(+}q+Et-5I+2pS9BpWGLNNJKLlSZ@o% z+K+z9bwKYtp6JgY2EP*=LWvRt7*R1*NurJG`I16%N{AIr5)M|p@8ElY1-{OD5=Eau zb7auIr#KVZaNgAz_<&Zi%a7F3@rXy>Ose7U5WN|s&&QM7V2)zN;ZvF*G(F(R0|WNf z?NFVM9Wn=DlVrgh`U4m;=+==L0KRlTt;^omUxN~x^>a~D`%PQRLgtU)d*l--xN_MC zeBL4;WK!Ogx%>mr871wHR1i{U%f3Z;T`cS-KDm}xd(|YWab)zQ4@@bJ(xf!RNOrf| z)X+=a}-Tc+VZ=btQN%GH{yKr*owwRrbFyzgku%E zk=rIm`RMhAY1eC1Hu?-da>z+KC3*A-)Ji-)UBT%9Z_F*Vvd~w%r3c%7vR?<45um zW-xRLot)Cj$3yHvjSFc_zx~8n>5rph?xV_dYrtmF5 z5VyazF-x8Yrj8_&#?LFSXdUCesD@;&vEwamPr11Ty&8Wz0{y%}<684zds!h1G)U_E zshw9};JJ$O6eZA5y)jzOvsGTveWOJAY<;5kF@qz;!og;97_M$c?qzMuOT*N{rTMeZ zrb6FuvG}r48MR*dJ)iQFgT6sV(~QDEMd1u|I($0G`2Ef>tZjj%3R1^LC9> z4Fn^#gQUnW6J^90(KfoKI9e2i5183&dKLMpk&KOcamb4;kht8`zAt+dy%a;nEi*C zj-w;u#DB0KQU2O3Y!LX;Fv?B%ZG4qE=bUtE&otw`fnzOE>449&@na1!f4zpLm$X-W zax-1F6#4#s)B@uDxi&}OZZgx*>*NHn>%7R6uS+$Y30*QFH^a-S9}m(xKz9S!<#Fbg zPXf+G^BQSB-x;P*xy*8V`L8yd?X!BnXtBS3L)CV zhqbZ=Px2-6knayf>$9B9-x($4UslH29Le8yP8ZF`!nVI1qE-hhZgg=wrinD9;q&5w`U%iU=O#zyOiFj)@|2)(M;yD7w zzA1;6S8zQqUCr7kLN&rQd@!>f;{Fv}ri*iB=+`1K0&9swXmR>~9g*PbC@p9rQX>4# z)dUQHvYj-A*6ftTB@g$bHUG;_0ku$lmhJ`IyMs7?q~_oP|id-Yc83B z--=|*sN9iz{pm-K>+zD7bOSz(xc9zTpNOOwQH@c!rV!576GX}|h>Zns%`xk4rsvmc zO!y$I+CJAr*|p)n3Q8gC9Akah$i(YXtkM~^r1vjs%7+z9NpJByLnjMT7Nq=HOGtHx z^S^-pf>qvs@D%sqPg#o!;(L+|b~w&4rxpHk0*u)Up-TiPl!zWs{wCgR-FC~Ds+mRQ z2V+k=Z*+-uZ}c;Fov>m>>T0t5E~TV1vwCeO8|(-JFR?i5mpo77ok0|sztjhuJ(*na z0hhNCui979mKBNI)PG3MzMPCTUK#F!iUtEOtW~(@xnM$g^waFy-52-%!7}Nr%6k3& zB6z#^%#IaJs2TOr>ig$#1TR;}SnX5Vf+s>`m{)%oZg=%&SK}z$c6ybRz?qOx8A*e4 z=S@uFSO2om>BJ(VrZ@B+w=B{46oG{C4M}QiJo?nMt>Y`_A^n@x8S$NO&o%r~7AA2n zvUitTZj{XspzpGb4MWE@yd{qYF&4sOth!~`n>0`N(2KC^MAnypYR=AFL^+~PipC8w zVe*<<3yHm4OYiCvS6DjBGW&#mWmx$$my6os148G`;1 z;r7X97<{6iVVUiZHrn+$%;j<>N*2MmeC9?vFUP> zB31gK)r7J7cj6bo)enIDiYQJm@~mJD(LkY0%18*BHaK2wx3GPmBr97x-Ug0p1aq5SR+Ci)gn& zpsG0mgc-gC5NN>xIy~uo>A05loDXA@gxDL)V`aS9G2tNg7l!njJxf~051|^GL5Djy z9O#QuB2;U7<$R8L#g)!r0TO8@IIS&&9YK*rJ!#$cpviND_qRH*i1-kaVKkurN7jQB z&F}F^qOh}`{q*bIfakhvl&xw*MV`45<@ayKcVAG1u;taq;c+Yzpx}_Hn~Z7~>oHnro4T`F%K(ZBJLQ|%qKq*EAH zVbo)Kf*eFFjM5)=4CgnqG>5U2NqdlV(t-ErF{1_Fg^=))yVTvs8egqk zXD|CaT+BIE&QN{Xm6MQ)6_*5Kh{tIIYstN6d$4x5{2rp8v(p$QMf{7(Vc<%%%uPT_ zgfBbJ*Yn!Ki_nMd?{rP4jy=?ps7zD711tvgFVR=xVB#cf@A>E!4CdLn+ytqLN-bH% zV_A~62QtPG0&Qv4zMIDy;C`pcm_ne22@ZO&t{D@P+nndMo7;Ew(i}hIZ*}s5jHJuz z4}%D`E+rL4{#`Q9W+pY=%NK?I&EkZ%5Bsl6^wX2ENZKU@IWR*p-# z`f|}bo>zzH(q&WpqBd5p3(}s~Z=cX!mq|0~Ik=oMxh!BUt4#^JM5gXuu);JVV1<{D zITJ_CpmRR7%Ol{Cu;P@6<)VQ~%vY0oCB4eKiUqURA64^H!l3%wG_y;Dmb9-N^_+Pq zE(f|eJ1>#=vUINhSSmr~=3*Fxc6;IYRKQ`Gwms((4|VcCw=LK(+W$lfbRs7s{M#Sr hPsk=Q^?yLdfUBQ=oH?v~Pybt?rmUq@a?2|8{{Y`rJ4pZl literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_example.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_example.png new file mode 100644 index 0000000000000000000000000000000000000000..7244328c084623ff7aff4c1b88c864e0616eafd7 GIT binary patch literal 14388 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 P{L@rXQdcaNM+f{L({k!N literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_initial_state.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_initial_state.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a41765b0f167b8cd7c851dcde770a339b72e0c GIT binary patch literal 21522 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�?W;JT1qrY!ewMhowk;_R+_8*`E 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_state_transition.png b/en/chapter_dynamic_programming/dp_solution_pipeline.assets/min_path_sum_solution_state_transition.png new file mode 100644 index 0000000000000000000000000000000000000000..2b01417e29f39880702d4a4ac21f79cb938f9666 GIT binary patch literal 18925 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

    GrA$r|DoMSj_1isRH0QOZa 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/dp_solution_pipeline/index.html b/en/chapter_dynamic_programming/dp_solution_pipeline/index.html new file mode 100644 index 000000000..0e9358726 --- /dev/null +++ b/en/chapter_dynamic_programming/dp_solution_pipeline/index.html @@ -0,0 +1,5345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 14.3 DP problem-solving approach¶ - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    14.3   Dynamic programming problem-solving approach

    +

    The last two sections introduced the main characteristics of dynamic programming problems. Next, let's explore two more practical issues together.

    +
      +
    1. How to determine whether a problem is a dynamic programming problem?
    2. +
    3. What are the complete steps to solve a dynamic programming problem?
    4. +
    +

    14.3.1   Problem determination

    +

    Generally speaking, if a problem contains overlapping subproblems, optimal substructure, and exhibits no aftereffects, it is usually suitable for dynamic programming solutions. However, it is often difficult to directly extract these characteristics from the problem description. Therefore, we usually relax the conditions and first observe whether the problem is suitable for resolution using backtracking (exhaustive search).

    +

    Problems suitable for backtracking usually fit the "decision tree model", which can be described using a tree structure, where each node represents a decision, and each path represents a sequence of decisions.

    +

    In other words, if the problem contains explicit decision concepts, and the solution is produced through a series of decisions, then it fits the decision tree model and can usually be solved using backtracking.

    +

    On this basis, there are some "bonus points" for determining dynamic programming problems.

    +
      +
    • The problem contains descriptions of maximization (minimization) or finding the most (least) optimal solution.
    • +
    • The problem's states can be represented using a list, multi-dimensional matrix, or tree, and a state has a recursive relationship with its surrounding states.
    • +
    +

    Correspondingly, there are also some "penalty points".

    +
      +
    • The goal of the problem is to find all possible solutions, not just the optimal solution.
    • +
    • The problem description has obvious characteristics of permutations and combinations, requiring the return of specific multiple solutions.
    • +
    +

    If a problem fits the decision tree model and has relatively obvious "bonus points", we can assume it is a dynamic programming problem and verify it during the solution process.

    +

    14.3.2   Problem-solving steps

    +

    The dynamic programming problem-solving process varies with the nature and difficulty of the problem but generally follows these steps: describe decisions, define states, establish a \(dp\) table, derive state transition equations, and determine boundary conditions, etc.

    +

    To illustrate the problem-solving steps more vividly, we use a classic problem, "Minimum Path Sum", as an example.

    +
    +

    Question

    +

    Given an \(n \times m\) two-dimensional grid grid, each cell in the grid contains a non-negative integer representing the cost of that cell. The robot starts from the top-left cell and can only move down or right at each step until it reaches the bottom-right cell. Return the minimum path sum from the top-left to the bottom-right.

    +
    +

    The following figure shows an example, where the given grid's minimum path sum is \(13\).

    +

    Minimum Path Sum Example Data

    +

    Figure 14-10   Minimum Path Sum Example Data

    + +

    First step: Think about each round of decisions, define the state, and thereby obtain the \(dp\) table

    +

    Each round of decisions in this problem is to move one step down or right from the current cell. Suppose the row and column indices of the current cell are \([i, j]\), then after moving down or right, the indices become \([i+1, j]\) or \([i, j+1]\). Therefore, the state should include two variables: the row index and the column index, denoted as \([i, j]\).

    +

    The state \([i, j]\) corresponds to the subproblem: the minimum path sum from the starting point \([0, 0]\) to \([i, j]\), denoted as \(dp[i, j]\).

    +

    Thus, we obtain the two-dimensional \(dp\) matrix shown below, whose size is the same as the input grid \(grid\).

    +

    State definition and DP table

    +

    Figure 14-11   State definition and DP table

    + +
    +

    Note

    +

    Dynamic programming and backtracking can be described as a sequence of decisions, while a state consists of all decision variables. It should include all variables that describe the progress of solving the problem, containing enough information to derive the next state.

    +

    Each state corresponds to a subproblem, and we define a \(dp\) table to store the solutions to all subproblems. Each independent variable of the state is a dimension of the \(dp\) table. Essentially, the \(dp\) table is a mapping between states and solutions to subproblems.

    +
    +

    Second step: Identify the optimal substructure, then derive the state transition equation

    +

    For the state \([i, j]\), it can only be derived from the cell above \([i-1, j]\) or the cell to the left \([i, j-1]\). Therefore, the optimal substructure is: the minimum path sum to reach \([i, j]\) is determined by the smaller of the minimum path sums of \([i, j-1]\) and \([i-1, j]\).

    +

    Based on the above analysis, the state transition equation shown in the following figure can be derived:

    +
    \[ +dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j] +\]
    +

    Optimal substructure and state transition equation

    +

    Figure 14-12   Optimal substructure and state transition equation

    + +
    +

    Note

    +

    Based on the defined \(dp\) table, think about the relationship between the original problem and the subproblems, and find out how to construct the optimal solution to the original problem from the optimal solutions to the subproblems, i.e., the optimal substructure.

    +

    Once we have identified the optimal substructure, we can use it to build the state transition equation.

    +
    +

    Third step: Determine boundary conditions and state transition order

    +

    In this problem, the states in the first row can only come from the states to their left, and the states in the first column can only come from the states above them, so the first row \(i = 0\) and the first column \(j = 0\) are the boundary conditions.

    +

    As shown in the Figure 14-13 , since each cell is derived from the cell to its left and the cell above it, we use loops to traverse the matrix, the outer loop iterating over the rows and the inner loop iterating over the columns.

    +

    Boundary conditions and state transition order

    +

    Figure 14-13   Boundary conditions and state transition order

    + +
    +

    Note

    +

    Boundary conditions are used in dynamic programming to initialize the \(dp\) table, and in search to prune.

    +

    The core of the state transition order is to ensure that when calculating the solution to the current problem, all the smaller subproblems it depends on have already been correctly calculated.

    +
    +

    Based on the above analysis, we can directly write the dynamic programming code. However, the decomposition of subproblems is a top-down approach, so implementing it in the order of "brute-force search → memoized search → dynamic programming" is more in line with habitual thinking.

    + +

    Start searching from the state \([i, j]\), constantly decomposing it into smaller states \([i-1, j]\) and \([i, j-1]\). The recursive function includes the following elements.

    +
      +
    • Recursive parameter: state \([i, j]\).
    • +
    • Return value: the minimum path sum from \([0, 0]\) to \([i, j]\) \(dp[i, j]\).
    • +
    • Termination condition: when \(i = 0\) and \(j = 0\), return the cost \(grid[0, 0]\).
    • +
    • Pruning: when \(i < 0\) or \(j < 0\) index out of bounds, return the cost \(+\infty\), representing infeasibility.
    • +
    +

    Implementation code as follows:

    +
    +
    +
    +
    min_path_sum.py
    def min_path_sum_dfs(grid: list[list[int]], i: int, j: int) -> int:
    +    """最小路径和:暴力搜索"""
    +    # 若为左上角单元格,则终止搜索
    +    if i == 0 and j == 0:
    +        return grid[0][0]
    +    # 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 or j < 0:
    +        return inf
    +    # 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    up = min_path_sum_dfs(grid, i - 1, j)
    +    left = min_path_sum_dfs(grid, i, j - 1)
    +    # 返回从左上角到 (i, j) 的最小路径代价
    +    return min(left, up) + grid[i][j]
    +
    +
    +
    +
    min_path_sum.cpp
    /* 最小路径和:暴力搜索 */
    +int minPathSumDFS(vector<vector<int>> &grid, int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return INT_MAX;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    int up = minPathSumDFS(grid, i - 1, j);
    +    int left = minPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;
    +}
    +
    +
    +
    +
    min_path_sum.java
    /* 最小路径和:暴力搜索 */
    +int minPathSumDFS(int[][] grid, int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Integer.MAX_VALUE;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    int up = minPathSumDFS(grid, i - 1, j);
    +    int left = minPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return Math.min(left, up) + grid[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.cs
    /* 最小路径和:暴力搜索 */
    +int MinPathSumDFS(int[][] grid, int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return int.MaxValue;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    int up = MinPathSumDFS(grid, i - 1, j);
    +    int left = MinPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return Math.Min(left, up) + grid[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.go
    /* 最小路径和:暴力搜索 */
    +func minPathSumDFS(grid [][]int, i, j int) int {
    +    // 若为左上角单元格,则终止搜索
    +    if i == 0 && j == 0 {
    +        return grid[0][0]
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 || j < 0 {
    +        return math.MaxInt
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    up := minPathSumDFS(grid, i-1, j)
    +    left := minPathSumDFS(grid, i, j-1)
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return int(math.Min(float64(left), float64(up))) + grid[i][j]
    +}
    +
    +
    +
    +
    min_path_sum.swift
    /* 最小路径和:暴力搜索 */
    +func minPathSumDFS(grid: [[Int]], i: Int, j: Int) -> Int {
    +    // 若为左上角单元格,则终止搜索
    +    if i == 0, j == 0 {
    +        return grid[0][0]
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 || j < 0 {
    +        return .max
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    let up = minPathSumDFS(grid: grid, i: i - 1, j: j)
    +    let left = minPathSumDFS(grid: grid, i: i, j: j - 1)
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return min(left, up) + grid[i][j]
    +}
    +
    +
    +
    +
    min_path_sum.js
    /* 最小路径和:暴力搜索 */
    +function minPathSumDFS(grid, i, j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i === 0 && j === 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Infinity;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    const up = minPathSumDFS(grid, i - 1, j);
    +    const left = minPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return Math.min(left, up) + grid[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.ts
    /* 最小路径和:暴力搜索 */
    +function minPathSumDFS(
    +    grid: Array<Array<number>>,
    +    i: number,
    +    j: number
    +): number {
    +    // 若为左上角单元格,则终止搜索
    +    if (i === 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Infinity;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    const up = minPathSumDFS(grid, i - 1, j);
    +    const left = minPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return Math.min(left, up) + grid[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.dart
    /* 最小路径和:暴力搜索 */
    +int minPathSumDFS(List<List<int>> grid, int i, int j) {
    +  // 若为左上角单元格,则终止搜索
    +  if (i == 0 && j == 0) {
    +    return grid[0][0];
    +  }
    +  // 若行列索引越界,则返回 +∞ 代价
    +  if (i < 0 || j < 0) {
    +    // 在 Dart 中,int 类型是固定范围的整数,不存在表示“无穷大”的值
    +    return BigInt.from(2).pow(31).toInt();
    +  }
    +  // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +  int up = minPathSumDFS(grid, i - 1, j);
    +  int left = minPathSumDFS(grid, i, j - 1);
    +  // 返回从左上角到 (i, j) 的最小路径代价
    +  return min(left, up) + grid[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.rs
    /* 最小路径和:暴力搜索 */
    +fn min_path_sum_dfs(grid: &Vec<Vec<i32>>, i: i32, j: i32) -> i32 {
    +    // 若为左上角单元格,则终止搜索
    +    if i == 0 && j == 0 {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 || j < 0 {
    +        return i32::MAX;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    let up = min_path_sum_dfs(grid, i - 1, j);
    +    let left = min_path_sum_dfs(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    std::cmp::min(left, up) + grid[i as usize][j as usize]
    +}
    +
    +
    +
    +
    min_path_sum.c
    /* 最小路径和:暴力搜索 */
    +int minPathSumDFS(int grid[MAX_SIZE][MAX_SIZE], int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return INT_MAX;
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    int up = minPathSumDFS(grid, i - 1, j);
    +    int left = minPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;
    +}
    +
    +
    +
    +
    min_path_sum.kt
    /* 最小路径和:暴力搜索 */
    +fun minPathSumDFS(grid: Array<IntArray>, i: Int, j: Int): Int {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0]
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Int.MAX_VALUE
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    val up = minPathSumDFS(grid, i - 1, j)
    +    val left = minPathSumDFS(grid, i, j - 1)
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return min(left, up) + grid[i][j]
    +}
    +
    +
    +
    +
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs}
    +
    +
    +
    +
    min_path_sum.zig
    // 最小路径和:暴力搜索
    +fn minPathSumDFS(grid: anytype, i: i32, j: i32) i32 {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 and j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 or j < 0) {
    +        return std.math.maxInt(i32);
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    var up = minPathSumDFS(grid, i - 1, j);
    +    var left = minPathSumDFS(grid, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    return @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    The following figure shows the recursive tree rooted at \(dp[2, 1]\), which includes some overlapping subproblems, the number of which increases sharply as the size of the grid grid increases.

    +

    Essentially, the reason for overlapping subproblems is: there are multiple paths to reach a certain cell from the top-left corner.

    +

    Brute-force search recursive tree

    +

    Figure 14-14   Brute-force search recursive tree

    + +

    Each state has two choices, down and right, so the total number of steps from the top-left corner to the bottom-right corner is \(m + n - 2\), so the worst-case time complexity is \(O(2^{m + n})\). Please note that this calculation method does not consider the situation near the grid edge, where there is only one choice left when reaching the network edge, so the actual number of paths will be less.

    + +

    We introduce a memo list mem of the same size as the grid grid, used to record the solutions to various subproblems, and prune overlapping subproblems:

    +
    +
    +
    +
    min_path_sum.py
    def min_path_sum_dfs_mem(
    +    grid: list[list[int]], mem: list[list[int]], i: int, j: int
    +) -> int:
    +    """最小路径和:记忆化搜索"""
    +    # 若为左上角单元格,则终止搜索
    +    if i == 0 and j == 0:
    +        return grid[0][0]
    +    # 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 or j < 0:
    +        return inf
    +    # 若已有记录,则直接返回
    +    if mem[i][j] != -1:
    +        return mem[i][j]
    +    # 左边和上边单元格的最小路径代价
    +    up = min_path_sum_dfs_mem(grid, mem, i - 1, j)
    +    left = min_path_sum_dfs_mem(grid, mem, i, j - 1)
    +    # 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = min(left, up) + grid[i][j]
    +    return mem[i][j]
    +
    +
    +
    +
    min_path_sum.cpp
    /* 最小路径和:记忆化搜索 */
    +int minPathSumDFSMem(vector<vector<int>> &grid, vector<vector<int>> &mem, int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return INT_MAX;
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] != -1) {
    +        return mem[i][j];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    int up = minPathSumDFSMem(grid, mem, i - 1, j);
    +    int left = minPathSumDFSMem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;
    +    return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.java
    /* 最小路径和:记忆化搜索 */
    +int minPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Integer.MAX_VALUE;
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] != -1) {
    +        return mem[i][j];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    int up = minPathSumDFSMem(grid, mem, i - 1, j);
    +    int left = minPathSumDFSMem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = Math.min(left, up) + grid[i][j];
    +    return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.cs
    /* 最小路径和:记忆化搜索 */
    +int MinPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return int.MaxValue;
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] != -1) {
    +        return mem[i][j];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    int up = MinPathSumDFSMem(grid, mem, i - 1, j);
    +    int left = MinPathSumDFSMem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = Math.Min(left, up) + grid[i][j];
    +    return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.go
    /* 最小路径和:记忆化搜索 */
    +func minPathSumDFSMem(grid, mem [][]int, i, j int) int {
    +    // 若为左上角单元格,则终止搜索
    +    if i == 0 && j == 0 {
    +        return grid[0][0]
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 || j < 0 {
    +        return math.MaxInt
    +    }
    +    // 若已有记录,则直接返回
    +    if mem[i][j] != -1 {
    +        return mem[i][j]
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    up := minPathSumDFSMem(grid, mem, i-1, j)
    +    left := minPathSumDFSMem(grid, mem, i, j-1)
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = int(math.Min(float64(left), float64(up))) + grid[i][j]
    +    return mem[i][j]
    +}
    +
    +
    +
    +
    min_path_sum.swift
    /* 最小路径和:记忆化搜索 */
    +func minPathSumDFSMem(grid: [[Int]], mem: inout [[Int]], i: Int, j: Int) -> Int {
    +    // 若为左上角单元格,则终止搜索
    +    if i == 0, j == 0 {
    +        return grid[0][0]
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 || j < 0 {
    +        return .max
    +    }
    +    // 若已有记录,则直接返回
    +    if mem[i][j] != -1 {
    +        return mem[i][j]
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    let up = minPathSumDFSMem(grid: grid, mem: &mem, i: i - 1, j: j)
    +    let left = minPathSumDFSMem(grid: grid, mem: &mem, i: i, j: j - 1)
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = min(left, up) + grid[i][j]
    +    return mem[i][j]
    +}
    +
    +
    +
    +
    min_path_sum.js
    /* 最小路径和:记忆化搜索 */
    +function minPathSumDFSMem(grid, mem, i, j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i === 0 && j === 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Infinity;
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] !== -1) {
    +        return mem[i][j];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    const up = minPathSumDFSMem(grid, mem, i - 1, j);
    +    const left = minPathSumDFSMem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = Math.min(left, up) + grid[i][j];
    +    return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.ts
    /* 最小路径和:记忆化搜索 */
    +function minPathSumDFSMem(
    +    grid: Array<Array<number>>,
    +    mem: Array<Array<number>>,
    +    i: number,
    +    j: number
    +): number {
    +    // 若为左上角单元格,则终止搜索
    +    if (i === 0 && j === 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Infinity;
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] != -1) {
    +        return mem[i][j];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    const up = minPathSumDFSMem(grid, mem, i - 1, j);
    +    const left = minPathSumDFSMem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = Math.min(left, up) + grid[i][j];
    +    return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.dart
    /* 最小路径和:记忆化搜索 */
    +int minPathSumDFSMem(List<List<int>> grid, List<List<int>> mem, int i, int j) {
    +  // 若为左上角单元格,则终止搜索
    +  if (i == 0 && j == 0) {
    +    return grid[0][0];
    +  }
    +  // 若行列索引越界,则返回 +∞ 代价
    +  if (i < 0 || j < 0) {
    +    // 在 Dart 中,int 类型是固定范围的整数,不存在表示“无穷大”的值
    +    return BigInt.from(2).pow(31).toInt();
    +  }
    +  // 若已有记录,则直接返回
    +  if (mem[i][j] != -1) {
    +    return mem[i][j];
    +  }
    +  // 左边和上边单元格的最小路径代价
    +  int up = minPathSumDFSMem(grid, mem, i - 1, j);
    +  int left = minPathSumDFSMem(grid, mem, i, j - 1);
    +  // 记录并返回左上角到 (i, j) 的最小路径代价
    +  mem[i][j] = min(left, up) + grid[i][j];
    +  return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.rs
    /* 最小路径和:记忆化搜索 */
    +fn min_path_sum_dfs_mem(grid: &Vec<Vec<i32>>, mem: &mut Vec<Vec<i32>>, i: i32, j: i32) -> i32 {
    +    // 若为左上角单元格,则终止搜索
    +    if i == 0 && j == 0 {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if i < 0 || j < 0 {
    +        return i32::MAX;
    +    }
    +    // 若已有记录,则直接返回
    +    if mem[i as usize][j as usize] != -1 {
    +        return mem[i as usize][j as usize];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    let up = min_path_sum_dfs_mem(grid, mem, i - 1, j);
    +    let left = min_path_sum_dfs_mem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i as usize][j as usize] = std::cmp::min(left, up) + grid[i as usize][j as usize];
    +    mem[i as usize][j as usize]
    +}
    +
    +
    +
    +
    min_path_sum.c
    /* 最小路径和:记忆化搜索 */
    +int minPathSumDFSMem(int grid[MAX_SIZE][MAX_SIZE], int mem[MAX_SIZE][MAX_SIZE], int i, int j) {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return INT_MAX;
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] != -1) {
    +        return mem[i][j];
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    int up = minPathSumDFSMem(grid, mem, i - 1, j);
    +    int left = minPathSumDFSMem(grid, mem, i, j - 1);
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;
    +    return mem[i][j];
    +}
    +
    +
    +
    +
    min_path_sum.kt
    /* 最小路径和:记忆化搜索 */
    +fun minPathSumDFSMem(
    +    grid: Array<IntArray>,
    +    mem: Array<IntArray>,
    +    i: Int,
    +    j: Int
    +): Int {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 && j == 0) {
    +        return grid[0][0]
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 || j < 0) {
    +        return Int.MAX_VALUE
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[i][j] != -1) {
    +        return mem[i][j]
    +    }
    +    // 左边和上边单元格的最小路径代价
    +    val up = minPathSumDFSMem(grid, mem, i - 1, j)
    +    val left = minPathSumDFSMem(grid, mem, i, j - 1)
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[i][j] = min(left, up) + grid[i][j]
    +    return mem[i][j]
    +}
    +
    +
    +
    +
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs_mem}
    +
    +
    +
    +
    min_path_sum.zig
    // 最小路径和:记忆化搜索
    +fn minPathSumDFSMem(grid: anytype, mem: anytype, i: i32, j: i32) i32 {
    +    // 若为左上角单元格,则终止搜索
    +    if (i == 0 and j == 0) {
    +        return grid[0][0];
    +    }
    +    // 若行列索引越界,则返回 +∞ 代价
    +    if (i < 0 or j < 0) {
    +        return std.math.maxInt(i32);
    +    }
    +    // 若已有记录,则直接返回
    +    if (mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] != -1) {
    +        return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];
    +    }
    +    // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价
    +    var up = minPathSumDFSMem(grid, mem, i - 1, j);
    +    var left = minPathSumDFSMem(grid, mem, i, j - 1);
    +    // 返回从左上角到 (i, j) 的最小路径代价
    +    // 记录并返回左上角到 (i, j) 的最小路径代价
    +    mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] = @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];
    +    return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    As shown in the Figure 14-15 , after introducing memoization, all subproblem solutions only need to be calculated once, so the time complexity depends on the total number of states, i.e., the grid size \(O(nm)\).

    +

    Memoized search recursive tree

    +

    Figure 14-15   Memoized search recursive tree

    + +

    3.   Method 3: Dynamic programming

    +

    Implement the dynamic programming solution iteratively, code as shown below:

    +
    +
    +
    +
    min_path_sum.py
    def min_path_sum_dp(grid: list[list[int]]) -> int:
    +    """最小路径和:动态规划"""
    +    n, m = len(grid), len(grid[0])
    +    # 初始化 dp 表
    +    dp = [[0] * m for _ in range(n)]
    +    dp[0][0] = grid[0][0]
    +    # 状态转移:首行
    +    for j in range(1, m):
    +        dp[0][j] = dp[0][j - 1] + grid[0][j]
    +    # 状态转移:首列
    +    for i in range(1, n):
    +        dp[i][0] = dp[i - 1][0] + grid[i][0]
    +    # 状态转移:其余行和列
    +    for i in range(1, n):
    +        for j in range(1, m):
    +            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]
    +    return dp[n - 1][m - 1]
    +
    +
    +
    +
    min_path_sum.cpp
    /* 最小路径和:动态规划 */
    +int minPathSumDP(vector<vector<int>> &grid) {
    +    int n = grid.size(), m = grid[0].size();
    +    // 初始化 dp 表
    +    vector<vector<int>> dp(n, vector<int>(m));
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for (int j = 1; j < m; j++) {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (int i = 1; i < n; i++) {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (int i = 1; i < n; i++) {
    +        for (int j = 1; j < m; j++) {
    +            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    return dp[n - 1][m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.java
    /* 最小路径和:动态规划 */
    +int minPathSumDP(int[][] grid) {
    +    int n = grid.length, m = grid[0].length;
    +    // 初始化 dp 表
    +    int[][] dp = new int[n][m];
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for (int j = 1; j < m; j++) {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (int i = 1; i < n; i++) {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (int i = 1; i < n; i++) {
    +        for (int j = 1; j < m; j++) {
    +            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    return dp[n - 1][m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.cs
    /* 最小路径和:动态规划 */
    +int MinPathSumDP(int[][] grid) {
    +    int n = grid.Length, m = grid[0].Length;
    +    // 初始化 dp 表
    +    int[,] dp = new int[n, m];
    +    dp[0, 0] = grid[0][0];
    +    // 状态转移:首行
    +    for (int j = 1; j < m; j++) {
    +        dp[0, j] = dp[0, j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (int i = 1; i < n; i++) {
    +        dp[i, 0] = dp[i - 1, 0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (int i = 1; i < n; i++) {
    +        for (int j = 1; j < m; j++) {
    +            dp[i, j] = Math.Min(dp[i, j - 1], dp[i - 1, j]) + grid[i][j];
    +        }
    +    }
    +    return dp[n - 1, m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.go
    /* 最小路径和:动态规划 */
    +func minPathSumDP(grid [][]int) int {
    +    n, m := len(grid), len(grid[0])
    +    // 初始化 dp 表
    +    dp := make([][]int, n)
    +    for i := 0; i < n; i++ {
    +        dp[i] = make([]int, m)
    +    }
    +    dp[0][0] = grid[0][0]
    +    // 状态转移:首行
    +    for j := 1; j < m; j++ {
    +        dp[0][j] = dp[0][j-1] + grid[0][j]
    +    }
    +    // 状态转移:首列
    +    for i := 1; i < n; i++ {
    +        dp[i][0] = dp[i-1][0] + grid[i][0]
    +    }
    +    // 状态转移:其余行和列
    +    for i := 1; i < n; i++ {
    +        for j := 1; j < m; j++ {
    +            dp[i][j] = int(math.Min(float64(dp[i][j-1]), float64(dp[i-1][j]))) + grid[i][j]
    +        }
    +    }
    +    return dp[n-1][m-1]
    +}
    +
    +
    +
    +
    min_path_sum.swift
    /* 最小路径和:动态规划 */
    +func minPathSumDP(grid: [[Int]]) -> Int {
    +    let n = grid.count
    +    let m = grid[0].count
    +    // 初始化 dp 表
    +    var dp = Array(repeating: Array(repeating: 0, count: m), count: n)
    +    dp[0][0] = grid[0][0]
    +    // 状态转移:首行
    +    for j in 1 ..< m {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j]
    +    }
    +    // 状态转移:首列
    +    for i in 1 ..< n {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0]
    +    }
    +    // 状态转移:其余行和列
    +    for i in 1 ..< n {
    +        for j in 1 ..< m {
    +            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]
    +        }
    +    }
    +    return dp[n - 1][m - 1]
    +}
    +
    +
    +
    +
    min_path_sum.js
    /* 最小路径和:动态规划 */
    +function minPathSumDP(grid) {
    +    const n = grid.length,
    +        m = grid[0].length;
    +    // 初始化 dp 表
    +    const dp = Array.from({ length: n }, () =>
    +        Array.from({ length: m }, () => 0)
    +    );
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for (let j = 1; j < m; j++) {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (let i = 1; i < n; i++) {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (let i = 1; i < n; i++) {
    +        for (let j = 1; j < m; j++) {
    +            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    return dp[n - 1][m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.ts
    /* 最小路径和:动态规划 */
    +function minPathSumDP(grid: Array<Array<number>>): number {
    +    const n = grid.length,
    +        m = grid[0].length;
    +    // 初始化 dp 表
    +    const dp = Array.from({ length: n }, () =>
    +        Array.from({ length: m }, () => 0)
    +    );
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for (let j = 1; j < m; j++) {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (let i = 1; i < n; i++) {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (let i = 1; i < n; i++) {
    +        for (let j: number = 1; j < m; j++) {
    +            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    return dp[n - 1][m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.dart
    /* 最小路径和:动态规划 */
    +int minPathSumDP(List<List<int>> grid) {
    +  int n = grid.length, m = grid[0].length;
    +  // 初始化 dp 表
    +  List<List<int>> dp = List.generate(n, (i) => List.filled(m, 0));
    +  dp[0][0] = grid[0][0];
    +  // 状态转移:首行
    +  for (int j = 1; j < m; j++) {
    +    dp[0][j] = dp[0][j - 1] + grid[0][j];
    +  }
    +  // 状态转移:首列
    +  for (int i = 1; i < n; i++) {
    +    dp[i][0] = dp[i - 1][0] + grid[i][0];
    +  }
    +  // 状态转移:其余行和列
    +  for (int i = 1; i < n; i++) {
    +    for (int j = 1; j < m; j++) {
    +      dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +    }
    +  }
    +  return dp[n - 1][m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.rs
    /* 最小路径和:动态规划 */
    +fn min_path_sum_dp(grid: &Vec<Vec<i32>>) -> i32 {
    +    let (n, m) = (grid.len(), grid[0].len());
    +    // 初始化 dp 表
    +    let mut dp = vec![vec![0; m]; n];
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for j in 1..m {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for i in 1..n {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for i in 1..n {
    +        for j in 1..m {
    +            dp[i][j] = std::cmp::min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    dp[n - 1][m - 1]
    +}
    +
    +
    +
    +
    min_path_sum.c
    /* 最小路径和:动态规划 */
    +int minPathSumDP(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {
    +    // 初始化 dp 表
    +    int **dp = malloc(n * sizeof(int *));
    +    for (int i = 0; i < n; i++) {
    +        dp[i] = calloc(m, sizeof(int));
    +    }
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for (int j = 1; j < m; j++) {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (int i = 1; i < n; i++) {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (int i = 1; i < n; i++) {
    +        for (int j = 1; j < m; j++) {
    +            dp[i][j] = myMin(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    int res = dp[n - 1][m - 1];
    +    // 释放内存
    +    for (int i = 0; i < n; i++) {
    +        free(dp[i]);
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    min_path_sum.kt
    /* 最小路径和:动态规划 */
    +fun minPathSumDP(grid: Array<IntArray>): Int {
    +    val n = grid.size
    +    val m = grid[0].size
    +    // 初始化 dp 表
    +    val dp = Array(n) { IntArray(m) }
    +    dp[0][0] = grid[0][0]
    +    // 状态转移:首行
    +    for (j in 1..<m) {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j]
    +    }
    +    // 状态转移:首列
    +    for (i in 1..<n) {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0]
    +    }
    +    // 状态转移:其余行和列
    +    for (i in 1..<n) {
    +        for (j in 1..<m) {
    +            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]
    +        }
    +    }
    +    return dp[n - 1][m - 1]
    +}
    +
    +
    +
    +
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp}
    +
    +
    +
    +
    min_path_sum.zig
    // 最小路径和:动态规划
    +fn minPathSumDP(comptime grid: anytype) i32 {
    +    comptime var n = grid.len;
    +    comptime var m = grid[0].len;
    +    // 初始化 dp 表
    +    var dp = [_][m]i32{[_]i32{0} ** m} ** n;
    +    dp[0][0] = grid[0][0];
    +    // 状态转移:首行
    +    for (1..m) |j| {
    +        dp[0][j] = dp[0][j - 1] + grid[0][j];
    +    }
    +    // 状态转移:首列
    +    for (1..n) |i| {
    +        dp[i][0] = dp[i - 1][0] + grid[i][0];
    +    }
    +    // 状态转移:其余行和列
    +    for (1..n) |i| {
    +        for (1..m) |j| {
    +            dp[i][j] = @min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
    +        }
    +    }
    +    return dp[n - 1][m - 1];
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    The following figures show the state transition process of the minimum path sum, traversing the entire grid, thus the time complexity is \(O(nm)\).

    +

    The array dp is of size \(n \times m\), therefore the space complexity is \(O(nm)\).

    +
    +
    +
    +

    Dynamic programming process of minimum path sum

    +
    +
    +

    min_path_sum_dp_step2

    +
    +
    +

    min_path_sum_dp_step3

    +
    +
    +

    min_path_sum_dp_step4

    +
    +
    +

    min_path_sum_dp_step5

    +
    +
    +

    min_path_sum_dp_step6

    +
    +
    +

    min_path_sum_dp_step7

    +
    +
    +

    min_path_sum_dp_step8

    +
    +
    +

    min_path_sum_dp_step9

    +
    +
    +

    min_path_sum_dp_step10

    +
    +
    +

    min_path_sum_dp_step11

    +
    +
    +

    min_path_sum_dp_step12

    +
    +
    +
    +

    Figure 14-16   Dynamic programming process of minimum path sum

    + +

    4.   Space optimization

    +

    Since each cell is only related to the cell to its left and above, we can use a single-row array to implement the \(dp\) table.

    +

    Please note, since the array dp can only represent the state of one row, we cannot initialize the first column state in advance, but update it as we traverse each row:

    +
    +
    +
    +
    min_path_sum.py
    def min_path_sum_dp_comp(grid: list[list[int]]) -> int:
    +    """最小路径和:空间优化后的动态规划"""
    +    n, m = len(grid), len(grid[0])
    +    # 初始化 dp 表
    +    dp = [0] * m
    +    # 状态转移:首行
    +    dp[0] = grid[0][0]
    +    for j in range(1, m):
    +        dp[j] = dp[j - 1] + grid[0][j]
    +    # 状态转移:其余行
    +    for i in range(1, n):
    +        # 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0]
    +        # 状态转移:其余列
    +        for j in range(1, m):
    +            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]
    +    return dp[m - 1]
    +
    +
    +
    +
    min_path_sum.cpp
    /* 最小路径和:空间优化后的动态规划 */
    +int minPathSumDPComp(vector<vector<int>> &grid) {
    +    int n = grid.size(), m = grid[0].size();
    +    // 初始化 dp 表
    +    vector<int> dp(m);
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for (int j = 1; j < m; j++) {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (int i = 1; i < n; i++) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for (int j = 1; j < m; j++) {
    +            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    return dp[m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.java
    /* 最小路径和:空间优化后的动态规划 */
    +int minPathSumDPComp(int[][] grid) {
    +    int n = grid.length, m = grid[0].length;
    +    // 初始化 dp 表
    +    int[] dp = new int[m];
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for (int j = 1; j < m; j++) {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (int i = 1; i < n; i++) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for (int j = 1; j < m; j++) {
    +            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    return dp[m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.cs
    /* 最小路径和:空间优化后的动态规划 */
    +int MinPathSumDPComp(int[][] grid) {
    +    int n = grid.Length, m = grid[0].Length;
    +    // 初始化 dp 表
    +    int[] dp = new int[m];
    +    dp[0] = grid[0][0];
    +    // 状态转移:首行
    +    for (int j = 1; j < m; j++) {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (int i = 1; i < n; i++) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for (int j = 1; j < m; j++) {
    +            dp[j] = Math.Min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    return dp[m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.go
    /* 最小路径和:空间优化后的动态规划 */
    +func minPathSumDPComp(grid [][]int) int {
    +    n, m := len(grid), len(grid[0])
    +    // 初始化 dp 表
    +    dp := make([]int, m)
    +    // 状态转移:首行
    +    dp[0] = grid[0][0]
    +    for j := 1; j < m; j++ {
    +        dp[j] = dp[j-1] + grid[0][j]
    +    }
    +    // 状态转移:其余行和列
    +    for i := 1; i < n; i++ {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0]
    +        // 状态转移:其余列
    +        for j := 1; j < m; j++ {
    +            dp[j] = int(math.Min(float64(dp[j-1]), float64(dp[j]))) + grid[i][j]
    +        }
    +    }
    +    return dp[m-1]
    +}
    +
    +
    +
    +
    min_path_sum.swift
    /* 最小路径和:空间优化后的动态规划 */
    +func minPathSumDPComp(grid: [[Int]]) -> Int {
    +    let n = grid.count
    +    let m = grid[0].count
    +    // 初始化 dp 表
    +    var dp = Array(repeating: 0, count: m)
    +    // 状态转移:首行
    +    dp[0] = grid[0][0]
    +    for j in 1 ..< m {
    +        dp[j] = dp[j - 1] + grid[0][j]
    +    }
    +    // 状态转移:其余行
    +    for i in 1 ..< n {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0]
    +        // 状态转移:其余列
    +        for j in 1 ..< m {
    +            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]
    +        }
    +    }
    +    return dp[m - 1]
    +}
    +
    +
    +
    +
    min_path_sum.js
    /* 最小路径和:状态压缩后的动态规划 */
    +function minPathSumDPComp(grid) {
    +    const n = grid.length,
    +        m = grid[0].length;
    +    // 初始化 dp 表
    +    const dp = new Array(m);
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for (let j = 1; j < m; j++) {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (let i = 1; i < n; i++) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for (let j = 1; j < m; j++) {
    +            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    return dp[m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.ts
    /* 最小路径和:状态压缩后的动态规划 */
    +function minPathSumDPComp(grid: Array<Array<number>>): number {
    +    const n = grid.length,
    +        m = grid[0].length;
    +    // 初始化 dp 表
    +    const dp = new Array(m);
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for (let j = 1; j < m; j++) {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (let i = 1; i < n; i++) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for (let j = 1; j < m; j++) {
    +            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    return dp[m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.dart
    /* 最小路径和:空间优化后的动态规划 */
    +int minPathSumDPComp(List<List<int>> grid) {
    +  int n = grid.length, m = grid[0].length;
    +  // 初始化 dp 表
    +  List<int> dp = List.filled(m, 0);
    +  dp[0] = grid[0][0];
    +  for (int j = 1; j < m; j++) {
    +    dp[j] = dp[j - 1] + grid[0][j];
    +  }
    +  // 状态转移:其余行
    +  for (int i = 1; i < n; i++) {
    +    // 状态转移:首列
    +    dp[0] = dp[0] + grid[i][0];
    +    // 状态转移:其余列
    +    for (int j = 1; j < m; j++) {
    +      dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];
    +    }
    +  }
    +  return dp[m - 1];
    +}
    +
    +
    +
    +
    min_path_sum.rs
    /* 最小路径和:空间优化后的动态规划 */
    +fn min_path_sum_dp_comp(grid: &Vec<Vec<i32>>) -> i32 {
    +    let (n, m) = (grid.len(), grid[0].len());
    +    // 初始化 dp 表
    +    let mut dp = vec![0; m];
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for j in 1..m {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for i in 1..n {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for j in 1..m {
    +            dp[j] = std::cmp::min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    dp[m - 1]
    +}
    +
    +
    +
    +
    min_path_sum.c
    /* 最小路径和:空间优化后的动态规划 */
    +int minPathSumDPComp(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {
    +    // 初始化 dp 表
    +    int *dp = calloc(m, sizeof(int));
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for (int j = 1; j < m; j++) {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (int i = 1; i < n; i++) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        // 状态转移:其余列
    +        for (int j = 1; j < m; j++) {
    +            dp[j] = myMin(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    int res = dp[m - 1];
    +    // 释放内存
    +    free(dp);
    +    return res;
    +}
    +
    +
    +
    +
    min_path_sum.kt
    /* 最小路径和:空间优化后的动态规划 */
    +fun minPathSumDPComp(grid: Array<IntArray>): Int {
    +    val n = grid.size
    +    val m = grid[0].size
    +    // 初始化 dp 表
    +    val dp = IntArray(m)
    +    // 状态转移:首行
    +    dp[0] = grid[0][0]
    +    for (j in 1..<m) {
    +        dp[j] = dp[j - 1] + grid[0][j]
    +    }
    +    // 状态转移:其余行
    +    for (i in 1..<n) {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0]
    +        // 状态转移:其余列
    +        for (j in 1..<m) {
    +            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]
    +        }
    +    }
    +    return dp[m - 1]
    +}
    +
    +
    +
    +
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp_comp}
    +
    +
    +
    +
    min_path_sum.zig
    // 最小路径和:空间优化后的动态规划
    +fn minPathSumDPComp(comptime grid: anytype) i32 {
    +    comptime var n = grid.len;
    +    comptime var m = grid[0].len;
    +    // 初始化 dp 表
    +    var dp = [_]i32{0} ** m;
    +    // 状态转移:首行
    +    dp[0] = grid[0][0];
    +    for (1..m) |j| {
    +        dp[j] = dp[j - 1] + grid[0][j];
    +    }
    +    // 状态转移:其余行
    +    for (1..n) |i| {
    +        // 状态转移:首列
    +        dp[0] = dp[0] + grid[i][0];
    +        for (1..m) |j| {
    +            dp[j] = @min(dp[j - 1], dp[j]) + grid[i][j];
    +        }
    +    }
    +    return dp[m - 1];
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_decision_tree.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_decision_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..5b67c8ace3c31018699c0e3c96769e927e1c41ae GIT binary patch literal 20980 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step1.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..afb660bee480c3e0cc5dad0b26fea382b2dbb523 GIT binary patch literal 13587 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 Js^_qv{{>g@R2~2T literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step10.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step10.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb9ce37fc7febb9b6009e61394ef020bd803aa2 GIT binary patch literal 14770 zcmbVy2T)W^v*?`Ng(YVY$*iD)fGDVBmZT_%fJ6~Vl5>!tfQJl{K@kLG1<4{&a#+bZ z2$BQ@iIOBK8Q%K+|Es$9RsFYK-KpB0p6M`sdV2cIOrJ1ywOf>AEMx!x%G=6{ng9?H zKtw+Yl2Gks2tFn>4%Ah(lul1i$JP!{7AAfy?k{XE?CtGo))f0!`$D@Z&sp^^S85CME_32Bf8>V`5@dRaKpxo!e*Hnwy)ow6xpX+YJmJ z9vvNNXlN)a-uicw=MZ{hH#Wq@sPXUUo$Bf7>F(|>tZ$F`99>ma zWomAHG&h#m`r6koR6#+Z{pZ5$`fOZ6+V8`|&WWE{rFCgpX?36b>+9=r1?3?zueT=$ z+uGV%dRwYTtJnVQPj0NQ?5uQF7Qcyp5fuo3`MFm&KjYT%xv4b&b$XtSgR8NLN&oCd zT}z!2zM`_GqqL%VY;t{dxF@}^qBuRJcW}0JX0o8TPQSh^B`q)5#|u9&Ik+$wHQ4<; zG|JV^x^=20HYFpZHn{og%;eH!Ti5vU_rbx*!Q=6+C_a`(#8@mNQ7V|7_=SxQb(b>4dm8;ALg z`A>so?xh7KUy1`ud?!~YvL{ALn$naKqn&ab3{oD{P49IN?Yu9@O6zQm#8=zAw`~1B zIWSP!-B(7WP0d3h`-?ft{A(ojt2WN6Z_*Z35tyA zh@t0a9N;3-nHgQ-ct>Bc|Ao+LZb?h;YpypMt7~{rIgdr>OcG~b(BQ6~(>c0M-6SqV z0`Z@{#G><<_D}VQ0^Au@?!&yk`KzCrq>LILPnw9HM7|>>@gA*FI5%Q)F``jc6YbEn zkxO%iW;H=717XK=MJ_UoMOgF&t1_u$ZOzQDWoxF@x70k!^zJvewBsCV4=wAR-|2o2 zk|IL&hlp4i=KL}u0Vo>aYXL4GNTxlAivnW-VlNeXs0bh$EP@0EblATH-H?=ubnl8+ zYWx+rs&%nkaB+wR%gMQ|sc8VRb@|>Bm`*|OxXxty6<8x}!H#nJ*-sh+gqWbFGKvNp z4epp!@pu`4{9(OvxfjEr{{2jqG_gG;l#?MGLCw zl*%_X0PRprm$8I!Ddm0SgTr6G3E^tvmnK*WcMmkx z#csFS3jfk~c$;arGRh|{Lzi&=889T%xwfB((#y5;S!!^O3C41WK9 z_k{+#cq^9%3k(r^=FVAQJ%6gzZaGm!F0GMZP+jy-B>=gJBa8yxU;2hv`f}ddo5NhM z;5(5T^=&d<0}puR*>-LKKrCHFjn(y0%7#4IEBo%)F0vQTa!TRpB2mxFD*@8Fr7rosiNumF;Sb`t++RbXhsYz;sFVyG@nX&7u zlhU^LO_*CZZTTL`h=+f6E&9r%lg#`k>#jFsKTgH+kmBb1z2F}z_DT=L!h_@oio+Qg z$S^;CaM3k{e8*$h4@mPAo>)B@(2*1yO7Hj0bVFG zj7|lm{PAgcM}T=osr*>Gk|hw~%8EQ}87efiVV4yC5~&giOm{DHdi>?3nZ;E}o^Yo9 zh2yvsjLq!3su344wDfyIkM#+owqH@b2xI8(2mecxfBlOJQs72BMieee|CAeLm2wx4 z6s`?NUZCj=Q=o~>5f&{V!zFjcBvlFTOQxAu9M^oT!|2zN7~IO&j|*BP;eK5QXu~LG zc^=T?HL_fyRYZ%PxQCWePrt*2q4%pQYi+YQ^qqm=pQW=Y>m>~CFQrXp+eGUqB zs~!1u56y4fw0i?V

    <#lW39bQqdV1c#-g|YLOd!c3-_X>%v(ON)i)4A8&=Q8cX|E zFu9#`dtvG1clm8;e=o?oPcfKbdrp9|X;{SKiznWPCN`=(M%A}r@`!mtZ|VUtJr682 zw#LY>Tr|`RbbjLBJ`-zN)nZ9-`G7!@;gqvojeHNk*hx1grzNk{HyoW;2O2+4$l0)w zrS=rl+EZfw!qvoCVl$0*`j{8}DhM1r$2A-?*$w7qG@lWAbMs^IcumPPNXDd!n)}J* zw31%Z$h%T+Q+$wOp1OM1(vt)8C0B;0LQs?) zVUHM1p1*4xW+rVB6JxrYNUng<(oK=OxMMdVxycjh*4kFqQp zy*9}RkyOL0{VKR}_5M$Vb`T}6DDh1Q3VcUOkFA`{?x&qNcPJgIY`4aQ#a}rvbE6IW zFo`7jX9Xx;BjuuqB>4HjkN^xj|8@TN3j|ILpv2>kK+%x4{dIc5kBeTM@g30(MsEsl zsS{9lnBpXTQF_q?jg$ku)zHa?&Q>zn_D(6g?TQ&z#y&tUuQ~eaIIXu{x|v{X)6vd!aqot4N~IP_x>LTmfO+|6nI$#1HSc zH7F17ntb{~eOo6jMxJ3^PI2OkIrqWY?To)fI%%x$rD5_X*AI>pH~H;`9reCTe-L5A z3m8o!6`T3UDHdT@;!DBcykp{?*;b`7wXw5UH!?}$95W@A51?%mW-X?mb?yo@#}~#~ z{v{iwknFP(MvG7b-wj0W#1@0jqY%c>P=gXSNRn+U{O_38l{g(C)kR)=@GB|ktD}xI z0WHCXFSKYVu_rO!3N}0d>su_=c27L1^SS$qk8+~1wAl=mkZ0zqL^Hd85v+=kOFCXL787c`Xv&$x2V)$<#2eaJh->7cq=ZaA1y0SF$G6X!lEXWs|sBc$IuWr<*E+t^C_ zWv#bJ2!?cEUVGVPUScRz*oYZ??6@6SoSJ#<`o|hwigkkHlfbuCKSmmp82<>Cu0LhN zWBNQ;i}X*1&jq-X@*ziqLMvOk>>+{}`=c|pnO>Y2Of~HTMMc7^M0R!P3Iw=l0QaZo zR+2|qXl^VF2#bvi27Xr|gg%1c=Om9w39il+!%OgX7@P3d`~N%Qw;KFxIYMyS7Qw*v zm{c7mP(tzvfQUr@-yIL#S4K%pm`UJi%kTbqxcFaz_*wafB4=Bvuu;q%HA)j~rzK^b zg?WO`JTQXfzSY>f7C%77)s4Gaaa8alo&c)i<`dYub5DP=pQyq2Xlk&!3lO-z`!Co8VjrOEH0e%k+DcVKPaRSd=W= zt0QcPP^4(w{aoGRHs0JAIT|9?7!31ky*uYMB(zA!c}bqoq>w-Qs)@=bCbJ>C;bxP{ zK(Y6H33EdJHh$2rL2^oNeV2V|?d@h$os>r&11T2D(Xw_WGyYoW3@rMl^YYs>qa-&>9sPkd6 zflP_)HTM@#WzmadTLyScWHiqfeLsJlm z*MFC%au@^wZ<_8A2X%ttxRpmf)_1#ECL=N@n~uFzVmKa1!Q6CE4nwQ~u)NOyYOQ>% zPaceWiBREJ&${`3JwYh%@?VDAJnteCar-v`ztS8N{`k&#{aB_cV4?i0ItB>MmpEAT5~l3S0A1;8te3+42U(p_Gn zqJaBe^~l=FP~7u&gjlO(-yzpuEcJAPeoYFPYFQTNz?TJ7Mq9N*V&g6JeTUrO)eo2F zL?_yJK$^*>{FKoQ)q^ExK&5^!?s3HJ5$v zZqs0D#i!q?J-OG|l#uya=(s7|K4i39;bIW`%8=lf``mMeF8A2wt*lLMlceL$8nO$7 z@8A8fTDyDvaLW4oX4k4?;x6!8Al`VBd09?vE=pGAL~z5rj+=a1rEZo8LQ$oZ-eRct z*VHFRiY4@MYJ?%hL~<<6q1qaT>h~cDAL+1IoHeACI=>~Ed0uyod|FTDMiw2)slMzg zy}XMD(y)Hp2wMFk^(&ZTr*@?S$-Krb=(wR!5F+h}z3n#lyS+al zqXhI)E!P`dqL-*}3I&Lt#eH8L9YQp1w!*j3`l@bCMO^Un?+OdG4$QiAbx+&)W{jry z!_Pffyi*!N!WDz*_3iYnYWK@&JUji3T!bx@>^=Ewj59{mSP-EMAX{3(F;6d?aL&U& zK*a#WFa}1^6eav>UdShbcwp>7mD)g9hc+#N)^F#MSTUnk;9pvBg%b*Y#tBHdAe8EK zTgUfb^jJiq04%%m``|8uq>SpuXAlFfW)JmOsS<%d%d4&;{bCym%aGPvUlJ-!JMF0mz8Q$U9*ieu!4;jwOt>8(M0 zpf8({?O5;Iej6J6Zw}}+Km?13zy@~?Zda!CxR-|ztkdKUAxILV{xO9+s=q)d-#`R! z^OY9{AIOY(OY`Lcl*ozy`EvwCV`a`3!b^dB$c$%!P!Fil=^U!SW0MYLb+(>gsssafJu&5Xxgr6fC}t&#_xa@shKuoyg2$BzfH5E#_diU84n5M- z#kkgp2G9JAWGDLjx@MT$?k>TuTN6VQ0ndH_-$#nGXND4Ni7*Px@8-pPRLj6o)B z&(Td@%~bM{Lsl$G@l#rZqBqfe5BjIkEaaFM8sxq>1VyeHoh8`39kFGWi)0L6Eji)bh*1)$1XTeh4VPIq;Fncq4eq`XO}<#dPXL8lOTcV={cg zvs!Xhf~D3La=LTw0aq(J`@i!3G#9C{5f|-Vfv@}y=x;g;29AxGv6$TmUQVX7$B9RJ zuff~TRR!aK*m3C-6&E)ZQp}SRPk)@ub%X4j^jX{*D^htbrFfN*@6f2_DQZLLs-)ss z{4`~q`k9YG?8HtRq_A$@4LPP%BHRY0Djcc9c7-jYz%{)XF38LG(fH+j z;bTFF!rX~V(l-7&d_eh4Vfv2yO?kKLPv72vulLmykWY&USlu^-)Z9(gEZ%tdg-wW* zCs5J;bQJpC_3HtG`LqAzI9R@6S8>I$U@1_zFn=7#3?CDnd|^P++^d^$g%vO11vL2P z!%s%k>l=|8>};VD-entR{^)c%z7PJ};4Jnn$=#g>GXjtv+ybt`ij?8dV-Uu|glq?N z*93?OK5C=qRchy@-~1PwZxnv^YS$1ZoEb|TWA*#6X^Q=uFij(1sEeZg!FUzhYJBFr z$-+xoKD9vNmf9Q5ujd;b%pcUq5cW9SejT($(MTL&cl21@a%;B^V!%Ry45lW~MZzXZ zyewy4C(=EVKnM{KSi*LR1`DD7-JG5St!80B-u(i~=@pQ7Ii<&I7cO3f0w=c6gb)f5 zF5Q4%DJfTxO8A4W)KFVOAg5Y~5ZNy@4+@DGuv`J7rwnSqPue>Osm5roxqF6rYIU;5 zhF*gKzga3g0o819d8o4GW^D$f-y~&hzD!nq)#5_v^aqsTs6UB6SM^dl>pPOt_Qo?L zbJ7oA%7n2ReO7(pe}kXHG4*A~X@!-}qLc1(i#O47J))CFtnGy8gryWikQi%-Bln{K zA_qx;O=z)zJRBhO^iVYTMhpy?hM!Xyk2eg3lNc8@U39dpJ2ZVQWI1-{hI_xSCUBkh z&G7tmY<}T9d}+6r_qNNXnIZ^aXG%&KH~qS_q8 zAhZfiyzrSQDwHAqwftjm06naEReJ;7Uw^Lbqk(zUQy=^AAlO>CMlof-pRHf^)Xy2ulnIaPWJLY4@M(+!c-~lbvDedjkrHe zA~oe%xg8bG=a$udf?&mK^x?tFcak#7ZCE6&WclE{Dtr<5$@b>gk9%@Qf=;tvO6PJb zhzWYUw9fC2-TCTEq_>b$u$=K%2Qr$(fbYkv))Fov%^x?#ej5B^+ZCOpbA|D;#PfKI zq>LwP%B#5J_aJXUK8;8A&;DqR815J1yQ+iUU)tr|1aS%L6TL^bvUwj2CNxux-y_4> z2&sprj5;@*cR$f`nPkBpMyXey&X=ej8eZw>WP3HcLic|a?G0A;km7jGv8F^+9uP-ivGvR7Ny^HlB=?LQ2iRsHQ<^_#-yVav-rx{oG&-=_Fp_-Ep_ z>J!RYOv`fbCpA-!-|IXh2a7w2yck$tU(Wv6?yd?lkLT3lQtG{QD4>W@+IEAy@eXt%9+&``KD2#j<#T)PaK;{r!<<+k(f5Ni3c1EI}JJb6~yFx4& zN>0|M2x*djONPe%A(mpI$EROK74gXuR`#`iH%Y>pF@5SqvJR7S!TVOdrwGE{O*p3- zmXtds;ewx9jTio{tF2C|`~u{*GmioRf)Ew};-C9|5-vax^T}lgD=5g`;z$BFS@6kS zyU69V#MV;iOhiIRo;dzHivnU!ZO`T8{jUqzGbgTpE`R4v$4UN2Dg3M7?%57Hf!57M zP0v+#T05Nf;Kys$R$0fT95$yK<(hIW9VCW=^w-PX(VN%rHL<(%x8wZJ6moc@eV%7o z4}MxA58d#l>WHs}f6bi1{HJ33_Nz#uN`3dtk4iH4CXZ8H@I$P7SKd{o!Q*IF?Ep%F*Z=F z@Mu_g2L2)4BqK)2$biZynG0c>xj1Egn*1`gv`DvM>^ z$HK73&Vu7AgAUzYhwVkP36)pdmy2jrL_+ZVaK*m&k#==dY>SV8_jxafHg-we%sRQQ zG4>bxcXp!nfZYJ=!5QxLW7CzvZ8p;^YZ=oiirUtoMK3RzjoLx>*x5Pv?EA3;5um+Gq51+)`Jx~`w!H66@;T=Q(k$pWj$vqcxF1dLvG_yk5& ze4AUfy6J8fhWt{(iCA*_$?kL$z3VOzXE^IpvrBv3>xb7PZ^Be)FiFl};0n1Brn~|v zYcJvmNteFn1eGs7q^oP}QG<377w{1+X5WoBi0er^E_}EEWM8`;{NcuEyq;XR3Oo09 z+SB_ze&cW?0-veV*q0+yraYd~CLE|zAcS`CO+ZmG^!W2r8{ChgiOURRhQ9rMPMEC_ zA4#j*JQR4blZS!XTO~N8xTxC4thuOlD|7)x7&o`+q{7P<;>@g&Q3LYNUo!90$oajl z`@{a{ut22n(*fne#*wj5Q_5+G*VK((yJ+@4l+){D+CpPdBPxwta~h|Oz}%*+!$Z1Y zQsYCJp@(LCl*Y-d$m)Xa9p8`^DOfS7i{M&?Cb8xt5nPlmE0Hazh&Qq>`bzfLLSo|p z!*0DNQ8(v(6r=PXqGMK^o?t8DSYtAET*&oIzY>xv-b6d&7DQ^lipW>a9154~yNp3> z(Z5l~huz3_+2`A26shM*SEqxduFh^y61(}e+1O0ZKH5(3MPe{l7LJ^Z5uVtOfd1fh zXoM#_5siC@ps0=DI;b>zY{pCP>+C)`BPg${{|!aM9vP2D4lt(4?hVUiz4X@JNPfn!pOEuQ;-`K*C0ha^?j z+hM&52qo}&euRu7I?a(;Ac6}!pJz-=Ju3}I^5`F*9>8-b45oN!Htg0Z;iWz|cBYc3 z9;1+ufVsWStCQ7d3jFTX?CdTg6FFp}J61P|WW>zQKjFBkXqwlCIKJCmdu&1-c0z*1 zQ~PMCQGcicELB3KYgHiXHWi1xK)<#zZCJrKXPciSoE&O`-J|;%J^lHS;%%Ae+ERZ~ zi|Y9&cIz^Q@`SG<{#8zj(dd8j*w~Z8NZfx9qK$8lYZYl*o!OqhO` z2)#2AmH)9(W+i8EU21Ug3CF@%UG2W_;(yKE{g*V}KOpClaD@7AX8EE!HofKn90_-A zKGbS-k$EO%u1Fq1gCDeCb%-OM(+(CV=Dba$&3g>RkE!0=F6#Cc?&uuQ&CrLd$#A`1~HxvwI;qzNdl0sQifc zh~us^!X1y@7!O`w#`W@4E+5ZMG*c{bVt8tes{^$CnTB4**eCqHjLSE9qV=WW!N>Yn z8pJX)VUT)gq8;f8CmMUVYi@`GtWo>bvjg#aCZvBT&z-Nu$wS>w4^A>J#+zsAPt~7} zio;peyPPCAPA@Yg6Q-G8E|yYn(Eo#|_H|=J>Y})#BFObo7ybeb_MSYDri6APCs7;s zD(r8sem`tX=BLAFj8OmLg?~LAmKr`O{>bs|!Y)#5A7|`py`J1ZDKc=)^KRG#=ILm#IR46Z!guLBCUTwOBKG>zhXO~%c zspPpcHvMt$iM>*i`a~A4$eGT66cgINDL%>GkbLpT=kUtzLu%u5V{i7dE+coV417}- zqmFnC^yu)czlS=p=9!4fA(sbqc;&lyd)7=(mvioldAz`|)~)t7WPi>Cf9ToGG~1&3 z{Q}I9V%LUwNvAsqpV>UJSGX{M?kP4;cYH%Hy|2LXhZf)AWZ?Zp4jeWrissaub9miR z0H{Q%R1nO!vj+oOPQDIYT92bm@0$p#*iY-{qU3s}d9Uy6#SdEGyLu`Q{JL3ZF*G8YHnUhSN2Xd1kd&Lxr=H_Z0)yGM6pXo^aHLuWC1U~O_a?mFZjubA*j%03pw9p!{ zDMxQ49rEWTX0ho0)3pb#4b&5v>=iYv`>PYK4$sa&48%QUPq*kgATf%&z&Mx1h^T)I zN48>}q?NgX9;+(qOgMLmW)5mcq1^dbR(ihso*viSeW78RNed^G_|!4&Q>}lq+ouNJ z@7qi7(rO0|uqkl@WQHYG;(J>mp*)ezm5nj=I2JIgl#JMF?eX`u>qe?OCaey1ez&_z z3NODjkg~B&EdN|^=SJ!1qg=8)D|CGvk@^_bNL{DI_|Bx!*!vrd8G&~$f%s4~?!*WB z#(qZ=EF0mW_Y7E_@76Q?%K41OS+}2T?bM1hg3jR|fCQFsdoN2J1`_A7NpYUfkK$78 zK_c;SA=J%}x8SV<6!$Qj5i<u`Ai$@`-k zhH=-68qI(>5BsL*^Q{5@d<(R)WhLMsF6iLVzJ_7H;VdDS5ceA@;t(J+=2mBp{qPcr zV^^8qz5v$RZ7Dhs%<^TM?;!!A+;B z>MK;tCq|_gxX950r)Lt9hkf4&vw&j+94I!{KUT&-USTuX2YVTf59f%^)?>nNb3Ay* z08>kMSH~l{%6h1Pxq-2+@;xnGU4vPm$e6eL3@%whI2SPEogh2<5F?^=&=~Zii5E}G z0drozc5N+&sDDI}KOMLXlH$$wZonU$^?`oDv&EjsT(lFjljy-UVesyqPbcNW8Q|Hx z@>@s~D0LvkR(U_&2m8Ea)Aapx#KMbx9xnAafNH=G!fCm2P$}4U*c_nS)%zg(C|R_g z8uYSInGC;XEZqh5C*)5MOJ&s(P4s*W2t%tMMtnTJdCQl|?hJAiWdNI&Q5dsp3_yYc ziAXyP=)AGViL4BNWARJK5W-c&I!xq4b`(K3nc;~!$c{4BP6Fu71UATNUnuATI&tr& zSo>S|Twz8D&~7tGjYs=EqlaS5K_XQPvQql#yGM=`c%yTgGcIJ%guSIt7vxl!J`o|M zR7GDIfS%59dq)4zt+XR-QXWXA43PiMV}=!I!)e+{z@pr8I7K@%%E6_rgx{y1>@Gh^-po$tN+i5{2Agu96{oKeht)I85ii zi-BWiZC!-k+0?Zf7ek;@@WC+-#8hNAL$zrq6*YNnyKxUM;*uXC@nwP>c%RWGWdD!m zg>J;g6$DpLeJkIFHZB;6>j>j?BPya2NOk~Mi*D*5nNgX1=YU&NA5#5E`e`+I`uU9- z0z37V4!vP8?Q5>xXHtcx0E6Y8z%XYXk@HR<2*{MC{dOt=4$U0gu*@`|#!`knArgLg zMnxB>@OkG$q8BjEcA;k54ZnhMBNzWS|E0@f8Rhgn=<1vZfE$ISkIiIF)`&%eI|P$=5Tmr}rxOHtc>U@YX7S|bi_ zzOQ-wcH{>Tpd_vXWZk3)&z!=-zIzP~mnAmHmE45{tTHCsKm=zV=s z4u0WtLFRui8psgLtt0_48_#MvM?kg+)YRx2- zSjPypCvaG4zJviyl5iZNQsOL(r+Qk{<^|MZGKf;fVl8%%5o+P(1Mg1wV>m>G2=^8vIwyX(&gnl=B8LmvQDPLYfU+ASWlchjsKu zd%3$f4^@tD8|I;56~l})_#A&WSqb%prH>OXKnCGm5L$gWb%79DYZ!t1tAVuik|1Wd zP6rUZ7GwjL;d$d<9!=x67+1BO^OVNL>9uU=>FrB8sxpy?Jrq)XjCxU|aToC#T+Eeh z0y}Fsw4~J!XcRR}^X!daI*9~DO&B?s-i61YmK@K{25wJ!fr&Q4H{amt&vR7i9LSB) zcM2gFLq1FCgF1`x+mWe1T%Pqo##atj#>Vt(NU-j}8?a_AMSs&$p}?D5f{(7hLUZX+ zalpogVLl>9%Pe<4e{_LRUHnAT<=zaJ!aS}};iDNdw0MbQxIY#3o4+eoirIdBIR?!P z8xRu{2et|VrG#tz3R7MdykmVeY~ab|u7KW$9B^6Go6pGeECwiRjt@VD1(9NkLWZQt zdqgm1kmZ`kkD}XI$T=ln8sr{}y1;>GVtlrcQn6V$*IcZb+-GSyI_uYzPRUBC-RRt} zwL>{e=Qh32cX}%jf$}fBu4GuvH(}(8~uWh&@QS4%5$Ej2n1`uI4zjdWW-Mgd)!FSZIJ$gtDx2Ytsh;B*- z_*2E>Hu_Q1Y@)a4FTG<72RmHP2M++-T?F0%OYfb=s|QS5nPeb_=7Ml)cQZCZJ1@_n`ekza zA_t7VWigw(*&_8EVt<)B{t_o|*zUjn<-&amE)_bwVmsNPw+T0V@tw!`5E1@@(evY8 zMKHui>2;y!XgPLd>iF$`^<<+gxB|yxgYtCkn;K~!k*xD!?Bf8-@x2E~yzP9mfDeDe z&HDG(;H)=Ax3j61in5y>BYbl|{d(O0;r?fwlWu7?YO(e9cV-_K)w@d4JLVK1k{SLv zK#3NvI|yNacEgm0IQ?R^{GI*B%NK*O!JFl98m) zKXWf}1u3-Gp5#aM$;S1x)QRXd9?4ByBLBhFSQoQ8eD(6^>llI!G^zzRw#>|I3{!%nd>PZwitfr z-TK^D2{euk&qOvA1@WZ68HL=WnFkdRuR4FBH)c@UWH?qRG~von;J=XGfdfNhVmGDE z{FLZLEiZ|w=?b+5h^nR?dA~!~yYR-d6z*Bw-(AE*y7wC>&k#Z2F9M47xujnCv+6PtAaIt@cE zMsAl5OQWF?u2K0<{#;8-)yPlG;bwG81zX^0&y>u)xoh))>he3O8T|l)*lH~Qgf!Ve z#%Lk_tQIa_zrLoU?O9Ii8X#7emTklkPZQ=s>x{CtWOz*Y`YLe11=mbEpsuyw7=QXB ziM0Z`N4qS8j52T~ z+@AMOK2dAu`SX3$balgZ66Q}U^~$x*e7;l_-G%p~h1uU7ek7U>N!L5M4h*@a8N%DF zHMjtT6Y`hM;3L!cO;+S8I)K>tDB#NqM_u%B+xs-(eG?$ChTY*@9I|^C-xrYKUvf&3 zhEK7}{dXr`@%hcCwq_|K+3%u*2g^pFu& z>1DmV&m7S?sD|I(!lJmqP$LCC`5PuB>wC%mD|MrXmixwc(ZNk!P{ zRrGWrLz9`PHO2WWBHPZ^m;1WCkghz707EyKzXuN9^?c{S%i$v~F#WPG1Zb^~Pn4ZL zY0XvF{44(EMz)TJeAW17K(UyO%lZVFxr{dp%>Dc}DF4cR#UYdo{H9%4JCu2$x%jS+ zlXAP)WaLJJ=cnfs9V2>WnILhTcl829O0zkl%1eTtpN!ZcxK{eO0#vs zTl{T=UyEhZ=w5ZlXWxD%0Abk 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 E0S&A*PXGV_ literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step12.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step12.png new file mode 100644 index 0000000000000000000000000000000000000000..78ceb86fcde22a066546c36934b7df78f9a4ec52 GIT binary patch literal 14705 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step13.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step13.png new file mode 100644 index 0000000000000000000000000000000000000000..e588f024b54287ef939761648c1617ec38271aab GIT binary patch literal 14821 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step14.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step14.png new file mode 100644 index 0000000000000000000000000000000000000000..f31b828aa31b663147368d7a5f8dd9fe174a75dc GIT binary patch literal 14765 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 nnHb2gi4dn((=;6aA~z>1PLO%6uAfSv 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 literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step5.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step5.png new file mode 100644 index 0000000000000000000000000000000000000000..67ab268eb16d4034a1f90494a0c7f17923cbaf98 GIT binary patch literal 14568 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 E0IB~TzW@LL literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step6.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..e8d11260ae6b4868ab609bf183e773bf03abd532 GIT binary patch literal 14624 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 D$=)8W literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step7.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..beeb86ee061207f671a3dabed7a57850689f2148 GIT binary patch literal 14634 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 CZpCx} literal 0 HcmV?d00001 diff --git a/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step8.png b/en/chapter_dynamic_programming/edit_distance_problem.assets/edit_distance_dp_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..235b7f7d2122d00e3bdcd68048ff262ecc7cc923 GIT binary patch literal 13233 zcmbVybzGHC^XPMe?hc7Vh#*Ke0tW#B0R;i+MhO8?kd8x0NJxjIASfW+eUR?%IST-JRVKwdV>1xU{$c01zlC%Dn^t40I7Zhz&u1 z&axg^pexsEDw^`Qx3^Qq`7;eQ(xgB_t%4*3VN@Q$s>R`uqEBZEdHf zrpjhc`hh|udc7JZ*F8{WL8#I4h{}bDAfA;dRtrD z&d$!umoGOrHx(5XYiepnMn*b2JA;CPWaZ@a_4PXz+mW-#pL3I6zkVGU7*Kuwe1Cu6 zySL5A*jP(TYkq!ydwUx>)7ml9pscKnL?ROs5{8C`yu7_mPfs^CHog^B_4f7#1O$wY zjb&tHXeDVL9UXOdcmMwVTcfT-S6A2B+4d&|qqlarHKy_xUd zzgJUNpZGHo8y6cD6{Vr6k)54Av3d6M=g$uxKbV=Cj_zzW^i73_hlhrSIyyRP>l^9l z=*-N_Ac7(gzKErzrPkI~v8Z5ocejOwh0@Ye)XqXnYfD*KSw%%fWMpJ+RdZ2M(Ytr= ztgWplCML!MQP^HlAe#`;@@J*A zw)FVo7`2Hyo*&zu=%4FqE-YzuEiVlIk`SL7--J4wKiFH|-I>_io|xI1{=1PgJ3h8J zmf6!093C8wtgZi*9q8rO-9Oj2+*@7O^}Zx8I>_Jtr=3-{rFQbG!G_8=d0AQ+Nj|0C zUWMUZ0KofBNlr%7b$YAW7i}B>BI7!jDi?fL{I4Yw=dH;=UusOh46t*HoZ(O0>LwklxEp626|jc96`X_kUb0Vn#?KO3JhjE*`XGB55sTS(+(@wyRSuC?Vnup z>BVACwTO#@B~IOY|CQh2_i42U)f|9;SlM4}Bz+I-7SqFYO6y;M#wHp|X&_y$E<%iA zN6#cyG~j@>sQ=_Qdub>D#s+RJ0Y@-4iVrerO9>@LnqwA|gP?E#2L^x@0T3}9;Kg!S zpu4!X*WPh72WDg&BvK?VqL=l!l_Q=l+Va($3x{q%OP_Ju$ znS&Dp1nl9v-Je z))N(JWQX%1ymKG6I{$p&0UU}SeHj2i-*Hemj{P6w@_x!jrjAaDk1G}p1;O53FB3!I znLr^A)7x;6?REXayFL)tcVS_K>L11*NMIPVI39C`!{Is;Nr!Y8p`$^fkmkI=FxFr) zSm#-&;annQQpwy2crjdiA8`jA>#ht~TGL}zoZ~taB>chpcBwAz0wsob18Z6P#NVUd zP*EVW1mzh0RPI?Pkf8+$)=}-R@!#i5?9sKai`LWcIC;4rU(8X3HAoQW#EPZ~RZDjJ z%4zM~u8$gW@xH%dvZ*8eY{owwPlyEM4|NfBQEv`C&u;K`>D3 z#?e3u2b35BxD&ql6g)!MPY0e*c$Lu=EMPG7M{5cd9OF9F&&s}KMgY-te&zG0B+@}+ zm*4Q-#qc3a1

    diff --git a/en/chapter_graph/graph_operations/index.html b/en/chapter_graph/graph_operations/index.html index 92ffdd08c..d592aca2b 100644 --- a/en/chapter_graph/graph_operations/index.html +++ b/en/chapter_graph/graph_operations/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_graph/graph_traversal/index.html b/en/chapter_graph/graph_traversal/index.html index 699c288e2..640fa88ac 100644 --- a/en/chapter_graph/graph_traversal/index.html +++ b/en/chapter_graph/graph_traversal/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2101,6 +2101,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_graph/index.html b/en/chapter_graph/index.html index 13a460cb1..8a34e2e70 100644 --- a/en/chapter_graph/index.html +++ b/en/chapter_graph/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_graph/summary/index.html b/en/chapter_graph/summary/index.html index 984ad56df..a3fe36ebb 100644 --- a/en/chapter_graph/summary/index.html +++ b/en/chapter_graph/summary/index.html @@ -18,6 +18,8 @@ + + @@ -1137,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1582,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2051,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + @@ -2196,6 +3655,27 @@ aria-label="Footer" + + + @@ -2296,6 +3776,22 @@ aria-label="Footer" + + + + + + diff --git a/en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_area_chart.png b/en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_area_chart.png new file mode 100644 index 0000000000000000000000000000000000000000..28023758d1c74f9e9a29a68caa58a3487b056a9e GIT binary patch literal 12437 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_greedy_strategy.png b/en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_greedy_strategy.png new file mode 100644 index 0000000000000000000000000000000000000000..713f30addbbad7f2a3c648de8ca35adab15b03ec GIT binary patch literal 20678 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 KtXr$?81oNvBgFau literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_unit_value.png b/en/chapter_greedy/fractional_knapsack_problem.assets/fractional_knapsack_unit_value.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4199ca0fea81e0e3129c6d4794b054180f0b1c GIT binary patch literal 20898 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/fractional_knapsack_problem/index.html b/en/chapter_greedy/fractional_knapsack_problem/index.html new file mode 100644 index 000000000..d9b608511 --- /dev/null +++ b/en/chapter_greedy/fractional_knapsack_problem/index.html @@ -0,0 +1,4353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.2 Fractional knapsack problem - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    15.2   Fractional knapsack problem

    +
    +

    Question

    +

    Given \(n\) items, the weight of the \(i\)-th item is \(wgt[i-1]\) and its value is \(val[i-1]\), and a knapsack with a capacity of \(cap\). Each item can be chosen only once, but a part of the item can be selected, with its value calculated based on the proportion of the weight chosen, what is the maximum value of the items in the knapsack under the limited capacity? An example is shown below.

    +
    +

    Example data of the fractional knapsack problem

    +

    Figure 15-3   Example data of the fractional knapsack problem

    + +

    The fractional knapsack problem is very similar overall to the 0-1 knapsack problem, involving the current item \(i\) and capacity \(c\), aiming to maximize the value within the limited capacity of the knapsack.

    +

    The difference is that, in this problem, only a part of an item can be chosen. As shown in the Figure 15-4 , we can arbitrarily split the items and calculate the corresponding value based on the weight proportion.

    +
      +
    1. For item \(i\), its value per unit weight is \(val[i-1] / wgt[i-1]\), referred to as the unit value.
    2. +
    3. Suppose we put a part of item \(i\) with weight \(w\) into the knapsack, then the value added to the knapsack is \(w \times val[i-1] / wgt[i-1]\).
    4. +
    +

    Value per unit weight of the item

    +

    Figure 15-4   Value per unit weight of the item

    + +

    1.   Greedy strategy determination

    +

    Maximizing the total value of the items in the knapsack essentially means maximizing the value per unit weight. From this, the greedy strategy shown below can be deduced.

    +
      +
    1. Sort the items by their unit value from high to low.
    2. +
    3. Iterate over all items, greedily choosing the item with the highest unit value in each round.
    4. +
    5. If the remaining capacity of the knapsack is insufficient, use part of the current item to fill the knapsack.
    6. +
    +

    Greedy strategy of the fractional knapsack problem

    +

    Figure 15-5   Greedy strategy of the fractional knapsack problem

    + +

    2.   Code implementation

    +

    We have created an Item class in order to sort the items by their unit value. We loop and make greedy choices until the knapsack is full, then exit and return the solution:

    +
    +
    +
    +
    fractional_knapsack.py
    class Item:
    +    """物品"""
    +
    +    def __init__(self, w: int, v: int):
    +        self.w = w  # 物品重量
    +        self.v = v  # 物品价值
    +
    +def fractional_knapsack(wgt: list[int], val: list[int], cap: int) -> int:
    +    """分数背包:贪心"""
    +    # 创建物品列表,包含两个属性:重量、价值
    +    items = [Item(w, v) for w, v in zip(wgt, val)]
    +    # 按照单位价值 item.v / item.w 从高到低进行排序
    +    items.sort(key=lambda item: item.v / item.w, reverse=True)
    +    # 循环贪心选择
    +    res = 0
    +    for item in items:
    +        if item.w <= cap:
    +            # 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v
    +            cap -= item.w
    +        else:
    +            # 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (item.v / item.w) * cap
    +            # 已无剩余容量,因此跳出循环
    +            break
    +    return res
    +
    +
    +
    +
    fractional_knapsack.cpp
    /* 物品 */
    +class Item {
    +  public:
    +    int w; // 物品重量
    +    int v; // 物品价值
    +
    +    Item(int w, int v) : w(w), v(v) {
    +    }
    +};
    +
    +/* 分数背包:贪心 */
    +double fractionalKnapsack(vector<int> &wgt, vector<int> &val, int cap) {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    vector<Item> items;
    +    for (int i = 0; i < wgt.size(); i++) {
    +        items.push_back(Item(wgt[i], val[i]));
    +    }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    sort(items.begin(), items.end(), [](Item &a, Item &b) { return (double)a.v / a.w > (double)b.v / b.w; });
    +    // 循环贪心选择
    +    double res = 0;
    +    for (auto &item : items) {
    +        if (item.w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v;
    +            cap -= item.w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (double)item.v / item.w * cap;
    +            // 已无剩余容量,因此跳出循环
    +            break;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.java
    /* 物品 */
    +class Item {
    +    int w; // 物品重量
    +    int v; // 物品价值
    +
    +    public Item(int w, int v) {
    +        this.w = w;
    +        this.v = v;
    +    }
    +}
    +
    +/* 分数背包:贪心 */
    +double fractionalKnapsack(int[] wgt, int[] val, int cap) {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    Item[] items = new Item[wgt.length];
    +    for (int i = 0; i < wgt.length; i++) {
    +        items[i] = new Item(wgt[i], val[i]);
    +    }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    Arrays.sort(items, Comparator.comparingDouble(item -> -((double) item.v / item.w)));
    +    // 循环贪心选择
    +    double res = 0;
    +    for (Item item : items) {
    +        if (item.w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v;
    +            cap -= item.w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (double) item.v / item.w * cap;
    +            // 已无剩余容量,因此跳出循环
    +            break;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.cs
    /* 物品 */
    +class Item(int w, int v) {
    +    public int w = w; // 物品重量
    +    public int v = v; // 物品价值
    +}
    +
    +/* 分数背包:贪心 */
    +double FractionalKnapsack(int[] wgt, int[] val, int cap) {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    Item[] items = new Item[wgt.Length];
    +    for (int i = 0; i < wgt.Length; i++) {
    +        items[i] = new Item(wgt[i], val[i]);
    +    }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    Array.Sort(items, (x, y) => (y.v / y.w).CompareTo(x.v / x.w));
    +    // 循环贪心选择
    +    double res = 0;
    +    foreach (Item item in items) {
    +        if (item.w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v;
    +            cap -= item.w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (double)item.v / item.w * cap;
    +            // 已无剩余容量,因此跳出循环
    +            break;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.go
    /* 物品 */
    +type Item struct {
    +    w int // 物品重量
    +    v int // 物品价值
    +}
    +
    +/* 分数背包:贪心 */
    +func fractionalKnapsack(wgt []int, val []int, cap int) float64 {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    items := make([]Item, len(wgt))
    +    for i := 0; i < len(wgt); i++ {
    +        items[i] = Item{wgt[i], val[i]}
    +    }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    sort.Slice(items, func(i, j int) bool {
    +        return float64(items[i].v)/float64(items[i].w) > float64(items[j].v)/float64(items[j].w)
    +    })
    +    // 循环贪心选择
    +    res := 0.0
    +    for _, item := range items {
    +        if item.w <= cap {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += float64(item.v)
    +            cap -= item.w
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += float64(item.v) / float64(item.w) * float64(cap)
    +            // 已无剩余容量,因此跳出循环
    +            break
    +        }
    +    }
    +    return res
    +}
    +
    +
    +
    +
    fractional_knapsack.swift
    /* 物品 */
    +class Item {
    +    var w: Int // 物品重量
    +    var v: Int // 物品价值
    +
    +    init(w: Int, v: Int) {
    +        self.w = w
    +        self.v = v
    +    }
    +}
    +
    +/* 分数背包:贪心 */
    +func fractionalKnapsack(wgt: [Int], val: [Int], cap: Int) -> Double {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    var items = zip(wgt, val).map { Item(w: $0, v: $1) }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    items.sort { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }
    +    // 循环贪心选择
    +    var res = 0.0
    +    var cap = cap
    +    for item in items {
    +        if item.w <= cap {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += Double(item.v)
    +            cap -= item.w
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += Double(item.v) / Double(item.w) * Double(cap)
    +            // 已无剩余容量,因此跳出循环
    +            break
    +        }
    +    }
    +    return res
    +}
    +
    +
    +
    +
    fractional_knapsack.js
    /* 物品 */
    +class Item {
    +    constructor(w, v) {
    +        this.w = w; // 物品重量
    +        this.v = v; // 物品价值
    +    }
    +}
    +
    +/* 分数背包:贪心 */
    +function fractionalKnapsack(wgt, val, cap) {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    const items = wgt.map((w, i) => new Item(w, val[i]));
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    items.sort((a, b) => b.v / b.w - a.v / a.w);
    +    // 循环贪心选择
    +    let res = 0;
    +    for (const item of items) {
    +        if (item.w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v;
    +            cap -= item.w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (item.v / item.w) * cap;
    +            // 已无剩余容量,因此跳出循环
    +            break;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.ts
    /* 物品 */
    +class Item {
    +    w: number; // 物品重量
    +    v: number; // 物品价值
    +
    +    constructor(w: number, v: number) {
    +        this.w = w;
    +        this.v = v;
    +    }
    +}
    +
    +/* 分数背包:贪心 */
    +function fractionalKnapsack(wgt: number[], val: number[], cap: number): number {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    const items: Item[] = wgt.map((w, i) => new Item(w, val[i]));
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    items.sort((a, b) => b.v / b.w - a.v / a.w);
    +    // 循环贪心选择
    +    let res = 0;
    +    for (const item of items) {
    +        if (item.w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v;
    +            cap -= item.w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (item.v / item.w) * cap;
    +            // 已无剩余容量,因此跳出循环
    +            break;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.dart
    /* 物品 */
    +class Item {
    +  int w; // 物品重量
    +  int v; // 物品价值
    +
    +  Item(this.w, this.v);
    +}
    +
    +/* 分数背包:贪心 */
    +double fractionalKnapsack(List<int> wgt, List<int> val, int cap) {
    +  // 创建物品列表,包含两个属性:重量、价值
    +  List<Item> items = List.generate(wgt.length, (i) => Item(wgt[i], val[i]));
    +  // 按照单位价值 item.v / item.w 从高到低进行排序
    +  items.sort((a, b) => (b.v / b.w).compareTo(a.v / a.w));
    +  // 循环贪心选择
    +  double res = 0;
    +  for (Item item in items) {
    +    if (item.w <= cap) {
    +      // 若剩余容量充足,则将当前物品整个装进背包
    +      res += item.v;
    +      cap -= item.w;
    +    } else {
    +      // 若剩余容量不足,则将当前物品的一部分装进背包
    +      res += item.v / item.w * cap;
    +      // 已无剩余容量,因此跳出循环
    +      break;
    +    }
    +  }
    +  return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.rs
    /* 物品 */
    +struct Item {
    +    w: i32, // 物品重量
    +    v: i32, // 物品价值
    +}
    +
    +impl Item {
    +    fn new(w: i32, v: i32) -> Self {
    +        Self { w, v }
    +    }
    +}
    +
    +/* 分数背包:贪心 */
    +fn fractional_knapsack(wgt: &[i32], val: &[i32], mut cap: i32) -> f64 {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    let mut items = wgt
    +        .iter()
    +        .zip(val.iter())
    +        .map(|(&w, &v)| Item::new(w, v))
    +        .collect::<Vec<Item>>();
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    items.sort_by(|a, b| {
    +        (b.v as f64 / b.w as f64)
    +            .partial_cmp(&(a.v as f64 / a.w as f64))
    +            .unwrap()
    +    });
    +    // 循环贪心选择
    +    let mut res = 0.0;
    +    for item in &items {
    +        if item.w <= cap {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v as f64;
    +            cap -= item.w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += item.v as f64 / item.w as f64 * cap as f64;
    +            // 已无剩余容量,因此跳出循环
    +            break;
    +        }
    +    }
    +    res
    +}
    +
    +
    +
    +
    fractional_knapsack.c
    /* 物品 */
    +typedef struct {
    +    int w; // 物品重量
    +    int v; // 物品价值
    +} Item;
    +
    +/* 分数背包:贪心 */
    +float fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    Item *items = malloc(sizeof(Item) * itemCount);
    +    for (int i = 0; i < itemCount; i++) {
    +        items[i] = (Item){.w = wgt[i], .v = val[i]};
    +    }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    qsort(items, (size_t)itemCount, sizeof(Item), sortByValueDensity);
    +    // 循环贪心选择
    +    float res = 0.0;
    +    for (int i = 0; i < itemCount; i++) {
    +        if (items[i].w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += items[i].v;
    +            cap -= items[i].w;
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += (float)cap / items[i].w * items[i].v;
    +            cap = 0;
    +            break;
    +        }
    +    }
    +    free(items);
    +    return res;
    +}
    +
    +
    +
    +
    fractional_knapsack.kt
    /* 物品 */
    +class Item(
    +    val w: Int, // 物品
    +    val v: Int  // 物品价值
    +)
    +
    +/* 分数背包:贪心 */
    +fun fractionalKnapsack(wgt: IntArray, _val: IntArray, c: Int): Double {
    +    // 创建物品列表,包含两个属性:重量、价值
    +    var cap = c
    +    val items = arrayOfNulls<Item>(wgt.size)
    +    for (i in wgt.indices) {
    +        items[i] = Item(wgt[i], _val[i])
    +    }
    +    // 按照单位价值 item.v / item.w 从高到低进行排序
    +    items.sortBy { item: Item? -> -(item!!.v.toDouble() / item.w) }
    +    // 循环贪心选择
    +    var res = 0.0
    +    for (item in items) {
    +        if (item!!.w <= cap) {
    +            // 若剩余容量充足,则将当前物品整个装进背包
    +            res += item.v
    +            cap -= item.w
    +        } else {
    +            // 若剩余容量不足,则将当前物品的一部分装进背包
    +            res += item.v.toDouble() / item.w * cap
    +            // 已无剩余容量,因此跳出循环
    +            break
    +        }
    +    }
    +    return res
    +}
    +
    +
    +
    +
    fractional_knapsack.rb
    [class]{Item}-[func]{}
    +
    +[class]{}-[func]{fractional_knapsack}
    +
    +
    +
    +
    fractional_knapsack.zig
    [class]{Item}-[func]{}
    +
    +[class]{}-[func]{fractionalKnapsack}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    Apart from sorting, in the worst case, the entire list of items needs to be traversed, hence the time complexity is \(O(n)\), where \(n\) is the number of items.

    +

    Since an Item object list is initialized, the space complexity is \(O(n)\).

    +

    3.   Correctness proof

    +

    Using proof by contradiction. Suppose item \(x\) has the highest unit value, and some algorithm yields a maximum value res, but the solution does not include item \(x\).

    +

    Now remove a unit weight of any item from the knapsack and replace it with a unit weight of item \(x\). Since the unit value of item \(x\) is the highest, the total value after replacement will definitely be greater than res. This contradicts the assumption that res is the optimal solution, proving that the optimal solution must include item \(x\).

    +

    For other items in this solution, we can also construct the above contradiction. Overall, items with greater unit value are always better choices, proving that the greedy strategy is effective.

    +

    As shown in the Figure 15-6 , if the item weight and unit value are viewed as the horizontal and vertical axes of a two-dimensional chart respectively, the fractional knapsack problem can be transformed into "seeking the largest area enclosed within a limited horizontal axis range". This analogy can help us understand the effectiveness of the greedy strategy from a geometric perspective.

    +

    Geometric representation of the fractional knapsack problem

    +

    Figure 15-6   Geometric representation of the fractional knapsack problem

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_greedy/greedy_algorithm.assets/coin_change_greedy_strategy.png b/en/chapter_greedy/greedy_algorithm.assets/coin_change_greedy_strategy.png new file mode 100644 index 0000000000000000000000000000000000000000..1f8b4e8d2b46329b849c7ef7d21148b70539ec51 GIT binary patch literal 30492 zcmbSxRa9I}u*05Ij{q}2cb@gE7EK!N=0Zu2=z|9!kwQPPlk zd3iZIJDZ=M7ZDM$3t6kFsR<7cKRP+0&dy}kYY`*(eP zebcYg+1XibZS91Dy_J=fy}iAz6}W_i#KpzM)YR0-$Vf>^$=KMKuC6W&22)m6mXeY> zIXNjPC~#;$o1UIdOG}H1iIJC=H!(5E9nMWkN}8FO$(g#6m6bg_Jlx&gU0PbQwY41` z9j&aaw6?ZZQBhf1zp=2eSX*2B^XE^0e}8Un?&Rd;_V%{Ay82CBZFzZlMn*AidxVShUAD@nn4i68H)6>(?&`@V*=a!b1?Ck7?g@y0mzptOHokv9(8XBITpFb=t z1O)|ER8%AJ+iPiQX=-W~78ai0o?l!&US3}A?CiL@x+W$jUfn+@ zBqV(M_ANFx_U88KmZDH*cO!Pajs6!#l!!6E7-epp>yK3uvR9Q28(tD3Hi7`T|-pFMSQbPSm_NQDR12L_h}Kkn_S zWX<~I{S3(uCZ;>)0RWdod1*-vkHw>|fPY5}faN@u5SM`eBmZyB(Csi43BW;u(P*lm zuNb_RVy8mRCe7u? zt5YXKdtDB~)4B6~_7-CxE4!1^`$2&>H`#pIFBuu*kTEf>i|5f%`@lUaj`WO&ck{cu z&(6DSG|n$!cZ}=wyV0`fjS`o>^sT%#7Sn%fd`YQVA$|f%gqDkl%8Os@PU8-I{JEug zGbw%+e!%0-^1VoX4$kXVrq9rS^MqIlCwpSc)EBYx`LG{*_xRdUsYj;Nx>=6sxNq_3 zV!F!e*Dl`Z_LYYGr;D$9pv(v9jPY0Vwq$*&B#X+LO9OAHZ;hHphsJN>1dT?e8^_nX zfO|EboLkE&q)(=K;@YtIb)ee#+ElUoTO%4=F&q9}nIf(<1VpNJ-Dew*Q_0vMijmjB zF=NF5<6Jvg#6-6Lqt3A@)zJZb@xknueP^$rbIF3P>D_I+b(+7i$9A% zmk1TqytV1_^j+W2+O(|lsz|`Ds;bJKYdYlk;x^n|C+s(EaGoaFG@x=5H%kdqNps!< z5;d2kJuSy%MrkUVS0vi@=}T#s? z5hBB@w8gfzHaA56XPkkIdj`SyE8MyFhG{ORxrbeWZx&xJ&OdsWTt2P)%&VIgTVDX; zQvQrE4U^I;Kdy*wc5#2eiYPn(8$kRGF#SMWfw|lYrr}>SbyA$zF%+&tnt;50BaeLn ziR^JzWl~3{?3crj3eJgA2#`pgU=db*jfS2K^wmO@0M6czaqxNs?M!2+7DS0F)*fE^ z2F-BU>)r$SnW9Un(vweCk977`f=~6-Z7i=#Q!IMSN9@fJU0bts=FbgE^qg2pW4K=i zQzn2a=WQwoV@civYLw$0BC$~Im66svh$!EFH zjC&EIg4cbSe$oIwD0MFItyNN;o1}^KjqAR+vBHM!+~cU-oW+;+B-KlY|B43RYc{S0 z)3|@}tJB4GU5h5|#4Tr=NK+}q} zxh$209C_wIizX?EV}fckIUfm8a8mYkFfRl{+g64j!hAnqixfwQd0GJ)S&f?Mhuki? z@RDxN(ZN{Koq!OHvf@t=%hzx9b78@1spX~0IW2J@9?c8V^S7E9QDM5f!@5GE<@w$o z9-j&@&WlPh@q{hoIAKJ8+DE&dZSVJ64J7yG_jg2Lu{hZ45j!7011YH+e=Z9)P`9Sg z*G{=B9Um)*;L&y6*sp(K_R$F}edz-?j)xTn=ainh0)rb7ia5rIJXgJyy1{(hP^aGk zhg`77ULKky`GKw0s2z&0w7`l+DdHJk$s;)%-&>=t>uZXZr6nCi*NzpReWFx!V0=l4 z!KnqOAoJ|&K-WADY9CR!bzI=~*k(+hAV`)s(NU_-V=^NhS&X5(mLGOEFQCc5RQyd4s-?<@ z{p&tHS)V#8r}McOWrOv?f)#PCKPxyo_NZm1uy4xYk3w!eo?3wCO(COStJseU6Wzge zNr+o$6Rz-BKe?h)8QN*9qGR4%79Ac~8GXvI0kRioNAfoQJMJDb*|muF2hT(G2_TLO4-?Itn8t_9=TXg1_A_Bj%EwTa`d z7JdqI>C%t+Ew}*BTU(1}!XK*?2Yw%3)sw+@1&V0eqsu?a(aY+R+%fp07&35UuV?am z-dHdRkiv6JOm`kWD!FUmr`p|Rgnj#?Cc)F4_iu4l4Nk-+V^93Zf7Du*#U}B8=;E-@ za^gubYlKpug^z_Fn=upAen7za$wSj7cLjo4y8-0yn7#lNX2OvCc+2PDKJabpS}gtV zQ~SS;-Y80bbN8)Ki=*0UntZbucX2%U`}s4YBO<{!c?O`?9*!H^nTo;_txTOfZsp9F zidHIWYV4CoIZ=`5^Nn;;_<<_X{*f%-wXY?r5+@dDKtI;}2XfBiR^V+)OJJ!asxBJp zQ5mQlm$+L7#ezZfT}-p>^1gc~R=>CtR(~xO+**3}m#p-37V;T)dJD?==yVY#Zex)I zciGvTl|Z-cxy~!zBSa5`hbO;-VKf?5z~sOSGqB8d2w;paMTu`?@svj79u7cR=Zd^Q zFm=h^=}IHjNuoU+!7>b1`VBBi(Q9+n&j0;8ddXT{O@N$ItZ7xiaqZeTTvotlOf>fn zY-vV?x!dP!mIjGJ2w{RzU$}F@~N@QW&y=f(_#(5LHw^VDE4z zkVrkftKEwmHvI}GV)PhrTb(-h07UvsL&(iGH=CI_VNv49B$JTT{@_thfI43rwC$th z@%PCCuyu3m6m*k4yFy*6Me z%o4=zI>`lTjy-BPEgTz+JJb#T{S{@RR9D}|T|pPD5N@(9JZ?8-jzWk`Im1nZ3#W7X z1}e`d5~3Lk;9Mgz>$&|C1W5h$AieTvFF{rbWCs%1Mf47g`wGS=>8 zNrwf45i@M}kae6=wmSdHi9TD`G1@j>izFL?V{=gqzy9cK28ifdt1$+$X2a z?X&>lPd7-8bHtboA~WR#36iSIHwjZYC{O>hL?&dpj~zr0Q&fWS8M0y{!sVqC->Phf z#v*Hf-dzs8At!cpe9-AKD!8$AQyCL-^8JTtBJBw5Jo-^DLfMUS-L964|UH+ zCx}%*44K(zS{PXnd!3&D3vO^3_bkWXn#h_q(jpmKdN=nN$!10BN~t)UmAoGwXk24fMbXZikse4O})@hDS+)vEM~sne6KTO+}!h3Er|b*wmE@$}~orAYewo2LcO_98ll#!khvjzv|0! z@*5u#iwAB5Q<9~D8(;C)pT*ZsL}AWbjE7YjSXV%Ynbg-Bi{Z*Zl=Yi0-kRi1brnWF z+2W$>ZN4!gg{@2HJdN;A2NHO2f{8k$xFP6%06-Q=qfH9aKxdkvr<(FTU_IkD|BK&L z{4+T)7+n#VBja{h8U&|w8wb!Q>3~+_QF8V@-Fz5#5v#Krj>2t7$xza^HX&tj5fn-a zisqc)?88TS)fF+s2`yzQ%V2&tp1h9$nh9tb)s(>m>+F8FffVkbF()-Z(xEclRy??& zOI;Cn){00=MFeumHA7NK5TYs9%1RMpygr4jcM*a{a6EgdNz;%WPV${$-b$ZLhDH6X zaN)33Uh%AYySfUipQ5H@S>r!nbHi$CCAq=#pwA|tBgm&&a50}CDam>0i8O%NYui+% z1!$mM_LqWa)5j6`-0;w54A{7?ZFcNvRNLtTS|#@FLS_uk@(f~`AnM8t49pKz#B!3oD@rWRRWRIEL=E= zg9s742_X9nIQN(}eCV|MfIN|iJ>7jIf{4WOBRVpFX7`))Fmt>W0sMe*>=HmSX4Clg zmBUr-MKA1I{Q464WUQ!)pOh@n(quNwpF@5d{R?lt2yx;U9^8iM8!7bfO#FJjFI;9u z`ZczMjN%U}6|Fhe+8lOSWk+~usv_a*+af_nnx2#yBrb*UoJ{T2% zoDWdJPAL)3WGq5ip$ix}rv%Wub(JTSN+P&9N_mVHQX!I>&0;8tQ$}@>V!!$E;QWqAiw+bIw4CfHp)fWTRRk-3^O2yBPN|n*e_F zgVqRjo$VFVi)Vi`6=2F~ODf%g*TY!e3HJuz+6D{ru$MAhaLAWckAAUbd(vB>55 z{`{Dge2+YWMbi=!Uj8o%iccLw*yy-ugOB{LzR~P*aN%}qZktiP$GZfs15yqm`(hYj z!|+}Wpc@T9{fjag!VeoH=W76nygl9(uH|T40YrGB#pxIXephTpnh4dQqiLW58R{e) zhWFTp{K2x^v5}s@o;Vq_veObD^tchX2Kw^v=4kg`n{Pg~_gt(8yhxUA7Bo1oqZR*Erk zod5DDg};^!t&-#W)I@0Wb~9vFtfsi8A#ACMpD z%nGvuKqn(RLFm0M1O*~b8|m6;co1NMTYmBFEA+ayO)tG6jqbpj#7cHOUq zAdn4U_LJ#V9?YK~Mw=HzbAHoS&j{%*V1zASD1n!MOje|0T%MdCdI4rrVlBTMkkLY% z<5qRR&0GM{Xj2ygg9cqbar`G0NHc@txD_ibaU|fXI-Y?udRaW>4X+mBD&8DFQPee1 z{xAKb&^3P6UVrzeD;xP%#M}KkLz(Dlie(s*jY}*c&3GRgaAjul551iE0zhdh9M~ zKW%@}`stXX^y@&9;8#h~>CGwv4Z>raF|MhX=L^?}?l&MAWNO(ZPe7QC5NEbAfNaG3 z+roK}D6Ybf8Xk(2Jm@bMDtoQjSp*mMXU>`W-MHgSgQ04ghJS|Ny` z$l|l@;^JVbEHK=~mG%!`luaCAHpgvNTzpP36sWdatS8-*+m+uHM%iI(=~;e1Ss}Lu z_g7GjhI2l1BT5-7Eq!s#bRztJnV88ctGz&yXj5E}C%;ncixWkTNR;OlBz* z+1G8|Jx&usCqNlSE&Ho?LcjUrX;W=>v&A**``1+P0z^2?-4kAwTPy~P{hMjqw?%1; zsWqy^?1D;7I1Ms^D4*S6(4Am616wSkqQ#&*iGFV{KLB%fe`0l?87FIh>_M0B1mqyA zpL0w#4q5hvx@^tvTJVKgtM+7Mc4-{&e`XL2fOIH6%*WYNA^3DqX6KCRLohZ6RnhYb z#zP0hi2dhJxd?g`!q+xqxA>I}AO*i#kT7m{t!^lm4tw4!v^kMQF@RGSQqf)`#4WJf zgd;OBAKicml4XL0iH6yBtS4eSq{8|W7$`zQ;q1(Z;z~W1+ZbKXKUs2F zcMGW(WJ<-273f(B!VX|5^L4UVyvk1Cz09!M7*B(+ufPE@b`E4f$Z|F4W_sbg6j|!K zxt6c_QGLx`^_~oGJUQT-gqA6JIdA|{p~oC?&7@hh1X?&2v8ZsI-Ro4b`vO(5I<(f( z$-{)b3`09Tjux4m`uB*YJ25osR1w+b*o`xvA-*&xG|3}U#2|J~CI1o1c!y-d4||Zj zJ?UWximwosV!FrjpLUhP-@@O2gaCFkCcT7}*&7w3!9x-Q{l<+x9Xcg~?4(U}%a}rm zY*I|(#`D<{HM$D@n(1xj^ZaV%XAUZH)UV?H{|%$PBkM|`OCP+%HCie85yP#Y1WISZ$-23HmkfSm}E}} zOV0+>-Bo?+btpSllHr_E%0KW5RoRm8wn)(r8J^0v zL+Rw_#?=!F6#uHk7aZ$2?Gx93{Uctiz{Tn0$qqr#Y z{o^ECqR>omOyWRubn<9n(54>q{K#HoM?A&;lndieBUMzgTYu{gx@!P12O;^f|EL0P zLtQUT%Gd18s*9Z^dJw{AR)P74_!hMFHahZu7;UrXMZ~eJ`}D<)d+ZA+Q>^6opECL1 zOsbxLxz&LHx5x(ZJqei^*^91O=1t4Yr2McTM>LuVx0>Jjl+A-4gmA%IyoMX?7K7-b zG@;CY9P^shVbLdk@1JOfKTy{_`NtwMS6g1epc%bLDfV=BNN0P4G`tehwl9*w0JwsP zdPGUbxv@wC8g}p@H!v98+C>y;QUJsEl+i`z`=N zP?6OKB@V_vPm!a65O5F{?0&q-3|qb&cd-*#`}RvoL>Y{d6V)?!*K4iPMr6c-2U8hX z!+`=DIH3SIEK(2w2ddliZvmThSpUR{9sk*A4tooLdSocTVYeE@3uQxQk#9ow|Bc}$ zSr;Z#hjSMu@G^NCl$Mv`;QyPxsj7L{qv6Lj_?a73cKcHYF0_YEhfMuWIS(h=A7ee> z*DDc=@+AR`;Eghxb*%M(nf*a7C{%H-17VHUeuJM<7(qV*!*lbuZDPKqeDd3=hQo(G zxiebO`Nm6ZLej-2H-{eXZq4e4ln%X~&PQN}*1-Tt12)uP^c5?-SV$^(9;8z|QnznU zg}o-}iBKv7ugYOY|AhQCoj}@wpYj&prwy&D4IY~F8Nnrox$f-!Q3@0Vi?v3gp4<2I zEee1Wc=IQB0F;Of*Bpcy%=){Bn(YB_A&XodjCpod`2Y;@MgthZX+NzBb%ZB^TievN z`qK(&a#NcT`Mcoe01SxP{s%bPx#!pC9=}MeqYY95nY&J-{jhX|qtc!1m~=v$9Il5Z znJ3hE@Y;0_^N>Hrsii=OZLT0u-xf+VH(-cC7gGh}NPod9x<}u5QjY7mS?z}6AX4!` zScfFKctijPUFTQ*(2pyN11)aaYx1AmL6a7m0$5Mt-alaS=CPpOVI; zJyyiVnY2IC`JAX8B-&p0Zq4c}7d z{&c}VoLMMxRGuhdeJE*`)THPajqD#z(Pa1dO z-(tkXuNZcvls3Wk9CVE*RnLte)8fi*_~VtQEiu2We5&KSBb)0ej~-*H;qPXhgM}5^ zP`g2DR%+&FoiETpjE;ApYWt6Ly>BcLG){tUFv&I?JQNbBBbvkC&qy<)jR+XlJ{xe+ z1aR=7Wq3|y@X+rKrGbeevQs#L5b=aUKlu))B`$$ZN#2@2n{-daMKi&IN`nn}-?7b@ zkw)q#y@-v{B(_4H6{n4_kyIYtQ6=dNt8i6XtQ^il@0{Im-e?3PdiXj#vU^ckGyO?Z9Q!YiV~j*O1NCZ4+eoD zKgj#MU29BSViedYVw^Ob(g(|X00l(D*rIbZd*EVIEuI91ibbwXD)Ic4FAOUC zrbRb;y6&d8)X#p||1c(!wwsKE#_j1_c*0b=Jl{sTj3ev2rY0r!Tcs-LWk}}MzeK0W zj+p@FU|(p!VKA)D3bY7k6N;VXPP4wURDFh$CW9L?BqLHckOVe*8A+KzH>v;_!nmHL zhyIHvJ(nsx1>~;@Ha~$WTIV1V+=Akg z7S$DNG7>xdt}QQ|CRTu68Ed=Pu6f$JnpgFUW4os(&(SND6wq4C$IkjjPAa~tF2%QCda|WrYsk#k2x$2!-S&5LQ z`NR_#D#l8F#U&5azyuA45wEx0!_hjj3l-s|C4y79=kQ#$)38l?zYZFx+k$RE53 zmD7MPgbOJ1bN(ChCh<|0SEOfL0?TLjl!&_Lr&UT`H?sw?YYI`b3H!$HFIo6e{Ir&F zeAc&hVMd^0$C%5wv}Wl!F2c3;>MyL&L>tW~TQB6{s3qcc#8}(wl<(pSa162PeL4|` zwND~c2;9oMKe8&_8@{c-URpwr?fbss3ZD)JdOsPO9tNc7P@Y8;%Yx8PBQS-o}X zFm}tt*GuW}jln=UCiKq5&h$aA){pr471 zU@Xe*S;O$kN7s|yrT_k&UxjsHYq=q5upgkg2gkHR_Q}M_;UgMXdtKR?6Bemm zL5#D0PsvMFN9P;vA}66R5}N&SN$d=fkb?P+h(-pH1}2e!S?Yz%-r*%73(;l4+=&*D zW@rOqGphP$0bhQNGPB#L$#7}$Nyt$(p7Rs)wZ^`*CNEp61w-|fR`%AgNql*0#tKCq z1PL8Opz=0$S9xh)y#k-;h5a+!jw&lTbdI(qOgTlkwIkW8w$>> zW~?}s9(_MI_2Yv2SQTrS zB@7j4Zz0SdBsX6{)($?6rcrST;?whl#2tZ;KEd>jT`@ikCL`WccJ$0gqmSyJ8Mcc> zX+|c7cm=HSPp?d3uGi5;)l;4-vuuwiFFescgfAw1QP`U|Y6Ra`{U z%$oq);PI&(1YW(sGOc+qfb`S{#Y$9e5;ga=e?qCI**sZtifD3Y`7lrf*Ye`kHv6b< zxaKU|sgTl$Q&Y#n#R_O4fzMHfMUD_hJEfBV>#n# zy`nFFs{BQ*d$BO!X-#d&jVNxpD#8BB<2K7F#Omx^krhf2s-o(OuP=rdPnaQf(}?hC zp#g~Xi0YLIqjXIYHXGhl(hU>M6n0NtQw^e1P`_^vpP)KcW^q)8>ROqd$&D zrLT^wW;}=;goWzHZB{sh0NBZ|s)jN@eqeT&?x%#2KE@Z15$v#D!rk~DNH9I7nMR;w z*0jwM#Kf>VV&M(}qnbZ8aPkIpJhP=~$v0#oBDsMagEc-)@&RaG+7o7=_`kY3RFN5H zGpC4s|6xPP^TJgSLI14eOmm*Zpa2_z{RC0mMO>6MRP-L&lHcdGKCen&wc^t4J7oJ> z^SkEE`%<3zPgNd!jSu*R(fSg{pO9Drh#Vil?*of}lRmr^WK2tJM$eW<97yD=4w4Wi z>H9U7_{2xTw;D7lANiVLz@#o4$vHs%yU7FQ8%4BFc3&lKL9mS8%zZ^4;q|*s^vOpZ zD{tZvVpc)jtWI|1cAxim-8Nio8mhUDNGw7tT1jQeC)H2tA1z$ot3T6US`DE)YyLsJ z>=p_*w3I^j3FRT7RLDjJ&$OT2mzR`dGsd}M_=s+$HTFS|ILCVo?4koYH$y)jJzO;m z%2FM1Z=Gj?J1P}Qu$l$2t6}v{Fxi$Kcd7BIxE=@K=X_1uOhY><8?usT}9!eYx z+;3`9vm;0cK3tEHG&z!l<>7b3acCq8*|Hlzso+E0XUG*&EvvvauV5oS2@Vq;v+*o8nT*kKLz$qvd{LK)?oFDsRN{0n1 zTH;q$f?dm=Y`b`xmN-Em6%j)-#7pe74gbmU#awdpcXXl{ayDaEp-LtL!|WoqaM~%d zQjVn=|8rQzXLmcRT<=(pLfA3KbEJ+h_Iqte<-#^sG+V6+Y191fj4`?5)?UkBwc$Le zXIb{zRGix%t-us( zts!4Re$dQN{E2on@%0U;SIeFTU*( znm^^-qyjv5QL zzifyCgspx~z6=RHOS*e&1|08PNxV}d*x~&vaxcX5_U)KD;$xJn&EzjTjo4%9!|3Oa zW7CHro2~Qu!JUVNZIkb-KccI{g&5tow^xA(i8{cBRL&g#nBCkX>q%fPAz>`}ZyUlBw zM{O&aA2(R{Z{#eTBDw7)CK7f#z4y*k!XYe&zd~`sn1druy0=wxBmz85S}&qc^E)dK zjWbT9>4elyGM*q4D8)0#XnYx>eJ6+Ed!8a07PkJU+3^5Bm^C{byC<`T8u7!GM{e_X z83x~%8*;#)1V|e1!+uS)*`A-@dTZcJF#l|JI_C8)>=##zM1S~clo9wXaaXi)g<9_l zUKhtAD_MmGJ)`A}8mHXnEv+w6zsbKS@o{qdA$JD6@e{EiIavQ!Y&+l@KP?x|9;33V~+YC@_=xO9oshK+yBffX%1t!_wZGfD=|A_Uz_(b zJdD0a+94IbU+)U~jzQxZ;D_5X{MJABhp_Np!_Zw}t{*8TEFrCp0)=^ zzJJm`seu|5C2t`*EH4l)lz!Kp9R}3S7~C1pjh9fP*7QXC?kCY89=v-;5Blmc4X8i< zxhYWt0Uj>zXa=o62gX{RJHO=*^#W=R3`O3Np7G)|^o@gRv7o$cly#2Lc=ZTS!Fm`2 zNZNUm6+HQT)h6q?270mqURx`NzWS#taG(d8r$M-Y!0b4C60|=DPG!?uty;j+B!S-B z%k=f%du`ZjkFXS0FkI)=cX7h{31yyUx}at^s^dYaFK?{a%a zu|8*gj*l{L>jkDdlhwBR<|l%|Tzc;6DY4+#9!+FJrK^*2KIr8GsQtjNC1>H92X@(1 zKyEEfO&udNy5vyWX)%3}76gn%9>$|?_iAzlfJ&0xtEf}g8;~yl)u4UOU1Sy%bU{x3xzf&jTK-y=&Yf0DKYAX0=$E1~h0o~*`YitFu==UgxukrT` zw?eco_aGiG)rH4ZmE+%MDEQ6Tj+UCL?zR?uAA&&zF(c)EFPS^RcBQwi$^II0(g9bS ztOWsWQ+OcjsRY{xKdOOnHhVB~>{zmM+s6-@hF_#p#m;$Q?-~S}LX(c8c7=L?sV3u( z(KSdgg$mY~e3tbe^~^MLMDX6mX3VfM5=4RR*sU)%8D%wyDzt@vMJLk<6dGV{w_Js2DUotDH?O6}J71{QeKEGh^)q>&?RPg2FAx%`}Z6x<0&X zM{08_RR64E4%r!YSZGlQ0lwte2T|0ng#S#ID0hZYyp>NcErZU4{KG!Oc-%bIXS4Va z#V?_4o*Tscqa+lC3!^Vg+^~A%z5+p{s{ke9wIT|BBkfirk}`^~xvw~?19S64F=#mC zwc1{I8S<-_nhwan+WmE^I2$M(CxKemoKGd3{_f^9U(~;O3d2G}rG^X~Mh3Dbe`CBt z>v%o!wz=4fv`l!a!j412m$opO3$`7>RA7}mKL;Bh`P6EQQglcUL+$juJA@+RlOSpD zd}C)$Me5NyElE8~LmlSocoW3CL63i5N;o;$`yjD>gBR!Ci8%AVg!4V$dXwcy+1i{7 zdPg{8=TSxOJ33q-KCIIJCrbi?>(5VGcQnJ#h#!vrEK`vEe6zP}d={P3ImX+}_lOg+ zs^5vyQFv(3j$wxq3Kf1TI_!T$RKEPPymYe^OCeNiKAKMduF>8fG?EK>DRK}t7Jt+u zS(~XcfnauEG99>ai#AQ)Bpr_%brDZusS6sU7!=O3_-9?uS=7L!v*$&!fA>XmVRaJD z^U4O9zKS_!$mrZQmK$I+({X@^9hC%ADdZ+f6(1{B;*p5BDtKiPep-Ry=@{5ro!*Bn3GNLlJ3e>W2-p%*YR{!iw0EX_5K zqBF9+QD^wQ#{CLaAk^Jq|ATed>oLgYZcR!_ zl81zQ;vl(jAriZ4{6#9mEftyb#XGt)4wF`ruEE(R zlC-H)cgFn-9_B9MRr{&o5_SoD)`~qUVVm~1`9YCbbWN*M4|gJ+UwPG)^*UTWBAvrl z=Ia69{Z_Nj>apfUo_LYO4^c9yfSA$*JvqDh=X&=xNXoQ>4gXWH-4T9W!}`4ueZY7Mh-uqb8e++mNkzfcRnoxy^*xT5_#H>%amp&9k~Q+MK;eXeOPECa;F!60wmNj{NMC1#;o)iN)s)H&n}+e-&@q_nkx&>P|hFP8v5Gq}f!V#L?ted%Aa5#s+Qj8>TIf1TL&-)3~P~@YQKcE)uby z8MZO~*=@1>6N;`v5jH&QnZfDaq#P9)UMM7JTM`^7TglmaPwK(q$g5sMoY27C!p<(_ zq~Nm5%;qxSteVHfAbL0u0X={ousIP}9PEna$#}z>Bs=vZnG8%u?mIDx42$)Rppum) z@J+Y#k0^c?&#TJXdkfFkve>gUuxF! z&IxwMf5DYGwf-R8ZBc=ejk{sTbz*YJ(6?X)yD(62MVqJJ!c$QXDkwWZZ9Y( zaKg#ccC5h&xh-6FQ~P+jEc7$-*=yL@)+Io{ znj`hM(as;l&aUfrHd+u#WF;OG+(>%yFRC1T;?T z1Jdu)ft&cdQU^559}H*+f|#;yfx+8fyniP;c8I|MXQi2^8@}`Wy-QWOl@^L-`_G6% z`t0zaAb|aVN%)Hmbr(89F@MIAMj4GhY)M{pr=ZjU??dhsO*3C66OzElN!Bd-6Q*!Lk*a4N*@=qt|dMyhS1L1dJypu)h-T)+-qpk!D;fy^W^j z+M2*km3>g}$_yfj4qtR*(0~kq z2n3IW=t0P3IR2s&BOKSP7n=o+Ej_cA3Dl$)|GfBoSXco_s?b0y7J9P-AHGO7rpmg~ zVzS~gtFsfWANkgGMFuHekH`A?&Q>yHZVx3Db`$X9_=a^1EeZ|&7BIHRpmR``F>lY8 z_W5a(-MO8ZgRmyW#Lf<;7QiACxk(DXpl+}O`{Zj*6O=o+HGBXadxGp(RNGo%ZY7*( zJUBTUU0ugw$z7JV&GZaUtB_UKhrLRHpl7 z#f24G0PnSU)AUE(@WZdabF&l%)aq#-T|!Wrx`K<*aZqDzxlMu#wVgTEnJ08pU71Iz z46aA#HE)TFu(PJ1c(^+}0@_U<-X#V~^)RMA<9Lg$5|c z@^=R!x2J7Y#WpiP^5Gfnz|MRdcMaRHp1D)JxxB?UcB^+8=BDxTpDdW-~uvuao_T=6p_st`MU7Q$EPUIcfK5jC;zO*|46PzHXe$iSA2A=Y{ zo6=AHO9~&)#gecISouJo*UC!8MFh={$^XD@-&|MtdjDY%<`b*iq+ z-WX}p0KI+X@vh=>t;t{Q4#!!@;o_u#yJF&`k#nzZ+Jpy$s6Xi1=H&O+i@3~iLKaNQ zokFL7bb4H0#1?#W4Jlc?Fh3s$wVF6OhjRNc-NoUrU!?B;*@EpGby2Dgp4f4ih&#o9w@clJhSQxcEC^NJhsH=E9bLQXJqb?4Xc1_!%>y&TFK&6-4Cs`y! zPSIT*&fm(KwhW@oXbeCp3CGGDma_6@z0|2k%+2^HdEbnLrL^kvNP#F0{6?&|34cR66Ar(6SGkTp3ITZDKJgXEy&P6iTiVWH4(su5=+C5h} z+}&h>r$()R#?p0gt3j1|F*O_yHg8xgaKf9-6{3`-^)Uh{&@KfAti#r|sfUeB8871# zAXN{ansG^Ke~n0WE#ky0gQOgmXBRMh*e=Qp8`HHShZIIq#0g_amy!@8u}&)0!YN2- z4IOn%`6<2>L#ogg%-|YL{;ZjQ*ZyByZy6QG^MsAgF76iGA-KB**bqnv9yGYSyTjt{ z8VK$hoZyQD2`&ll?k+)Je*b&Vx#!&Tew(hYs;;i?nd#}Sdgh~h+^?hf0Tl%WY9@_y zT@W@ z-}Mpv23;cH9(_*5Z-dmg(T{OJS9gwnF8nOLSbQE?s}_yN@f|s1RsuqAGxj3Mv$qJ9 zvjgJ1*L`hj+}ho`Bi;*_KHQBDN;s>Q!MdcZAw8}i^HHxXIx?~0Z*06)2{|)+*soY6 zgpr}xg#*Ms1(P6y@ch|HEHGsFN(6b9hf3im79gsRngt1(HP%3BYG48FVLdy?TX3Yp zYkcICGWqbXXKMu)&L}M`y%IWe*ZPd6^D}K)_%mmQX(#*zmbZK5q9k^(<73+!0qbR} zTavd?JzrfIWK|P#1;0T1NU0|EFu-_ptdGKyH+_;|$9ZF_9Z!JCkCi?YW z<~d_NhTNGMTwIqT-Xvj&wi7&rlk{*JATc!YzUi5=dawEl6xPzd<1ssvg!BgkYSx2r z2SY!9<19X)7olN!s)F`)4zN%dL*LEBZw$s#+E59K3et$KTvMPvTqI+1_%vhGR{0fz z88GAB(9^w?gvwZ%5~Sem*HjF>@Mg-bl>6y({PQjg+!(EwqXyfQ3j73ht$I#If zpyvBf+ge?LxVQ7;@8|Zks%`EBaWQtD4s$nzyD}A%X>o5B3*(aqE`w?=Grpe|Rgd_$t&q zHV<&UzTz_+#<{S!p>g_;q#){FsL-N&Uh0i@14IG1+BJ7+|YzU#NgBsk@B_&7F( z&sw;RSQ_61$8xqJ^IxRos{H%k!HHXI*v56UCUGE?Iii^AjY*q)dXj$RRAfa^7xZ@m zwlxe1sc3NsqvU3no;^lTTGC+R0{$)=;?Y@-^4RtKGM|r zMH1Y2UosT-sr|X(=yG)??7BzAS@0O|$e}WTT}2jNnD6@2;?xIx1u6cU&a6HB?x#*tO}b1c%34uW_3`nE4VbaKZKEwm@QJR1QR0zSg) z+S=jH9n>>=z(w6CPaV#L&yfAonP4aq-d=haNN$|M)@rqvLze-{4Arrk+ni~51L6Z6LdL?&>7LP9?- z9@%19J>pXKd|{3wGV__@B2T12(X3Fj8@BOPW3sLF`<51Yf7*lugbCJ*$KJ2cS5j*z zCTU4i)qVrCv}n2A1G9nW$Q0YEI=jeq!Bw3FiLac|IB`@}zMDx22o75-T@UESAL(e( z)_!&jU7`_P#&tYc%F~AT3O>t)KGGBt8RIr*%qdxh^BQ(HC^z!w$WFU2yKJ0BHj)a{@Ifnhr%zeOuO$!H&Sa@Z=nfE?cSZ_Y6 zsJAiV4Ka-IJaqGU{sJz2F9$CDzBq>5wS>#3I))66i2BgzyVC{f{Krx3hrE~wpxSRL z0~Af7VX_x6$Zu87)0O{%YH%F&7u}$+uWJDGzuQ|EB?pk*xsu8PMI$%5QPa?3Ys$#q>QU-ulZSySPxkJ6NZ^Q2Q1tshvc1-f zPTVA;f{CPsWVoP{@wl5_A|M*=vTr>AA`uM9{+BF!CxQ{VqxbiF34UY1c3Qg46vq-w zgbp#`L!98Qz#R+-CxWoNRruSyq|A?*+{ak;_wGQp5BNCi^z3|mru!QXyDc7qKX=65 z7e2=p%3;2rWSs;q-DTRQ(R~+>GUT*IE!ZUR0Es37XmR%_z#SP0< zb(_Y(o_s<&`>5zJ3R5H(HUM_FnN^(9ayKMHv+0QqXs=QhJRvn zLDh-hKB!T>h=%S@!X{&7c-R+k&_SzErY!Q9AJ^(Yq(=*j{mx>0_!GWEE;M~7k9I`im!AKol|~}qEPDU1_Q+9mLqPPs1-r|sh z5n5xtufvI7&8^*2d+{S*+Qd5adAfi5Nf@zwS({GF8qkUgKcGLuHn%%){A>opyWz;V z)x0@IF8c>ZJth>DdljWLR3a^@bv?a@N9?(TMi#u!>-Lo1l|EK~369WIS+ebCqH{tQ zgfG+&mPsV7QF^)$Az}1c<)8Fxsoy04mGN&*9sklCWTZ0meOxNLdXbM1>Kcx?+20VE z;#O&#Mgq~Fie6(^HLeC*4`JkUdx`kB^4fPaJ4#x< zzl8<97$O@h)ubMg&X1{CHNApRLVvz;Rckik3o}fd&*J{An!#>=bD2=TO7G$|qDtl< zyj{p789whwO~Csa{v*f2#o`N7Kj%wcN5$R4o-6mo7SsA8pQNxr-oLlOrQQbY^PWOc zR$_jGxct8^H1^jT=qG2pn3JjZ^_Hl?-Xe$h?QS8b)Vr2M`HOedx7JO>sC{bstK0T^ z>S_q8YMQB=F@Q;~sO?2kGwgQeUCJV_t2(R)MM zg9#kha^+eo*S!fv7+9qb`*ci&se>uxxREpTM)^%Uz8BvIg8rU^h-w@ zG$y~Bf5=n{FA}lAgQQ=ZS}#96Qq&wWP*FfIB0hx=Z;%GG|5CIz81*k$azZ20=F5$z zw6#|wWrTf4Ea0Ef&w}kqVQ{{Ue;Rnk=gnP2c5J7gBH$BWh$Jt+zGB$hyhNXGdOJ5S zt>8b!l^#(E!}%I1nH-^x#AQE_>f~GAi9T+I)EfJOtbeZ^)ceI(N%AE%^?UVMdw)Di~0|LwrFC=3l4S1ho8uM zrSDv)C~Iv`2gwe`{pHe?lV*@vue)exC^Hnk7(8cWXqFi_j;rRio0+nxPA-rj!t8YKERrf4M58kC~XZVX|;3jK9#BR8`#CeXgWIFlm&vxoIHq&GgCnw8J z2CBa^6C#&E9xDsa=jT;?1ydA*t+P?k&M0W6jJ0e&g4)*5z;Hp>Y+;M~N!1&!dR9!J zwoBI%hNGu1_p#Fv{*9Nhpv#X*ioRH#1x7IHZT%O4lmoPhOmUW#IuCV$q>APZuJdUU zGZ41BpgPx>izi+>BJ7$EzEyhcPc#&xV2aW375ZDCm`nusdKBwX&@>jXQ zRByl<%JWlG*RWU(8W_1E#ndl`UfOJjzTY^UoGn6*HA+yhPo?1mD2``)d2D)_ui9^; zdVn0ZeQXT>y)cbw44^1`$>7= z!#Qk60Z$n_%@rr0Bmm7cg>FLxWG9SIxW?ty5(%U{tDf!%uF_%_G0Z5$kfKAAq`+jR znr9S1@h=JwqZ%fNgdj$N*>^3_LysRpc4iUgszDk2$M;{&KHxNplnjjj)> z&=bukj;+H$oFeTWo8ck!In_Q&v`NTWiB9~llcrZo@@`MHCQxDAM)A#eJKBifLJXySZhe;^m)vC0W)hIK41t_M+i>EaxXZ1r! zt}Ut*v|r?nYk+;~-U-Io15Qb>B;Qqb!ag@h;ex;e6%Ze34wyFrWfx8VpjPPiSRuoF z%@&v|Cl2eV@$AOC5##-5HIT z{#UTrs1n2LxyTqKTHs_ zX_PDjwz#k5F+K$laPY2lL_LCCHL~j{YdC5eLN?&9K7wv0onO6pQvFxm3!Bozp$cna<8lM- z{0q*P^I{Dg=gA}w>_@D3$l37ku{OGco~`+_`t04cR5HIw+xX`M5jC5+r5&65|M>RU zOF}iFIi=@}am#d8^7;`gX`&z@Qa<3SemzI}`^5q)Sq)C|!5zl!#qP?s=C1!^pc-Zb52D5Jqycffr3^VaY#`&c!YZ=%;X*2IF*e0#~ zU~OsBppy^Gs;7!{(e7t8erQEfvEH1OvD7s{mmnP`Nn?eWN!R=$HI)5R{2s0h11Y-7 zVg7B766TRtYxa^b->;K%K8cKP9y-uD)LT8Aj)|!PtbQ_s0A!_@VGG;Y)Yov9qY2&5 zbdI)H6}@TZUBv`P{8hOo-G;ZGeAnyM5zf&3eLZM@UH|qT6|Z{$A@McAv$uAK;e>RU z{#qat05$2Qhy zTI8s(7l%4L_PlkTYpdv8`9>1X)yD>L zG$pM!XS4-qiG`huQv!CrmX%0#3J80&ReT7gw=iFl=V94RN!ToZ3EbV>yg<)X4OeR` zKYBh^oOS7Y1ms7Q5<|9q1Yz&#%FA4ZSI`tI5<-K#B80@RX8@Q?^KbiBl><6rzM|&` z1vLxcUcl-DX1j~&c#~n6+rUM4%)I4vgf13V?C>GkVgM6SrJ*;Ggn;PF)o@sP_y(4K zC&nTb=oe)dc86CE%ES(5aH=O~cO*5;xD5$sy>Tlpqkx{X(7M6jy$S170Tt!gMWuhG zsGG844`j|F8&=ZoqV8t*18et(dv*G7M%s=gCx#J03Xgla0FZ^V$0+~bK5=48MC8jI zvnBl;66IdoDL0}mm1Y~i10khH`2!Uf#$E}VfyuCHaIt25n*nmoUy3I8gW)8F?E)j1 ziNUdq@6WA+6gR7l_3Nf-yx8C-2M)5(K_1f|wMTb!M?)putisLqo-0+0s`A+2*nr-P zs719^(D%-o_PUww#wwFdcBi$7_LrM;@@hslP$wg^3$iVD)`wwPBB|P=fL#2%Q_zAe z%P=9PQC_3ENu z&F|n>ibCch@jxXKgHSZkk4HW*9b}O<&m4icCd9ic2X#OcyLhU>igRu2O=M({_bze| z^C#u|mc4pW0v`IzbPIY~Y{U2|8YFh?P?R3eDR$>IA3->?XAV`~f5{@>q=XNDZ>;=7 z?CXiyh;lg}x%6q}2T|R_Jo%koWZ|b7>%#qPmKJ9^IdH)=a63o^JoumZrYM~a_u{sc zIVC!GhJ<`E3LRsVW0GK22zHb>b3bTw zv#-UTs02`r(wPhDED_cjT2gZse$Z?Ge(zz)jQzQZgIx04o7*}}B-hIW|3ZDjB#c2D za|d8P_e!QlX$VAxOcM;vM>N9#W+M!l6$6lx$Nbrqn1RLuB&;0&w=k%&4!ZnOi&_>EsUT@#D6oUeQBhbKs>^I zBbfbc_5)>5>K%PCl8KlhLuduvugYh<-vK9dqgIfzU!(Yt9r66nhh4M{;i`~Wr6F%5 zCVr+`+S$P-Hi18e?ELn5Fy{blkNc$k0PSexhX-~ zQYL72pP!?jH-UJ=3Da*-s%_Sw)4T=qeDTo7*;oTrRR8-{Dj6qeMmN-Ap|!M{nb+w{ zBhYfQOAHAeQYz&VX6NpKW@N9!#1w)s$=K)w7?q+sUJTJ9__92uw-yH+FPQSwShK?9 z^oM9U(T)ES)ql1QpebP47`M2;@p=;b(zSZ(>OTwC@83cu`dFBD*ZPRTMzQ|;d>s)k zlI%(7wDY$mhy!-`NWuU^H^vP%lzx*xxR(gk+Z}!1ro}A|3wXv3OgW|A!}^gthAGFh zvHY$Ohv}maI(qLT%f=Uk=euWL>wfD<6v2ge1)qb&*3i)Jl6Q3~1IG)#FY#OntbExz z;P6I?1Gq=J7>d&@+0NQ_J@v22Mr4(@G7MDVX%;1t6ufAkTu~Y%Hopld+wUHH>Cw^H z*;5S5eFv(?4o1SXagwQsRE&KX_jqrwck89gv2On3Wk*e}2z!U1uh4s+8MHnn=~MbC zrJl1pp!mth2X_h3Lzb8uCr1*rbbvfsjmrKcQii8WaXANbL4R~_lq$l*<@;!qSNex_VxwuiEg)JI<&dO%SM_Nq+&^JlfQ>Qg0}NI9 zww;tZ1+&W_aQgCWzbQ*!wqj$vo zuu_rh?D6)S-}oOA!rw(Ad}YfPJ$J)XAu0bXAy-GqC-hI3Y>kD$AO%_7&U591(eJkw z$}`wbh491)Mh|Rn&hXJ{B#uN5JXf+7`;rxMC1j94jCm7c|EG!k#sjYU!ad$l?kn_C z(K)wETSSo1IGyXY6k~-uiE(-^YDClzo&_I$_j-Q(*DcQq!;QFEYH^JSzk^7H*1|df z4)N74PnaHof#-K!(RI%i_E!PKTkw*b@1+@mLD}FZy`E7-E_CAnXHa%qmnRQejftHX z97U5SL6D)10|%^sXp|LpfoylWP!N8w67lEX>c3%5wT)99H=o>2+Fea3UG7%XZuTzu zTV?Z>>+VOR(-W;}#9q!={qf&+Xc*^obP}0GO)ip*Zi2}Nxd?~JTy4swOf(Yum~PmN zHfuyx<|1qlV^RElN#v3aS@$|!aq&UoEuK!|d1*zsmhHL^cfXB*-La!vlYBTDFGpr# zksoj11U33$@M9)NT*H%Td;UtFxuDKlZk4O9mT-3RfrpsxV&S+(K-!AbpR`&EC@&@6 zBsvjnoA1g73!+AE#Xyxm&j}qavuuPz;R8Nxv9~?oOY*WHI+UgNPUB(0L?Q}-`UDUT z8}JKwMk_{vxt0fTJ$;-O-qhR zqc7-da?w5AR6$CP^;f?R%-IN~ciXx@=$bTO>PVX){Y+Fkt=8S}dgW9eni<}{Fu^}@ zZeh(pm>{Y=U8v$!@*o+K#A8(W5M~=82vITdDv>=X-v|sRNR`={UYJ1=1@Ead1JRGh zWUbl}CLl!`I)jNMt}buH-0iuCLpaPf$zdqyF)IK1(2lH;U?L$L0o|I0+pE&|2f)}d zw8Pr=M{-cU3?t2%eRAr{kdJnzS63Z~SLLA!-C=FGeirtT%E@QNjUNLr3$S;StdJbF zQp0+W`k>(YmL?6F$R#dl18`yziRP;n8D+d~S!a`j&)i}a!pJNm)UzY^iD5C?yZx(h zBMHHNdRiZ_6WCSddI7V0-EWM5-b(AP7kh%2SXH?aAp53G0Cg|w?$7rD zeMf9dnO_Yk23&;FgNV_`m;!v^yv0Tt@Dm=15n+ho($37qp8*!!16xl^?1U3ln{Bvs zCo66G8u#|ut>)3IFkc?^6cW^)Gke$wOeh-<$58F39W`UPI?LSL*EwW@_uV}`MvmQM zJzkWMtyhdxY}uSI^_t{KF$1N}Zyk57PglHqmbVuFnVV?`#^GR0E^h2{IX$%fcySjfhVk2doX2MLg9KtBC#IXj-c;P!NFBO0TR9*uRZ3H=O|VwZ4(9E`&8T(; zYC);pph2m!k#ytTVg{8spk;ag1ABPj!8TcvuZ_*_f{ZiS^Jaqk^mxw+}E3JVDD zj&3&{zOaHbZ#v}g86K43;a>Wh=W{a!!IySBBy!$Xn0In57H~WhYkF`5&7ZCLFGNMD zQFFHC0U0I0<;--B^W!u=gex~jBKq4!osEYd2G3iM$GIf$gnbb$kZK_{yoEMn)(7$- z*}=mHEVkHb>j@J?UbE4vy7d*Z*_IiEbkb`94B|g_=7Gk6=S^n zF?;`0vw+6_?o^10GI5;Q90tl-0PDiHFx;{+W8+zW_9{x{Dv|UXI1=Md zTuiy{U>K`MMHQ4XcTH1vuauuAHT~ty`yy0pM<;_G@#+Z{m~>_8yPx8D)I7OdihAur zNTxlXfAx~Ky`S~({g&*~ym`a$^bQX<8K26kJA9o-QjKI%`(UiL0kPqIIG4cV%@z8O zF$G09-gA6e-s86_T9#Q8S*kKKCyX^0kedwY{L;T4YxZnx2*>bcZshMc0)lk-(2WW1 z>f2b2 zLhz*&;VfY2w+EbXCOj#RVN`2^UdKEzXLFE+W^L2h!_?N9A)UROGN4Zrxh+ZaXC&B? z_Da97K1^UmqEN-}<2~)m^$L2EDa3fgMx3{E5s+ABJiAmM@PB)MC|X2PC8Rj@s5oov zO>My#(El0wA_h;$)@4eqyx(1wxFf$=3D3LJqxq!f-!^4W7&PnpBp=Wy;~eWJ##Yqj zFWEzQGiKKKda}?XK_$DE^RbClDm6>8UzXG!RqxM)RBFG01=BoHWLX}^Is>ET+c@l2 z)?}Ny{Wi5JX`!j>HF_Q=rStD0Nuh~66zOr^C*&-<$VD#@aC@Nzd_`}$xN&JP`0S5y zc&iHvqdLH?S&mkE)x{{W%-^$GjPeV8DHQ@i`@T8IN|&C0e2q(@IrRaQi1an<&u;GW_<}#i1FQuWJkjU%v=W)i>H#f6jfmmaN@_8`5Ac!kJGDT z^>gh$_|gyl5*hQu$UERxkQD^dx3kdsQxQ zX32KZZGcJrr|XDkFdk>XNq(lKoDIqe9j--GCiGL1!s_}FyFI>ZNIzpk(lFxTHymT;*#^KpaZXwb3|=x%&`ve83;FyFN8X z!0I3HI4H(&4ghw%^6l{NN)U4WhCsP`p9qz(Wmu^;ZhzF{k@%kWi64a+1on9r8qS;> zkwk|j$crHM!8q^lS?>*-q11T3HBPu^?~ou?Xqtnt?YC=R4m?Nammir`5!LVYfu9fa zI@Ex;DBo!T<+EKPt^=)}M0!Y)_Xi*x7h5$kV9J7G&QUZ~owZ|6uFiQ80q-qIEI^{N z$Qhkb?T&HtCnh3Z$%E*`cu$7ar64-EUkJd}wnG%dt4Hij57ZQl5iMz7E~)@T=TVat zRR196Hc{in6G3m~EedQ4(nKQQD|byu4T~jY-u%F=wg_WIf{2S|23;uyqG%Z5vt1u> z#WScnB$5oGr5^{H7<@rYUm~tCcIi1fp1)}(y* zP%vStQT=Y{P!>q>qHuGOAX2S@?!pcW6o10*k57+XEr#JOT)+j8aR8>{C39d zB|XJ3X+#1#_&W%Q$ous}6749 zDj20r38q@seP(9mLl81;(X0H?_`TDsR;P+N(hR1}4p<_tM4SiWyT>Tc#>*Hm61J9$!-R1*p(t-O#lb<`&PRs=nUvS=N&(3bYrI8)|3;+_6#+s=-}Q0J zT5W1s)*I@6Aqp83plKO62IW)6admTfLD71@jw{XUnQaEFNsB_li$sCy5+51>cSfAnd1LllN4-;eh047f01Uy%K`GTtRJ)ci?)H``E-2Ogu8 z?S;ai4EXNkmR1cW%=`1^uHnxe==rI1!F8fPRZ3?sz?XnXh9dG_Wv>99@dPLoLX$tr zRCOI?J*VLX1dVH1&m8DY*(I89+EcS@Pl{XFeR${A0VNYG&s*S=_$VrBJJXC-iOR*M}p_x>{*alr9 z5lTlH3e)-M*L+MzSk>mITqvoYW%?+wldln|7me%#aKFXK+A9*+i8c!PhIT;Xf%T~# z)B5e1&ALtMKVBkpN6Ud?w*m5`*T-6}Vvx{mvVsO>m+CQ?H*hR8WJwxfY?%NRmLrn4 zYCDNe#`=y{-5%#ai2#R#7iXK)8PlVW#h&r+flN;sYI`VXBBcx>l;X$wci z=gk^r;~N{ZYPPRzBYK?Z%OP@T|J}v8C0-=aQ@e_j2z%pNbk}JeJb!IzkbBN*Mk^bJ zm+=|7BTa~zbaS2MKgGE4714?Jiw2@yB8MlMOPXap-fVqcUOoySAD=a(n}>IyeCet` zFBY;FSF}$p|B3gNEcoBq$0Gppy4<;0Eh;yYIJYuE2eA^FQr% z)ifHz{>-GrY5hpvBPO-gD3l-QA+-plCotM>29~9YPW&-5s(z_yUvZn~YZ8Y{Hza>o zUVQOAJ%bb~=1?lcLFw&l)1awn|1VLUW?Z~9Np|uYEdEXL`9mRcxb(=i%PlhvRT7`Urk2Nkt8HY^aki>z z%n~M;Vl%i{xhkM0Wz@fqaS@gL^Zd?iaBwj<6F3xn6XB-?pZu~V7wS0a(xrTA`y$zO ze1i>-<#Q_iIT-Y<=s8gQp5x%JG#k(D_xs$;kHDZ?FdVW44OQG!+;nTR6*fo{2beV> zN|T=zK(s5P<#Y7Cm#n!R^F00FCAKC`t|#UUdDolWkU(HXder4w^tjJ$JthRL!T}8_ z-cT-zbQ7hG$NJfgg~CYp6s3H;+yvL83dMJ?pDXreYJJZYO=^iZi;tGP;QA1i&yAm& z!zJ&L1^c0Q=;p8CwfK`bPc{OXK@a?kln>G&rPw;@AE;2NJ>tR|X_PiTo2K6PUM}tt zYSY7+eW&uGO(Nh(7IwI)#A=`1tcYF;cxzC%Om!8Bn zrk6g3fZ0C^c@l}&h@E{zcRE*l|M%Gqae~tz#-24BZxtd<7sZccD1N%uWmFde))af$ zF4A`9hx`2}sP`^U=ZQiGHvMSC&}EL)NNNL%#-=qd~ZX+cjX#397e zFI^pM6Ka=^jOoCLHhknc=t}SYVYHv}mwjCb`JvYRQ^r@-7Eio9uQX9V4WvqzB^DuK zp?Mrg?;X}mgNI@0hApXgEQ+7lN)mHtWtWsTXNLP)!}rRSy{@7|_dwr|{$;$2DCvv2 zem*`bseiVY$=ppm{ zFDx40%U`$8ew~bF&4bO02o#Tp2RJRnY@1``poop5=?w%6+Tmgcc&>V zfVf=eS#sdJ@(-=vgjI%$@VzeQONUeZ3+knG|Fsexn*z(NRatmeSb?Lx97 zNYvIxL71i@DC(YNo_Uj3WmF$8gM-@GbRdDvypTe5(t0iHO+)`7a~l zw~jYx{4suu1CbaY3{7X;J^8+@d{ci!8rTJ^I`vq{uO@~(Nx&l_#yKZNERo# zgy-st&1atHHXQ&n241vt39u|*Zu`AL%`ygD_*|Tcrl_Zlj=n0UQ_2o-xBsHmkYN8R zh>~pjYspiTa&C~|RUz2a)BGg=uP?Bd$@dCg3;)|`ekrRgZ+ZEA)cpS`cQ0M1nekBi z^1OutGP$fABf1OCEwhw9^^yQ68KSARL-9>?I@{ju)lyu>@xT}xmxit3SA1I~@byxC);oT?hWEe{12CRkK+~k_m|TDJoSn-94>|O3a1-|3r41T zU94k6{_`yK>;LD{ee1wirlM}(h8YkXwTgKap1k@K?}q@CXjg^K;J>b!T=g;brp1Am zAiY!l*|H&l+J9fe8OMtZ3kDK%_(NXvLsIZ(L_@FZrK`Jm6oF*E!$OO+P&p zQf)^JJb$zUvI-P#^YoiH!+hpAq2fJ^7*+fVC0RAL7;7i-h583?d}MAiHBW(1SJUjw zB>S5$uRnwlNfKl#9CSA|PnMdeu{hcMBQEVVl2`$P8T(B3#TnaII5VJY!0rF}Mw}SFvV8WNIjgfwDYJ1^kST8&(^G7zE)0@P+F^`GoDv>F2Pif_&qlcrTP~s) zS_37WYOQnbqoV{QH|PdsS@SJotw}6)u5PCTmRq;UqQ`KT94BG{%(5E%jIWZtDrz#@ zEy%*%T@U1IwtXLkLk-Kmj05T<+M@9yqyz%vX3tx98HMgy4D~-kc7Ml|#Mz6*f;+U_ zYIxv~*9>nmnU^)f)D-tH*B}B>uW8pToTP`N{q_Pa+hxi4#~?E1XP-X}YIZtmTBGD# zP=Lbj+pkR1?|uiN*`Os$-m(~PM2GTk-f?Zj7KC%ZF$`>(n8UMq^O~Nh3B@^~3%d}>ZRXedn5CBU< zX7Qfn2EIPa#TLsTo*>A6mzT5NoUNI5HAE99Wj0^TD%yo&Of9$?@69i(fBTtyrnku2 z)_hu$B|G6D_%jDWrgwid6ge|XJvuSgZhQd_v-POL_Xdscsdcps)1@n-g#IZnaJbmG zij8A&gv83vi}tk3>qZQWCX^&p{Z*Gj1iGZw<`vs(ZynW3+BngU^u#JS#$97gvm`ox zIz8Y#4?LMY>e~S?-{rrEDX#GH0e7q4asObpuYvBcJjZi#oZ$Yiv-1B>T>IqhApIYa iYVXBbKmGr$HXwi_+Tw}qMeq5K@L5VhvRc9*@c#gXQ5#tR literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/greedy_algorithm.assets/coin_change_greedy_vs_dp.png b/en/chapter_greedy/greedy_algorithm.assets/coin_change_greedy_vs_dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d13ed01a164acf11e3520d36017c4e6c056b7479 GIT binary patch literal 20841 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%0A4$11AjWAn~Wl~1Es}he1Vgc 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 SUR*xs)B`m=)l%gb!T$m%M!vTI literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/greedy_algorithm/index.html b/en/chapter_greedy/greedy_algorithm/index.html new file mode 100644 index 000000000..7d3b32449 --- /dev/null +++ b/en/chapter_greedy/greedy_algorithm/index.html @@ -0,0 +1,4231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.1 Greedy algorithms - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    15.1   Greedy algorithms

    +

    Greedy algorithm is a common algorithm for solving optimization problems, which fundamentally involves making the seemingly best choice at each decision-making stage of the problem, i.e., greedily making locally optimal decisions in hopes of finding a globally optimal solution. Greedy algorithms are concise and efficient, and are widely used in many practical problems.

    +

    Greedy algorithms and dynamic programming are both commonly used to solve optimization problems. They share some similarities, such as relying on the property of optimal substructure, but they operate differently.

    +
      +
    • Dynamic programming considers all previous decisions at the current decision stage and uses solutions to past subproblems to construct solutions for the current subproblem.
    • +
    • Greedy algorithms do not consider past decisions; instead, they proceed with greedy choices, continually narrowing the scope of the problem until it is solved.
    • +
    +

    Let's first understand the working principle of the greedy algorithm through the example of "coin change," which has been introduced in the "Complete Knapsack Problem" chapter. I believe you are already familiar with it.

    +
    +

    Question

    +

    Given \(n\) types of coins, where the denomination of the \(i\)th type of coin is \(coins[i - 1]\), and the target amount is \(amt\), with each type of coin available indefinitely, what is the minimum number of coins needed to make up the target amount? If it is not possible to make up the target amount, return \(-1\).

    +
    +

    The greedy strategy adopted in this problem is shown in the following figure. Given the target amount, we greedily choose the coin that is closest to and not greater than it, repeatedly following this step until the target amount is met.

    +

    Greedy strategy for coin change

    +

    Figure 15-1   Greedy strategy for coin change

    + +

    The implementation code is as follows:

    +
    +
    +
    +
    coin_change_greedy.py
    def coin_change_greedy(coins: list[int], amt: int) -> int:
    +    """零钱兑换:贪心"""
    +    # 假设 coins 列表有序
    +    i = len(coins) - 1
    +    count = 0
    +    # 循环进行贪心选择,直到无剩余金额
    +    while amt > 0:
    +        # 找到小于且最接近剩余金额的硬币
    +        while i > 0 and coins[i] > amt:
    +            i -= 1
    +        # 选择 coins[i]
    +        amt -= coins[i]
    +        count += 1
    +    # 若未找到可行方案,则返回 -1
    +    return count if amt == 0 else -1
    +
    +
    +
    +
    coin_change_greedy.cpp
    /* 零钱兑换:贪心 */
    +int coinChangeGreedy(vector<int> &coins, int amt) {
    +    // 假设 coins 列表有序
    +    int i = coins.size() - 1;
    +    int count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (amt > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > amt) {
    +            i--;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count++;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt == 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.java
    /* 零钱兑换:贪心 */
    +int coinChangeGreedy(int[] coins, int amt) {
    +    // 假设 coins 列表有序
    +    int i = coins.length - 1;
    +    int count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (amt > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > amt) {
    +            i--;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count++;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt == 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.cs
    /* 零钱兑换:贪心 */
    +int CoinChangeGreedy(int[] coins, int amt) {
    +    // 假设 coins 列表有序
    +    int i = coins.Length - 1;
    +    int count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (amt > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > amt) {
    +            i--;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count++;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt == 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.go
    /* 零钱兑换:贪心 */
    +func coinChangeGreedy(coins []int, amt int) int {
    +    // 假设 coins 列表有序
    +    i := len(coins) - 1
    +    count := 0
    +    // 循环进行贪心选择,直到无剩余金额
    +    for amt > 0 {
    +        // 找到小于且最接近剩余金额的硬币
    +        for i > 0 && coins[i] > amt {
    +            i--
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i]
    +        count++
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    if amt != 0 {
    +        return -1
    +    }
    +    return count
    +}
    +
    +
    +
    +
    coin_change_greedy.swift
    /* 零钱兑换:贪心 */
    +func coinChangeGreedy(coins: [Int], amt: Int) -> Int {
    +    // 假设 coins 列表有序
    +    var i = coins.count - 1
    +    var count = 0
    +    var amt = amt
    +    // 循环进行贪心选择,直到无剩余金额
    +    while amt > 0 {
    +        // 找到小于且最接近剩余金额的硬币
    +        while i > 0 && coins[i] > amt {
    +            i -= 1
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i]
    +        count += 1
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt == 0 ? count : -1
    +}
    +
    +
    +
    +
    coin_change_greedy.js
    /* 零钱兑换:贪心 */
    +function coinChangeGreedy(coins, amt) {
    +    // 假设 coins 数组有序
    +    let i = coins.length - 1;
    +    let count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (amt > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > amt) {
    +            i--;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count++;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt === 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.ts
    /* 零钱兑换:贪心 */
    +function coinChangeGreedy(coins: number[], amt: number): number {
    +    // 假设 coins 数组有序
    +    let i = coins.length - 1;
    +    let count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (amt > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > amt) {
    +            i--;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count++;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt === 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.dart
    /* 零钱兑换:贪心 */
    +int coinChangeGreedy(List<int> coins, int amt) {
    +  // 假设 coins 列表有序
    +  int i = coins.length - 1;
    +  int count = 0;
    +  // 循环进行贪心选择,直到无剩余金额
    +  while (amt > 0) {
    +    // 找到小于且最接近剩余金额的硬币
    +    while (i > 0 && coins[i] > amt) {
    +      i--;
    +    }
    +    // 选择 coins[i]
    +    amt -= coins[i];
    +    count++;
    +  }
    +  // 若未找到可行方案,则返回 -1
    +  return amt == 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.rs
    /* 零钱兑换:贪心 */
    +fn coin_change_greedy(coins: &[i32], mut amt: i32) -> i32 {
    +    // 假设 coins 列表有序
    +    let mut i = coins.len() - 1;
    +    let mut count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while amt > 0 {
    +        // 找到小于且最接近剩余金额的硬币
    +        while i > 0 && coins[i] > amt {
    +            i -= 1;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count += 1;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    if amt == 0 {
    +        count
    +    } else {
    +        -1
    +    }
    +}
    +
    +
    +
    +
    coin_change_greedy.c
    /* 零钱兑换:贪心 */
    +int coinChangeGreedy(int *coins, int size, int amt) {
    +    // 假设 coins 列表有序
    +    int i = size - 1;
    +    int count = 0;
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (amt > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > amt) {
    +            i--;
    +        }
    +        // 选择 coins[i]
    +        amt -= coins[i];
    +        count++;
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return amt == 0 ? count : -1;
    +}
    +
    +
    +
    +
    coin_change_greedy.kt
    /* 零钱兑换:贪心 */
    +fun coinChangeGreedy(coins: IntArray, amt: Int): Int {
    +    // 假设 coins 列表有序
    +    var am = amt
    +    var i = coins.size - 1
    +    var count = 0
    +    // 循环进行贪心选择,直到无剩余金额
    +    while (am > 0) {
    +        // 找到小于且最接近剩余金额的硬币
    +        while (i > 0 && coins[i] > am) {
    +            i--
    +        }
    +        // 选择 coins[i]
    +        am -= coins[i]
    +        count++
    +    }
    +    // 若未找到可行方案,则返回 -1
    +    return if (am == 0) count else -1
    +}
    +
    +
    +
    +
    coin_change_greedy.rb
    [class]{}-[func]{coin_change_greedy}
    +
    +
    +
    +
    coin_change_greedy.zig
    [class]{}-[func]{coinChangeGreedy}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    You might exclaim: So clean! The greedy algorithm solves the coin change problem in about ten lines of code.

    +

    15.1.1   Advantages and limitations of greedy algorithms

    +

    Greedy algorithms are not only straightforward and simple to implement, but they are also usually very efficient. In the code above, if the smallest coin denomination is \(\min(coins)\), the greedy choice loops at most \(amt / \min(coins)\) times, giving a time complexity of \(O(amt / \min(coins))\). This is an order of magnitude smaller than the time complexity of the dynamic programming solution, which is \(O(n \times amt)\).

    +

    However, for some combinations of coin denominations, greedy algorithms cannot find the optimal solution. The following figure provides two examples.

    +
      +
    • Positive example \(coins = [1, 5, 10, 20, 50, 100]\): In this coin combination, given any \(amt\), the greedy algorithm can find the optimal solution.
    • +
    • Negative example \(coins = [1, 20, 50]\): Suppose \(amt = 60\), the greedy algorithm can only find the combination \(50 + 1 \times 10\), totaling 11 coins, but dynamic programming can find the optimal solution of \(20 + 20 + 20\), needing only 3 coins.
    • +
    • Negative example \(coins = [1, 49, 50]\): Suppose \(amt = 98\), the greedy algorithm can only find the combination \(50 + 1 \times 48\), totaling 49 coins, but dynamic programming can find the optimal solution of \(49 + 49\), needing only 2 coins.
    • +
    +

    Examples where greedy algorithms do not find the optimal solution

    +

    Figure 15-2   Examples where greedy algorithms do not find the optimal solution

    + +

    This means that for the coin change problem, greedy algorithms cannot guarantee finding the globally optimal solution, and they might find a very poor solution. They are better suited for dynamic programming.

    +

    Generally, the suitability of greedy algorithms falls into two categories.

    +
      +
    1. Guaranteed to find the optimal solution: In these cases, greedy algorithms are often the best choice, as they tend to be more efficient than backtracking or dynamic programming.
    2. +
    3. Can find a near-optimal solution: Greedy algorithms are also applicable here. For many complex problems, finding the global optimal solution is very challenging, and being able to find a high-efficiency suboptimal solution is also very commendable.
    4. +
    +

    15.1.2   Characteristics of greedy algorithms

    +

    So, what kind of problems are suitable for solving with greedy algorithms? Or rather, under what conditions can greedy algorithms guarantee to find the optimal solution?

    +

    Compared to dynamic programming, greedy algorithms have stricter usage conditions, focusing mainly on two properties of the problem.

    +
      +
    • Greedy choice property: Only when the locally optimal choice can always lead to a globally optimal solution can greedy algorithms guarantee to obtain the optimal solution.
    • +
    • Optimal substructure: The optimal solution to the original problem contains the optimal solutions to its subproblems.
    • +
    +

    Optimal substructure has already been introduced in the "Dynamic Programming" chapter, so it is not discussed further here. It's important to note that some problems do not have an obvious optimal substructure, but can still be solved using greedy algorithms.

    +

    We mainly explore the method for determining the greedy choice property. Although its description seems simple, in practice, proving the greedy choice property for many problems is not easy.

    +

    For example, in the coin change problem, although we can easily cite counterexamples to disprove the greedy choice property, proving it is much more challenging. If asked, what conditions must a coin combination meet to be solvable using a greedy algorithm? We often have to rely on intuition or examples to provide an ambiguous answer, as it is difficult to provide a rigorous mathematical proof.

    +
    +

    Quote

    +

    A paper presents an algorithm with a time complexity of \(O(n^3)\) for determining whether a coin combination can use a greedy algorithm to find the optimal solution for any amount.

    +

    Pearson, D. A polynomial-time algorithm for the change-making problem[J]. Operations Research Letters, 2005, 33(3): 231-234.

    +
    +

    15.1.3   Steps for solving problems with greedy algorithms

    +

    The problem-solving process for greedy problems can generally be divided into the following three steps.

    +
      +
    1. Problem analysis: Sort out and understand the characteristics of the problem, including state definition, optimization objectives, and constraints, etc. This step is also involved in backtracking and dynamic programming.
    2. +
    3. Determine the greedy strategy: Determine how to make a greedy choice at each step. This strategy can reduce the scale of the problem at each step and eventually solve the entire problem.
    4. +
    5. Proof of correctness: It is usually necessary to prove that the problem has both a greedy choice property and optimal substructure. This step may require mathematical proofs, such as induction or reductio ad absurdum.
    6. +
    +

    Determining the greedy strategy is the core step in solving the problem, but it may not be easy to implement, mainly for the following reasons.

    +
      +
    • Greedy strategies vary greatly between different problems. For many problems, the greedy strategy is fairly straightforward, and we can come up with it through some general thinking and attempts. However, for some complex problems, the greedy strategy may be very elusive, which is a real test of individual problem-solving experience and algorithmic capability.
    • +
    • Some greedy strategies are quite misleading. When we confidently design a greedy strategy, write the code, and submit it for testing, it is quite possible that some test cases will not pass. This is because the designed greedy strategy is only "partially correct," as described above with the coin change example.
    • +
    +

    To ensure accuracy, we should provide rigorous mathematical proofs for the greedy strategy, usually involving reductio ad absurdum or mathematical induction.

    +

    However, proving correctness may not be an easy task. If we are at a loss, we usually choose to debug the code based on test cases, modifying and verifying the greedy strategy step by step.

    +

    15.1.4   Typical problems solved by greedy algorithms

    +

    Greedy algorithms are often applied to optimization problems that satisfy the properties of greedy choice and optimal substructure. Below are some typical greedy algorithm problems.

    +
      +
    • Coin change problem: In some coin combinations, the greedy algorithm always provides the optimal solution.
    • +
    • Interval scheduling problem: Suppose you have several tasks, each of which takes place over a period of time. Your goal is to complete as many tasks as possible. If you always choose the task that ends the earliest, then the greedy algorithm can achieve the optimal solution.
    • +
    • Fractional knapsack problem: Given a set of items and a carrying capacity, your goal is to select a set of items such that the total weight does not exceed the carrying capacity and the total value is maximized. If you always choose the item with the highest value-to-weight ratio (value / weight), the greedy algorithm can achieve the optimal solution in some cases.
    • +
    • Stock trading problem: Given a set of historical stock prices, you can make multiple trades, but you cannot buy again until after you have sold if you already own stocks. The goal is to achieve the maximum profit.
    • +
    • Huffman coding: Huffman coding is a greedy algorithm used for lossless data compression. By constructing a Huffman tree, it always merges the two nodes with the lowest frequency, resulting in a Huffman tree with the minimum weighted path length (coding length).
    • +
    • Dijkstra's algorithm: It is a greedy algorithm for solving the shortest path problem from a given source vertex to all other vertices.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_greedy/index.html b/en/chapter_greedy/index.html new file mode 100644 index 000000000..101002e1e --- /dev/null +++ b/en/chapter_greedy/index.html @@ -0,0 +1,3794 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Chapter 15.   Greedy - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    Chapter 15.   Greedy

    +

    Greedy

    +
    +

    Abstract

    +

    Sunflowers turn towards the sun, always seeking the greatest possible growth for themselves.

    +

    Greedy strategy guides to the best answer step by step through rounds of simple choices.

    +
    +

    Chapter contents

    + + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_example.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_example.png new file mode 100644 index 0000000000000000000000000000000000000000..4d4b883dc1d214b20de075899238ba1684a1fe5b GIT binary patch literal 11436 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 Df;^^C literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step2.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..3f2a0839426ff5b885d82ab258e2baec0a5a276a GIT binary patch literal 17319 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%0D2E&Le%=&w@{Jr$z+tqh`Y_ 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 Z>q75BqH literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step3.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..581ee2701cf6f5477e4d3bdf138524d563523ed0 GIT binary patch literal 17598 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step4.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e6e18126efea3ead167b93feef424a5a6e3798 GIT binary patch literal 17967 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step7.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_greedy_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5a1c47d38258553e3ebadf750c0b65b7435b50 GIT binary patch literal 18099 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 +^MX$%k) z6-^GFy1i|x==h3#=^^mg%Eveq^|G3_(tSz(ah-5u357u@tDgFxlHjIVj86%f;h#7zm4bpV9v!W0>1Io zd)=jq;YX`4lo*WeJWUAWdQg%wK2Jji2`!osD)};TWFo&J%F|VuSgtKlcjGw7ydloT zMVX$c`zb*sF2#a=wvBUQW7-%LIEqqy+~*D?)gI=N!LBmO6h|)WvQcxu6oe}D>NOU- zE)c#X8hAE_FR|~*Fc2#b*!|wgbdr0z?WqiM4zMB@nphaVNL~g|Zp7T_<3BdL!b&&fEI0R9{;){N3h(a-lm?UF!H_X}}e!js_ ze4f|wJYYmF*^}{Z&=OcA{h<{f++9WuC#ntdbx-&p`(mbhWOPRK06`hn(c?4u(JX+U zAez}YdeI(DT&+b2=ir zx(7wtQuH<_1zE7t9#=+b93P5D35kBUFI%SharbX^Jzif#zU!7F@xZRKDyPKvc{CogXF1QE)6NAP4CE_jN8W1SK}@` z0{uMezNq~%`m=errhrENQPoK3n9uJROS@%}^n}uvRQ|DY;*4nwGUD^k zYB*vk&q+eA=l z&jMp4EKZQNsk961fYpUSP4v(VR`yTqr?*2$O@VI<2m4(w$ z>%;$vz7Pi%BUCdCxly;~{aSkOU8*E9m>337Lfxd5eN_MaY?FVT4=9@c9>jDfg)L4h z|A<}kGqV1G3Ysd#n@W*X_7Uwst`(Z0u)5!P2q#* z09EyBQ5pK)E?#TCPkU1XzeqT|hsk1>ef)hdM4UQe%}%JG4g1DS+;|#Uz7LdY8z2!3 zR8XmKP|j6ek!!p~qKsSb+2$Aj&1f_8T6sun%W@>g{*~*UNf@R?k3sw$RgozD_e%#< zFVuG){>PJxR9>LoUtR!}%2tScOuOA_!i^_(<)b5J9&+AIL{Bz6Bsk=Eni=7A1e3|24?9C!{+^$)5SAc@d{_c8^l5cbC?WHZt5uUUd%59;K5`8?|)l!2%OBEXFuNl zE|j`c0V=>IK5?#FIL)DiVlPS<7_dr{=t!75%+Gg+Wb!wJ&kPKuaF$I59rUeY^dJvo z!)RW}7z=aVpRwXLs}M-ZDzhg-=61dnQ9@aWC3sdo`vpuDxc4z=_5cDxd%sR|D>Irl zNUUzL!E?4U#^_w40TQxoPM>8DlENYZMX#~RgGhi>8_O;V-_0+J2nPougUs3MK3&}< z_bxNm5#AF%xbj3T5PzVW$qD{)^6R`U(d~CNb}XIKW&^aGuAn~!lKZy1CoB(LxkJH= zra#}mFD%1AU1Va~QKIk^*Yytuz_5UZ5AIiYB_`x)94ojG%kJ+__M}8sjeJfB<|0U2 z$H(fn%H}Ya-Vb#H9%%U=yM5&6ogZ;Fo!L_Fq7HVS;2a4eP=f%l5P6hWopC)Q!q+U- z8Fr{5k(ls;P0x3S_?g+y8U(MhHH=ltGwCo2t##)1y!&-eIrK)dKcZ=|D;+$~90;Ce z*kTwX=L{KONqnF9_>-rmpN}l~&CY^&0O9S3b44L;#rf8{TI$|A_lp46(DiCGY%wU~ z+V{-qmK}(2M(&FgID9Ce^`YuLGy5*+Hsv#njtB!8C=ao6Yq0ayZf9lfcATU5kIr@e vhdk)<;SY+xe|LlCJXQF;|NAA{--ZWz^7R)8r4o<)+mn@4lqeTB{`kKDN7Tmc literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_initial_state.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_initial_state.png new file mode 100644 index 0000000000000000000000000000000000000000..5ffb164065e78756c9da1ee30d464cab7cda0c96 GIT binary patch literal 14995 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_moving_long_board.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_moving_long_board.png new file mode 100644 index 0000000000000000000000000000000000000000..cf00baaa89cfd2433ea6941c4c05c8652e1ca27d GIT binary patch literal 16031 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 b|IM)hm4l<%!U*Hf{}Ghr)#Sd*T7>>@kMA)y literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_moving_short_board.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_moving_short_board.png new file mode 100644 index 0000000000000000000000000000000000000000..7f082e87ac828bcc0a0e63ce19e7fc9006893534 GIT binary patch literal 16028 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem.assets/max_capacity_skipped_states.png b/en/chapter_greedy/max_capacity_problem.assets/max_capacity_skipped_states.png new file mode 100644 index 0000000000000000000000000000000000000000..45b3b52d087bddfb36d65a1c9ddf24772bee55c2 GIT binary patch literal 22811 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_capacity_problem/index.html b/en/chapter_greedy/max_capacity_problem/index.html new file mode 100644 index 000000000..490685274 --- /dev/null +++ b/en/chapter_greedy/max_capacity_problem/index.html @@ -0,0 +1,4244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.3 Maximum capacity problem - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    15.3   Maximum capacity problem

    +
    +

    Question

    +

    Input an array \(ht\), where each element represents the height of a vertical partition. Any two partitions in the array, along with the space between them, can form a container.

    +

    The capacity of the container is the product of the height and the width (area), where the height is determined by the shorter partition, and the width is the difference in array indices between the two partitions.

    +

    Please select two partitions in the array that maximize the container's capacity and return this maximum capacity. An example is shown in the following figure.

    +
    +

    Example data for the maximum capacity problem

    +

    Figure 15-7   Example data for the maximum capacity problem

    + +

    The container is formed by any two partitions, therefore the state of this problem is represented by the indices of the two partitions, denoted as \([i, j]\).

    +

    According to the problem statement, the capacity equals the product of height and width, where the height is determined by the shorter partition, and the width is the difference in array indices between the two partitions. The formula for capacity \(cap[i, j]\) is:

    +
    \[ +cap[i, j] = \min(ht[i], ht[j]) \times (j - i) +\]
    +

    Assuming the length of the array is \(n\), the number of combinations of two partitions (total number of states) is \(C_n^2 = \frac{n(n - 1)}{2}\). The most straightforward approach is to enumerate all possible states, resulting in a time complexity of \(O(n^2)\).

    +

    1.   Determination of a greedy strategy

    +

    There is a more efficient solution to this problem. As shown in the following figure, we select a state \([i, j]\) where the indices \(i < j\) and the height \(ht[i] < ht[j]\), meaning \(i\) is the shorter partition, and \(j\) is the taller one.

    +

    Initial state

    +

    Figure 15-8   Initial state

    + +

    As shown in the following figure, if we move the taller partition \(j\) closer to the shorter partition \(i\), the capacity will definitely decrease.

    +

    This is because when moving the taller partition \(j\), the width \(j-i\) definitely decreases; and since the height is determined by the shorter partition, the height can only remain the same (if \(i\) remains the shorter partition) or decrease (if the moved \(j\) becomes the shorter partition).

    +

    State after moving the taller partition inward

    +

    Figure 15-9   State after moving the taller partition inward

    + +

    Conversely, we can only possibly increase the capacity by moving the shorter partition \(i\) inward. Although the width will definitely decrease, the height may increase (if the moved shorter partition \(i\) becomes taller). For example, in the Figure 15-10 , the area increases after moving the shorter partition.

    +

    State after moving the shorter partition inward

    +

    Figure 15-10   State after moving the shorter partition inward

    + +

    This leads us to the greedy strategy for this problem: initialize two pointers at the ends of the container, and in each round, move the pointer corresponding to the shorter partition inward until the two pointers meet.

    +

    The following figures illustrate the execution of the greedy strategy.

    +
      +
    1. Initially, the pointers \(i\) and \(j\) are positioned at the ends of the array.
    2. +
    3. Calculate the current state's capacity \(cap[i, j]\) and update the maximum capacity.
    4. +
    5. Compare the heights of partitions \(i\) and \(j\), and move the shorter partition inward by one step.
    6. +
    7. Repeat steps 2. and 3. until \(i\) and \(j\) meet.
    8. +
    +
    +
    +
    +

    The greedy process for maximum capacity problem

    +
    +
    +

    max_capacity_greedy_step2

    +
    +
    +

    max_capacity_greedy_step3

    +
    +
    +

    max_capacity_greedy_step4

    +
    +
    +

    max_capacity_greedy_step5

    +
    +
    +

    max_capacity_greedy_step6

    +
    +
    +

    max_capacity_greedy_step7

    +
    +
    +

    max_capacity_greedy_step8

    +
    +
    +

    max_capacity_greedy_step9

    +
    +
    +
    +

    Figure 15-11   The greedy process for maximum capacity problem

    + +

    2.   Implementation

    +

    The code loops at most \(n\) times, thus the time complexity is \(O(n)\).

    +

    The variables \(i\), \(j\), and \(res\) use a constant amount of extra space, thus the space complexity is \(O(1)\).

    +
    +
    +
    +
    max_capacity.py
    def max_capacity(ht: list[int]) -> int:
    +    """最大容量:贪心"""
    +    # 初始化 i, j,使其分列数组两端
    +    i, j = 0, len(ht) - 1
    +    # 初始最大容量为 0
    +    res = 0
    +    # 循环贪心选择,直至两板相遇
    +    while i < j:
    +        # 更新最大容量
    +        cap = min(ht[i], ht[j]) * (j - i)
    +        res = max(res, cap)
    +        # 向内移动短板
    +        if ht[i] < ht[j]:
    +            i += 1
    +        else:
    +            j -= 1
    +    return res
    +
    +
    +
    +
    max_capacity.cpp
    /* 最大容量:贪心 */
    +int maxCapacity(vector<int> &ht) {
    +    // 初始化 i, j,使其分列数组两端
    +    int i = 0, j = ht.size() - 1;
    +    // 初始最大容量为 0
    +    int res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        int cap = min(ht[i], ht[j]) * (j - i);
    +        res = max(res, cap);
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i++;
    +        } else {
    +            j--;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    max_capacity.java
    /* 最大容量:贪心 */
    +int maxCapacity(int[] ht) {
    +    // 初始化 i, j,使其分列数组两端
    +    int i = 0, j = ht.length - 1;
    +    // 初始最大容量为 0
    +    int res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        int cap = Math.min(ht[i], ht[j]) * (j - i);
    +        res = Math.max(res, cap);
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i++;
    +        } else {
    +            j--;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    max_capacity.cs
    /* 最大容量:贪心 */
    +int MaxCapacity(int[] ht) {
    +    // 初始化 i, j,使其分列数组两端
    +    int i = 0, j = ht.Length - 1;
    +    // 初始最大容量为 0
    +    int res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        int cap = Math.Min(ht[i], ht[j]) * (j - i);
    +        res = Math.Max(res, cap);
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i++;
    +        } else {
    +            j--;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    max_capacity.go
    /* 最大容量:贪心 */
    +func maxCapacity(ht []int) int {
    +    // 初始化 i, j,使其分列数组两端
    +    i, j := 0, len(ht)-1
    +    // 初始最大容量为 0
    +    res := 0
    +    // 循环贪心选择,直至两板相遇
    +    for i < j {
    +        // 更新最大容量
    +        capacity := int(math.Min(float64(ht[i]), float64(ht[j]))) * (j - i)
    +        res = int(math.Max(float64(res), float64(capacity)))
    +        // 向内移动短板
    +        if ht[i] < ht[j] {
    +            i++
    +        } else {
    +            j--
    +        }
    +    }
    +    return res
    +}
    +
    +
    +
    +
    max_capacity.swift
    /* 最大容量:贪心 */
    +func maxCapacity(ht: [Int]) -> Int {
    +    // 初始化 i, j,使其分列数组两端
    +    var i = ht.startIndex, j = ht.endIndex - 1
    +    // 初始最大容量为 0
    +    var res = 0
    +    // 循环贪心选择,直至两板相遇
    +    while i < j {
    +        // 更新最大容量
    +        let cap = min(ht[i], ht[j]) * (j - i)
    +        res = max(res, cap)
    +        // 向内移动短板
    +        if ht[i] < ht[j] {
    +            i += 1
    +        } else {
    +            j -= 1
    +        }
    +    }
    +    return res
    +}
    +
    +
    +
    +
    max_capacity.js
    /* 最大容量:贪心 */
    +function maxCapacity(ht) {
    +    // 初始化 i, j,使其分列数组两端
    +    let i = 0,
    +        j = ht.length - 1;
    +    // 初始最大容量为 0
    +    let res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        const cap = Math.min(ht[i], ht[j]) * (j - i);
    +        res = Math.max(res, cap);
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i += 1;
    +        } else {
    +            j -= 1;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    max_capacity.ts
    /* 最大容量:贪心 */
    +function maxCapacity(ht: number[]): number {
    +    // 初始化 i, j,使其分列数组两端
    +    let i = 0,
    +        j = ht.length - 1;
    +    // 初始最大容量为 0
    +    let res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        const cap: number = Math.min(ht[i], ht[j]) * (j - i);
    +        res = Math.max(res, cap);
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i += 1;
    +        } else {
    +            j -= 1;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    max_capacity.dart
    /* 最大容量:贪心 */
    +int maxCapacity(List<int> ht) {
    +  // 初始化 i, j,使其分列数组两端
    +  int i = 0, j = ht.length - 1;
    +  // 初始最大容量为 0
    +  int res = 0;
    +  // 循环贪心选择,直至两板相遇
    +  while (i < j) {
    +    // 更新最大容量
    +    int cap = min(ht[i], ht[j]) * (j - i);
    +    res = max(res, cap);
    +    // 向内移动短板
    +    if (ht[i] < ht[j]) {
    +      i++;
    +    } else {
    +      j--;
    +    }
    +  }
    +  return res;
    +}
    +
    +
    +
    +
    max_capacity.rs
    /* 最大容量:贪心 */
    +fn max_capacity(ht: &[i32]) -> i32 {
    +    // 初始化 i, j,使其分列数组两端
    +    let mut i = 0;
    +    let mut j = ht.len() - 1;
    +    // 初始最大容量为 0
    +    let mut res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while i < j {
    +        // 更新最大容量
    +        let cap = std::cmp::min(ht[i], ht[j]) * (j - i) as i32;
    +        res = std::cmp::max(res, cap);
    +        // 向内移动短板
    +        if ht[i] < ht[j] {
    +            i += 1;
    +        } else {
    +            j -= 1;
    +        }
    +    }
    +    res
    +}
    +
    +
    +
    +
    max_capacity.c
    /* 最大容量:贪心 */
    +int maxCapacity(int ht[], int htLength) {
    +    // 初始化 i, j,使其分列数组两端
    +    int i = 0;
    +    int j = htLength - 1;
    +    // 初始最大容量为 0
    +    int res = 0;
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        int capacity = myMin(ht[i], ht[j]) * (j - i);
    +        res = myMax(res, capacity);
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i++;
    +        } else {
    +            j--;
    +        }
    +    }
    +    return res;
    +}
    +
    +
    +
    +
    max_capacity.kt
    /* 最大容量:贪心 */
    +fun maxCapacity(ht: IntArray): Int {
    +    // 初始化 i, j,使其分列数组两端
    +    var i = 0
    +    var j = ht.size - 1
    +    // 初始最大容量为 0
    +    var res = 0
    +    // 循环贪心选择,直至两板相遇
    +    while (i < j) {
    +        // 更新最大容量
    +        val cap = min(ht[i], ht[j]) * (j - i)
    +        res = max(res, cap)
    +        // 向内移动短板
    +        if (ht[i] < ht[j]) {
    +            i++
    +        } else {
    +            j--
    +        }
    +    }
    +    return res
    +}
    +
    +
    +
    +
    max_capacity.rb
    [class]{}-[func]{max_capacity}
    +
    +
    +
    +
    max_capacity.zig
    [class]{}-[func]{maxCapacity}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    3.   Proof of correctness

    +

    The reason why the greedy method is faster than enumeration is that each round of greedy selection "skips" some states.

    +

    For example, under the state \(cap[i, j]\) where \(i\) is the shorter partition and \(j\) is the taller partition, greedily moving the shorter partition \(i\) inward by one step leads to the "skipped" states shown below. This means that these states' capacities cannot be verified later.

    +
    \[ +cap[i, i+1], cap[i, i+2], \dots, cap[i, j-2], cap[i, j-1] +\]
    +

    States skipped by moving the shorter partition

    +

    Figure 15-12   States skipped by moving the shorter partition

    + +

    It is observed that these skipped states are actually all states where the taller partition \(j\) is moved inward. We have already proven that moving the taller partition inward will definitely decrease the capacity. Therefore, the skipped states cannot possibly be the optimal solution, and skipping them does not lead to missing the optimal solution.

    +

    The analysis shows that the operation of moving the shorter partition is "safe", and the greedy strategy is effective.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_definition.png b/en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_definition.png new file mode 100644 index 0000000000000000000000000000000000000000..fae0741147109f3c52b7562196b4aa2cb1ba5a6a GIT binary patch literal 10708 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 Vs%O4IiI;wTt0`$H<|~-`{~IgbnM(iw literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_greedy_infer1.png b/en/chapter_greedy/max_product_cutting_problem.assets/max_product_cutting_greedy_infer1.png new file mode 100644 index 0000000000000000000000000000000000000000..b6d6539e3a501bc1d0b4ab2429cbff2b8e9dd4bb GIT binary patch literal 9497 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 literal 0 HcmV?d00001 diff --git a/en/chapter_greedy/max_product_cutting_problem/index.html b/en/chapter_greedy/max_product_cutting_problem/index.html new file mode 100644 index 000000000..9b8f67a96 --- /dev/null +++ b/en/chapter_greedy/max_product_cutting_problem/index.html @@ -0,0 +1,4218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.4 Maximum product cutting problem - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    15.4   Maximum product cutting problem

    +
    +

    Question

    +

    Given a positive integer \(n\), split it into at least two positive integers that sum up to \(n\), and find the maximum product of these integers, as illustrated below.

    +
    +

    Definition of the maximum product cutting problem

    +

    Figure 15-13   Definition of the maximum product cutting problem

    + +

    Assume we split \(n\) into \(m\) integer factors, where the \(i\)-th factor is denoted as \(n_i\), that is,

    +
    \[ +n = \sum_{i=1}^{m}n_i +\]
    +

    The goal of this problem is to find the maximum product of all integer factors, namely,

    +
    \[ +\max(\prod_{i=1}^{m}n_i) +\]
    +

    We need to consider: How large should the number of splits \(m\) be, and what should each \(n_i\) be?

    +

    1.   Greedy strategy determination

    +

    Experience suggests that the product of two integers is often greater than their sum. Suppose we split a factor of \(2\) from \(n\), then their product is \(2(n-2)\). Compare this product with \(n\):

    +
    \[ +\begin{aligned} +2(n-2) & \geq n \newline +2n - n - 4 & \geq 0 \newline +n & \geq 4 +\end{aligned} +\]
    +

    As shown below, when \(n \geq 4\), splitting out a \(2\) increases the product, which indicates that integers greater than or equal to \(4\) should be split.

    +

    Greedy strategy one: If the splitting scheme includes factors \(\geq 4\), they should be further split. The final split should only include factors \(1\), \(2\), and \(3\).

    +

    Product increase due to splitting

    +

    Figure 15-14   Product increase due to splitting

    + +

    Next, consider which factor is optimal. Among the factors \(1\), \(2\), and \(3\), clearly \(1\) is the worst, as \(1 \times (n-1) < n\) always holds, meaning splitting out \(1\) actually decreases the product.

    +

    As shown below, when \(n = 6\), \(3 \times 3 > 2 \times 2 \times 2\). This means splitting out \(3\) is better than splitting out \(2\).

    +

    Greedy strategy two: In the splitting scheme, there should be at most two \(2\)s. Because three \(2\)s can always be replaced by two \(3\)s to obtain a higher product.

    +

    Optimal splitting factors

    +

    Figure 15-15   Optimal splitting factors

    + +

    From the above, the following greedy strategies can be derived.

    +
      +
    1. Input integer \(n\), continually split out factor \(3\) until the remainder is \(0\), \(1\), or \(2\).
    2. +
    3. When the remainder is \(0\), it means \(n\) is a multiple of \(3\), so no further action is taken.
    4. +
    5. When the remainder is \(2\), do not continue to split, keep it.
    6. +
    7. When the remainder is \(1\), since \(2 \times 2 > 1 \times 3\), the last \(3\) should be replaced with \(2\).
    8. +
    +

    2.   Code implementation

    +

    As shown below, we do not need to use loops to split the integer but can use the floor division operation to get the number of \(3\)s, \(a\), and the modulo operation to get the remainder, \(b\), thus:

    +
    \[ +n = 3a + b +\]
    +

    Please note, for the boundary case where \(n \leq 3\), a \(1\) must be split out, with a product of \(1 \times (n - 1)\).

    +
    +
    +
    +
    max_product_cutting.py
    def max_product_cutting(n: int) -> int:
    +    """最大切分乘积:贪心"""
    +    # 当 n <= 3 时,必须切分出一个 1
    +    if n <= 3:
    +        return 1 * (n - 1)
    +    # 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    a, b = n // 3, n % 3
    +    if b == 1:
    +        # 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return int(math.pow(3, a - 1)) * 2 * 2
    +    if b == 2:
    +        # 当余数为 2 时,不做处理
    +        return int(math.pow(3, a)) * 2
    +    # 当余数为 0 时,不做处理
    +    return int(math.pow(3, a))
    +
    +
    +
    +
    max_product_cutting.cpp
    /* 最大切分乘积:贪心 */
    +int maxProductCutting(int n) {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    int a = n / 3;
    +    int b = n % 3;
    +    if (b == 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return (int)pow(3, a - 1) * 2 * 2;
    +    }
    +    if (b == 2) {
    +        // 当余数为 2 时,不做处理
    +        return (int)pow(3, a) * 2;
    +    }
    +    // 当余数为 0 时,不做处理
    +    return (int)pow(3, a);
    +}
    +
    +
    +
    +
    max_product_cutting.java
    /* 最大切分乘积:贪心 */
    +int maxProductCutting(int n) {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    int a = n / 3;
    +    int b = n % 3;
    +    if (b == 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return (int) Math.pow(3, a - 1) * 2 * 2;
    +    }
    +    if (b == 2) {
    +        // 当余数为 2 时,不做处理
    +        return (int) Math.pow(3, a) * 2;
    +    }
    +    // 当余数为 0 时,不做处理
    +    return (int) Math.pow(3, a);
    +}
    +
    +
    +
    +
    max_product_cutting.cs
    /* 最大切分乘积:贪心 */
    +int MaxProductCutting(int n) {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    int a = n / 3;
    +    int b = n % 3;
    +    if (b == 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return (int)Math.Pow(3, a - 1) * 2 * 2;
    +    }
    +    if (b == 2) {
    +        // 当余数为 2 时,不做处理
    +        return (int)Math.Pow(3, a) * 2;
    +    }
    +    // 当余数为 0 时,不做处理
    +    return (int)Math.Pow(3, a);
    +}
    +
    +
    +
    +
    max_product_cutting.go
    /* 最大切分乘积:贪心 */
    +func maxProductCutting(n int) int {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if n <= 3 {
    +        return 1 * (n - 1)
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    a := n / 3
    +    b := n % 3
    +    if b == 1 {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return int(math.Pow(3, float64(a-1))) * 2 * 2
    +    }
    +    if b == 2 {
    +        // 当余数为 2 时,不做处理
    +        return int(math.Pow(3, float64(a))) * 2
    +    }
    +    // 当余数为 0 时,不做处理
    +    return int(math.Pow(3, float64(a)))
    +}
    +
    +
    +
    +
    max_product_cutting.swift
    /* 最大切分乘积:贪心 */
    +func maxProductCutting(n: Int) -> Int {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if n <= 3 {
    +        return 1 * (n - 1)
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    let a = n / 3
    +    let b = n % 3
    +    if b == 1 {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return pow(3, a - 1) * 2 * 2
    +    }
    +    if b == 2 {
    +        // 当余数为 2 时,不做处理
    +        return pow(3, a) * 2
    +    }
    +    // 当余数为 0 时,不做处理
    +    return pow(3, a)
    +}
    +
    +
    +
    +
    max_product_cutting.js
    /* 最大切分乘积:贪心 */
    +function maxProductCutting(n) {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    let a = Math.floor(n / 3);
    +    let b = n % 3;
    +    if (b === 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return Math.pow(3, a - 1) * 2 * 2;
    +    }
    +    if (b === 2) {
    +        // 当余数为 2 时,不做处理
    +        return Math.pow(3, a) * 2;
    +    }
    +    // 当余数为 0 时,不做处理
    +    return Math.pow(3, a);
    +}
    +
    +
    +
    +
    max_product_cutting.ts
    /* 最大切分乘积:贪心 */
    +function maxProductCutting(n: number): number {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    let a: number = Math.floor(n / 3);
    +    let b: number = n % 3;
    +    if (b === 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return Math.pow(3, a - 1) * 2 * 2;
    +    }
    +    if (b === 2) {
    +        // 当余数为 2 时,不做处理
    +        return Math.pow(3, a) * 2;
    +    }
    +    // 当余数为 0 时,不做处理
    +    return Math.pow(3, a);
    +}
    +
    +
    +
    +
    max_product_cutting.dart
    /* 最大切分乘积:贪心 */
    +int maxProductCutting(int n) {
    +  // 当 n <= 3 时,必须切分出一个 1
    +  if (n <= 3) {
    +    return 1 * (n - 1);
    +  }
    +  // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +  int a = n ~/ 3;
    +  int b = n % 3;
    +  if (b == 1) {
    +    // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +    return (pow(3, a - 1) * 2 * 2).toInt();
    +  }
    +  if (b == 2) {
    +    // 当余数为 2 时,不做处理
    +    return (pow(3, a) * 2).toInt();
    +  }
    +  // 当余数为 0 时,不做处理
    +  return pow(3, a).toInt();
    +}
    +
    +
    +
    +
    max_product_cutting.rs
    /* 最大切分乘积:贪心 */
    +fn max_product_cutting(n: i32) -> i32 {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if n <= 3 {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    let a = n / 3;
    +    let b = n % 3;
    +    if b == 1 {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        3_i32.pow(a as u32 - 1) * 2 * 2
    +    } else if b == 2 {
    +        // 当余数为 2 时,不做处理
    +        3_i32.pow(a as u32) * 2
    +    } else {
    +        // 当余数为 0 时,不做处理
    +        3_i32.pow(a as u32)
    +    }
    +}
    +
    +
    +
    +
    max_product_cutting.c
    /* 最大切分乘积:贪心 */
    +int maxProductCutting(int n) {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1);
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    int a = n / 3;
    +    int b = n % 3;
    +    if (b == 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return pow(3, a - 1) * 2 * 2;
    +    }
    +    if (b == 2) {
    +        // 当余数为 2 时,不做处理
    +        return pow(3, a) * 2;
    +    }
    +    // 当余数为 0 时,不做处理
    +    return pow(3, a);
    +}
    +
    +
    +
    +
    max_product_cutting.kt
    /* 最大切分乘积:贪心 */
    +fun maxProductCutting(n: Int): Int {
    +    // 当 n <= 3 时,必须切分出一个 1
    +    if (n <= 3) {
    +        return 1 * (n - 1)
    +    }
    +    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
    +    val a = n / 3
    +    val b = n % 3
    +    if (b == 1) {
    +        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
    +        return 3.0.pow((a - 1)).toInt() * 2 * 2
    +    }
    +    if (b == 2) {
    +        // 当余数为 2 时,不做处理
    +        return 3.0.pow(a).toInt() * 2 * 2
    +    }
    +    // 当余数为 0 时,不做处理
    +    return 3.0.pow(a).toInt()
    +}
    +
    +
    +
    +
    max_product_cutting.rb
    [class]{}-[func]{max_product_cutting}
    +
    +
    +
    +
    max_product_cutting.zig
    [class]{}-[func]{maxProductCutting}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    Calculation method of the maximum product after cutting

    +

    Figure 15-16   Calculation method of the maximum product after cutting

    + +

    Time complexity depends on the implementation of the power operation in the programming language. For Python, the commonly used power calculation functions are three types:

    +
      +
    • Both the operator ** and the function pow() have a time complexity of \(O(\log⁡ a)\).
    • +
    • The math.pow() function internally calls the C language library's pow() function, performing floating-point exponentiation, with a time complexity of \(O(1)\).
    • +
    +

    Variables \(a\) and \(b\) use constant size of extra space, hence the space complexity is \(O(1)\).

    +

    3.   Correctness proof

    +

    Using the proof by contradiction, only analyze cases where \(n \geq 3\).

    +
      +
    1. All factors \(\leq 3\): Assume the optimal splitting scheme includes a factor \(x \geq 4\), then it can definitely be further split into \(2(x-2)\), obtaining a larger product. This contradicts the assumption.
    2. +
    3. The splitting scheme does not contain \(1\): Assume the optimal splitting scheme includes a factor of \(1\), then it can definitely be merged into another factor to obtain a larger product. This contradicts the assumption.
    4. +
    5. The splitting scheme contains at most two \(2\)s: Assume the optimal splitting scheme includes three \(2\)s, then they can definitely be replaced by two \(3\)s, achieving a higher product. This contradicts the assumption.
    6. +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_greedy/summary/index.html b/en/chapter_greedy/summary/index.html new file mode 100644 index 000000000..fb92e55c5 --- /dev/null +++ b/en/chapter_greedy/summary/index.html @@ -0,0 +1,3785 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.5 Summary - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    15.5   Summary

    +
      +
    • Greedy algorithms are often used to solve optimization problems, where the principle is to make locally optimal decisions at each decision stage in order to achieve a globally optimal solution.
    • +
    • Greedy algorithms iteratively make one greedy choice after another, transforming the problem into a smaller sub-problem with each round, until the problem is resolved.
    • +
    • Greedy algorithms are not only simple to implement but also have high problem-solving efficiency. Compared to dynamic programming, greedy algorithms generally have a lower time complexity.
    • +
    • In the problem of coin change, greedy algorithms can guarantee the optimal solution for certain combinations of coins; for others, however, the greedy algorithm might find a very poor solution.
    • +
    • Problems suitable for greedy algorithm solutions possess two main properties: greedy-choice property and optimal substructure. The greedy-choice property represents the effectiveness of the greedy strategy.
    • +
    • For some complex problems, proving the greedy-choice property is not straightforward. Contrarily, proving the invalidity is often easier, such as with the coin change problem.
    • +
    • Solving greedy problems mainly consists of three steps: problem analysis, determining the greedy strategy, and proving correctness. Among these, determining the greedy strategy is the key step, while proving correctness often poses the challenge.
    • +
    • The fractional knapsack problem builds on the 0-1 knapsack problem by allowing the selection of a part of the items, hence it can be solved using a greedy algorithm. The correctness of the greedy strategy can be proved by contradiction.
    • +
    • The maximum capacity problem can be solved using the exhaustive method, with a time complexity of \(O(n^2)\). By designing a greedy strategy, each round moves inwardly shortening the board, optimizing the time complexity to \(O(n)\).
    • +
    • In the problem of maximum product after cutting, we deduce two greedy strategies: integers \(\geq 4\) should continue to be cut, with the optimal cutting factor being \(3\). The code includes power operations, and the time complexity depends on the method of implementing power operations, generally being \(O(1)\) or \(O(\log n)\).
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_hashing/hash_algorithm/index.html b/en/chapter_hashing/hash_algorithm/index.html index f50310174..9e5da9570 100644 --- a/en/chapter_hashing/hash_algorithm/index.html +++ b/en/chapter_hashing/hash_algorithm/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1653,7 +1653,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_hashing/hash_collision/index.html b/en/chapter_hashing/hash_collision/index.html index cecf041e1..993f70a45 100644 --- a/en/chapter_hashing/hash_collision/index.html +++ b/en/chapter_hashing/hash_collision/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1686,7 +1686,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2095,6 +2095,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_hashing/hash_map/index.html b/en/chapter_hashing/hash_map/index.html index dd49035b8..6e1f5d9a4 100644 --- a/en/chapter_hashing/hash_map/index.html +++ b/en/chapter_hashing/hash_map/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1653,7 +1653,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_hashing/index.html b/en/chapter_hashing/index.html index 2e05fd80d..48975d153 100644 --- a/en/chapter_hashing/index.html +++ b/en/chapter_hashing/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_hashing/summary/index.html b/en/chapter_hashing/summary/index.html index b320473ce..645605911 100644 --- a/en/chapter_hashing/summary/index.html +++ b/en/chapter_hashing/summary/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_heap/build_heap/index.html b/en/chapter_heap/build_heap/index.html index 07a3b2070..d8b9b4707 100644 --- a/en/chapter_heap/build_heap/index.html +++ b/en/chapter_heap/build_heap/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_heap/heap/index.html b/en/chapter_heap/heap/index.html index 01e5517dc..bd04f2491 100644 --- a/en/chapter_heap/heap/index.html +++ b/en/chapter_heap/heap/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2104,6 +2104,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_heap/index.html b/en/chapter_heap/index.html index 49c8e05f0..24e9a5514 100644 --- a/en/chapter_heap/index.html +++ b/en/chapter_heap/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_heap/summary/index.html b/en/chapter_heap/summary/index.html index ab629401a..6adfb33e9 100644 --- a/en/chapter_heap/summary/index.html +++ b/en/chapter_heap/summary/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_heap/top_k/index.html b/en/chapter_heap/top_k/index.html index de0fd98ba..ac9bcab79 100644 --- a/en/chapter_heap/top_k/index.html +++ b/en/chapter_heap/top_k/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_hello_algo/index.html b/en/chapter_hello_algo/index.html index 6a7d8be59..759606a40 100644 --- a/en/chapter_hello_algo/index.html +++ b/en/chapter_hello_algo/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1584,7 +1584,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1993,6 +1993,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + @@ -2050,10 +3507,10 @@

    Before starting

    A few years ago, I shared the "Sword for Offer" problem solutions on LeetCode, receiving encouragement and support from many readers. During interactions with readers, the most common question I encountered was "how to get started with algorithms." Gradually, I developed a keen interest in this question.

    Directly solving problems seems to be the most popular method — it's simple, direct, and effective. However, problem-solving is like playing a game of Minesweeper: those with strong self-study abilities can defuse the mines one by one, but those with insufficient basics might end up metaphorically bruised from explosions, retreating step by step in frustration. Going through textbooks is also common, but for those aiming for job applications, the energy spent on thesis writing, resume submissions, and preparation for written tests and interviews leaves little for tackling thick books, turning it into a daunting challenge.

    -

    If you're facing similar troubles, then this book are lucky to have found you. This book is my answer to the question. While it may not be the best solution, it is at least a positive attempt. This book may not directly land you an offer, but it will guide you through the "knowledge map" in data structures and algorithms, help you understand the shapes, sizes, and locations of different "mines," and enable you to master various "demining methods." With these skills, I believe you can solve problems and read literature more comfortably, gradually building a knowledge system.

    +

    If you're facing similar troubles, then this book is lucky to have found you. This book is my answer to the question. While it may not be the best solution, it is at least a positive attempt. This book may not directly land you an offer, but it will guide you through the "knowledge map" in data structures and algorithms, help you understand the shapes, sizes, and locations of different "mines," and enable you to master various "demining methods." With these skills, I believe you can solve problems and read literature more comfortably, gradually building a knowledge system.

    I deeply agree with Professor Feynman's statement: "Knowledge isn't free. You have to pay attention." In this sense, this book is not entirely "free." To not disappoint the precious "attention" you pay for this book, I will do my best, dedicating my utmost "attention" to this book.

    Knowing my limitations, although the content of this book has been refined over time, there are surely many errors remaining. I sincerely request critiques and corrections from all teachers and students.

    -

    Hello Algorithms

    +

    Hello Algo

    Hello, Algo!

    diff --git a/en/chapter_introduction/algorithms_are_everywhere/index.html b/en/chapter_introduction/algorithms_are_everywhere/index.html index 618619982..e8eb5968a 100644 --- a/en/chapter_introduction/algorithms_are_everywhere/index.html +++ b/en/chapter_introduction/algorithms_are_everywhere/index.html @@ -1151,7 +1151,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1596,7 +1596,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2005,6 +2005,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_introduction/index.html b/en/chapter_introduction/index.html index 579815334..65740e66a 100644 --- a/en/chapter_introduction/index.html +++ b/en/chapter_introduction/index.html @@ -1141,7 +1141,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_introduction/summary/index.html b/en/chapter_introduction/summary/index.html index 5c4e01c34..b0fff8011 100644 --- a/en/chapter_introduction/summary/index.html +++ b/en/chapter_introduction/summary/index.html @@ -1151,7 +1151,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1596,7 +1596,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2005,6 +2005,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_introduction/what_is_dsa/index.html b/en/chapter_introduction/what_is_dsa/index.html index a0a148003..77eaa8e5e 100644 --- a/en/chapter_introduction/what_is_dsa/index.html +++ b/en/chapter_introduction/what_is_dsa/index.html @@ -1208,7 +1208,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1653,7 +1653,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_preface/about_the_book/index.html b/en/chapter_preface/about_the_book/index.html index e193f2603..d412ca804 100644 --- a/en/chapter_preface/about_the_book/index.html +++ b/en/chapter_preface/about_the_book/index.html @@ -1208,7 +1208,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1653,7 +1653,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_preface/index.html b/en/chapter_preface/index.html index 4fc899654..0f21f65e1 100644 --- a/en/chapter_preface/index.html +++ b/en/chapter_preface/index.html @@ -1141,7 +1141,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_preface/suggestions/index.html b/en/chapter_preface/suggestions/index.html index 2652acb32..66f47a973 100644 --- a/en/chapter_preface/suggestions/index.html +++ b/en/chapter_preface/suggestions/index.html @@ -1226,7 +1226,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1671,7 +1671,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2080,6 +2080,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_preface/summary/index.html b/en/chapter_preface/summary/index.html index 1886dd50b..a2b859ae6 100644 --- a/en/chapter_preface/summary/index.html +++ b/en/chapter_preface/summary/index.html @@ -1151,7 +1151,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1596,7 +1596,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2005,6 +2005,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_reference/index.html b/en/chapter_reference/index.html new file mode 100644 index 000000000..8be107621 --- /dev/null +++ b/en/chapter_reference/index.html @@ -0,0 +1,3679 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + References - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    References

    +

    [1] Thomas H. Cormen, et al. Introduction to Algorithms (3rd Edition).

    +

    [2] Aditya Bhargava. Grokking Algorithms: An Illustrated Guide for Programmers and Other Curious People (1st Edition).

    +

    [3] Robert Sedgewick, et al. Algorithms (4th Edition).

    +

    [4] Yan Weimin. Data Structures (C Language Version).

    +

    [5] Deng Junhui. Data Structures (C++ Language Version, Third Edition).

    +

    [6] Mark Allen Weiss, translated by Chen Yue. Data Structures and Algorithm Analysis in Java (Third Edition).

    +

    [7] Cheng Jie. Speaking of Data Structures.

    +

    [8] Wang Zheng. The Beauty of Data Structures and Algorithms.

    +

    [9] Gayle Laakmann McDowell. Cracking the Coding Interview: 189 Programming Questions and Solutions (6th Edition).

    +

    [10] Aston Zhang, et al. Dive into Deep Learning.

    + + + + + + + + + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/binary_search.assets/binary_search_example.png b/en/chapter_searching/binary_search.assets/binary_search_example.png new file mode 100644 index 0000000000000000000000000000000000000000..9051addbd4de1c44becd24acf81cb1a2cc4401d0 GIT binary patch literal 16862 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

    Kg;y+VjS2I}$s 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 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search.assets/binary_search_ranges.png b/en/chapter_searching/binary_search.assets/binary_search_ranges.png new file mode 100644 index 0000000000000000000000000000000000000000..93bc6a3249de243dd83a8825f8e39b822df056fe GIT binary patch literal 26366 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 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search.assets/binary_search_step2.png b/en/chapter_searching/binary_search.assets/binary_search_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..60637300612daf9003cd315f8064552a215be2f6 GIT binary patch literal 13595 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 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search.assets/binary_search_step3.png b/en/chapter_searching/binary_search.assets/binary_search_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..0184c3a23db8216b9a57213ea69d2f41835eb315 GIT binary patch literal 16961 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 E0E#oCO#lD@ literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search.assets/binary_search_step4.png b/en/chapter_searching/binary_search.assets/binary_search_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..54e8e12c38ffa2167cd58c646619010ea699bc20 GIT binary patch literal 13035 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 H!0-P6xL#^n literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search/index.html b/en/chapter_searching/binary_search/index.html new file mode 100644 index 000000000..9f08e352b --- /dev/null +++ b/en/chapter_searching/binary_search/index.html @@ -0,0 +1,4546 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.1 Binary search - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    10.1   Binary search

    +

    Binary search is an efficient search algorithm based on the divide-and-conquer strategy. It utilizes the orderliness of data, reducing the search range by half each round until the target element is found or the search interval is empty.

    +
    +

    Question

    +

    Given an array nums of length \(n\), with elements arranged in ascending order and non-repeating. Please find and return the index of element target in this array. If the array does not contain the element, return \(-1\). An example is shown below.

    +
    +

    Binary search example data

    +

    Figure 10-1   Binary search example data

    + +

    As shown in the Figure 10-2 , we first initialize pointers \(i = 0\) and \(j = n - 1\), pointing to the first and last elements of the array, representing the search interval \([0, n - 1]\). Please note that square brackets indicate a closed interval, which includes the boundary values themselves.

    +

    Next, perform the following two steps in a loop.

    +
      +
    1. Calculate the midpoint index \(m = \lfloor {(i + j) / 2} \rfloor\), where \(\lfloor \: \rfloor\) denotes the floor operation.
    2. +
    3. Compare the size of nums[m] and target, divided into the following three scenarios.
        +
      1. If nums[m] < target, it indicates that target is in the interval \([m + 1, j]\), thus set \(i = m + 1\).
      2. +
      3. If nums[m] > target, it indicates that target is in the interval \([i, m - 1]\), thus set \(j = m - 1\).
      4. +
      5. If nums[m] = target, it indicates that target is found, thus return index \(m\).
      6. +
      +
    4. +
    +

    If the array does not contain the target element, the search interval will eventually reduce to empty. In this case, return \(-1\).

    +
    +
    +
    +

    Binary search process

    +
    +
    +

    binary_search_step2

    +
    +
    +

    binary_search_step3

    +
    +
    +

    binary_search_step4

    +
    +
    +

    binary_search_step5

    +
    +
    +

    binary_search_step6

    +
    +
    +

    binary_search_step7

    +
    +
    +
    +

    Figure 10-2   Binary search process

    + +

    It's worth noting that since \(i\) and \(j\) are both of type int, \(i + j\) might exceed the range of int type. To avoid large number overflow, we usually use the formula \(m = \lfloor {i + (j - i) / 2} \rfloor\) to calculate the midpoint.

    +

    The code is as follows:

    +
    +
    +
    +
    binary_search.py
    def binary_search(nums: list[int], target: int) -> int:
    +    """二分查找(双闭区间)"""
    +    # 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    i, j = 0, len(nums) - 1
    +    # 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while i <= j:
    +        # 理论上 Python 的数字可以无限大(取决于内存大小),无须考虑大数越界问题
    +        m = (i + j) // 2  # 计算中点索引 m
    +        if nums[m] < target:
    +            i = m + 1  # 此情况说明 target 在区间 [m+1, j] 中
    +        elif nums[m] > target:
    +            j = m - 1  # 此情况说明 target 在区间 [i, m-1] 中
    +        else:
    +            return m  # 找到目标元素,返回其索引
    +    return -1  # 未找到目标元素,返回 -1
    +
    +
    +
    +
    binary_search.cpp
    /* 二分查找(双闭区间) */
    +int binarySearch(vector<int> &nums, int target) {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    int i = 0, j = nums.size() - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target)    // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        else // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.java
    /* 二分查找(双闭区间) */
    +int binarySearch(int[] nums, int target) {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    int i = 0, j = nums.length - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        else // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.cs
    /* 二分查找(双闭区间) */
    +int BinarySearch(int[] nums, int target) {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    int i = 0, j = nums.Length - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        int m = i + (j - i) / 2;   // 计算中点索引 m
    +        if (nums[m] < target)      // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        else                       // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.go
    /* 二分查找(双闭区间) */
    +func binarySearch(nums []int, target int) int {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    i, j := 0, len(nums)-1
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    for i <= j {
    +        m := i + (j-i)/2      // 计算中点索引 m
    +        if nums[m] < target { // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1
    +        } else if nums[m] > target { // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1
    +        } else { // 找到目标元素,返回其索引
    +            return m
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1
    +}
    +
    +
    +
    +
    binary_search.swift
    /* 二分查找(双闭区间) */
    +func binarySearch(nums: [Int], target: Int) -> Int {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    var i = nums.startIndex
    +    var j = nums.endIndex - 1
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while i <= j {
    +        let m = i + (j - i) / 2 // 计算中点索引 m
    +        if nums[m] < target { // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1
    +        } else if nums[m] > target { // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1
    +        } else { // 找到目标元素,返回其索引
    +            return m
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1
    +}
    +
    +
    +
    +
    binary_search.js
    /* 二分查找(双闭区间) */
    +function binarySearch(nums, target) {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    let i = 0,
    +        j = nums.length - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        // 计算中点索引 m ,使用 parseInt() 向下取整
    +        const m = parseInt(i + (j - i) / 2);
    +        if (nums[m] < target)
    +            // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        else if (nums[m] > target)
    +            // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        else return m; // 找到目标元素,返回其索引
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.ts
    /* 二分查找(双闭区间) */
    +function binarySearch(nums: number[], target: number): number {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    let i = 0,
    +        j = nums.length - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        // 计算中点索引 m
    +        const m = Math.floor(i + (j - i) / 2);
    +        if (nums[m] < target) {
    +            // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        } else if (nums[m] > target) {
    +            // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        } else {
    +            // 找到目标元素,返回其索引
    +            return m;
    +        }
    +    }
    +    return -1; // 未找到目标元素,返回 -1
    +}
    +
    +
    +
    +
    binary_search.dart
    /* 二分查找(双闭区间) */
    +int binarySearch(List<int> nums, int target) {
    +  // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +  int i = 0, j = nums.length - 1;
    +  // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +  while (i <= j) {
    +    int m = i + (j - i) ~/ 2; // 计算中点索引 m
    +    if (nums[m] < target) {
    +      // 此情况说明 target 在区间 [m+1, j] 中
    +      i = m + 1;
    +    } else if (nums[m] > target) {
    +      // 此情况说明 target 在区间 [i, m-1] 中
    +      j = m - 1;
    +    } else {
    +      // 找到目标元素,返回其索引
    +      return m;
    +    }
    +  }
    +  // 未找到目标元素,返回 -1
    +  return -1;
    +}
    +
    +
    +
    +
    binary_search.rs
    /* 二分查找(双闭区间) */
    +fn binary_search(nums: &[i32], target: i32) -> i32 {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    let mut i = 0;
    +    let mut j = nums.len() as i32 - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while i <= j {
    +        let m = i + (j - i) / 2; // 计算中点索引 m
    +        if nums[m as usize] < target {
    +            // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        } else if nums[m as usize] > target {
    +            // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        } else {
    +            // 找到目标元素,返回其索引
    +            return m;
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.c
    /* 二分查找(双闭区间) */
    +int binarySearch(int *nums, int len, int target) {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    int i = 0, j = len - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target)    // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        else // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.kt
    /* 二分查找(双闭区间) */
    +fun binarySearch(nums: IntArray, target: Int): Int {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    var i = 0
    +    var j = nums.size - 1
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        val m = i + (j - i) / 2 // 计算中点索引 m
    +        if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1
    +        else  // 找到目标元素,返回其索引
    +            return m
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1
    +}
    +
    +
    +
    +
    binary_search.rb
    ### 二分查找(双闭区间) ###
    +def binary_search(nums, target)
    +  # 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +  i, j = 0, nums.length - 1
    +
    +  # 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +  while i <= j
    +    # 理论上 Ruby 的数字可以无限大(取决于内存大小),无须考虑大数越界问题
    +    m = (i + j) / 2   # 计算中点索引 m
    +
    +    if nums[m] < target
    +      i = m + 1 # 此情况说明 target 在区间 [m+1, j] 中
    +    elsif nums[m] > target
    +      j = m - 1 # 此情况说明 target 在区间 [i, m-1] 中
    +    else
    +      return m  # 找到目标元素,返回其索引
    +    end
    +  end
    +
    +  -1  # 未找到目标元素,返回 -1
    +end
    +
    +
    +
    +
    binary_search.zig
    // 二分查找(双闭区间)
    +fn binarySearch(comptime T: type, nums: std.ArrayList(T), target: T) T {
    +    // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
    +    var i: usize = 0;
    +    var j: usize = nums.items.len - 1;
    +    // 循环,当搜索区间为空时跳出(当 i > j 时为空)
    +    while (i <= j) {
    +        var m = i + (j - i) / 2;                // 计算中点索引 m
    +        if (nums.items[m] < target) {           // 此情况说明 target 在区间 [m+1, j] 中
    +            i = m + 1;
    +        } else if (nums.items[m] > target) {    // 此情况说明 target 在区间 [i, m-1] 中
    +            j = m - 1;
    +        } else {                                // 找到目标元素,返回其索引
    +            return @intCast(m);
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    Time complexity is \(O(\log n)\) : In the binary loop, the interval reduces by half each round, hence the number of iterations is \(\log_2 n\).

    +

    Space complexity is \(O(1)\) : Pointers \(i\) and \(j\) use constant size space.

    +

    10.1.1   Interval representation methods

    +

    Besides the aforementioned closed interval, a common interval representation is the "left-closed right-open" interval, defined as \([0, n)\), where the left boundary includes itself, and the right boundary does not include itself. In this representation, the interval \([i, j)\) is empty when \(i = j\).

    +

    We can implement a binary search algorithm with the same functionality based on this representation:

    +
    +
    +
    +
    binary_search.py
    def binary_search_lcro(nums: list[int], target: int) -> int:
    +    """二分查找(左闭右开区间)"""
    +    # 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    i, j = 0, len(nums)
    +    # 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while i < j:
    +        m = (i + j) // 2  # 计算中点索引 m
    +        if nums[m] < target:
    +            i = m + 1  # 此情况说明 target 在区间 [m+1, j) 中
    +        elif nums[m] > target:
    +            j = m  # 此情况说明 target 在区间 [i, m) 中
    +        else:
    +            return m  # 找到目标元素,返回其索引
    +    return -1  # 未找到目标元素,返回 -1
    +
    +
    +
    +
    binary_search.cpp
    /* 二分查找(左闭右开区间) */
    +int binarySearchLCRO(vector<int> &nums, int target) {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    int i = 0, j = nums.size();
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target)    // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        else // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.java
    /* 二分查找(左闭右开区间) */
    +int binarySearchLCRO(int[] nums, int target) {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    int i = 0, j = nums.length;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        else // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.cs
    /* 二分查找(左闭右开区间) */
    +int BinarySearchLCRO(int[] nums, int target) {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    int i = 0, j = nums.Length;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        int m = i + (j - i) / 2;   // 计算中点索引 m
    +        if (nums[m] < target)      // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        else                       // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.go
    /* 二分查找(左闭右开区间) */
    +func binarySearchLCRO(nums []int, target int) int {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    i, j := 0, len(nums)
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    for i < j {
    +        m := i + (j-i)/2      // 计算中点索引 m
    +        if nums[m] < target { // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1
    +        } else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中
    +            j = m
    +        } else { // 找到目标元素,返回其索引
    +            return m
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1
    +}
    +
    +
    +
    +
    binary_search.swift
    /* 二分查找(左闭右开区间) */
    +func binarySearchLCRO(nums: [Int], target: Int) -> Int {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    var i = nums.startIndex
    +    var j = nums.endIndex
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while i < j {
    +        let m = i + (j - i) / 2 // 计算中点索引 m
    +        if nums[m] < target { // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1
    +        } else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中
    +            j = m
    +        } else { // 找到目标元素,返回其索引
    +            return m
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1
    +}
    +
    +
    +
    +
    binary_search.js
    /* 二分查找(左闭右开区间) */
    +function binarySearchLCRO(nums, target) {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    let i = 0,
    +        j = nums.length;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        // 计算中点索引 m ,使用 parseInt() 向下取整
    +        const m = parseInt(i + (j - i) / 2);
    +        if (nums[m] < target)
    +            // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        else if (nums[m] > target)
    +            // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        // 找到目标元素,返回其索引
    +        else return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.ts
    /* 二分查找(左闭右开区间) */
    +function binarySearchLCRO(nums: number[], target: number): number {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    let i = 0,
    +        j = nums.length;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        // 计算中点索引 m
    +        const m = Math.floor(i + (j - i) / 2);
    +        if (nums[m] < target) {
    +            // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        } else if (nums[m] > target) {
    +            // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        } else {
    +            // 找到目标元素,返回其索引
    +            return m;
    +        }
    +    }
    +    return -1; // 未找到目标元素,返回 -1
    +}
    +
    +
    +
    +
    binary_search.dart
    /* 二分查找(左闭右开区间) */
    +int binarySearchLCRO(List<int> nums, int target) {
    +  // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +  int i = 0, j = nums.length;
    +  // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +  while (i < j) {
    +    int m = i + (j - i) ~/ 2; // 计算中点索引 m
    +    if (nums[m] < target) {
    +      // 此情况说明 target 在区间 [m+1, j) 中
    +      i = m + 1;
    +    } else if (nums[m] > target) {
    +      // 此情况说明 target 在区间 [i, m) 中
    +      j = m;
    +    } else {
    +      // 找到目标元素,返回其索引
    +      return m;
    +    }
    +  }
    +  // 未找到目标元素,返回 -1
    +  return -1;
    +}
    +
    +
    +
    +
    binary_search.rs
    /* 二分查找(左闭右开区间) */
    +fn binary_search_lcro(nums: &[i32], target: i32) -> i32 {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    let mut i = 0;
    +    let mut j = nums.len() as i32;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while i < j {
    +        let m = i + (j - i) / 2; // 计算中点索引 m
    +        if nums[m as usize] < target {
    +            // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        } else if nums[m as usize] > target {
    +            // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        } else {
    +            // 找到目标元素,返回其索引
    +            return m;
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.c
    /* 二分查找(左闭右开区间) */
    +int binarySearchLCRO(int *nums, int len, int target) {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    int i = 0, j = len;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target)    // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        else // 找到目标元素,返回其索引
    +            return m;
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    binary_search.kt
    /* 二分查找(左闭右开区间) */
    +fun binarySearchLCRO(nums: IntArray, target: Int): Int {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    var i = 0
    +    var j = nums.size
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i < j) {
    +        val m = i + (j - i) / 2 // 计算中点索引 m
    +        if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1
    +        else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
    +            j = m
    +        else  // 找到目标元素,返回其索引
    +            return m
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1
    +}
    +
    +
    +
    +
    binary_search.rb
    ### 二分查找(左闭右开区间) ###
    +def binary_search_lcro(nums, target)
    +  # 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +  i, j = 0, nums.length
    +
    +  # 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +  while i < j
    +    # 计算中点索引 m
    +    m = (i + j) / 2
    +
    +    if nums[m] < target
    +      i = m + 1 # 此情况说明 target 在区间 [m+1, j) 中
    +    elsif nums[m] > target
    +      j = m - 1 # 此情况说明 target 在区间 [i, m) 中
    +    else
    +      return m  # 找到目标元素,返回其索引
    +    end
    +  end
    +
    +  -1  # 未找到目标元素,返回 -1
    +end
    +
    +
    +
    +
    binary_search.zig
    // 二分查找(左闭右开区间)
    +fn binarySearchLCRO(comptime T: type, nums: std.ArrayList(T), target: T) T {
    +    // 初始化左闭右开区间 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
    +    var i: usize = 0;
    +    var j: usize = nums.items.len;
    +    // 循环,当搜索区间为空时跳出(当 i = j 时为空)
    +    while (i <= j) {
    +        var m = i + (j - i) / 2;                // 计算中点索引 m
    +        if (nums.items[m] < target) {           // 此情况说明 target 在区间 [m+1, j) 中
    +            i = m + 1;
    +        } else if (nums.items[m] > target) {    // 此情况说明 target 在区间 [i, m) 中
    +            j = m;
    +        } else {                                // 找到目标元素,返回其索引
    +            return @intCast(m);
    +        }
    +    }
    +    // 未找到目标元素,返回 -1
    +    return -1;
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    As shown in the Figure 10-3 , in the two types of interval representations, the initialization of the binary search algorithm, the loop condition, and the narrowing interval operation are different.

    +

    Since both boundaries in the "closed interval" representation are defined as closed, the operations to narrow the interval through pointers \(i\) and \(j\) are also symmetrical. This makes it less prone to errors, therefore, it is generally recommended to use the "closed interval" approach.

    +

    Two types of interval definitions

    +

    Figure 10-3   Two types of interval definitions

    + +

    10.1.2   Advantages and limitations

    +

    Binary search performs well in both time and space aspects.

    +
      +
    • Binary search is time-efficient. With large data volumes, the logarithmic time complexity has a significant advantage. For instance, when the data size \(n = 2^{20}\), linear search requires \(2^{20} = 1048576\) iterations, while binary search only requires \(\log_2 2^{20} = 20\) iterations.
    • +
    • Binary search does not require extra space. Compared to search algorithms that rely on additional space (like hash search), binary search is more space-efficient.
    • +
    +

    However, binary search is not suitable for all situations, mainly for the following reasons.

    +
      +
    • Binary search is only applicable to ordered data. If the input data is unordered, it is not worth sorting it just to use binary search, as sorting algorithms typically have a time complexity of \(O(n \log n)\), which is higher than both linear and binary search. For scenarios with frequent element insertion to maintain array order, inserting elements into specific positions has a time complexity of \(O(n)\), which is also quite costly.
    • +
    • Binary search is only applicable to arrays. Binary search requires non-continuous (jumping) element access, which is inefficient in linked lists, thus not suitable for use in linked lists or data structures based on linked lists.
    • +
    • With small data volumes, linear search performs better. In linear search, each round only requires 1 decision operation; whereas in binary search, it involves 1 addition, 1 division, 1 to 3 decision operations, 1 addition (subtraction), totaling 4 to 6 operations; therefore, when data volume \(n\) is small, linear search can be faster than binary search.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/binary_search_edge.assets/binary_search_edge_by_element.png b/en/chapter_searching/binary_search_edge.assets/binary_search_edge_by_element.png new file mode 100644 index 0000000000000000000000000000000000000000..b2799062a78c0d406461770f1a2c4a6808934ef2 GIT binary patch literal 14311 zcmbVy1yq$^l<#*h9nvY?ASoasd8NBkBm_Y~QfUM(AV^7v2uKSE(w&#?u1jCKTe{x$ zKl9$qtT!|7t@&8%#6J7%`0c&V{l2pZ)lidvg#8#B0Dwn|3Nl&%fQB4`M=(*4-DNiS zTjbfgV+yK8Q4Ze(PXHIUiY*LQJofjB^{t*tFBEtQm%+}zx>wY9l9J9l??56;3v zLP8`YB*wi8TwFXbFfcMQl8}%P9v-fv zqcb-*7Z@10xV#L9!{g)QH8eEZ+uM_qlfQK({rU6f^5&|xw$`tr*viVPvZ5j;CI$k5 zG&D3678c4TMNUji)Q=2hWo5n1%P=)Hy}P^H-`{VUZ*g&Pk&=?q*Vq42Tj5<+2fYfV*^hlht|T7td3{npl2RaseJLx5Upyz=+htd3SEC#U=c z_|KuAQBhH8J*iQxk>YV-os$zK!^KWTKl6V69G#o385-#9?99#06^#vT938HkuC*`B zIk`NEZm8*8>}YCg`qt9m>*F)OJ3q5CqmUfaIx*IR=s~oL*gf5i zj*ian?uhS*JG!{6YTaL5Tbr1lLxQz&d^EB?5*!pXaj`S$kq*v8t_;(}#+y=P@{*D9iOY5rSRYr{+fw6-Fsx~y+!^G9#z@cN&@$y3)V zMB2=F^Vo<CdV|S z$zPh$+(E5F9!K~x{K1jJjxX;lWzUCUf-{3Z2b0wpQH#vZ4IR3`>8TY0GuQ$u9^?;C zhg2kG4V=-IrY$@QvGhP??(ZO!% zr(+Q%=tsHLhs$ZFbae9op{88GfzCwf+GzGKTf6OMgHU%(|GFzq0BB*|L5@Jh_(Qfi>o*LPGXi z-_VbqhJ=*AL3aXRNkPAwFcA&)9pH=_mHE7c=Qq14xI=eAG<_&5K`4Uhtb{+x37*Es~CQG<4OpIO`{U#&d7sj@+-mEQjRs91(mD zDSu0A4A)58SP_|ugU3N+X5mT=!iqd0-6Fx;`YmRzaoZg;s|87X)a8kI0U_+fR@IHk zlC;ldI!w{|J_rUtn4h4sDqflFQZy7(Ne)t`2stl)rvtZ$7p{UsLio+lM`(mts&LJ) zwl3a5j3!2?sy0eQ&SQyV5_Y{*X>5P3zk$tb;!cxctSUjKKWws8nJk_t;?t_7k2EK_lq2+MTQFCZ z|Be#S;#YT$wI!CIV^P{{BP~j282X%^u}>rZ^WH4xwFc8~8&LWzdO`&4Xw&6Y$um*~Zq>Wv8`mx83_QnAzBZ%J*;lS= zqo!7Qo5bh%>FVh=?~_i2wc>sXM2%4Wu0-H1aK=38y1-CRzh(23a5*S>p%q7zZ0%Sv z7AA^I*Qzu61OKkSizym!;bMA08@WW`ST>d=>O$8_a(q@tEI{k;Vx4}R>XP!~PtRK^ zaub_TnqY8FNJs}S=q3@L<|g8!?-=*B3M*ax@7Ff_G>k&|^o*yuukTH%VT zC!E~%f#96T*Pv=0_Hi=#zr_9jO^lLn>Q4QEmv)mXAX?C!<9n4rw(t_9CEwA#^x|qn zf>V^^r?GFYth)wuA`>9Z0OxR_h3o#+s!drz8aziqe)0LTE0w>LT!{C640xckCef&K*=+%Q8HA}jzr=gOdd|M ziBVW62M2dEqXlEU77Kdipducu?2EVfI=;Fwiu~?DUOe4f3t46~_N$yVoYF%S8ITEh z(wYQ?o!HL#D=D!Q+SV1!rRaMgL#t&_0P@_3^qIio803k56C&*M4QvGRLV-n^SI_Kn zxO-^9Dz!;rzE6`Re+ordE2?8_oGA8^nxRIcSr@pqxv72C;^D>xHrDQU%;g9Wn3yR= z@=;FDjM#ew-sr(4Y=}^WL96H2TPv^VbNhgNdo+(av0etiy(VvdxvuEZW%#Zm>BlPz z+xEl@fQ8OKf6}&K{A#>i+j{{QsOSuN>QL3UeDr1uqwl?&A#plq34WN-^9L#DlL+NB zW*9dEA4xS@QjnWUDnHHlBks1rhn1H!8LDZhhTni8s{jsNK-bX@l|tGgzyU?U-Mf#D z)@S?A1`wDUU;R=G8jCMqsPlw_mnE{o))xhL(E*Wa?+718acs7|Jqr7x<_y|lQs;OA zq0&``ld%EC`NI)9P$>V6p_qcKs{$$F8AVhZ$E0^yIiVT2n57>Bad;jtDQ4s;^ijJn zAP4DAl%7qy`zklcK{LjIYP}7-MnY;P8~DU7T%M2B?(wBtIRUvD`N)FXs}cj$BvR~? zQHpcX>>u(32vTTxHt)uE!dAz*9`s;r%wA>E)DpcbJvh(C{Q6708>+C&W++L<+K3_c zk(^&2?u8y&4}R0hV?NooXEWRvEeTw=-k_ldn@7PscH!Q3wP{#5r6>`wGOSZd*#Iv3 zlhzTh6>uZ$@&1n|FbSt#9GC;PhYaW(imnLd16@WUC70Sb=gDFUtTr*g@FWGTkC)8K z_LVW|)0zVT3^U=C^)bTg*H}1w;B1j+z#Ng2;W0fqH4}Peb19%|$43_mwnH(lKK@OZ zF^+1j>i_XOAh3bNJJ8Cq@ntbUB_zN+`x@Ff7^7mmAV4-T$N+B_kI(+R%=OYB}GKvpzDUwm7NdlPqq)>jgbA7`hvj7u=FJneLCtr zHX@82Mmw^Omcfrs6bsBj4>eK0z3GIqp|QVss{ob}=CYjsd`J%~3fm5wU3nbw?tBZA z;vx%7o&C#6%!~_BzVZ^wsm^ywn6L>|!Z`F014^6)Y(f?`1MooMj1c+2OimZj$-on& z`_jRz5ZIKd67_`->K3>lA2`$_MKCEsL1u)n^~8F{Ml^+)0)Q6avi!#*R%{In3)s*{ zY-t8eCx@&Jc3D&kz=s3U%WxVDn1Uqbp%T#9t)TA4D5Ns_C$M*Xtc6NWFFkO(mTx|` zP1=>w(^a==2J!k=^r@#9}VoK2TMLuBD(?|^~T&G5Ysni|jpTQzf)Z^P_lBv!m?f}h(sXab$9 z3`FjJutQh|v0;QGq~saevXh$D;7V}PArWzNDryY1peT4RUT6=8&zGZY$+Y=louzbB zSdBb{x|@{LY#d|EQws~!PE_4VBSejbqfzFsqb>rgSV=BLXIu9n|aEwV(P|*1RqG*8eCh!}W>c5{BGANhS{sOj*J#tq{LN zkdvFyy|+!YMuY!mY@fE_#2C>Jbk;Y1L?qi|*%{c?vqhj~erDITT>(*gIu-9(5y(*5~fBbK&kd zqTaXB{Xht7_b~~6`JXy@H5<22eisS~HW%ra>WLkWI|-SuabKQlZXuRo zB!pmV{QYB$0V99J!12hq=K_A^?=U!sz)wkn+Z!N4{;A_%$&ayVU5eg#nVCUiWiuxp zetVs=6Yb?OqG4)4N$CHx_SOiR`Q7?Uq`4vWLY$QB@nsC_zCXA_gt?*CwvlEw+`i0R z{R8RMs{Hp#3~Ykk=)Krq$8K9i)v^~kIx&*IIg7OH5X4V_TW5I+pJuY0LdxhWCuaLI zt=L$qxCYcfp50y}=+S~k0rw7@y%x(jzP*6__XZ4oiqZfLgR}i7_FJESIYzwO&5@J4 z3PY-HT}LmX_j_PBxl|JVBb88sF8_Dw_IVTE@lh3Dw_72nv-)z z?%1EaOG~?}pB4&}#^`zHrNu@?73aloPbHg)!dz(_)rZJ;sQH>T0wVfO>yX&Gv0Q0M zvbmo9_d@93Jr8-|-TY%yE14bHC~F@tCVWy7o=Obd+`kKzLz<%e{L;AVavYzGg^Y$i z^Ty$*DdL!EWqB8%^f{={tKjcyS6&*fQQ||IT4B0LZkbxKyJ?8r3D5`4TovA&ScR)| z#@si%KtIzq=LI}q!B6b>3GfaAElZ&o*_9`@Z^{l&sh2V629EfpiyEeB?(^PI2z`0*p*Y_a zHK3s%+4s1tIWsqvn4haj_um2h9lF|EyvCOwe)(jftX<82E#B?)J=jJX=y^~-TEDUl z*fif8xKm9hsABX~?A#mb3L%9YI#}HOZrcX@CEOMU6Q(6-=*Rk`qwxM6(*JRIgtu`j zg%wh1XK%<3^8dN{J53#jg?^~WG22(~I36k(zIr}=oYlqwavqv(s=&@e%}K8LeFW0M zQmC*qT1LqyinbE5!B+{u&|sk-EOIoO`G@2@djFA71o{NztTxA#N2-XW@NvvdxB#LA z`5st3{<2dOJoZ{`RxPd{I~z6U#m*e@b#_=5YL2I{w-tVd5+t?#Jfa=@q~d?qJ2(Oa5*t*i7Y5x6g* z8GD_JBoX;}zoJqqVu9kH?{7ZaM&7e{@aB`RG}C;bc=FWcjWEY`77+1hUNoQwE5K<17Wux{dl32LyY}v&r~87k}ll9GyV^WdE^jg2Yq1}cW`QnHnP(`( z)fi3^^QZnkhi&3muTMM{V`zu5p?pgyn7no{D45;6e-ERYv9V3*`_)H^o{AE5`ZkTH zG>g6U({K6~fphNbt;DM#OACs+-Mw%W11nMeS9Oiv1ny=EAd<4T=W5>?KZKL+#Vyl& zDOJ4++QXPW8OSxC7b_nF^~gOu<{jO@9(SX<+lL0|vB^k~}FB6M0@}NbYF_SK}=aper353hceZ?ylQR{k)Ig#Ih)_k+e@nDvCPm|Q&Nd1GDfjaQsZixbJN#+EgYE3UJdq=&H3m6r? zc++tLmXfTe3>JIoAT9 z+Hc+@6{A=PVU%)qa|Oo+X20IZO#97VpP0Nactzbs0wGkkih8E!gK|I*QfnGJcc%1t z)J0i``f&=Q^nj`l9}LfG=)kJgsf%LBp;_-{r5)@0e?c@Z&rkX_8DAS_{7kR2YF zVnODJ9a<)0xBz|ePrlLJV9!4%f{}i}hrFZxiH!Df2@IwHY_1NNqG){PK=MS+SbP=L zN1tUwb@GXNO9{=BKoOY2;PbT1_mu)foy)I?;AWIo|7u|*{7wXVkMbdr3$VYx08zVc z7Xl*Nn5%OGU=ATOxqpyz3Scr{1*z;kOZHo5-e#SuNqI?8CJrq_gt#J$qjWvi@R0LF z+hu?H;%q@_qz-eKR4xKdtBT?_)SEJ#i(-CS@UYJ>Gs~!Ikn*NZ3j*)nLr_2sbpQ%fl zW(^R=LwtI3%kUUqFP?qnI;1?zab?$xt}<=&ye`ThI{4crGc zkO_TO%ts~}myEmemJ0>X;Fd-pO|f?P&*kMYr?p#h2s%D>gS^XWjyKV3XvE!>rQ}{e z4#)oK6|O?pwEz9+TP~8|lSQ^i?bMOX=I&yE*J)g6tp+Ot_vJNFc6hU)Lhx`6dr9}1 zdhMK&%(S>L?-%JG)&2JzvpZ%)_eUR?6IEnRa5Of2uImZ6)VUH7Dp~IIi4l)JrwLRE zzip|YlBvYoifK2lWobq0fj{QD@zu<;-3`yLL$Q%la2|#}?&{-n46pYE;%GI7Nw$+(_6eR-}7NGc8t+ruLL*X(6(4hdwwUsD79-K}ONkZ8^<5!EXo@kd!@{EOzsOa$ z{|r>*`r4V8hf;qL24I6UFFJp8Bw@Y4i$9U#w-cx%Ls&A3gjD2s&c`CaZ;Mc(?p1ls z?44pY4lpgX@IZgCIo=ufqxe?sb^rctYMv_{9qzd6mbrmSxW6P@Y4Y1IsbZM0BK!+I ztpcTM6o*2v#!CB16pJ?zDXFIG?(@}D#RfN($BeUCU2Li~*Lcsj+T_pF1K$751y{sg z#k}ZV!|!vqRyojl(y0^)0h!ily%4ar#%Dz#r>QVXihYDKDQ>rj8MDc8Rus1?05@jH z!bx|C{Zk%}7NTNP|G{WKD31z_;=GUOvv{b)3!S$_JL@OdXddC;_X5{>2x*p-Tzqi| z_dlox;6#^InVyelOWAP4xWWqJ{qv*8G2lt5kz_TDRjcGe|i)ZKcHsrCk%ywyQ$ zlPM9F2O6_gnKYskaDlfrY=7Ra^JzxdIGO-nrbyO`9>N(u8F$ZC#tnOxPJlLVnn+De<{ zZ7cRjH67(E?x<`k!z{`)b1gt=v}-9@C~?fP8R4W1!prDWneKaPB+7`V^K}k;Wb(b1 z8^V74T?3P-P)4V5to>*e7ah|->Az#6 z8Wd7=0`XUq^)HV9@u@0})`ArKfUYg1Is$up8#PNlI|~-ne!>`O&e~2Suh~&=ZoCQE zdd#(}CUu=tn5nxNyQN=a4jux#ux3gt)ui_}0fW-aG*fgzju7vs?2g_o0$4ndu6tBC z%VggC{LOZB~Hrv>ouXu_~@Ts7ol{;YKs$5 zsFRcm_?4&3`<}qM;KHoU_f3UYQF=7WQsid*uYQn?eaHsp*fN)Nd(B$O1(115PXB{= z6zlMg_C@NKDd{n1;lJr?r$L(7f|Fs0gAJflwjZ@HG>#T=`V$FZ3?-?q#fux2L9e0InXhEi!3tFKp+9L5 z4)8bxuav;KJdDAPd+DC5)Jzw?Z~cnSGw~G;!E#8x;>#y0SeCZUxZID+uN_}tyR*qp zw6#<&;)Hu3(OZ4vi%`IYgE1r!*JYaXj(?M+N&a4T85N}hZ^(-J!iPa9bS2E@4M(mk*dU8t2@K6>*Tv|Hk z^|1v$kE!VH%e1=Vb-juGh2tyC*{!!k_lr8cN8pVlMqkEI72#(B2R7*i4NU3og5>kT zoaBc!tgS7${$-L@0(#2!wmLJOlLu@8Jcz$2?v9n~v$eH~x=TG}ARX~c5f1etiYS|e zf1Z328eB;(d7i}Utrk%BFeFqo>!f86>nT}pM#ZM79`LmKi9yrJ<@_fGQd-_@PGKw@ zNo4pZg;q^F|K|943(t*e>gTQ~WF_ zIT1=d$tz91h~zu!BnxP4fA?yo6NKsiMg4su`~|>Ja&xy=CUb}f5w^VE05I;2~3 z_0##==eRytV<-cf%Oz1e+@Oxn4>V0I(9@0AN%z<_Q&Ah-pnv;ByB(x>qzuU^v#+l~ zmHD;f>WCGhGr7A+L{RW+x`~BeOSi-ux%|uILjC;UTUDrV#Omd$#-+18`WMt^U!>`` zofL^tJDE@)zf#JeY*2g}nHyM`l9B!KOLGKbj{Q3E6VF#xgCOeqThC^?o`r|meT=0K zE?CL{gXfvcFcCz-M0}wFl^|AM{elbhd2MoB{QtF7)gYO?FIlE^vr;)z`n7$xb*Jp^ zp#Ex+sGSHRXyUVfK&SlOV7*6O-F`J!lCH>av9huhmEfzsY0HiF?lIW3z!}(gE;Hy8kNv7N{k=|5%JU=(j zk6ho8^kUu)nz3^ct5MQavW34Kc9bui&fX?g##aWG_kJ|_ykCs3$u2KCp-s&7vYdJP zJm&rS2ex|yn#4e9zgQgJ$t?V zos{V}cgnuonU~=G3ch!5(-1lS)fjC z!@gOPFRHt=98$>#O=s{QTPWip_1$`(3-#QZe6zQ7#4^XCPhF@m{Zq4`(6r0fu<9=pJekY2FCWeg|6K77$^3Zc;%vl)^G1BzqHP8l+abS!=6F`D zcgSc9KP#8)KMlbgKbtd;yJKphWl2TG{I83yYa$yGiuxNuGZ%LvYQle26eKlS zDk~aGe!3FB2{OG-bUH`ksx9E{EgDOvpZz0e#_b&CfoqfFAK|VQH5J=bbNcIVMQ^6> zJstjqT2)cgw%3sJVQhA&d5gU!eJ0&7zyKVQHKh*{pRlEy?eZ*~ zmv=KkDho84{}vNe(>n-8}gAgP*yp!3#0XyORj zSa;V;M=XlAVNmv3()={RV&COEQ~I~kM2>DX&uOEkhbw%v!3MEZ5x46W$h#A=w6X;6 zzrB6sAC)Fmr9bFgp?3pye{WB!ikolFwcAK>N%JHa6Fiat>@=T1q9pW*SKf^EM1hWw z{F-wa_NRuRWqryyB^LA+sK&uTxB`n9v=Lt8J*6|o7qR-fvyLFmN**ZQt!CInmXG`mCr|(d@KKqNPn3#DFXI zFd!bqbZeS)=eVLG+@T72dATHZU3xxu^CMJAAi(~ZmAYn<$fW31%#lcD1ZD<(!=2z%-)v=E3pM7ID0AsRI`;wO2lr>N`PfoA=5o*_*p?wOgG%AUlYBA zu);bu6u=JHCq^snv^}yg@8aG|B}-1|^NG=zSMI<~MdHZfQRX}rLL}mcZ)!Zp-i&H~jGBdM(wk}Gp-Ms0Sm9j zjMu=YK?C#LL8T8(^r>i0PhMzL`C*KB(V#~VdB00ftKor>nEtPr zs*W!hM@J1(b?bXz49oKQ*?F{~(Vr^hZ2L>Zl<=LrIi6+Fl_OkUoq;$jQub3(g2%CX zx~Liii=5C&zJ%%qoOz-A$?TK{n0}>A+M2U~PW*gdnnMBd#m=x5N0!(1gIlDuRzN(P z{6#MQBQrj;*zJ$PAejSrMr?~A2ElQcY>*rt^keW4aYKA#{JBR!64oN;S|uhgv}aAx zO^Xp4a6}6#N{_wfo(C8i6A%}$#Vrm15D4+2&_;GpC0lc-!26O;CiZuA40hb$N)(wM4E~G zub%UMiA#m@)EMRhI!p!S&2H8g1DBw9;I%VYrd^H{Iz+=&d-4gU-nVUh{hQ$h7T6aU zZDAYi=|&CzJH3MofKg%sF?aen)}iM9!v#$X?TMIiHm}n?pXqF$3@=vCltRZ`9Um< z_vn1>ksk_$a}xbyJ<=nTEjUiM9RA>Ve^4H!hgUh-EFYl6m3@L2 zi7}M4>)Te>vZw7tqp`_K3Gq#m#TAl-rY|cJ7^OWc+OmTs{X02V|II;sk68|?qu1V8A-HupckpmX?v0(w+$uZDL-6sN+&m?lBu*Ul0%N zlYrknkuI(BvRf_0aPmeyFGBgIWwVE3?eG-_NuD*#+5E)VvPUNape=v&?8MwN#5nr= z8mLvZ{|Zx}v}0Vt@O(4ziV&f(8-<<0e zqk<_;3Ct0~PSJWJ@4`)bun;gBe}9Yb_|!ieT_S&7o`B{nFSLPNi=dt8XBln&4LG={ ze(!jrTfe?k`&gPl4`#n%l2tg?q05bZ0^%w8KG#@6QzkfMJl+eOn z+qJ)_22(Um^t^IXqcs~i42hr<9>bkwY+VbPn7fx}+@ra2`3s1($9Iys=s7$y=cidu zlU!^&PnX$)uM%W+bAJcc%ktBK2%f%ZoyIehxOGGUY9@tL>D3<_V%33cW>$}%CE?nS zESLTev{`(giWtTOv4Uy`Ed z%MV`R5oD2>zw3H3H@^Ai0zXccbO16%O3dH~F7pB%CL7r@zt?aau!3g#hj<4DGQJ+- z2kfK1=OiGK&r!h(JM)>3I_h-LW_Mgkl#^I{S@|6GFDwAEPxMt_Co0x2UuqRVl9zEu z`q*ZYmyVP`Qe3BSP?fd7QYdVC%$9u7dBY(#(881scA@be!O}IAhKZ2en^P|&(xgCl zGWD2~;bz2sFTfpKYPsxXt-Zq2J@OTo0aNHLj%!j#0Anl;8sUdb(U+1hD|a|6?WUV~ zM_&xN^sR>88>aPc)>vye@($t*f7~3J2kvqCl}!Z+9=Wg1q#2QKajKh$`ze{uH+!F+ zujbd8NHoy7&paEHzHau`r<>7)hDL*d4%!spzifovFTa*%(%r0)cNEzu|MnINMpek=Vuy6QF7bb4Z+j&fdDpej zl3tKRHMzpVi0x)#DPmTT-D#4ZQ_%!)7WMc&V4VF@kP1Y*kgk;^u*5FXS?iTVH0d2W z#iFGE!c>38m5KzTELz?&H0s2CA?M6ellGzI!80#W*HjflleK*N2YCg zLs0Nv0=^MwX!*3p6c)TpJYPFnnfl~Sw|iK7XuBk?@LxvSzE3D@Kr=kSZzeJ07^Lpf zZ>X>qeU_EkD2)&viU9kt#aXae)`Z;R%Hyd%f$SJ zMItmVm$c?v#Y+np%c4KXcuID(fhWw>JK4u8+~yd(csU(MPdndypE7@FAw^InR)Y7m ziwY&E|74x&RkK5&bmpd@J~$nzS&%uMNxr&|`1yk&sCd1gx>{{J19(o-?;`0~@Ni`q zL%y2j4tIm}r>MO2{g*C)-dP>Zk3NXySzs-h_Dg&GuT22gBdTMcDDe z2<2%}CoHzn4qZc^d}&$PIx!LER@alM3^(cJHQkC+`BzJXSK*iJ=gN`m)`zlxJPo)V zD&f2T>>q+MIfmF$$2fY*Jko{ka9XTGNV5dT*piVxYjKETYgmfo{(PZCV_#c=HokPH(L|LHG2Yo@~P++$AXeE?VpmfYX9E9dxr}V){jm!w}6N ze)xHqY)fC;XEkgzOf$rezJM-Mc~&*k!ey{ zsQ4`^u2V3%1Y8D{913i@AMO(0xJ7{ZFi}BApJ1fZYY*y=SW&g$hP{JgZ{Bp0swj%R z2Hq$~q6|(cw_Ray)3un#cJM(njSo3ZVvn#;>+M@2qL`t2oh6*U%%Ht~F|&ustkc;4 z@KyQ$H-V;z-xxX*hh+=j_fKWxkn0l_*AjFDbjZ@v*SZrgWyEhh`h;OxaQM_Gmz871 zo++MZtYr!Rt+2p_(*jK@<$tOKk;gne+U&~H&yUkyU5X3%W$UE3ELFC0VEyaV5|H+0 zd4CyGs@?K57`VqQ>)-q7KB}z{2okIOSk}NoH`p0%kB6B1%`aGO8=S@YgwCyNH&xlV zDPFp4cV6DHKgK*5*clE$u{c=}&977dyMv;v!iG4H3t#Vn$yk})&dC_Pn6q9aRj_HEme01ucLgOU9 z>0V@OWD9LkA9NQNKJPOLs;M_UJQgu@uKef#96dJ4Q~dtx_Qk~V63`N9P~?-S8kUZ6 zR2FrvNXIouM^xc8-(7(tdi~aIfcL#;nQsNPXXnPNLJA1LtBsqNC0y10^+*i*PW;n6 z1x#zPNZ-=uY{WoYfd?OhPgnGS1kKWDPcS*?f)5Iq6uV4k+8O_$7D7MDa9>qzc?yl; zuVDUEAi9g#-{N9VihbRpt5)^g=y3TF0gU&kY!@$&C+c~C;bEkzFtlLhES)U98LRB) zP11y&v#v!IXMkEZyJunG$#sZ|e#H?jIsvR-Rmo9=(r_vHE7P&nD!Y^*1-o~>P<%q7H z*u{fnFahW9{qjT literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_edge.assets/binary_search_right_edge_by_left_edge.png b/en/chapter_searching/binary_search_edge.assets/binary_search_right_edge_by_left_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..6f10b838e6ed6c921ead5705a59318b6c76f2415 GIT binary patch literal 13399 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 Z@1msEa%kd4eL4gH3Nk9vWs;_T{{`_vS*ZX3 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_edge/index.html b/en/chapter_searching/binary_search_edge/index.html new file mode 100644 index 000000000..ff1f8446a --- /dev/null +++ b/en/chapter_searching/binary_search_edge/index.html @@ -0,0 +1,4343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.3 Binary search boundaries - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    10.3   Binary search boundaries

    +

    10.3.1   Find the left boundary

    +
    +

    Question

    +

    Given a sorted array nums of length \(n\), which may contain duplicate elements, return the index of the leftmost element target. If the element is not present in the array, return \(-1\).

    +
    +

    Recall the method of binary search for an insertion point, after the search is completed, \(i\) points to the leftmost target, thus searching for the insertion point is essentially searching for the index of the leftmost target.

    +

    Consider implementing the search for the left boundary using the function for finding an insertion point. Note that the array might not contain target, which could lead to the following two results:

    +
      +
    • The index \(i\) of the insertion point is out of bounds.
    • +
    • The element nums[i] is not equal to target.
    • +
    +

    In these cases, simply return \(-1\). The code is as follows:

    +
    +
    +
    +
    binary_search_edge.py
    def binary_search_left_edge(nums: list[int], target: int) -> int:
    +    """二分查找最左一个 target"""
    +    # 等价于查找 target 的插入点
    +    i = binary_search_insertion(nums, target)
    +    # 未找到 target ,返回 -1
    +    if i == len(nums) or nums[i] != target:
    +        return -1
    +    # 找到 target ,返回索引 i
    +    return i
    +
    +
    +
    +
    binary_search_edge.cpp
    /* 二分查找最左一个 target */
    +int binarySearchLeftEdge(vector<int> &nums, int target) {
    +    // 等价于查找 target 的插入点
    +    int i = binarySearchInsertion(nums, target);
    +    // 未找到 target ,返回 -1
    +    if (i == nums.size() || nums[i] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_edge.java
    /* 二分查找最左一个 target */
    +int binarySearchLeftEdge(int[] nums, int target) {
    +    // 等价于查找 target 的插入点
    +    int i = binary_search_insertion.binarySearchInsertion(nums, target);
    +    // 未找到 target ,返回 -1
    +    if (i == nums.length || nums[i] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_edge.cs
    /* 二分查找最左一个 target */
    +int BinarySearchLeftEdge(int[] nums, int target) {
    +    // 等价于查找 target 的插入点
    +    int i = binary_search_insertion.BinarySearchInsertion(nums, target);
    +    // 未找到 target ,返回 -1
    +    if (i == nums.Length || nums[i] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_edge.go
    /* 二分查找最左一个 target */
    +func binarySearchLeftEdge(nums []int, target int) int {
    +    // 等价于查找 target 的插入点
    +    i := binarySearchInsertion(nums, target)
    +    // 未找到 target ,返回 -1
    +    if i == len(nums) || nums[i] != target {
    +        return -1
    +    }
    +    // 找到 target ,返回索引 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_edge.swift
    /* 二分查找最左一个 target */
    +func binarySearchLeftEdge(nums: [Int], target: Int) -> Int {
    +    // 等价于查找 target 的插入点
    +    let i = binarySearchInsertion(nums: nums, target: target)
    +    // 未找到 target ,返回 -1
    +    if i == nums.endIndex || nums[i] != target {
    +        return -1
    +    }
    +    // 找到 target ,返回索引 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_edge.js
    /* 二分查找最左一个 target */
    +function binarySearchLeftEdge(nums, target) {
    +    // 等价于查找 target 的插入点
    +    const i = binarySearchInsertion(nums, target);
    +    // 未找到 target ,返回 -1
    +    if (i === nums.length || nums[i] !== target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_edge.ts
    /* 二分查找最左一个 target */
    +function binarySearchLeftEdge(nums: Array<number>, target: number): number {
    +    // 等价于查找 target 的插入点
    +    const i = binarySearchInsertion(nums, target);
    +    // 未找到 target ,返回 -1
    +    if (i === nums.length || nums[i] !== target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_edge.dart
    /* 二分查找最左一个 target */
    +int binarySearchLeftEdge(List<int> nums, int target) {
    +  // 等价于查找 target 的插入点
    +  int i = binarySearchInsertion(nums, target);
    +  // 未找到 target ,返回 -1
    +  if (i == nums.length || nums[i] != target) {
    +    return -1;
    +  }
    +  // 找到 target ,返回索引 i
    +  return i;
    +}
    +
    +
    +
    +
    binary_search_edge.rs
    /* 二分查找最左一个 target */
    +fn binary_search_left_edge(nums: &[i32], target: i32) -> i32 {
    +    // 等价于查找 target 的插入点
    +    let i = binary_search_insertion(nums, target);
    +    // 未找到 target ,返回 -1
    +    if i == nums.len() as i32 || nums[i as usize] != target {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    i
    +}
    +
    +
    +
    +
    binary_search_edge.c
    /* 二分查找最左一个 target */
    +int binarySearchLeftEdge(int *nums, int numSize, int target) {
    +    // 等价于查找 target 的插入点
    +    int i = binarySearchInsertion(nums, numSize, target);
    +    // 未找到 target ,返回 -1
    +    if (i == numSize || nums[i] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_edge.kt
    /* 二分查找最左一个 target */
    +fun binarySearchLeftEdge(nums: IntArray, target: Int): Int {
    +    // 等价于查找 target 的插入点
    +    val i = binarySearchInsertion(nums, target)
    +    // 未找到 target ,返回 -1
    +    if (i == nums.size || nums[i] != target) {
    +        return -1
    +    }
    +    // 找到 target ,返回索引 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_edge.rb
    ### 二分查找最左一个 target ###
    +def binary_search_left_edge(nums, target)
    +  # 等价于查找 target 的插入点
    +  i = binary_search_insertion(nums, target)
    +
    +  # 未找到 target ,返回 -1
    +  return -1 if i == nums.length || nums[i] != target
    +
    +  i # 找到 target ,返回索引 i
    +end
    +
    +
    +
    +
    binary_search_edge.zig
    [class]{}-[func]{binarySearchLeftEdge}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    10.3.2   Find the right boundary

    +

    So how do we find the rightmost target? The most straightforward way is to modify the code, replacing the pointer contraction operation in the case of nums[m] == target. The code is omitted here, but interested readers can implement it on their own.

    +

    Below we introduce two more cunning methods.

    +

    1.   Reusing the search for the left boundary

    +

    In fact, we can use the function for finding the leftmost element to find the rightmost element, specifically by transforming the search for the rightmost target into a search for the leftmost target + 1.

    +

    As shown in the Figure 10-7 , after the search is completed, the pointer \(i\) points to the leftmost target + 1 (if it exists), while \(j\) points to the rightmost target, thus returning \(j\) is sufficient.

    +

    Transforming the search for the right boundary into the search for the left boundary

    +

    Figure 10-7   Transforming the search for the right boundary into the search for the left boundary

    + +

    Please note, the insertion point returned is \(i\), therefore, it should be subtracted by \(1\) to obtain \(j\):

    +
    +
    +
    +
    binary_search_edge.py
    def binary_search_right_edge(nums: list[int], target: int) -> int:
    +    """二分查找最右一个 target"""
    +    # 转化为查找最左一个 target + 1
    +    i = binary_search_insertion(nums, target + 1)
    +    # j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    j = i - 1
    +    # 未找到 target ,返回 -1
    +    if j == -1 or nums[j] != target:
    +        return -1
    +    # 找到 target ,返回索引 j
    +    return j
    +
    +
    +
    +
    binary_search_edge.cpp
    /* 二分查找最右一个 target */
    +int binarySearchRightEdge(vector<int> &nums, int target) {
    +    // 转化为查找最左一个 target + 1
    +    int i = binarySearchInsertion(nums, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    int j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if (j == -1 || nums[j] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    return j;
    +}
    +
    +
    +
    +
    binary_search_edge.java
    /* 二分查找最右一个 target */
    +int binarySearchRightEdge(int[] nums, int target) {
    +    // 转化为查找最左一个 target + 1
    +    int i = binary_search_insertion.binarySearchInsertion(nums, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    int j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if (j == -1 || nums[j] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    return j;
    +}
    +
    +
    +
    +
    binary_search_edge.cs
    /* 二分查找最右一个 target */
    +int BinarySearchRightEdge(int[] nums, int target) {
    +    // 转化为查找最左一个 target + 1
    +    int i = binary_search_insertion.BinarySearchInsertion(nums, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    int j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if (j == -1 || nums[j] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    return j;
    +}
    +
    +
    +
    +
    binary_search_edge.go
    /* 二分查找最右一个 target */
    +func binarySearchRightEdge(nums []int, target int) int {
    +    // 转化为查找最左一个 target + 1
    +    i := binarySearchInsertion(nums, target+1)
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    j := i - 1
    +    // 未找到 target ,返回 -1
    +    if j == -1 || nums[j] != target {
    +        return -1
    +    }
    +    // 找到 target ,返回索引 j
    +    return j
    +}
    +
    +
    +
    +
    binary_search_edge.swift
    /* 二分查找最右一个 target */
    +func binarySearchRightEdge(nums: [Int], target: Int) -> Int {
    +    // 转化为查找最左一个 target + 1
    +    let i = binarySearchInsertion(nums: nums, target: target + 1)
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    let j = i - 1
    +    // 未找到 target ,返回 -1
    +    if j == -1 || nums[j] != target {
    +        return -1
    +    }
    +    // 找到 target ,返回索引 j
    +    return j
    +}
    +
    +
    +
    +
    binary_search_edge.js
    /* 二分查找最右一个 target */
    +function binarySearchRightEdge(nums, target) {
    +    // 转化为查找最左一个 target + 1
    +    const i = binarySearchInsertion(nums, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    const j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if (j === -1 || nums[j] !== target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    return j;
    +}
    +
    +
    +
    +
    binary_search_edge.ts
    /* 二分查找最右一个 target */
    +function binarySearchRightEdge(nums: Array<number>, target: number): number {
    +    // 转化为查找最左一个 target + 1
    +    const i = binarySearchInsertion(nums, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    const j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if (j === -1 || nums[j] !== target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    return j;
    +}
    +
    +
    +
    +
    binary_search_edge.dart
    /* 二分查找最右一个 target */
    +int binarySearchRightEdge(List<int> nums, int target) {
    +  // 转化为查找最左一个 target + 1
    +  int i = binarySearchInsertion(nums, target + 1);
    +  // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +  int j = i - 1;
    +  // 未找到 target ,返回 -1
    +  if (j == -1 || nums[j] != target) {
    +    return -1;
    +  }
    +  // 找到 target ,返回索引 j
    +  return j;
    +}
    +
    +
    +
    +
    binary_search_edge.rs
    /* 二分查找最右一个 target */
    +fn binary_search_right_edge(nums: &[i32], target: i32) -> i32 {
    +    // 转化为查找最左一个 target + 1
    +    let i = binary_search_insertion(nums, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    let j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if j == -1 || nums[j as usize] != target {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    j
    +}
    +
    +
    +
    +
    binary_search_edge.c
    /* 二分查找最右一个 target */
    +int binarySearchRightEdge(int *nums, int numSize, int target) {
    +    // 转化为查找最左一个 target + 1
    +    int i = binarySearchInsertion(nums, numSize, target + 1);
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    int j = i - 1;
    +    // 未找到 target ,返回 -1
    +    if (j == -1 || nums[j] != target) {
    +        return -1;
    +    }
    +    // 找到 target ,返回索引 j
    +    return j;
    +}
    +
    +
    +
    +
    binary_search_edge.kt
    /* 二分查找最右一个 target */
    +fun binarySearchRightEdge(nums: IntArray, target: Int): Int {
    +    // 转化为查找最左一个 target + 1
    +    val i = binarySearchInsertion(nums, target + 1)
    +    // j 指向最右一个 target ,i 指向首个大于 target 的元素
    +    val j = i - 1
    +    // 未找到 target ,返回 -1
    +    if (j == -1 || nums[j] != target) {
    +        return -1
    +    }
    +    // 找到 target ,返回索引 j
    +    return j
    +}
    +
    +
    +
    +
    binary_search_edge.rb
    ### 二分查找最右一个 target ###
    +def binary_search_right_edge(nums, target)
    +  # 转化为查找最左一个 target + 1
    +  i = binary_search_insertion(nums, target + 1)
    +
    +  # j 指向最右一个 target ,i 指向首个大于 target 的元素
    +  j = i - 1
    +
    +  # 未找到 target ,返回 -1
    +  return -1 if j == -1 || nums[j] != target
    +
    +  j # 找到 target ,返回索引 j
    +end
    +
    +
    +
    +
    binary_search_edge.zig
    [class]{}-[func]{binarySearchRightEdge}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    + +

    We know that when the array does not contain target, \(i\) and \(j\) will eventually point to the first element greater and smaller than target respectively.

    +

    Thus, as shown in the Figure 10-8 , we can construct an element that does not exist in the array, to search for the left and right boundaries.

    +
      +
    • To find the leftmost target: it can be transformed into searching for target - 0.5, and return the pointer \(i\).
    • +
    • To find the rightmost target: it can be transformed into searching for target + 0.5, and return the pointer \(j\).
    • +
    +

    Transforming the search for boundaries into the search for an element

    +

    Figure 10-8   Transforming the search for boundaries into the search for an element

    + +

    The code is omitted here, but two points are worth noting.

    +
      +
    • The given array does not contain decimals, meaning we do not need to worry about how to handle equal situations.
    • +
    • Since this method introduces decimals, the variable target in the function needs to be changed to a floating point type (no change needed in Python).
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_example.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_example.png new file mode 100644 index 0000000000000000000000000000000000000000..3803db33d528c044fec74aba37c966fd70590114 GIT binary patch literal 16290 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 L<#!blhJOD85E8n2 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_naive.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_naive.png new file mode 100644 index 0000000000000000000000000000000000000000..b47ffd79ab5a8db3d010341a3c17719ade99d6f2 GIT binary patch literal 12330 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 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step1.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..7717114a25ac9a708a243d829f7f0bccb0085e7c GIT binary patch literal 15249 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 DE?p-q literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step2.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..13b9fec08afe3cbc076347efb570c8f195d6b352 GIT binary patch literal 13156 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 S{Q(6x0!2ABS?rt8p#K4N)1@x} literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step3.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..4f26ada2494428bb01581f775b33a4ca32e80ef7 GIT binary patch literal 17056 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�@8bPS6MjXe1Mu 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

    ;@a6cq$n9PHC3>qwn2!k$lzx8nkyZ-Upn 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 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step6.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..56433a0134f103d866fd558a1aec806c9eb32ec5 GIT binary patch literal 13192 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 OmzGcvFA~-B_&)%sO7#u^ literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step7.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..127eb70fcdb8fd164a968f8afba074286fb22b5c GIT binary patch literal 16273 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 R{NdlZlAOA1xil=`{{nklii!XL literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step8.png b/en/chapter_searching/binary_search_insertion.assets/binary_search_insertion_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..d322ffc3cabc7a22cc56dfb722d92898ec109ca7 GIT binary patch literal 12570 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 KQmB-J2K*n;gEh(k literal 0 HcmV?d00001 diff --git a/en/chapter_searching/binary_search_insertion/index.html b/en/chapter_searching/binary_search_insertion/index.html new file mode 100644 index 000000000..b8149729a --- /dev/null +++ b/en/chapter_searching/binary_search_insertion/index.html @@ -0,0 +1,4466 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.2 Binary search insertion - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    10.2   Binary search insertion

    +

    Binary search is not only used to search for target elements but also to solve many variant problems, such as searching for the insertion position of target elements.

    +

    10.2.1   Case with no duplicate elements

    +
    +

    Question

    +

    Given an ordered array nums of length \(n\) and an element target, where the array has no duplicate elements. Now insert target into the array nums while maintaining its order. If the element target already exists in the array, insert it to its left side. Please return the index of target in the array after insertion. See the example shown in the Figure 10-4 .

    +
    +

    Example data for binary search insertion point

    +

    Figure 10-4   Example data for binary search insertion point

    + +

    If you want to reuse the binary search code from the previous section, you need to answer the following two questions.

    +

    Question one: When the array contains target, is the insertion point index the index of that element?

    +

    The requirement to insert target to the left of equal elements means that the newly inserted target replaces the original target position. Thus, when the array contains target, the insertion point index is the index of that target.

    +

    Question two: When the array does not contain target, what is the index of the insertion point?

    +

    Further consider the binary search process: when nums[m] < target, pointer \(i\) moves, meaning that pointer \(i\) is approaching an element greater than or equal to target. Similarly, pointer \(j\) is always approaching an element less than or equal to target.

    +

    Therefore, at the end of the binary, it is certain that: \(i\) points to the first element greater than target, and \(j\) points to the first element less than target. It is easy to see that when the array does not contain target, the insertion index is \(i\). The code is as follows:

    +
    +
    +
    +
    binary_search_insertion.py
    def binary_search_insertion_simple(nums: list[int], target: int) -> int:
    +    """二分查找插入点(无重复元素)"""
    +    i, j = 0, len(nums) - 1  # 初始化双闭区间 [0, n-1]
    +    while i <= j:
    +        m = (i + j) // 2  # 计算中点索引 m
    +        if nums[m] < target:
    +            i = m + 1  # target 在区间 [m+1, j] 中
    +        elif nums[m] > target:
    +            j = m - 1  # target 在区间 [i, m-1] 中
    +        else:
    +            return m  # 找到 target ,返回插入点 m
    +    # 未找到 target ,返回插入点 i
    +    return i
    +
    +
    +
    +
    binary_search_insertion.cpp
    /* 二分查找插入点(无重复元素) */
    +int binarySearchInsertionSimple(vector<int> &nums, int target) {
    +    int i = 0, j = nums.size() - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m; // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.java
    /* 二分查找插入点(无重复元素) */
    +int binarySearchInsertionSimple(int[] nums, int target) {
    +    int i = 0, j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m; // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.cs
    /* 二分查找插入点(无重复元素) */
    +int BinarySearchInsertionSimple(int[] nums, int target) {
    +    int i = 0, j = nums.Length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m; // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.go
    /* 二分查找插入点(无重复元素) */
    +func binarySearchInsertionSimple(nums []int, target int) int {
    +    // 初始化双闭区间 [0, n-1]
    +    i, j := 0, len(nums)-1
    +    for i <= j {
    +        // 计算中点索引 m
    +        m := i + (j-i)/2
    +        if nums[m] < target {
    +            // target 在区间 [m+1, j] 中
    +            i = m + 1
    +        } else if nums[m] > target {
    +            // target 在区间 [i, m-1] 中
    +            j = m - 1
    +        } else {
    +            // 找到 target ,返回插入点 m
    +            return m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_insertion.swift
    /* 二分查找插入点(无重复元素) */
    +func binarySearchInsertionSimple(nums: [Int], target: Int) -> Int {
    +    // 初始化双闭区间 [0, n-1]
    +    var i = nums.startIndex
    +    var j = nums.endIndex - 1
    +    while i <= j {
    +        let m = i + (j - i) / 2 // 计算中点索引 m
    +        if nums[m] < target {
    +            i = m + 1 // target 在区间 [m+1, j] 中
    +        } else if nums[m] > target {
    +            j = m - 1 // target 在区间 [i, m-1] 中
    +        } else {
    +            return m // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_insertion.js
    /* 二分查找插入点(无重复元素) */
    +function binarySearchInsertionSimple(nums, target) {
    +    let i = 0,
    +        j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m; // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.ts
    /* 二分查找插入点(无重复元素) */
    +function binarySearchInsertionSimple(
    +    nums: Array<number>,
    +    target: number
    +): number {
    +    let i = 0,
    +        j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m; // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.dart
    /* 二分查找插入点(无重复元素) */
    +int binarySearchInsertionSimple(List<int> nums, int target) {
    +  int i = 0, j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +  while (i <= j) {
    +    int m = i + (j - i) ~/ 2; // 计算中点索引 m
    +    if (nums[m] < target) {
    +      i = m + 1; // target 在区间 [m+1, j] 中
    +    } else if (nums[m] > target) {
    +      j = m - 1; // target 在区间 [i, m-1] 中
    +    } else {
    +      return m; // 找到 target ,返回插入点 m
    +    }
    +  }
    +  // 未找到 target ,返回插入点 i
    +  return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.rs
    /* 二分查找插入点(无重复元素) */
    +fn binary_search_insertion_simple(nums: &[i32], target: i32) -> i32 {
    +    let (mut i, mut j) = (0, nums.len() as i32 - 1); // 初始化双闭区间 [0, n-1]
    +    while i <= j {
    +        let m = i + (j - i) / 2; // 计算中点索引 m
    +        if nums[m as usize] < target {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if nums[m as usize] > target {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m;
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    i
    +}
    +
    +
    +
    +
    binary_search_insertion.c
    /* 二分查找插入点(无重复元素) */
    +int binarySearchInsertionSimple(int *nums, int numSize, int target) {
    +    int i = 0, j = numSize - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            return m; // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.kt
    /* 二分查找插入点(无重复元素) */
    +fun binarySearchInsertionSimple(nums: IntArray, target: Int): Int {
    +    var i = 0
    +    var j = nums.size - 1 // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        val m = i + (j - i) / 2 // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1 // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1 // target 在区间 [i, m-1] 中
    +        } else {
    +            return m // 找到 target ,返回插入点 m
    +        }
    +    }
    +    // 未找到 target ,返回插入点 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_insertion.rb
    ### 二分查找插入点(无重复元素) ###
    +def binary_search_insertion_simple(nums, target)
    +  # 初始化双闭区间 [0, n-1]
    +  i, j = 0, nums.length - 1
    +
    +  while i <= j
    +    # 计算中点索引 m
    +    m = (i + j) / 2
    +
    +    if nums[m] < target
    +      i = m + 1 # target 在区间 [m+1, j] 中
    +    elsif nums[m] > target
    +      j = m - 1 # target 在区间 [i, m-1] 中
    +    else
    +      return m  # 找到 target ,返回插入点 m
    +    end
    +  end
    +
    +  i # 未找到 target ,返回插入点 i
    +end
    +
    +
    +
    +
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertionSimple}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    10.2.2   Case with duplicate elements

    +
    +

    Question

    +

    Based on the previous question, assume the array may contain duplicate elements, all else remains the same.

    +
    +

    Suppose there are multiple targets in the array, ordinary binary search can only return the index of one of the targets, and it cannot determine how many targets are to the left and right of that element.

    +

    The task requires inserting the target element to the very left, so we need to find the index of the leftmost target in the array. Initially consider implementing this through the steps shown in the Figure 10-5 .

    +
      +
    1. Perform a binary search, get an arbitrary index of target, denoted as \(k\).
    2. +
    3. Start from index \(k\), and perform a linear search to the left until the leftmost target is found and return.
    4. +
    +

    Linear search for the insertion point of duplicate elements

    +

    Figure 10-5   Linear search for the insertion point of duplicate elements

    + +

    Although this method is feasible, it includes linear search, so its time complexity is \(O(n)\). This method is inefficient when the array contains many duplicate targets.

    +

    Now consider extending the binary search code. As shown in the Figure 10-6 , the overall process remains the same, each round first calculates the midpoint index \(m\), then judges the size relationship between target and nums[m], divided into the following cases.

    +
      +
    • When nums[m] < target or nums[m] > target, it means target has not been found yet, thus use the normal binary search interval reduction operation, thus making pointers \(i\) and \(j\) approach target.
    • +
    • When nums[m] == target, it indicates that the elements less than target are in the interval \([i, m - 1]\), therefore use \(j = m - 1\) to narrow the interval, thus making pointer \(j\) approach elements less than target.
    • +
    +

    After the loop, \(i\) points to the leftmost target, and \(j\) points to the first element less than target, therefore index \(i\) is the insertion point.

    +
    +
    +
    +

    Steps for binary search insertion point of duplicate elements

    +
    +
    +

    binary_search_insertion_step2

    +
    +
    +

    binary_search_insertion_step3

    +
    +
    +

    binary_search_insertion_step4

    +
    +
    +

    binary_search_insertion_step5

    +
    +
    +

    binary_search_insertion_step6

    +
    +
    +

    binary_search_insertion_step7

    +
    +
    +

    binary_search_insertion_step8

    +
    +
    +
    +

    Figure 10-6   Steps for binary search insertion point of duplicate elements

    + +

    Observe the code, the operations of the branch nums[m] > target and nums[m] == target are the same, so the two can be combined.

    +

    Even so, we can still keep the conditions expanded, as their logic is clearer and more readable.

    +
    +
    +
    +
    binary_search_insertion.py
    def binary_search_insertion(nums: list[int], target: int) -> int:
    +    """二分查找插入点(存在重复元素)"""
    +    i, j = 0, len(nums) - 1  # 初始化双闭区间 [0, n-1]
    +    while i <= j:
    +        m = (i + j) // 2  # 计算中点索引 m
    +        if nums[m] < target:
    +            i = m + 1  # target 在区间 [m+1, j] 中
    +        elif nums[m] > target:
    +            j = m - 1  # target 在区间 [i, m-1] 中
    +        else:
    +            j = m - 1  # 首个小于 target 的元素在区间 [i, m-1] 中
    +    # 返回插入点 i
    +    return i
    +
    +
    +
    +
    binary_search_insertion.cpp
    /* 二分查找插入点(存在重复元素) */
    +int binarySearchInsertion(vector<int> &nums, int target) {
    +    int i = 0, j = nums.size() - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.java
    /* 二分查找插入点(存在重复元素) */
    +int binarySearchInsertion(int[] nums, int target) {
    +    int i = 0, j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.cs
    /* 二分查找插入点(存在重复元素) */
    +int BinarySearchInsertion(int[] nums, int target) {
    +    int i = 0, j = nums.Length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.go
    /* 二分查找插入点(存在重复元素) */
    +func binarySearchInsertion(nums []int, target int) int {
    +    // 初始化双闭区间 [0, n-1]
    +    i, j := 0, len(nums)-1
    +    for i <= j {
    +        // 计算中点索引 m
    +        m := i + (j-i)/2
    +        if nums[m] < target {
    +            // target 在区间 [m+1, j] 中
    +            i = m + 1
    +        } else if nums[m] > target {
    +            // target 在区间 [i, m-1] 中
    +            j = m - 1
    +        } else {
    +            // 首个小于 target 的元素在区间 [i, m-1] 中
    +            j = m - 1
    +        }
    +    }
    +    // 返回插入点 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_insertion.swift
    /* 二分查找插入点(存在重复元素) */
    +func binarySearchInsertion(nums: [Int], target: Int) -> Int {
    +    // 初始化双闭区间 [0, n-1]
    +    var i = nums.startIndex
    +    var j = nums.endIndex - 1
    +    while i <= j {
    +        let m = i + (j - i) / 2 // 计算中点索引 m
    +        if nums[m] < target {
    +            i = m + 1 // target 在区间 [m+1, j] 中
    +        } else if nums[m] > target {
    +            j = m - 1 // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1 // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_insertion.js
    /* 二分查找插入点(存在重复元素) */
    +function binarySearchInsertion(nums, target) {
    +    let i = 0,
    +        j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.ts
    /* 二分查找插入点(存在重复元素) */
    +function binarySearchInsertion(nums: Array<number>, target: number): number {
    +    let i = 0,
    +        j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.dart
    /* 二分查找插入点(存在重复元素) */
    +int binarySearchInsertion(List<int> nums, int target) {
    +  int i = 0, j = nums.length - 1; // 初始化双闭区间 [0, n-1]
    +  while (i <= j) {
    +    int m = i + (j - i) ~/ 2; // 计算中点索引 m
    +    if (nums[m] < target) {
    +      i = m + 1; // target 在区间 [m+1, j] 中
    +    } else if (nums[m] > target) {
    +      j = m - 1; // target 在区间 [i, m-1] 中
    +    } else {
    +      j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +    }
    +  }
    +  // 返回插入点 i
    +  return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.rs
    /* 二分查找插入点(存在重复元素) */
    +pub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 {
    +    let (mut i, mut j) = (0, nums.len() as i32 - 1); // 初始化双闭区间 [0, n-1]
    +    while i <= j {
    +        let m = i + (j - i) / 2; // 计算中点索引 m
    +        if nums[m as usize] < target {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if nums[m as usize] > target {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    i
    +}
    +
    +
    +
    +
    binary_search_insertion.c
    /* 二分查找插入点(存在重复元素) */
    +int binarySearchInsertion(int *nums, int numSize, int target) {
    +    int i = 0, j = numSize - 1; // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        int m = i + (j - i) / 2; // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1; // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1; // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i;
    +}
    +
    +
    +
    +
    binary_search_insertion.kt
    /* 二分查找插入点(存在重复元素) */
    +fun binarySearchInsertion(nums: IntArray, target: Int): Int {
    +    var i = 0
    +    var j = nums.size - 1 // 初始化双闭区间 [0, n-1]
    +    while (i <= j) {
    +        val m = i + (j - i) / 2 // 计算中点索引 m
    +        if (nums[m] < target) {
    +            i = m + 1 // target 在区间 [m+1, j] 中
    +        } else if (nums[m] > target) {
    +            j = m - 1 // target 在区间 [i, m-1] 中
    +        } else {
    +            j = m - 1 // 首个小于 target 的元素在区间 [i, m-1] 中
    +        }
    +    }
    +    // 返回插入点 i
    +    return i
    +}
    +
    +
    +
    +
    binary_search_insertion.rb
    ### 二分查找插入点(存在重复元素) ###
    +def binary_search_insertion(nums, target)
    +  # 初始化双闭区间 [0, n-1]
    +  i, j = 0, nums.length - 1
    +
    +  while i <= j
    +    # 计算中点索引 m
    +    m = (i + j) / 2
    +
    +    if nums[m] < target
    +      i = m + 1 # target 在区间 [m+1, j] 中
    +    elsif nums[m] > target
    +      j = m - 1 # target 在区间 [i, m-1] 中
    +    else
    +      j = m - 1 # 首个小于 target 的元素在区间 [i, m-1] 中
    +    end
    +  end
    +
    +  i # 返回插入点 i
    +end
    +
    +
    +
    +
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertion}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +
    +

    Tip

    +

    The code in this section uses "closed intervals". Readers interested can implement the "left-closed right-open" method themselves.

    +
    +

    In summary, binary search is merely about setting search targets for pointers \(i\) and \(j\), which might be a specific element (like target) or a range of elements (like elements less than target).

    +

    In the continuous loop of binary search, pointers \(i\) and \(j\) gradually approach the predefined target. Ultimately, they either find the answer or stop after crossing the boundary.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/index.html b/en/chapter_searching/index.html new file mode 100644 index 000000000..b575087ff --- /dev/null +++ b/en/chapter_searching/index.html @@ -0,0 +1,3795 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Chapter 10.   Searching - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    Chapter 10.   Searching

    +

    Searching

    +
    +

    Abstract

    +

    Searching is an unknown adventure, where we may need to traverse every corner of a mysterious space, or perhaps quickly pinpoint our target.

    +

    In this journey of discovery, each exploration may yield an unexpected answer.

    +
    +

    Chapter contents

    + + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/replace_linear_by_hashing.assets/two_sum_brute_force.png b/en/chapter_searching/replace_linear_by_hashing.assets/two_sum_brute_force.png new file mode 100644 index 0000000000000000000000000000000000000000..33fca976ab7f3704de7bd37cfc08319341cd410b GIT binary patch literal 13071 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 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/replace_linear_by_hashing.assets/two_sum_hashtable_step2.png b/en/chapter_searching/replace_linear_by_hashing.assets/two_sum_hashtable_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..bed0ac02f10e98dc721c0376c6e6681bb246cd52 GIT binary patch literal 14673 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] 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 E4}Jhu0{{R3 literal 0 HcmV?d00001 diff --git a/en/chapter_searching/replace_linear_by_hashing/index.html b/en/chapter_searching/replace_linear_by_hashing/index.html new file mode 100644 index 000000000..b85ce3e94 --- /dev/null +++ b/en/chapter_searching/replace_linear_by_hashing/index.html @@ -0,0 +1,4375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.4 Hashing optimization strategies - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    10.4   Hash optimization strategies

    +

    In algorithm problems, we often reduce the time complexity of algorithms by replacing linear search with hash search. Let's use an algorithm problem to deepen understanding.

    +
    +

    Question

    +

    Given an integer array nums and a target element target, please search for two elements in the array whose "sum" equals target, and return their array indices. Any solution is acceptable.

    +
    +

    10.4.1   Linear search: trading time for space

    +

    Consider traversing all possible combinations directly. As shown in the Figure 10-9 , we initiate a two-layer loop, and in each round, we determine whether the sum of the two integers equals target. If so, we return their indices.

    +

    Linear search solution for two-sum problem

    +

    Figure 10-9   Linear search solution for two-sum problem

    + +

    The code is shown below:

    +
    +
    +
    +
    two_sum.py
    def two_sum_brute_force(nums: list[int], target: int) -> list[int]:
    +    """方法一:暴力枚举"""
    +    # 两层循环,时间复杂度为 O(n^2)
    +    for i in range(len(nums) - 1):
    +        for j in range(i + 1, len(nums)):
    +            if nums[i] + nums[j] == target:
    +                return [i, j]
    +    return []
    +
    +
    +
    +
    two_sum.cpp
    /* 方法一:暴力枚举 */
    +vector<int> twoSumBruteForce(vector<int> &nums, int target) {
    +    int size = nums.size();
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for (int i = 0; i < size - 1; i++) {
    +        for (int j = i + 1; j < size; j++) {
    +            if (nums[i] + nums[j] == target)
    +                return {i, j};
    +        }
    +    }
    +    return {};
    +}
    +
    +
    +
    +
    two_sum.java
    /* 方法一:暴力枚举 */
    +int[] twoSumBruteForce(int[] nums, int target) {
    +    int size = nums.length;
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for (int i = 0; i < size - 1; i++) {
    +        for (int j = i + 1; j < size; j++) {
    +            if (nums[i] + nums[j] == target)
    +                return new int[] { i, j };
    +        }
    +    }
    +    return new int[0];
    +}
    +
    +
    +
    +
    two_sum.cs
    /* 方法一:暴力枚举 */
    +int[] TwoSumBruteForce(int[] nums, int target) {
    +    int size = nums.Length;
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for (int i = 0; i < size - 1; i++) {
    +        for (int j = i + 1; j < size; j++) {
    +            if (nums[i] + nums[j] == target)
    +                return [i, j];
    +        }
    +    }
    +    return [];
    +}
    +
    +
    +
    +
    two_sum.go
    /* 方法一:暴力枚举 */
    +func twoSumBruteForce(nums []int, target int) []int {
    +    size := len(nums)
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for i := 0; i < size-1; i++ {
    +        for j := i + 1; j < size; j++ {
    +            if nums[i]+nums[j] == target {
    +                return []int{i, j}
    +            }
    +        }
    +    }
    +    return nil
    +}
    +
    +
    +
    +
    two_sum.swift
    /* 方法一:暴力枚举 */
    +func twoSumBruteForce(nums: [Int], target: Int) -> [Int] {
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for i in nums.indices.dropLast() {
    +        for j in nums.indices.dropFirst(i + 1) {
    +            if nums[i] + nums[j] == target {
    +                return [i, j]
    +            }
    +        }
    +    }
    +    return [0]
    +}
    +
    +
    +
    +
    two_sum.js
    /* 方法一:暴力枚举 */
    +function twoSumBruteForce(nums, target) {
    +    const n = nums.length;
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for (let i = 0; i < n; i++) {
    +        for (let j = i + 1; j < n; j++) {
    +            if (nums[i] + nums[j] === target) {
    +                return [i, j];
    +            }
    +        }
    +    }
    +    return [];
    +}
    +
    +
    +
    +
    two_sum.ts
    /* 方法一:暴力枚举 */
    +function twoSumBruteForce(nums: number[], target: number): number[] {
    +    const n = nums.length;
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for (let i = 0; i < n; i++) {
    +        for (let j = i + 1; j < n; j++) {
    +            if (nums[i] + nums[j] === target) {
    +                return [i, j];
    +            }
    +        }
    +    }
    +    return [];
    +}
    +
    +
    +
    +
    two_sum.dart
    /* 方法一: 暴力枚举 */
    +List<int> twoSumBruteForce(List<int> nums, int target) {
    +  int size = nums.length;
    +  // 两层循环,时间复杂度为 O(n^2)
    +  for (var i = 0; i < size - 1; i++) {
    +    for (var j = i + 1; j < size; j++) {
    +      if (nums[i] + nums[j] == target) return [i, j];
    +    }
    +  }
    +  return [0];
    +}
    +
    +
    +
    +
    two_sum.rs
    /* 方法一:暴力枚举 */
    +pub fn two_sum_brute_force(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {
    +    let size = nums.len();
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for i in 0..size - 1 {
    +        for j in i + 1..size {
    +            if nums[i] + nums[j] == target {
    +                return Some(vec![i as i32, j as i32]);
    +            }
    +        }
    +    }
    +    None
    +}
    +
    +
    +
    +
    two_sum.c
    /* 方法一:暴力枚举 */
    +int *twoSumBruteForce(int *nums, int numsSize, int target, int *returnSize) {
    +    for (int i = 0; i < numsSize; ++i) {
    +        for (int j = i + 1; j < numsSize; ++j) {
    +            if (nums[i] + nums[j] == target) {
    +                int *res = malloc(sizeof(int) * 2);
    +                res[0] = i, res[1] = j;
    +                *returnSize = 2;
    +                return res;
    +            }
    +        }
    +    }
    +    *returnSize = 0;
    +    return NULL;
    +}
    +
    +
    +
    +
    two_sum.kt
    /* 方法一:暴力枚举 */
    +fun twoSumBruteForce(nums: IntArray, target: Int): IntArray {
    +    val size = nums.size
    +    // 两层循环,时间复杂度为 O(n^2)
    +    for (i in 0..<size - 1) {
    +        for (j in i + 1..<size) {
    +            if (nums[i] + nums[j] == target) return intArrayOf(i, j)
    +        }
    +    }
    +    return IntArray(0)
    +}
    +
    +
    +
    +
    two_sum.rb
    ### 方法一:暴力枚举 ###
    +def two_sum_brute_force(nums, target)
    +  # 两层循环,时间复杂度为 O(n^2)
    +  for i in 0...(nums.length - 1)
    +    for j in (i + 1)...nums.length
    +      return [i, j] if nums[i] + nums[j] == target
    +    end
    +  end
    +
    +  []
    +end
    +
    +
    +
    +
    two_sum.zig
    // 方法一:暴力枚举
    +fn twoSumBruteForce(nums: []i32, target: i32) ?[2]i32 {
    +    var size: usize = nums.len;
    +    var i: usize = 0;
    +    // 两层循环,时间复杂度为 O(n^2)
    +    while (i < size - 1) : (i += 1) {
    +        var j = i + 1;
    +        while (j < size) : (j += 1) {
    +            if (nums[i] + nums[j] == target) {
    +                return [_]i32{@intCast(i), @intCast(j)};
    +            }
    +        }
    +    }
    +    return null;
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    This method has a time complexity of \(O(n^2)\) and a space complexity of \(O(1)\), which is very time-consuming with large data volumes.

    +

    10.4.2   Hash search: trading space for time

    +

    Consider using a hash table, with key-value pairs being the array elements and their indices, respectively. Loop through the array, performing the steps shown in the figures below each round.

    +
      +
    1. Check if the number target - nums[i] is in the hash table. If so, directly return the indices of these two elements.
    2. +
    3. Add the key-value pair nums[i] and index i to the hash table.
    4. +
    +
    +
    +
    +

    Help hash table solve two-sum

    +
    +
    +

    two_sum_hashtable_step2

    +
    +
    +

    two_sum_hashtable_step3

    +
    +
    +
    +

    Figure 10-10   Help hash table solve two-sum

    + +

    The implementation code is shown below, requiring only a single loop:

    +
    +
    +
    +
    two_sum.py
    def two_sum_hash_table(nums: list[int], target: int) -> list[int]:
    +    """方法二:辅助哈希表"""
    +    # 辅助哈希表,空间复杂度为 O(n)
    +    dic = {}
    +    # 单层循环,时间复杂度为 O(n)
    +    for i in range(len(nums)):
    +        if target - nums[i] in dic:
    +            return [dic[target - nums[i]], i]
    +        dic[nums[i]] = i
    +    return []
    +
    +
    +
    +
    two_sum.cpp
    /* 方法二:辅助哈希表 */
    +vector<int> twoSumHashTable(vector<int> &nums, int target) {
    +    int size = nums.size();
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    unordered_map<int, int> dic;
    +    // 单层循环,时间复杂度为 O(n)
    +    for (int i = 0; i < size; i++) {
    +        if (dic.find(target - nums[i]) != dic.end()) {
    +            return {dic[target - nums[i]], i};
    +        }
    +        dic.emplace(nums[i], i);
    +    }
    +    return {};
    +}
    +
    +
    +
    +
    two_sum.java
    /* 方法二:辅助哈希表 */
    +int[] twoSumHashTable(int[] nums, int target) {
    +    int size = nums.length;
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    Map<Integer, Integer> dic = new HashMap<>();
    +    // 单层循环,时间复杂度为 O(n)
    +    for (int i = 0; i < size; i++) {
    +        if (dic.containsKey(target - nums[i])) {
    +            return new int[] { dic.get(target - nums[i]), i };
    +        }
    +        dic.put(nums[i], i);
    +    }
    +    return new int[0];
    +}
    +
    +
    +
    +
    two_sum.cs
    /* 方法二:辅助哈希表 */
    +int[] TwoSumHashTable(int[] nums, int target) {
    +    int size = nums.Length;
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    Dictionary<int, int> dic = [];
    +    // 单层循环,时间复杂度为 O(n)
    +    for (int i = 0; i < size; i++) {
    +        if (dic.ContainsKey(target - nums[i])) {
    +            return [dic[target - nums[i]], i];
    +        }
    +        dic.Add(nums[i], i);
    +    }
    +    return [];
    +}
    +
    +
    +
    +
    two_sum.go
    /* 方法二:辅助哈希表 */
    +func twoSumHashTable(nums []int, target int) []int {
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    hashTable := map[int]int{}
    +    // 单层循环,时间复杂度为 O(n)
    +    for idx, val := range nums {
    +        if preIdx, ok := hashTable[target-val]; ok {
    +            return []int{preIdx, idx}
    +        }
    +        hashTable[val] = idx
    +    }
    +    return nil
    +}
    +
    +
    +
    +
    two_sum.swift
    /* 方法二:辅助哈希表 */
    +func twoSumHashTable(nums: [Int], target: Int) -> [Int] {
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    var dic: [Int: Int] = [:]
    +    // 单层循环,时间复杂度为 O(n)
    +    for i in nums.indices {
    +        if let j = dic[target - nums[i]] {
    +            return [j, i]
    +        }
    +        dic[nums[i]] = i
    +    }
    +    return [0]
    +}
    +
    +
    +
    +
    two_sum.js
    /* 方法二:辅助哈希表 */
    +function twoSumHashTable(nums, target) {
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    let m = {};
    +    // 单层循环,时间复杂度为 O(n)
    +    for (let i = 0; i < nums.length; i++) {
    +        if (m[target - nums[i]] !== undefined) {
    +            return [m[target - nums[i]], i];
    +        } else {
    +            m[nums[i]] = i;
    +        }
    +    }
    +    return [];
    +}
    +
    +
    +
    +
    two_sum.ts
    /* 方法二:辅助哈希表 */
    +function twoSumHashTable(nums: number[], target: number): number[] {
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    let m: Map<number, number> = new Map();
    +    // 单层循环,时间复杂度为 O(n)
    +    for (let i = 0; i < nums.length; i++) {
    +        let index = m.get(target - nums[i]);
    +        if (index !== undefined) {
    +            return [index, i];
    +        } else {
    +            m.set(nums[i], i);
    +        }
    +    }
    +    return [];
    +}
    +
    +
    +
    +
    two_sum.dart
    /* 方法二: 辅助哈希表 */
    +List<int> twoSumHashTable(List<int> nums, int target) {
    +  int size = nums.length;
    +  // 辅助哈希表,空间复杂度为 O(n)
    +  Map<int, int> dic = HashMap();
    +  // 单层循环,时间复杂度为 O(n)
    +  for (var i = 0; i < size; i++) {
    +    if (dic.containsKey(target - nums[i])) {
    +      return [dic[target - nums[i]]!, i];
    +    }
    +    dic.putIfAbsent(nums[i], () => i);
    +  }
    +  return [0];
    +}
    +
    +
    +
    +
    two_sum.rs
    /* 方法二:辅助哈希表 */
    +pub fn two_sum_hash_table(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    let mut dic = HashMap::new();
    +    // 单层循环,时间复杂度为 O(n)
    +    for (i, num) in nums.iter().enumerate() {
    +        match dic.get(&(target - num)) {
    +            Some(v) => return Some(vec![*v as i32, i as i32]),
    +            None => dic.insert(num, i as i32),
    +        };
    +    }
    +    None
    +}
    +
    +
    +
    +
    two_sum.c
    /* 哈希表 */
    +typedef struct {
    +    int key;
    +    int val;
    +    UT_hash_handle hh; // 基于 uthash.h 实现
    +} HashTable;
    +
    +/* 哈希表查询 */
    +HashTable *find(HashTable *h, int key) {
    +    HashTable *tmp;
    +    HASH_FIND_INT(h, &key, tmp);
    +    return tmp;
    +}
    +
    +/* 哈希表元素插入 */
    +void insert(HashTable *h, int key, int val) {
    +    HashTable *t = find(h, key);
    +    if (t == NULL) {
    +        HashTable *tmp = malloc(sizeof(HashTable));
    +        tmp->key = key, tmp->val = val;
    +        HASH_ADD_INT(h, key, tmp);
    +    } else {
    +        t->val = val;
    +    }
    +}
    +
    +/* 方法二:辅助哈希表 */
    +int *twoSumHashTable(int *nums, int numsSize, int target, int *returnSize) {
    +    HashTable *hashtable = NULL;
    +    for (int i = 0; i < numsSize; i++) {
    +        HashTable *t = find(hashtable, target - nums[i]);
    +        if (t != NULL) {
    +            int *res = malloc(sizeof(int) * 2);
    +            res[0] = t->val, res[1] = i;
    +            *returnSize = 2;
    +            return res;
    +        }
    +        insert(hashtable, nums[i], i);
    +    }
    +    *returnSize = 0;
    +    return NULL;
    +}
    +
    +
    +
    +
    two_sum.kt
    /* 方法二:辅助哈希表 */
    +fun twoSumHashTable(nums: IntArray, target: Int): IntArray {
    +    val size = nums.size
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    val dic = HashMap<Int, Int>()
    +    // 单层循环,时间复杂度为 O(n)
    +    for (i in 0..<size) {
    +        if (dic.containsKey(target - nums[i])) {
    +            return intArrayOf(dic[target - nums[i]]!!, i)
    +        }
    +        dic[nums[i]] = i
    +    }
    +    return IntArray(0)
    +}
    +
    +
    +
    +
    two_sum.rb
    ### 方法二:辅助哈希表 ###
    +def two_sum_hash_table(nums, target)
    +  # 辅助哈希表,空间复杂度为 O(n)
    +  dic = {}
    +  # 单层循环,时间复杂度为 O(n)
    +  for i in 0...nums.length
    +    return [dic[target - nums[i]], i] if dic.has_key?(target - nums[i])
    +
    +    dic[nums[i]] = i
    +  end
    +
    +  []
    +end
    +
    +
    +
    +
    two_sum.zig
    // 方法二:辅助哈希表
    +fn twoSumHashTable(nums: []i32, target: i32) !?[2]i32 {
    +    var size: usize = nums.len;
    +    // 辅助哈希表,空间复杂度为 O(n)
    +    var dic = std.AutoHashMap(i32, i32).init(std.heap.page_allocator);
    +    defer dic.deinit();
    +    var i: usize = 0;
    +    // 单层循环,时间复杂度为 O(n)
    +    while (i < size) : (i += 1) {
    +        if (dic.contains(target - nums[i])) {
    +            return [_]i32{dic.get(target - nums[i]).?, @intCast(i)};
    +        }
    +        try dic.put(nums[i], @intCast(i));
    +    }
    +    return null;
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    This method reduces the time complexity from \(O(n^2)\) to \(O(n)\) by using hash search, greatly improving the running efficiency.

    +

    As it requires maintaining an additional hash table, the space complexity is \(O(n)\). Nevertheless, this method has a more balanced time-space efficiency overall, making it the optimal solution for this problem.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/searching_algorithm_revisited.assets/searching_algorithms.png b/en/chapter_searching/searching_algorithm_revisited.assets/searching_algorithms.png new file mode 100644 index 0000000000000000000000000000000000000000..fff1066ffc033f9e73dbde2e0bc0c9428dbb4d85 GIT binary patch literal 34523 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.5 Search algorithms revisited - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    10.5   Search algorithms revisited

    +

    Searching algorithms (searching algorithm) are used to search for one or several elements that meet specific criteria in data structures such as arrays, linked lists, trees, or graphs.

    +

    Searching algorithms can be divided into the following two categories based on their implementation approaches.

    +
      +
    • Locating the target element by traversing the data structure, such as traversals of arrays, linked lists, trees, and graphs, etc.
    • +
    • Using the organizational structure of the data or the prior information contained in the data to achieve efficient element search, such as binary search, hash search, and binary search tree search, etc.
    • +
    +

    It is not difficult to notice that these topics have been introduced in previous chapters, so searching algorithms are not unfamiliar to us. In this section, we will revisit searching algorithms from a more systematic perspective.

    + +

    Brute-force search locates the target element by traversing every element of the data structure.

    +
      +
    • "Linear search" is suitable for linear data structures such as arrays and linked lists. It starts from one end of the data structure, accesses each element one by one, until the target element is found or the other end is reached without finding the target element.
    • +
    • "Breadth-first search" and "Depth-first search" are two traversal strategies for graphs and trees. Breadth-first search starts from the initial node and searches layer by layer, accessing nodes from near to far. Depth-first search starts from the initial node, follows a path until the end, then backtracks and tries other paths until the entire data structure is traversed.
    • +
    +

    The advantage of brute-force search is its simplicity and versatility, no need for data preprocessing and the help of additional data structures.

    +

    However, the time complexity of this type of algorithm is \(O(n)\), where \(n\) is the number of elements, so the performance is poor in cases of large data volumes.

    + +

    Adaptive search uses the unique properties of data (such as order) to optimize the search process, thereby locating the target element more efficiently.

    +
      +
    • "Binary search" uses the orderliness of data to achieve efficient searching, only suitable for arrays.
    • +
    • "Hash search" uses a hash table to establish a key-value mapping between search data and target data, thus implementing the query operation.
    • +
    • "Tree search" in a specific tree structure (such as a binary search tree), quickly eliminates nodes based on node value comparisons, thus locating the target element.
    • +
    +

    The advantage of these algorithms is high efficiency, with time complexities reaching \(O(\log n)\) or even \(O(1)\).

    +

    However, using these algorithms often requires data preprocessing. For example, binary search requires sorting the array in advance, and hash search and tree search both require the help of additional data structures, maintaining these structures also requires extra time and space overhead.

    +
    +

    Tip

    +

    Adaptive search algorithms are often referred to as search algorithms, mainly used for quickly retrieving target elements in specific data structures.

    +
    +

    10.5.3   Choosing a search method

    +

    Given a set of data of size \(n\), we can use linear search, binary search, tree search, hash search, and other methods to search for the target element from it. The working principles of these methods are shown in the following figure.

    +

    Various search strategies

    +

    Figure 10-11   Various search strategies

    + +

    The operation efficiency and characteristics of the aforementioned methods are shown in the following table.

    +

    Table 10-1   Comparison of search algorithm efficiency

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Linear searchBinary searchTree searchHash search
    Search element\(O(n)\)\(O(\log n)\)\(O(\log n)\)\(O(1)\)
    Insert element\(O(1)\)\(O(n)\)\(O(\log n)\)\(O(1)\)
    Delete element\(O(n)\)\(O(n)\)\(O(\log n)\)\(O(1)\)
    Extra space\(O(1)\)\(O(1)\)\(O(n)\)\(O(n)\)
    Data preprocessing/Sorting \(O(n \log n)\)Building tree \(O(n \log n)\)Building hash table \(O(n)\)
    Data orderlinessUnorderedOrderedOrderedUnordered
    +
    +

    The choice of search algorithm also depends on the volume of data, search performance requirements, data query and update frequency, etc.

    +

    Linear search

    +
      +
    • Good versatility, no need for any data preprocessing operations. If we only need to query the data once, then the time for data preprocessing in the other three methods would be longer than the time for linear search.
    • +
    • Suitable for small volumes of data, where time complexity has a smaller impact on efficiency.
    • +
    • Suitable for scenarios with high data update frequency, because this method does not require any additional maintenance of the data.
    • +
    +

    Binary search

    +
      +
    • Suitable for large data volumes, with stable efficiency performance, the worst time complexity being \(O(\log n)\).
    • +
    • The data volume cannot be too large, because storing arrays requires contiguous memory space.
    • +
    • Not suitable for scenarios with frequent additions and deletions, because maintaining an ordered array incurs high overhead.
    • +
    +

    Hash search

    +
      +
    • Suitable for scenarios with high query performance requirements, with an average time complexity of \(O(1)\).
    • +
    • Not suitable for scenarios needing ordered data or range searches, because hash tables cannot maintain data orderliness.
    • +
    • High dependency on hash functions and hash collision handling strategies, with significant performance degradation risks.
    • +
    • Not suitable for overly large data volumes, because hash tables need extra space to minimize collisions and provide good query performance.
    • +
    +

    Tree search

    +
      +
    • Suitable for massive data, because tree nodes are stored scattered in memory.
    • +
    • Suitable for maintaining ordered data or range searches.
    • +
    • In the continuous addition and deletion of nodes, the binary search tree may become skewed, degrading the time complexity to \(O(n)\).
    • +
    • If using AVL trees or red-black trees, operations can run stably at \(O(\log n)\) efficiency, but the operation to maintain tree balance adds extra overhead.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_searching/summary/index.html b/en/chapter_searching/summary/index.html new file mode 100644 index 000000000..ef139f991 --- /dev/null +++ b/en/chapter_searching/summary/index.html @@ -0,0 +1,3781 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.6 Summary - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    10.6   Summary

    +
      +
    • Binary search depends on the order of data and performs the search by iteratively halving the search interval. It requires the input data to be sorted and is only applicable to arrays or array-based data structures.
    • +
    • Brute force search locates data by traversing the data structure. Linear search is suitable for arrays and linked lists, while breadth-first search and depth-first search are suitable for graphs and trees. These algorithms are highly versatile, requiring no preprocessing of data, but have a higher time complexity of \(O(n)\).
    • +
    • Hash search, tree search, and binary search are efficient searching methods, capable of quickly locating target elements in specific data structures. These algorithms are highly efficient, with time complexities reaching \(O(\log n)\) or even \(O(1)\), but they usually require additional data structures.
    • +
    • In practice, we need to analyze factors such as data volume, search performance requirements, data query and update frequencies, etc., to choose the appropriate search method.
    • +
    • Linear search is suitable for small or frequently updated data; binary search is suitable for large, sorted data; hash search is suitable for scenarios requiring high query efficiency without the need for range queries; tree search is appropriate for large dynamic data that needs to maintain order and support range queries.
    • +
    • Replacing linear search with hash search is a common strategy to optimize runtime, reducing the time complexity from \(O(n)\) to \(O(1)\).
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/bubble_sort.assets/bubble_operation_step1.png b/en/chapter_sorting/bubble_sort.assets/bubble_operation_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..7c53d16c7101df7d5fe89efad61c0867c8641c0e GIT binary patch literal 11251 zcmbt)bx@qm((kjoxVyVs&;+*-Gz1F}BxoQwgy7DS-~y>)iQccBXf_e?2oj-Cgrcn7XP0HU1ikw z>gDBSY;3HquHN6@zrVj98yjn3VR3qTnvjs- zzrVkZj!tfF?$Fv$b#-+`MMY9?VqjpPUYf3(ta#U0q#vfA-4CO2=|XR8&-O zOOTS1Qb|ckK|#UT*qE7_+4=c-Z%*GuT2$R7<31xrd^nqII6t*72rJ>Ko(O59k2E z@mfjtxt7P`erEt;?Ez@keGzF9_;2$+D<+p~(*JM{Jl5fBY5&J1NJ1FzA33M~_DKJ+ z6m4x&TpXmoa-es{l+XV^)wm|60#oHEKsuRN0IKudEVxC8Q|zn+um6H~?Z0>Uz+mFV9AI9Ale=?RZSC=E%IOb>ex8st5xXy*oX6UG1ZM!)XI~qrVdd zv>*CD{P0k^PwcqyAA^}YZTRZ;lSs7t<9mj>i^JYxWuUd5-Q6?{H+U?ddS6YZ3E~Br zUW@H^S#A}~V+zKq3u$jqpOz0S3qp}Xb6;lHKN@o+uQvTi_jvj0LgIALmLCUg zNLmgEZC1!bCT&qx5qt}|!L%!mgNn^a{T*&~S{Dq+hj=-67mI8QV#^l^{X1Qg~FW90lK_i|x9)<#*I zK{CJCCnmXYDYvXBPo83Vb`^hWR+ZpmKWf)7R92|3z!0;@6MlKYXa8hS*KLTIPJ=b* zbb?kQ(J8Zy$NHUlNuiLC(1mIf64NdNIvK>a=|@Jzgctw9z_+K_l=pvDTivB1i=!1i z@*_UX*qyF$NWOP6m!KT;u6dROm0e*;vd7@sgc;?Wa-$w@@^q3Vq~`F26-K}O@rt%> zhibhgGca8Wr?-<4qB#AYBWVR9fPPYNRZjtCeYYXQmkN?Qnj(NM?h)8tG>+u#>Dadltdho!I!kB0(LrKF%}%uJrykVkPZCoEZ_ zb>GDIuJsMnevhX(*OlHk^LK44_c!SW;()HC`OldM7mxwy8Vyx5+9ao$fB zd1Ljj>$g24E>?|SK`!6ny5PJ!Si$qqeUOjdk#VM4IbeL*v{V7=zm7Zjs#bG*Kj+!} zv#$!JHMBoN0vZ{?H|c2HN`+2R<_ief>ae1lMA835doj%b9TOSK_h1Ek2#r-&L_9w` z@T@=k4g{O!Vy-ndeR)KNHv-Krd`{8doLct^aI$2P@I;`d%nGIbe1I1g-2~@7+iDYV zDX(`)Q?s>nRNZ!PW{5-BWbUln#q|R8^&DhiQh+h1zyM(j257VhTyBJi=y~4*VdZ$z z=QW=XI1GU!Tz0)46kgLWJ|MaZ8G$KO$KtEK>YtEAr=I$;77Nh85=>SH&4lkdoqBpu zH6R3bZ^AoJMK;Y>08=unou%^35QWALF{?LVu3?eQB2;!Y=l5heW9{S;Om%sM=IFXo?Xj`+bZr)4yYu*e85E7>TZ8L9rx2IRveQe z&4nUothcSWl^p6?T>wEI=Gv|da2CCw1|hrlCxxkKYe!306zA7(JCVW)ils6jM?-6` z_(rjIK=Ic8&&0iu#wSgZAn@loV*o)NhDn__dsW5r`m;&fb~|w6k7|2D7$2|a00ob; zfdsUmg01}cg;A;`)_N7Jvy%2ogKIs7!n-jQo<;gdj+aDmHIN3A4g2wpMLE4LSxRDr zl-KE<3C0?cRK^$ljr4Y&%l@enMhma1ALj(s4i-GDc~s~^*TPWEbqT!eL#N5qMad0G z8<(Fmu>u*^`La7Lkv*XXa%Wh{g*C0UTPjyt(~^trq~6>I)2D>T2x@%(B+2SV5(9Z^ zewf#X3Jy|)E7&3kgyE5?@atnUVh0KGX(wPxXRDr0#!;;5S{1%;Ua^urI!L!JFaQW# zm_7*xg#M*Y&}>hdRLlu|y`%17sh#wwfJ`H7h0E3<}aa{+`OPE?>Y z`hgfMG&o$cPIb?SHoA^Q%-Ks`9B{{M0PYJ+xMyreH!@QC7*Oo|=ThW|kXy>o!(3pB zcS6-ne{>Il^8Bq!R#{PUmW1__>xzK~{1vpw~hJjI4-dX%6=&m<076! za^S5}4{c>dZR&A4sjl&_eboID*0LD|TlG_&@&gs6j>jC!3RgsEEue{_jdx zCUrW1_gNYsnhKA35NoC2jteo*4}Gr#0vz6I5AxKx17`;tp=g1>-#FPJ^CsUGAa&Ic zP~*|$0fO4Vi$N(yvdn~9WZpPj$23m5SMNa$3ozaU;BLMyZLYQxh=L!(g?I*QT4$1O z;>hHb=3 zV`OFDRb)}AWPD;93X_Q%Y7CKumxlUAMUU^*e(pEr58FHi(K)K2%TAH@8>?6atPmf{5zO zYr>I%hRm1lX+%Kq%-6a<;K{wKKlbK&u|fPI!rglgH^k^6`EracwOHen^S*SIm@K&h zue()O9Tsaj@taC|XwM*D%?h z>Ddu1$`34GZTx9q@7w@Jl0aQCcOW&F5R_c~C1bfwrWzh=R|s$n6^+;CK!lYc^F{*1 zA^D?tI1!Q^py)5h?*`SGKv*r4;elEct{J(lqc~tT8y|dn=2ESc)~fcTf$z*wSSIX9 z@>qB!*XG3KDo0$*PVVdESi9|rwM@rRnX6-j=w45#f~~yFua-Q-jmXj&+?JfEXO&3- znN`yQGN&*m=nF*>^xttswx356%%zYke=?ItDdf-(mP>P(1eXXwJn9zgz6e9V3b|h= zC zYLX9&^{G+^sj9C#q1hY6}264$ZffXXEGA#e02lA|7*!D*}dp888L8}(N4 z^GQs_T}7hr3D-?`8;P|sE&k7ZGSVjJTHahZI%j~_#0e0>Z zFBbb?^i1fOB*aR1`s4fS*$NQW))~Q|+F4WkBbqqnvC!rna2Z=L++#9rCwRaFJ++8} zyg$9odHzBfHM*?Ui-J9-;i}1L!Zge1v&PpcysIN$WLc6jIsPsz-Z_Ih-N}>v)X8ET z@yfit=1vV!<-&nCdY%sCPs?C#c1UB( z#>rG7$;irJ(S^~6ql*QMa4oN1b);q{GSImui;ZHXp6Pk)sg=XF(k^SYCOSIaN>k;# z=qa?;@GI_})ae9{8@&ENsr9y5gFZ$26Av&=FJZqHoDZ*7LQ7D2eK`u2iVL=XWUyYS zx3@zcXG33bjyuU!Dvv@l$(j1Cj->7`l#P~99xHG8Zm)Kk)S5R$JjB$QTw3Y&&8G)s za>0eVha@bwLa$!?sv z-zz7aEN|xl6GGVjrBV!mWNf91Tx3csB*qkHyS8hK9~yU_5&A%_0fR#dbvO4of#*PM z88NR{QAxJeCaP-eJMXjOrE5Pxfr(L6#N%TeMP$CRG3xPMB25m%G9}fE#_h$|GlLUP ze#3e{WB36_jPW;9Q}Krfpk_*YANeNmF-@~%Mr9LL7LzYywtt6)G*u$6Zii}FTTIb( zSBt7Auem6V&ev5e!7@iuoLiVITGHXxkQHc6$L1eHR&dih-7 zrKMm*qnWVzvqnWP4N(((RPJgP!=(OF5Q>|O&@U!CZU~#w&yby;M?`q25_{$nz4j!$ z7O>X=tojC>Q}oUkz4kUjP_}6!dN5k+Ar-hlkz&P10n4^3RMm+hs6@6sG}S4H5~Gi^ ztBAzVjp=)^4~g)8A6mXUdQLBuQ)$r1dw}`(65jovGVre$s-mjQZ>${7-_?92)gWg| zDO_qSDBb|KV*B&Lz4K|u7u_V6l9R{v!PReHN-@jKeJXFQ66#P#gGH&c>%w7d_OWQY2ewJBFsT>41m< zp?;c!Ufpuq>AD5ly@SzjcLM4-Ol=?I3@^_isr;vLGdF=Wd&HR>3&;!`gcL3bGbN~j z%D8v&bjyj)WG9*;HNCTpjV!J{V$7?2z|JB0DXilq4@!^-!ChPVRvy6eUM z=xfyr$bSZw^HS6$=!yT!2%e93PDFu6xdvf-M8_Yk=0ScQd3l^Aj37JaDrNBnSC%{ellF2h+jAMrUEmI-yFwp2fS5@ zCzu5Knma{$esm3{p_NWggJ%FyT)XBXZwfX1yK_4BE@i%_ryQZE^9?XiReNMc<&Tw^ zBf{I~2L2#ZLA}aBwA2@I`ZVm5&n;XvfA5~JkeQ$Efs?~+3R%4I^x3K>~5ur&8Uc8k3|Mb#S=pp z6AEHvA6>4)+6=o&rNRif z7bZ%gp4t8iM8^$~Py)lv3q!Sw*IIT4v8og@L5sxP@9^T5ztb&*1HKNq&>c>L3F|!c zX*ToLrz+{f7K^tY4JPqTYyS24y8-1baLD{zY3^fo!@qos%dYI>g9Zry*CKhhfOCGl z9EA)6>1Uo(qL7LedFg|F#jd#li6?;ry1h}Qs`j^y7eZU7ZrGWawkUINhf=?sgcZnb zQMFg+FdeWso@ira;uVS5tPQV_YHpSa53UsX@`(2M5GyDD(Z>o7!$LTNPn ze+02tTtS4bbi4!&7cUA)b&I^wEx8IN_N51iq{1t@pCFWAJ&J%NuV>N(vieo_Bq~=s zngf4ozuF(?4x5uCiAID$Zx^W0cZ2Q$lAYh9@k>XHVfISZ&=#T_w4~l>qQ7y98=*Dt{>TQ^=vJU;U!f77>MHNM z-j#rcc@u-;KcH#k5^Jf^&x~zJi1IdeUyDOGi`8;8FG?Tefhm@{*1z1Tj~85yzx?b6 z*L_Wp)-$_R0Ll$ATig(wL@~7_V9^}aHfdTa#Y|pRy~8cxH%EAxsN=UmbFOm!l%ak= z5~j1-nh1wnm&Ounqo~KJj`$P63QiZF=;53%i{KWPiD@n(;YlniUH7HG`&lC2=AAN2 zHn1L`e@zws1kBbGVgv{+V93fq=HbtvKQ3?99M8^JOO`km{qjtyks=sJH3&BdY z{27?Fo|-*Z_Ncz_3Nx75yNLFNCX_mcptVTHr*{*sYbpW~L6*BDdYl9Cba5`95I{oW zS(kncfm|Rfo_F)aIVE9F9E4DgKt17a2x!v8KJl~IX=<3U9L?^zBa(}4jp{vAUWe-5 zQ^Id}y0I1lcT9?4J?;Pu#C>R%=1K1?NL&YT>k?o4=aj3GDI=E$+k~D&OV7DOQZvGf z0x#~vGyVjt+$F;55JNK?5`p>ZHOzXj$8!t%o*#zhlr)`=7=}jz`hVjeK?!{ z0bx<-kmc>31^&r9u5SUOxSME@Y_;K(HBk<9F~>;fX>aiUJ65P;GI-ih zI#WNU>))xw*k_kX5+N#=xUrO z`u6)79aJUW@EXK*_f8F2{wa|Vbbwtkp8+{b+g`>4K0da{sm?0W{S(_{*lG|F-imH+ z0adcjH$aj-faySXY457XujdzZ^lkv%z>L2obEnjd2Z~+YMhg?=DD5N^O2MAJjbXNC zH~otf(LHc~|0&=5!Zn(!2s`pgDB!iu|4TZY8I5uE_D?;>c)rlS{No#-rZpB3sWs0w zK~(X-4}e{*fQ9VSrp)_6Zt$+N$Q>klAhvc%FD0d(xtB=OBPmv)iNx6 z2%EdCrr%hcj3ai3BT^F5h9#mI%#H-|F(sAuy0>WFuWL!+uwNU>y~@Q&=)f{LRlx@9 zn#%uk$aPS8%c?@kfWBTS8D%(jvq!t39j;s$(Bgq{`=8>$@k&+#w72hQzrcOe)B{Pkm^l-`DaN zB7wN7{-(MGTM-c9njNfJ(6knyA?ov(H?CuU0%|x%sRGYD+CCp)TERi z7$>4+In#~M(COalREl}w9(V~URMj=?z|0R2_v9mM=ySf%fFI28Bu?j}Ey*!xnDMN0 zoG@3BT;L{BXXJhq$|<@fU1l-|@}w4;T4rm%17F~qzvEYu$&4v~3jWNOOE%@8r04$f z9G*o~cg5Y%c5v09A3x9VcCl+eYj)c`sawhEDkPpNs#TDOLi&nSZ}ewUaMZS^rUP^_ zz4hMa;_VH6_W@tt8MrbtZj+dX%PUu+GG+jEFD+)Dad^aOoXY$CD893@-CERG;X4)% z{0bUse@Up6t_}Ui5p28@!gmq${pvIN=qCEof?)TatyTqIU~xs zfsF@EfZFMr{H;_I1djE0)p824uI2 z+d0#sn*P3TxLL|kvHBC-Bm;O=`Q_Q^u=_^6TsqXJWagCwfP2c$y7M@+`Z|N;y9W$BjVh5;LS5_S5sSOEA~iE%OYxv`j(vj8~vkhY+o#WQ(UvzR{(! zdP(zDg?lSnssF0?`y4T&${GGAL$pQmL?(I{?vJ}`-W5L6D5**s4~kFpK_oMb<&UEu zJN#_lvQXGq$QSL6`=STC-b(^~p=WA*6m_q(Eac&Hos4v)WpW*(Yccvm>4gc_8kdSI zKvy+GxzI^gX5_A8e3S+C;22$HX=snGYzFa6TvR^QAka1B1eveapmdm=_{vBwt*h5F z_D#cHUyDWFpAv$G%k2th&FQCv@j@&4Ay$BC16CF&aD^X=g6B32P)N@|`G@$>auQu( zT(Djz+-A>XHgR%u?B^kg`(a_b-Y_^D?&jR|IF%t;f7LzJ-wSlXZ!C@+^eK_Syiro$ zL-_oNw%3^Hnz&3IewFd_on(IsS5lN&I>If9uftTdd4j%V7y>gKfZ!X@D_$FxZ*k=&t@Vh{C(&n0!}?)Er+!r`wUr*4I1#MplswC?*BZ?mLl%oJ*4vgo zkmNJ>eN7A4@1nbA!R>x5Vuu>gLOluL-bUdK(sBbWL;Q#qksY;wgY(3j7*9AI6tj-1 zLem)~W}vOkL+2;vnz5uKan9#-au|j1LOcJ(uijssK)Vb_#1%PfTPPKhqZWh)qPUTX zzE(#bJiNjQ+ly&gr{L`_*(q`^pZkDpfijMo9TcVCqAyMXV_sWoL-yl>PE>2)A~`~O z{_2?T1NzFongNt!(60{7`xu0-@}TFETcA|($(>d?;lVafh}PJh@T3`S%OJWZgkv1UJcfvKhL3JC+k;vyp047*E zq6-Z3;H>$X$++DfTm1R_KpZ}7iZ8-T54~UoVP*EVkU7%AeB+oT$3H9;#lKwpD*FfQ z@p|g*>}AI@nrXz2IGX|Se(GfW^j>r0`>DVi85b5P zd8HT{Tz}0Usj_PzP4qY0$N0rNdY4FztbEmQj^%;PbIq=nuOOydl<>3iu8^T$KHM+K zMj<<9wQ1t)r_50P={N2*9tA9FuUm+qT$dyTTJJUlpt4dU4Y~wU`Zfy6zZ(98D*qy! zaL1r~WJSYQ=>qtnvOWKo>O9TRTj?Vk65>94q-{)UifCM0lzDolvobv*1w1cRfg>rd*_P^o~cpm_~&N^~DuEBdTM;g8x(BA62#4 zi(y;B2-a%#M})1;Padn<0%)@=5p0XYZ>4@<9w#bY5$aGO1vGH!*|GMyBfr+G)2xtkCVyeYoAB!y!fo01_mQn$I_!zbb8 zo0*ysGT8i`b}VCbA7FHA+b48QLkDnW{_?!Ayg2zmyaAgL?cG|v$)fSK*gDUWugH*uF23j!z!^eV5Uh7PozBmbp^{YY`2oxM$Bcc=RSQ>a$xAT^vTaGNa!O5DlmqE zVBsM_RQ_yBxh^A12X3VyMZZrO{#tv;YwMj<(w4a2rZ&y3XyK2EIijs%3{c=viduRk z_7$#L+JZIDIcg#WY`=>d32#m0tUFQEl}sgg8f~o^D^6R8SRC?4*x9=n_?tL<#hN-eMm`XIHhrh`EhN^>Dd)$3{Z+ql=DeB<2os@!* zOe(-m@z&6{BkzrL`WQ?RJk{(-jIrS;GTwI%Q->3+;P`xl5Az}#bkT*FN zAE9;_Rr)9nCBOr?v|`m9DCce}YW(<7xp(wC?*(?K3x4On5$vnJA-E5hY)1DV9=pn3 zic(Y3l6ic5+}hd-ZVFmES-ZZz78Vx%{Q0wXs#eWRb$fd|YzdYB zssCMXU|>L3S9fu5v9+}|uqt3+bztjsvwXa4c4M|+!ZF%BU*L)c240u_OajVy+iIlP+7w(bn2 zpqp4XypQSIRO>4)2mcO7fyg11DF^lX zY5Dtn6YhN9_io(BK|s0kj+0YiQ>%Oa8#fvtnteO?U;hg^Fz8w#MZ9s|LFK7t!!q)d z;w=q8J#4*CWp$1Xcv+h6tvU|#{_Oz#s>VoeWkH~t1*u>A0UGG2Flvu;>K!Pspy2*c zzwn_a{#W_E(`fTyjHU$emCxhEq%k1Fp-ww>r`WE2BwRJe!$TY7jfDV1(L73TUxv7; z1+rc>2LxuYR`P!XfxKWIAijABzxGZMXGn>b6tf~1babZ)NbXX%O~u4`_k_9Oh2W=W z_0CA^Fv<6+jkUoCY|n3ImJ}s(hB+W^QX#?^CkquH-{sgIJyJwSJik&krgFbXs$FjI zK@bUXjDq7u#k|PQK(}2L0~8=P|50SnY+AOIz)2>|1 zDh)6?jZ{IQrBLM4AHEz3fKStPJV#UGnCncCmvamS$0&hoUIYCj6Sr6KIL#-tH<{2a_GjwXp_;Hdk>J;z5B(SgVUp;ryVOXC2J5cC z-_astici0jfF@B{H2+;{ep(4(Lu|Ou&V+c@96oF;t$mSX4DomqiFf<&8$R)D1V0Z! zsQ&htc;&SjkmFnav!nf!khR0#IX`WT)A23fL*2x=_>Ev@+rHqB#&PfxM%fHT_QDCv z>1!m|$Av$_xVDd*NK?8Zy$8$rP}9?BDa8jL(GMz6<3QLfBa{ zzlCtBV9W(~tJm2~{7>NRdWY9~4M~Fp-)ma*iOjkt#%F z`)eoPvDweVfpEjXrVPKXm8Px%Gz*8h+=}6y9?}+lvOfVj*EVjf(6qG2mYJXC%A6v5 zDwpD@+7H+yF_nR#loIBrhpakE_+9{8Y6M7Y7gBp^l*rD9$(&$*6qe^RHW ztC$cnzMyzm6?Bq6mnT|;Za1OAj}lX98iU1SU{M8A-GA`K{cT|P;I3l$`<6JNx_EFeo@w)7a zrZYy=cin^|Pjs}f3E(|{=`)Q^d3i3ydk`IAq;97|k=Y_eOV+E@ZAcBQ?X7}=t>TYN z834pHvTacO8VR?Yv;slzyD*Y7G8{KXI>Ev^>H`SfA&1<_Q7C-86JR^kyTqXJMUn0A*`@mT@IW5`6-eisk+@;kNCB%+NW z*b4*5=_J*p=@vjzLs-hrtG2mE&?C)2L4(wW@5Do+M8%*o=n+L;${;`A_W}KN)1z=c zmgTQN)vIfyG5A|801MxhsdWP2azV{x*m#-D9HotH^jh`f+}17>a5Dj`g`mMdbK@Nl~L#J)`g z2ik%)G)IjJNn4Vwy>miRliE|PM1(54>|)al7Z6U|eME^#S@{zH5&>HXK9j(MX*78e zWLO5;qKSmDniwX*YLK9q{@7#F_!55&z$d^vp>rk{JdKnK?}0ZSZz^6Q$cZd_gNKYh z2K7Ij-2!A7_%KZ^dvwT6gL@!#qVZ@8SfKa1iR$(~04;AXz=<530%=}OuEqj}+DfP% z-|d=d)NdrACslDAzXFpAqnu_QS0wz3x%8rjA1{ex)0nS;8|c6(ZJz@aU_8)SPv^>R z*5kh+#s08kVUG|zaiDli9u5;hUydF&~S#&k$wzoh8gDS zTel8y&(J|VuCdjoX;?Dyr@Mrp)vmk3D9&gV;{Hw>O{2rO>vaIR`gasG8h;+dR4MlN zH!G2r7~;7o!a^P;ax7sByq;JzYM}!8Y7US6G&5%I@fsKQ&5s}MD^cH}O z47g5z`CHMQva18iSNX|P0z8RGJZ-RbdC3kQ76Z7z8z;2VG%hydskjUk2oarye7A*XK|3I|1R7K%*f@YG_9 zo!<}bJd(a3Wj2U1VUu~~2O?mFt~BG1QC}gC8A+@>LLB-G5Uy{wZ}ejD{Su^k5uKw( z2=s4SUSIsGVB9(%aA_s$B7KoC0|c}*dUM*yuRfsd1!|PZ%7Hn8&F#`O2Nd{rqAO|b zFyKe=-@h}SAP#5p)0OqhMp=-9$LCPgdiFbByFHM;$gTqdnwUiivM_8yi6nZ#;j6Nw z<~TZI1+AoI)aG4N#4v0AMAaY+8$>(_wdI@QfBd1~Kc2|uk0D7wTeG0A5E1Pt0z)u5 zME-vMnCY0>e08qToTxsCDXNoJJhX#3wEoj_?l{8S`&>CZvJPS?8C;J1N*aMY)*xIk zEmu&BSGol)+6rZK)JEdwx#;h;Z^t$t(#GS{rfd9H6T%V$LCt?vxBD5EMQdgJm*_6C zp%*x$C^^>be_eNtVPC(ImNPBi*Sgq@pea7KDQ!Fh zFly%GgxrT|4I|~*Kk>iI0eJWC&r63z>iom4ub==j&0yXjRq&uQD;O05aOV&N+ttR4 z-;T+dpKUvr26gGz1zb zN%Gd8ae*D-_hH&J$PxfT{JTGu{skX>7RvtBEEUCv3UdKIG=p2+GbSv><}xp4@`SiC zp};>HmCavwr?y7BPLlfUopoa%6bSG(f#Hu<-J02bX+<3SfWKx0&e6&~6oCsG^oKL^ zu>SI;A3->^_;O&uckycK7Z9K;Ayv)@vDqlITILP`oGHs4ziWX14<%E#OczF<7YO(; zC{Iz|;s80gCZ?!SuE*`bZjOL5{=KUD$Qg-*NjJmii%)l;hS!xh;#g6CM7Az4GIy#3 z-pI#E$8yj`X4CWA_FSMqaMuM?G~LK-(|V?G{*R;f9Rvp(@wpAXGkGET|KUtOR~|wR zH6=w2t|R1FvwWaI&r%kTJtV^|7XCk|{ohr~-fQ=NSrCSP@ca{tD8wvepZF>@ZV`(P}Rxr5K3<2Jj@9g|>i>P>Tb3QXO-R znCPvUlrs-T*WX9LP33)~R$8iy?dobidtUOixZuvkix?s}XNGQ$q6I{W|G#Dlmo&(v7n-5;;JLjf(Tz0(a=Msq=`Zi z)jkzS6%~G4gAmvw!84R9`~(P?9J= zxjeqceWULw3bo}}?z)_LS$?^UaUtLh%#=eBYcR$C2gEX7(1s|^u|$9O<%24qxyjC# zE0^QdiREj80f$C5)}up&upt9bTRp)3Ke=RuZ{iwA^7q9n+0@e$uu^8~sb7rF`t&NT z?kQ6g@Eam~&*?P*xTA5~XsNb0Iv^zxBsMU}K_&4_7LaupbRq1M7M0DYT(7ECzm zf^wsSX+ITa&*m+}IgUY54L<-lppPKRSn&!f>7tES<2VQTH{@gXb-2a6@qE@4hLm7{ z86DVeb2!iw5XG}79dB><1d74seO%Y22I=3E!F z(CP^emX#l9y2%62hLB66mDCbs6{qR-gLNQuGkRcvCn1@*KYsSS*o-rYF4Y?vSHhx9 z*}tz~eK7Qt>LM1zLW4}|EYY3@B<7AQMVAY?PoMN5O4UZk4cMU``kpHeYB_V910RH=5)~C$#f&;?*htWN%t+8L#33vBxGM+G+Dg>y z>RE#npSwj!55qykW-9iH%@>T{joLU8_4%tB|IJn@YP0+$RHXlHNqUk8F2cGkGTG~f zktH2RuUx+37!|v%4jjmr?;}~eGs7F0$~hG(?r(say+MDCxkG1zas& zk-`)k7!z_|z+{xj8bA)K?oV6cA%Ran5s+Nt^3^eM;I@Xhf(*9lzc(&jt#m2d2dufI zqzO9-3*H1FaH=R?&79mfE%OmBa*>bW4~r4D|J+JEW38b6velQWymgiKt;=P=w}TBZR$6Nvi_t)ayr*SNF*X!pc)sCUhk|j z562Rx-Jnjdy3rA1_FAwZi?lz1>sdqJ@|uu5ve~Ia*(c2Ft`W-Ge5^1R(w)FFLSz=A zXe9IE+DW|Zks?ROTBQ;rvQi8U8PbF!tBR_VM^L_?{&LB;%F6HF0sP3X&W=0c`FoG@ zu>26ZDN?FHr~8o^P~F2Jkfe21e&gB)dT5ZSj}xa`Uk|WS4{Abo3)@=&!mng(cY6+w zBs2yfmO7rn=~geP4(;$HTJ^V&!Q7+Zls89Q)|~jq(^k5gBoe*z#tU$&f`mm};kd1c z)0$GxB1R;gP2S`~0&o2~7I9=}l+I~iD00u)$*AzK_Mw(J7)0Ujt%sKRCfu_hnF~ax zPiZ5Dk*V-G1EAqKD#W3_<{SKVCJ1{H8(wB$RcIdI99I z;B{y~c&`&0mBtYc@zcmhgB*qtVzxsL^T`2t2L!qGdoX9=uY<{S_q zyj+%SaMB~a;edXt&Z{xLLPyuAasv;=dE3}#9ZIU(gHsBmUAd}c&E<(`Hojwl5X=9# z<2Yk-9_=v86U;>idtkHM;)oe{RV=)x43;Zjlr3LlAwoJ;-bckIvJDnALavzhjyDvi z;;?w5+b+V{3!G+Xq~^iu61p#a|=v)K>jAOc;z zj4quGhS=+WYPLj?Iqx{38T+?o?D4#$vGZDn?blP{cV)@DVS#dXj?O-%?v4+~ZCe zbcoRF8&0(Gnv1eqapA>F$*WmVP4PweI;~u89S)bb&^XKPGOdL3nZPcrjh718uHCL8 zsrk4p`UJ~iz$jQ*t1hJKTpU)Nd9T8{sMG3Va&JN?mI>!v>Y`@8 zQ(4uju`KoZBqm*YR%P!M|8dRO!oOY~z}@udolSrAjuRZhLT;22=V5J2R>-m6qmQ4E zGOt>s2zb&!Z=8_nuKjVtYGA2et8YnTv|6mkLTcirk)yTe$B(mqFP5moyw^#9_K-r8(0pZj$~VB`eOh?v7Pf+}Wj)u)%Hno1U#PrDUa{1UM; zgN^X^!2~9%nu^2o_jrM7@6nCRC{g(_hjaMN+eq`Udn96~Q!TdjQQIusw*A|%ZBfjJ zV0?1ZFHeE1EA&2besO=ORV?`JuVC?QYfO{e?$q8UQ!8UbEb^Y8FHW)FKgC}PhQsns z7Csy1D^7@_1L7%d)fS`DO(wfCG9~5V4vBfW9{-ouyMz@rcrY`IMIOws%$#1OF&C^S ze<}c(Gl|rl+Z?TE_n92R6MNNYi8cup?wK29=9x?QQVAa97hBW(zPJLhaZc8Dd)lF) zVEEebv$?eKirI3B@XcfD*@;w=IFjb~vwNqY2Q0qY`)K1kdyP`(-d8LIbME>D?RHZB zxpZYWyQseQbrtlCfaS|HE<=`YD(;gCZ=!`Cu{rF;nJ#kP<*jedNEOxpq%tk~E%ZG{ z=PWSJbTCxe_jSaxEW$#U@cm09)Szt09pV%Uot_3Od(xYSmy5pU4gOH>T8^ zir;nNobU2~f}B1c@>i_gbvq+}8DYjGVp!V~IbTcqXLoM|X8KJVQjAe`g$fUf;)mNw zQhvX)_YL4z>Way;+h*QhC-hR7lVi|nntP)Vd+&p1{A1%TNI7v-v>lupMmvm(`>Cn% zw|u7#o&D!Tk|)7MU>@%eA}Qr<5gt#Zn`_b~Dom#XR$fktU(f)_CL8}1R8uxANNhl8 zvRR{Q{s`Pu;*#jQP@&c&8XRLoNBBJ(DA}DSSh;!M?GJ#6OxuV^ynbq`I{KzZ(>|U2 z$xBvm3Sw&Vfe;Bbli4>?eii8*s@Y8vlLe4|BW89*a|+@mYi5Qi*Y#MrekB;FB7oJn ztrNNd9EA4hZF+QAgo+(vqx>14`!2t`7FAjCt3R{f_2Xr_vymMgRM#(pxffH+-5Up< z?ozVnl9z11@hH*~zq*!9xt)La4ybKA4`VRV*~vzKo2Yx8u%l2K7bf`xVcHe2Amqk~ z6OI{=lmF!s5L@{}=!x2U&9yeV4E)R9aMym7s!!;)j0Z1OKSPCt<&x_+E~CRKr;(Lh zjA825PW(_%Yje7_Tv3|@Bz5X}xd?ep7~E@m?N!W&GY{di9e|X0&d?{*-2}j!^B;gL zc7xYfJLqG^Ri4_R$*C$=RdYn9Z2f3D+}}YWWa zY*WG{5=61`Nv_sx81+`LGp}&_V@lXj_H+cMHT$oh_QbzULw@1SbHa=go3@Eyo?(7q zs>JgH+#5hPQmh2YSp*?wTcL$a`D?KdPx)Nla`C1B28nHt>nV0-wx%fPUCx?*GP6Ki z^;HuwY>Wo5xRDPW4NW%BDS0|>?AfG06Ia#P75c4W8RD|_C$$4fD zIe(9O>o%7gvxZd4WgJ#37V!I9JeBwNh~oMH>=h6jeTo_&ZOhW7vwMbS4~pVKquFgP zLOHkA4h+t+moqDJG|JmHCufsbGCVoeYRpZdt zEqP*?BC$$&tiNKZ`#W05M|L$ado3O*lB~H63$=VO!8w*u_kO+?o-4K7KC!gP(Q{`d z_ZOhLsaCBH~|KNvxQ>ioN9344#05dI3 zr^F~iXt7^haSefgElq^rf5`y)BFqg5SZS2E_$LB54NniYRc^@DIQi{ zZ2V%qavL=d{~~eqZl{S}#Y}6^+3!~=5|hijUlL;vQ@lf5Me4z4N+eF+ zCd9b#I_~4DLY95zAqHei#9~OpXB>!fl{x?Wt4WoAb|g0|_zvkw;~}T?I8qoc@aHo; z1?%&nz8C%3kSl{@0Cbm<|4p}FSeyeSB-{W3*I4(Xuqv&HU`XC?-Y{{6*|jRp zk^eK`DgR-Zz&A3gS>pT2;Ra1p%tkR@QWoVg>M7#94HK=o|E8Nk)czJh2Q-!D9tt7d zPdDuJl$pknP2@<@YgCiJ1lh+Oms2_SlA6#zkvTQR(REh`i-Gk@xYb|(E<}M0>__o! z+fEY9R}te$^nX`~deKXfTF-Qyc`<*Wp?zwbwiFjp2(LGa`ziYH^4Z7Z_+IO{siPeG zYZr;FZlqT-Lw`nP!1y%u*YgP}W|e?3IR~N7Jm+(LY8h+wBb`YcWOetQB+p_1&%L)D z50`Ib=}gMZQ+VgrXt<23$FUP(NzAgXvob%tm0$7Xnaa4gP^f$@5ZiNpJLXoWtp9x0 z${3s-f23m(D>Y)RwC9wEEz33Z%vEsUjkR8ClIdBo`@bn$vd&x=Kkje&_-y5hRf{&G z0d@CA+#ccLG#`V)a35KqI2K2E#(tZkY}I0y1S#pF5_I~7KCOe!tyE8$jz;wX0F#o> zRMAZqBiu}du@^}sp1g*a?8WukaI%YZ|4_uMhfhx;r$bh4e+s!vq8$Cg0#%|t16%?i z=?q(Vf*8aMiA$HSB`xo86dFF_RFNlW!uE2CSjJosEAc6aX({xHbWk-=7Vkc@m5llp{i;B7H8L$*s>1bBnB49k_1&TS7l=f*us*m z(7a61VMyNrDF;xHm_8Oz3}ma*PP-xQWh3?Kr&RJny8{oGOzaobD04xXH$cqQkA*77?At?I_g{AQbVU@yTj4pbNbM zkmbU(2k_cJC942nS;)ksuYDnQyH=@Wq#52|s&s2%#Yu6Xucy}SUkXF(4 zEEo83E_{sW%qiS2EY#mAQ@R;_rt}QMyHq^0-zwWD$1W;DFVkGvzBvJld{M*xBeTQg z0+0szIl0C#-j}16f(15isC+e%d0hX60u24L4FnRTB>wRo)>zIv4%9QJ^iM&{4C`-N z92+<#cAG>bGi?iIT^5X0I=O{*rO7`cU-ShD>H)}#&7Z({<~2jK0CtY3E$%L2<3GQB zMW9qisL^0eW`{S2OC9xJbR^Kh^bthE(-%e2tJ;_iK=+=f)cM*{S8oaKO& z;yvKjz@mGQZNRwSqs9w{TcsS&amm>qelX4FTndkaa&=!kXr9%a9UU^UE{`XR*`sE+ zN0AYy+3_w<8%Ybe6a?5$jouuO2SUv=+yHf;7&DV%PYHxQnQ{&v+l6~S!OU6CsaW$d z?)iDNQrNbZO6a3FTkv>c(a5xZ9wYgZwX`=Sk-HFP05&1u7G9IDAU+tXMvWtOLsh`cZt;SLc}XH#J{2ciA1awk_(usClRuB+LDX zKf(8p^Wn6=(V=aw@z|#%l8|m%@bXhYi4_J>sPtvxiw@Knl!7#2ULUxbnm39gM|q(> zLFt3|dZ=fdV4GM>4PCt#RR0(RK?C%qvHe#rM63})ms$3eXz(V>^CZjw3^mqI%oSEu&yv_5&-zB`8!YxmK`LbV! z%!ZdA;b79W(6H^=z0}Aba9&cR(>P&ANlm_OR}v;At#`U5`9xZszvI0}3tf1B*^~6M z{}+G!tJB$M=7pXko6CRc>aypU_WQqdb;EOz!_$4vaj!o|J!!-La@+rfL6=Lc=N=__ zp#INx81DMx-w;vZA`mI6DIgSg9$bFTX@*aHrN2TjuC@>cgyyN7b$LU9?i3Q5(6OLi zUdSg?R)e8ww8(izpew|mj8d#h7EYD1u{GZ}}_0TQu2qxgIKWnBadsCzKw(^!}E zm}Cx3e9%Xyn~lFBw)BJqWJdbAEhZ5X*9@a)%2EMv@mM3$r|Ynu9h}TP3_yz(3P=DT zC;$dPhyWNBK*R-}K8C}U0InB-o>c!52N?ilh^k-eu!@~`*)^zoOWM5JDviEa8U=tG zfGQz=I!ceE?PbqEKgz#Ht?P_LKk5;2CC)A09Or2yr1He_RDU%1mX|Z01b}VQOAILb z-;0O3GF+X2mIi&5HfvF7pgsLXj+V_nk{V*p(&3Jl(iawd z=^P9p8QKEwc`6QPh9d+Z#4&-4W&{=NZ7kgnJi5$POUeaHZgwiF6Mmd0ixWi`^LZ#s`MGW!~CD$-fzXJR0v~1gmLtl7!3x=dc6U~ zplR|=)+heI#%r^NkkoOzeF({9-w{F$&Jw&auJ_{QW(SjEeel^qAc@|@e4c(GpO!i0 zvg6?evvax}`FDMWosJS+rP~1%58|8aC)x6<=vddbYtp7>AUiYc%qDK&e2E0ghS>fL z*N_`|`x}QMkBR8FdM!*ApYlRiFMEnG;W_C;ELfY%=gbsP3>slpb`FGkMo{|x*9J_u z-bkW08or=!KsZ$VaJj>NQjG$3rt5_m5QFIXi63V?g_lZ*zBZzLPJlSqmHn#Ifr?3!fh?{$!bX6iW}~jS*F*21DTp+}4aD|S@PvS;rQxV5Id!k} zbB?~(oYAn{9}XzNt#5$!znwomP~hFV5^&JFJ#jp2|8Yg6X z3xB(uTJWqM5Yy{+B$dHY`arp{M}h%Hg%^#WjD7spupp39SNr2leO>h7&Cw9zm`}`Z zP}t-SfdnwSy*tT=O!mPA5WTMkRGt)LFC2)sIUG^$@?G^(_x5@` zx!IVcNnNz<9>4G7@)ueW+jh=x7pe$)`2PV_UrAC~K3oZW`JzpXY}AVVU0{&Wn@ z&TA+eZ>4a5DKyK7pckRPX>Ymbmm%}fHt?68RoN%|WZz&TV$O+UCdalI8)EDDSY$PO zFzVeAgGRv?_wv9!gvke#khfzsoS@hex2pwA>iM+`R!wA_9OdpG(N|shHL6AoTD@8* z$=m&=5&KoHZ3RyPAc^bCC1ggJ#}4=Bgtlq?NZ5yjhY>P@_4>7#2}bD*l3Ftg1-~t6 z4i=VZ<|+6lME=Uwb2NP7UrOVQC3b&>61!I%!GVsr&!N4XUI0%*)h-X4TRUu#Ww>`Z z*kfw-^@+|0yJX@1*%!;|EI|ul`#+xiMvBL=j6G*mMAv8FLvF1A9?Vc9&#qDP(nyh& z^7G+R0Dz%S#jyT2NtmEetBdM+mLxrcB8KlCoS)t;Y+)k5{QQ*CI67~bd6!=p*$j|p zeUiQ`+>)|Vm>=!pkpKc=ogTl8w~-l<^9Gg`{vtFa!k5ZB5Um(vO84262eJcz+G~0L zmL;*!d($k@mr#JC41b=_soUA6+@LR)8pi9&Kkc88<}BZUl|WhZU7Mg@a39gtB897^y9_2c_)Dcygjxg z4=;Z|vg*bLf7ko`1rj_kHYq~7_+WtBn*PHF@bmvK{x8aDqo@G=^Lw}#kF}gi|1$#i Y(j{m_ti}-=|G6zMqas}<1quFt05A~#lp(UGMql?Dd?z_mlgneL^+W74WdBumJ$TQ&N=G0su7R5Il^Df_z=(a#{ia z$X8QUNABU_VSRl);J5$s;qv9>rKqTAXlQ8dWQ}f$PD@J*d>)=NkS!r0p{%SN*yuku zH&-=Y<>%)Y5fRba+A1q6>)_z9yu6&+lai2-fH+t(F)>L=O>uK`D=aLGijEo`9i5q( znVOpN@$vca;e(l(*~#fiPft%)R+f~Ml!Af+0)cq@_U**PL`6l#z`(%T+FD6z$?ffJ zAM#o0ZES2D9v=4e^qkt7?Ck6e2nevTu~}GH=v(Qludk1bi__83QBzY}U0rQ&Z$CRf z%g@ihzrQy!GTPnU9UL6Y&CQ+Jndx5cN=ix!3JR*Jt7F#u(-E4 zju{-JIBw@b!1l=*DPn zcg}|&?>iSdqW?s<^|v*)H=1XeeJKjm)?wuV0Pb2PSt%XQ*}YbOq;ddQ)?E>K5%_WV z-#z9R2gfL0Pms6}+So*^2@QtMboo`P- z{~c$@RWR?kpAULzYpvC;l4TKK3!p2ITPO=+$t^G4wDB9!s>_GmZ@_k3Epv&J-&TX*aDc*}(6BZ?%pxzuF(&*c*&nOQdF;YS zOiZ6Z9P}5X>i6+O3n9qKgiXMEuDk@1%!YFB{y-SeCA-ZDMiDIc9Q4qx|(hYWP;& z=dq&Gk|YfYJk%^wIB$7g9N5|y{iy8o;PVYApai&^?% zhJuDFArb*>c$HiR4W?BLrZEV)1HPMhSg6D7u<*9upQWbfgS@XG=udI8JnC_fU@5>R z!Ro#(x6!G!2)xy@7!L;962e)8_7;Q>e(`v+ehrYnJ0tpGbakj5XjmI-CKzws4)lLNS zqa~wbK+Cl`N29I+09#$wDt0awbi{QG64m8UF(VGFwGoy|V@SQ*QT%kpRZ`Lc1?=QX z;V+d8$S`GLug3we8yM{LE38Y!nnsE{BSW z`1GRiK1Fh{SWuvOd=U_uQw?hznKr1Xk!5rd^Hoffjs1+Nd6je+vR9eT#w!dH6F%Yk$y_4@+g&;iNE&iOxEFCnV{_-dCY8-gNXi8wY_7!0idapz;RY|A z4T}pH6tWu{7@mR zS&eDm|H{}(Ccfo86O%}nqA>v&DjGZEpx$`*u`yG#(?=jp*UX{#SGxCt`2Me(k@rm| z3OX@qcPi%^{ra)(QA?i6@n$?B7shDD8?rM;!kY&x;zz?Dvd?v*TlRv11j{SsKd=8O zS2zlSyr@l7$Nnu}HLXAZD14~Zypl?2Q9k$seaL6s58Sm*ey{Il@aI*e_?^ur_6o<)%Ypv4&fG7CpOsv3cId?tBT$O?Q5Y z3GAa?#{T|wH-oyB_shNagG@zWSY1lRXZ#GX2KbLTBorW5H_fg4;51^KYdX%ZHn#CB zL?XA=2~VvvL4WH?Vu$fBAzGn8g2R0pVnT0&S?5Doju#yhX1x z(sAqtsqcXAPEKl(-EXoyuj)!oVPb|=d(`^r6t^ZS@1KnMFX?xHkQY3_5(8Y!>xK{Q zUJzWnYbjBlhA<2P{DgwJ^mSfwwY-9fHF3713O%LbL|Rp|42<;ZmIsUOE{$v&PfVq_ zp1{^$`#OAE@Bnm@-Xrt_jSJ_uN`f>FF4PY^Pnb_mgoqFMyoYh{;FAUjmp^=NG6i)h z_e9!~F~NBYb99gl`(hoH(P5{x8iL4fe$9l~-dlnB@xb4g8b5znZjv+`Ed=89!2FzO z^^8X7s{X6rPdxlr#Gt?@Ld3@-5ILga6L7L&>Zkq#FQu9jHQ88QHP_2-v0?^Ci11U9 z{X3;SB7Z=x|JNH(xkq?A$0rgeI`b55Q+7-U>>gF<6qCn~(kD8aCS!`s%1~a`%8NIE zp#o45(JJi#pJ~KvKY=hPC33frd8&54{gZmf@G069yPK3|^B{IVl@t{d8V&UCII78d z>`HZBG~fRuL*!xm)&YXDjr*+;8WvB%bgQ`*f-*<*J#Z2?M7hrQRg}M8cn!eSUr1iR zV29QE1I^p#qzqRig)dOivz}%Q42~_TXMXca)v|wMHMCga>hVc+_s7bKu9H_;i^GJc z%9aH;7LN!f4>5-s7c@csz*Uv5EOrUMpBYZU2LZ~dpTO8_{Q@k;zPS7RLD_h@c0`?{ zj6v-vQDV}m^2Gm-UMCp?An5-}&u#pj)B`&)L&->0GTC+akt|uHFm@%S8yqlx-iPAH zre(u~5ofFLwGIf30ynfSY9Elzz(X93lWgV9(_* z&Ckk@BXFW8w)9kSk{)ykE>Dw92!QHc zz9AH+=)6PGdRVBmkjsWlNF#5_F~Lah9rjfduVK!itqDx1^+)kZ9B=ExP8^}(u34b^H@G#Kyt2lyS40pXMOMb4 z*s6cC7`yAJ`iLI*6>)VNeU>bd-MAsxf7_i=x%jtWw(<5GMUxzqsS4zbM*|23zHr`~ zC$|}(|9uK!ju0vq9igvvxVlq-j=4lzRy|U{}@Cm&7mfRN3f=y)ZN$lWjH%M`DoGl65 zW1MZ03FtCuZM0-bDG~)?^W0iOPh!&9c)s2Pm-NFXM8;HJ=J*K-IOOI9;GQpWd7sEo zZa_zVS)yl^N*xfL=)|$JeDn?>6abFOMx4C9Ur`D(E=(19i;x81A3h#T*Eup^!|S(E zXn&Zil65EBo>TQWg&(bTYVo{G4hS4}Vi=JN9JU>6X?j1;*df$BMyOKMvP8k_C)OmI zX$DyFi|9*+-=+(zR!OS83cQfM#>i3wG>C?wktF+TLb z=jmyk_5)p_O>p7oHy#Blc$pTx+@87E{e`_4U6j1WimhdwWF~N(`Nb)dpx#lL%Sgaw zEdjbaWVikRM3ymDPy&K~nP9KX^YTY7-I6>@m##v!@XB@IjJuMEu4fH-xB)*%L_aF@ ztrot$n+I=YLg{M22nskWW`GwfT}EVM$5KUq$J^Um`eoFqU7Dh&)&V_YoA|9*s* zwT^=>W({QN0)nk(;h~fggQ$triK{6f0OAM;Y&6UWE!;6QM%m)VZMXzy zxdSEUi5d}?{q|A7r(~K;XJLsoBHn9IC4sqK2tUCJXSnhl0EX+b&3Rt+(FXzGEz&0f z7h`RH01FJbmJ3ZtGP)hFgFu11*mqSi;)fmGgV*eJ>KK6e@;gxcs6C!-jus{ZETal9 zi~rv~j)AYE1e{!$7xfO%HI>*&+7XJ$198+Z62&;1(2+AMs%9|G+VsuDd}x&N%i?C_*X^P z96&un%d4t=mFz?8Nao(WL^-y1ni;;mz#*9Or^%T(w&@@B;X?UH*Kqq( z#=Nxt0i5M(!lD`c%@4R{5N0__#T#e5LK&u4`ebWfTIa)6=1x=WrgjgUDaW$d6-(%+ z7GNEt{4XW2-*h0#e@bG8hbei@|Gv~Fz1Yn{H>W@k$l?rAu1uE9m9`zb-J^t*i2g6g z{@;dNrNwJ<`?OF&(JMu8c2a^O!+_=eGlp*oG)AB^bAYY{FdCM8O3|hK853bKwP-|) z(Z&;bYAn_!E$dLHD6T_nCw>kcsWdXGQ*_EMlkPYAg?Zt!aOl^HT|N zcGZm?0>0I!41#cahC-OM4}LYuJuriUb1bX~NJ7h{zFg8Uu)w4{NINikI71+r;4i3} zA@u>#05+jMgb2#Gf-MbZlQou71cE}IV`61NoP!isFOtY@tzO!ikMaLo#eJ~2^r>Eg zC*~qfkJCf_oGemnLS`CsdGE(U9nBcRklQ6g^Tc_v_Wjpz1k`${9YmUEEKKr!V_%=Y zi+{%|wpzACH0jM+Yjc7R-{U_54`CUO9ll$#J>3T7)Mr zEVM?zrmw(gRgaBZ)E1{=P4uWSv>2Kba{jcvJ8{@5DCG(}%Ob{@=HUrUW*5BFD>Y{G z1w1`*ijI4IAPpM7^ImxH%Aq%L;b-O3zeE{xdUY(XRzLWo^pQktrYF7BwrbVD&|A~( z*!lhnacM7#=v&h(;bxziir9hLY?8x-fXKDGS+~tz3pN<5VF;#qtKK~4k-w?3qa8<= z_HTI)ORAW!* z{mCP>IeT%XW?&&EuaLUaQ2aNFo#qDnWaSkseikZevm6>CGj%`d;Vi%Id>X?Jnj6s$ zPU-^3p9@P0R;aAeZ9|>w+nGdQ%5w*ceUw>{;{Y}}_B)azX#O|&%ii1Lujug{hM7VW z8M-`&#HY97!UkyMjPf=%z`y!+Ff_pj8{-K3fIxW!53!?X_!~sC_^p5a#F2GM1gva1 zWxl~H0^20bcds7yx;HKQ#(K_8igqGM!MK9;N_jjHIvB1EU%c{bsi|Qk5nWx%FTk;4 z`z-m?J{;SrvSJ9!Mj*j7GqPQ2(z~0{D>idz^Lqd1rvjyn-R&aE=U=#_`pzacB4Rzz z4bYI(2WEoe3yJikcE*1jM~(~FRMTUzr?Pql+JhLF{O({21t%9gva z`Qau#E>3N8g@U>b{r7|jI+mxkAdJOZUVvMTO9`EKbg_w> z$OPM_9Q?M{G@_5%JCMfE9K$ESsDC>1;e(4Sdgtr@Nk!HM-6%SbafWzs0oRGq3sYX80s4ReyVpH9S-Q+o`#VV=K;KlW3BJcJ?1d8PZ3;E&mxlDgxWZB#mVb zc&}KF5#6ru;V&;eQ?x|DVC{SzUh~{45v?*^^Qe#)X0zODchYJ#j{3eA5OV2t#|qHZ z(OypTb^uQclYW|^#`D1j=>RCPT_kNi@g-%zq(#^|40fvQEFY*`gYt6q=x(cX3gDEI@_n~<*kb!ySVO@zCAqoWCBYVm zT5D(7W?XekM+F1j$W7f??c0+Z0K+Qwmmz>-@umfg_-k?=j3Z$9T2+E_jUrhD-HwL9 z66of{ZWqZT4T^a*43f157CQm|0^9_=R&S=Sd{fw!*PE98=nuALjIL{u0(t2l`gE~ zNZnK@TuY)l9Vt=?I_t><_MwzAZtE#KDsuvp^G|9HUQ&O;F15ozzarZt%lmYQ-M2gT z0mrYqEI7DdERFMMGo4ZK=^2BkZ_6iBl~^P0AG3p@xO+G}B?64@wGvWoL9JC7Oij_KQ*gV0kd^TwcWGQ9J+11 zuYcDaO?X?yKP3cD!#0tbP}J;i%kg7szoP5nSw%Gy*H{5vGPL*amY*;G*iS&Q8TCglYX2(E zfs0c_LH*v```Pke4$T<1#`rdJrqn>Ur@o#BU2YG+XgD#nDS~<;Z`g@W`m#@}=2;%! zwlWYTwvmR5I}}N# z3|ges5RAoJTo!Li{-7z}@I~gY!MGXa3r8;%%P=(f@T)lMork#L9I9$mdKoKpgRuM^ zhN5z};~A9{4)x-rxRFcZxq@Bq&rhncv=d)25dVv93*FIFlr!;)MXIR>;TW6Ts-<|g z%-N6s^Sp1pdIgqCj2VUQ-Z2>w4z)q-=q~hw6M^+`A zJ${45J6rEK)Mp94=QY&Aibv!ZIYAZ?UtN%xcj@X?OWsWpj-g#yO2}T(RV931{XSUK z^?o;oFG87G0LeTCu6NjRLR#Nzkk~pk$I!s4Op*t{W!Ulcg??8ZVe_ab^UV=Yn9JO% z9&n!1_!j=Oo{Hc6-7&~M%J_wd+B7mLq~YDO;kVh(v*_cSudEeBN!Ig1fBHq(C;4>6 z6L)=1T564sJ8)gbAxR9#HAi;kbSRLEnh?x>J3rLxOq|*I z&@@G+)d!WAhQcvISlu&nIDpen)S_}(}mvHs^kyHHU1Eu?bUtwKXJ}3r=?!nvN zJUI9zjUb1~YPr}|yTXLs4Gb1nanE-fimPsGG24)Y&EI~&bLU8RgN(@vF)iU4ysX8L zbtU#t`We|;F#$zKRuIWbW$P4eSnjh1)X}N)Ih$&behSC|mB)jCp`X+d za=2k6voUt5+QQdkOiWj8{eYl{?=nUZBi7e1{`B)2`?7CG0IW;Tp<(vzzkK*(a$}Kc zvGXwE@Y(#=U)1crp6HtE>(3}h{V6$532BBbz4>713Q)TgJ)`&E=zp;Z8rx>V>B zjU*q>H+^;+K>YGR`IYqt&R+W8#Bl3yn)%h5QBRuIq#X{^vVn9!T`56TETWQmn(>2# zGDYAs8%dd#XD2VgqOggz@5*e@0wy_%~;L!(2;i` z>0g4I`T^&2xgttlk#zNLT#%zZ=<>~(R)t3j>hNG(D8EGS)}_(i=_Y_;2}Ds9u}b@w zl+?iaUKpXJE(;3=Ip++s z!6ypeV#)G%QA0ym|Gg0(s^>y76m6lAavh0XDHK$8LW83!I`$84xM$%)fSSZty7e!p z^G(bjR87ul!|xw+XIN>-}n#BfrT=_$||HH&%EgwnxSlquwV?+{Q@L16c>HRn0W@e%T zi|~6-g1P-p&Oh-7)R#C-==WbUR97;Qg}QU)5#E!8!)X^4(w|(!292ui?g}qMB&Xhh z{TLO|9+Ht1pnN^7&vpr|a|dkJWR^($pA>!bYaOBHg%J=469kp5p5mraRnd}HihZRq zM{FI`?bHMa|_$Mma zyPWpuswDQ7{pqmb3P1^Gv9@+hJ1)mx;ngPf$!Zqj3l?-^GXw1Lfhu{4*)&3*5E9`7 zt#I=)`bB4u%CjxSm|Z%*C?u)OF!Ar~bgXcbEIDR~qQ{Rjkg=w)|Ek6^&s)yDrpUdBV+N+ev?mOVPjv|4AhFaNe#52x*8X6dBf z;&j;rRpk}B)0;{f)X}%RUmu7^X!1n2S2G{O|1g4^tgO`x=JTbfoF~d!2xUmD?Go++oUj?!?VO^;$#&rvU!eG4#g{TM09Py&|@@gs$!+vP1kg)X*! zG+R4DCHqI0l~Q{0S1oBIjoOhES{P57OhyBbIX6Tpk{IeW#-h{;&UlhQFLmiX)VN}K zF9Y_IMdlQQffY;5AUE~la>TpHB2{x2ln`obe?D}Wz9_6N^qFHqwI{*ZhFB1D|DXfe zs*^yPnr-rGBQ5;qh2eJ{3yk4ey4ZI_^9HgG`<&yp71>?mv>oK+)4BFD_k6Hi( zSH}{tk}EM8QdlBWH}()=D0r)87Jab(#}XQ($$flM2nG{z1mm42_Lm?$yZ%tUTTT=h z?Unu@AXKG9TOoy%;9$Fe&p*+uF(~3|oJef|AL_7gH++)^MoOmu!X+(QnQV}o4Vgz9 z#`2^8px8u<#zTg75g1rk>vT;x3Q%ewcPU{(+H#`(|&zgN6>8s z8FsO!M@CVt!SaSl$T7#5HTu$3_zRd2%#1`GZ*)O{0UHq;P95o8o4B@x26Bj|KVpLo ztGfkFW@CGbB#a4|B5gx9XIY6k)(TM35{C2b$f=tcan5T8^I1p#T`-Eq)zHI~1?@HD zNqnhrnn#164R0vFuE6>JHj3EK74TJ`z2t=5MOwssA0$W*drccxihB%3I;U7XjcaJC zAz(LJyefQ$Tl5X$T}i9QtP#{5LYnekPiftR8t#>$M}>)UnW#*;EzVAlAQhgWfu=n} z*Z|M_kHo8P>$mj2W0l-Yt0F0^UbdrU#-6Kkj<9j(&D*vQ=>*Z}ZPTS(feuK8jWnH& zFlntkgJ4o77Mv7m#-RGz3jy?_02)9N#dZ`$zN`4cO2d(MizC~Yx5MET(r_6CS|@eV zzN;eh504dquKxR(v+6EU_Qz)$g{yAP72XCIZ9u9BFyYd4)DU40L*e_wjBlP!Cf)6| z0R%tU8u&Bu)$<9G&5sm6`HXj1(tU@1DK<_@vtXNlklsas(fl34q?yKD`yfyC=3Juf z*^xV$zZ6Qg8i_c+Z*aUts209AP zYFoQhMHkj@5yL%Z%_*fDnurf;-L-U_!!zY3oaIlwQrmf8A%DmF`zzca-Xw6npjxBj z{5BtnOkNCJw;;W-#=VawiI8t4d0g7&j2$hQS!$zw?#?zJci1h_Y-4M^vH$AO#%RY~ zrPu_gH)e2OLP0HPJe{v4-b8^781_$wqA*j~5yPrhuk=HZb}J-1?U z8q;)!0#5tp!z3eMwvH#<^_O`(gfj2=v6Z_g^w^75dJJVuMUM?^mjA@IyvN3MjLu_J zi~UdITI(^)DYE}(@;TOHD_dF#_;qq00aS$< zG-rc=FZt@n?OrgTGnt&>%dmepzj=rSdW>IXA~zx$j4Kt7AjDvhje((%nJY4b)BP$9 ze!W;5Ybuxg-+KQDD*}AfM=0#pj9Tiyzj@G|E_+Li{KpRn;F5(WG`g9}+diaJLyJk| zzceytVEk`*{|C_A_^&y&hX&Z(GkTtyoDYKw3+Ki)V8AI2M^qM25DP6BJZ}u4p3`-i z}8&}IVcrGl7<{Icm>{%t+@ZLwHmt;qI$w96CA zRKaZj(;e(jdCOe=Tm}G*Up}DNUZVmMs1N{?0YF}iF~9&Q0D=Kv0E7yFF#$g+_@z1h z^GGZP*mK4b_vsHZc6^3QGu=I5{>vAvtT3P)R;qpzyjUuq*y!s!!*zXOx+KWXsRhQ& z@~Wm<%2SR{Ib|udKdhBVQ2;>v>Ko(=eU7Zz-=E&x02e4q>D=87;>fwqye;J}Z~3Up zYK>B@?2ukdWsJWj*UE*@WXUZlk(v}IaN*2Oj6d^ZB}KhBx64oDz1yngXK~@y7mk5q zwywH4)wbE#>EquqlunymT6j;Dg5}uOZ&_df)zedz_%!-bHzIiCx=~CXyC*?$X{jmu zCh~I7_WQtxJn2g1#7)qAYFv;@PQ-UPA1dgR4MEjIQ5U2C!J&K9HWeuROX);+aFay| zeS^erXnmrm9M_!xJ^9l9dg+BHI?5xf!6}QVCZa89ktj-heEn;x#z6l>^Y=CfmO|SFM9yoBwFU^$A>>_i+)6 zZr4}}haGWXj`P97LwOHa)KL3N`ZGNk7!~H-*o;*zOu&7vCq!b-!_}40M}W5FzO*#_ z%~}V>hz$V_)C#?3?C(}XjVkEy>XJVDVbx5DU$2VpbggQ_s9t&PTk#Y%mxcb=@f(%` zf#FTt{3ZAEj{D_5H<~L-6nx3i?=ElqZ59}EZ0>3Zem40I=N_V63Vpk#H&5L^ED)T=p`zN@Q$L;90Z8SoEcxvuO37CM`qr`tZH6Lpe?SWC?3)}odzGB6{oT^WE zAu+jBM~w9x(7=LPk9V|(s2~{H@HX~`n{DIw6;p0{3It2|j@0jThlbFuK3>{j4qb0b z{O$c2)zWEpc%%*i41o0VV$L~@fPk()Cdt!@3N{gQ5)(TkTu!7r*)iR|l4C@@Vyu#AfzS zDOrM<|B{(6$b*TnX$guBdz=fN5yuJt)itQf;h*hY7OTFKyH$&~#o>f9kuboQ)K^)f z-Wpc&QFfvAK zStPmjgi&?hglp=PanFAM3&s@RLy0k@_v(|M!NaDcg%(CBoW=S|8?7Y&+O)+IXsxA) zL|MvQW;>}Nd7lrl%zaZ%<0`U7?uW9cGO(g%qVJ%FQ+cT1yi&(DVCv2DK|pWC%u-$Y zOM%WZ-?^nhtV1Xp89vgQ-fuYZ-v$x}^R?FkCI|c0*u&P(WV<4JzSCiyq%gZ0!_c}T zx(?XHhJUMk8wy0)XIf3}iEa019$IT`r@s}cdIH)ot~kizWx?Qj9Z5DjJn`?qX9039 zPv$Qo1P1^JK`@=ajqHutTSJ(_rK!lxTN7t%g-meC^cRw(ag|wPZtmG+_CC2wV3(*s zl5+ABHDQ30E2-;K<)FMw z3{P;1W{OCnsDviSOHH$Ex>U!GMR*Ttlyj_VW5n(y>?sIt0NBmo1kz5BUE8Eu^il literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/bubble_sort.assets/bubble_operation_step4.png b/en/chapter_sorting/bubble_sort.assets/bubble_operation_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..cc63734ffda0a6b834c5e18e178ff429f926eee7 GIT binary patch literal 12581 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%0AE81n4)owgS#B+9%-1=80XO>)yI{-BYAzOy z+uvO;)t*3Oqabsd*a|T$WFgG^5z!2o@!rQj6Q(dmRF0)eV+Jaz>>Zt#eu-evn-WgT zbUJO-?GA;`(MU9R=P5(sh@*Ok<|OBCs>^)8My1R8SK98C$Z7M@yEhO^w*iJcy?cd` zryWlq&R*O~4U=NPBNm93`<>1fFxkF2u+KaFvqCZ0Gi_n1b1gb$D*}{$B**&-hDxWX zCdUe!&o}k}4PlulyrZ5i=C1GuYmHV-K7|J#8OtFJzEPof1&$rp1^IoWhMz*|#p#u5 zU zSjJug+CM+)dj5eq>9<;GF-o=rPrnug0b*QLR&Tb9`Eo5@C0prkTltG z`EiBKGSSz0{={Mf0hg`UQO-eun2PI#*wFymaau-;r95Tm8qdh#5jw6bR(OlGH=NKh zOpT-Gs#fwdh1Q)3R6B`99BTL{vXioT+vtQin{p5^fxCXqFuqEf%jDi3@({e;#era|ifNyZoQ(lajZJNPC%ucP4PXqh6Y zzNUe>4`l?Y4X9#^#cpN(CCos~POgWHZ4-B9FRdji%KW?N66t6yHNQd*Tk>!V2wqPo z7GKyWM3ey}_~Lxtd4(c2$$}d&`rgyRWGm_}qJZgT2@~KsoRMQL>Kp3?s1;8MKQKDX z6xTr3%G3yAp+$=}+ltQ%PCx&=K4Tf@WYNIFD=Y~(b&Dr4rA;9Sv+qOu_ao>a(G+$?^Fitk))p;y0`1vfUTU}wdkNbl@Hcnnz6_l}Ro0#%y5 zzRm&K)0QIjSi?T#`hn{R@~LwP#wxx8XoeS1lkRWA>VQO2EAe4_D-v706{1?7x@SZm zW-Zb+z%!`14S?;zji$L^65%cc&v(B^e1MnhNERx=#F6Nr{?&U|*ScjF#Bht4^4Pzo z!Zq=ela zr}}^#-blj_9E8sxSE(vX?z}vQFz_b>2humZbb={m7oa^FgYA;|2s&i05NG8WV&CNH z9NYbJheQ|8XiF*1-5I5n0wJ+u+BZ~(yNrSB@G^ve0HZ>9FPgE2av0`UoQ_N?qMC0)1}jnM0`BJq5WF*IsijwH!5_g|j3*r(?(K2<-yi zrZei12#bC0TTTKlUgmpk6>vFQ+EBE|p7a!}FhY*h-=?@$syC<_4)U@0ag(50jCOeu zk}o&qpxbsxHq5Qb?OKXNMXqk-Fr48)CRM{0eu$RDD6fL@b7%Q-r=RMfTvE zMbCWOb!Cgjbtl{0uSlH68bQ)nxUhVQ$MfU=z%iZ>D0~%6oOgJy2<92d@PMsx?(W7a zkAjn~WtbyAU=!u(g9vCrd+Q?wMyh$4FOphz7=gbm(3AeK2dECjZrn$i)jNzWr+|nN zePen}jrUg6BtL+3V&dMrWXgUoJSycT2jQ*;uYjAYO;7ZA$BYJjk0|v%61KA1?o>q* znUgLn;c29+3G8-reOVa_`23Z6p7OMS8Iilqkp(?umHtHeSQt$AL%s_U|BOB8gT7r) zsQ@=}K*2MemmDiMVM0H(D(m~^cH#2c$~sK$d#I23F*DkyT^YDfN#AO{9aAYUH1+}K~oow|3SpnKL{!na3fKUU?@tY zb){mBvG(cVKxrkpdMh!K4;+-3Nz=6O0Q-E^Rkb{hV?0*OM7c9+`jut>vzqvSb0axp8PVa z?Z;5npe`<<1aJTHLE>n;o3OR^T@LBI=1Z0*wG+QDIWPB^9ls9fV2R)<&`dOS2kD-? zsK+k_a-V8On@>uAz{$=vM@b|V(rX%oB4}k9LT*M{Wct98rK{nf6X?fI5n>V%y^|o) zM9^n%1pL*D6;aDTv%^r0uJ)I3G84pl_9Y;`6Dz{w_NrgoeGs#Nk0?6qxRq-s268oF zy>6u`noST$7D=f;va1iYEOz2^0&_<5kZU{am-wAJB`pg1qgDr8cweS0+#{Y6^+uyc zr7zZ`e=-o*I^Xbc>>2g0a>CFCc{tVE+EJN4snWRI*vg;!*SdLlyts3QQnlpzwy6+jD zrSl<9zI1isyiNw9gS41`m&waadUFFv@_|m^>Vy`P8iOF0^Iw@9QSz||*b%~x#6l>) zV+e!*u3E#MwhW!BuT%{nC_Wrxnk>N?r{kf{%VP4}G9$0FuKJa&9U|KnEdfTP5WA(m ziJX)`F#uaXn9QWI0$5}4s(i}!?1;hg(mgAcCLhD$z;u(Bg9qJE!2O5^V8HpCqhBlM ziqW2VNty=tifD^#;s~{xs31`W5xMH;x?IrOy@OfXz>Wtn0^l` zZKUrYj7!S}NcnWD>3D#-IHeaZ+$0C#Zdt@{dLHB1&)C1x5(TuqnLA3#=MJz3G}5K| zzGBI3YyNRC?YnRUFn8f!`OAdfbe^8UWSnWx^l!tM0_a?_NQ(wuARsH1R}&$P<$pj+ z;`=}<1seJWA}0!`%EK-vGcy0?L1>Yj^$&d(wuvi@4xs0`N$yV{SH?+$@;A(l+DKUr zxWZE;Fw02gB5|49N+M-E@2RlEufAI1!axzta7X7sLhFrZU23;;W2QxI6ohaU{N*aR z4sBDH(uQL^U;$Gy^ks-pQpqu@FQ`mSi?h-5!QUzGt$8?suoyCQ^QFzHfR@s4p#AQZ z5RGrx+6d&XK$G;~{5OE#$H43U%Tba(wqFm`sfxOObgamr9_4WB_Ad3qknv+W)J3PUv+Gk%K+@ow&6 zxqoEZ7Q0`e`$avR&$(A7Z`@eTN2EjXx zk$9K{f=+=Piy9L?dek>v6FyM<9fH?xe!C`9tP_xN!ySQWJt^Ng)!y;7?+@lh_%xxg zYg|wsr~YfS3u{!a;24P$ysse>Go@4n^=^2=jFX_TdhY994VxXA_luw>(aE85fA8_Y zzgf86-|GD8pOV~L1NyWN+W)E4m+=0U=Z9!d1^f@Uzg7EcOThmVoCSA!Wo!#Z)VsL; zoYaN5=g?}ar;)==H1to%V0^7FQGG|FO_Gq>o&}ftrgzsNgG2dh^8zYG1sMyc$#bj- ziu*vEMlhI%=&G?-WX=TP*Mrct(J)HYz@*~uQ9DQ6A_e9 zaF+d^2}ht0snVq^42od}iM|%iaop%n%-+G!Bi^ym^!gs=NF@6OhRU2@xh=Y!0bRXW zd3NYM`EC4d%erS<#Wx$W2&L@-(9sftRy2A#%4FXGIJtPEvIzE%wuVhV42}xg9Y3KC zV&@|*r?B&!nY1b7>Dz;jFqahr<<>rRLtR04-!?a`(A;T1HTt5wrioFMXLqHZM9w+$ zk+9j5VW*Lg3gCoTx95tu_Ae4=B1gU;28YJ?OX-I2Q~Wp=tIA36uRKsah>?`AEqr}Y z0BQu4nYg~5LnhI=WUP=h@ieNc*ZH+d`2`Z{rjDl@)G^zXHvPk&=gZnPiLWRHuejXm z4NP6DSk21X`m;KNdRn+nnu^xZuFKLR`i%10+FZfRWc=gSkr2Y>4K)Vm2Na64kT^}8 zN)Q1S85tP_$tqRTq17b1D^-f%TYB$>X)qHxSqwcoy4|<1Ho({uBuFTVa=$|5H1chE zZy(f*jmi+VNR)EWCc^F)+d-p=1T_n>F{v8EPWWVi)}=y?6Z}Em_wgxKdt>uRgyrcc zGms%v=@f7z&n;|#lI#1Y8CL<8X(wlN(;q%s+nrF+ZEPtn#&N>%v~bb8wP0CFxKWd? zuX(;1$U}Xr4D!M+^6VZrn);8?^LfB{*U<#js32Ju8OLZleKHnA@o9|g%WkYUVl+(# z7>ld#QsiU^Ol&6yOL-|2e3VK8%Ed`*-b1< z14jBvg2Z+f5Y>t2>h)H1hcjB>jb*1qGYD0))}phR#l*kUL-Lc|(p zEt-AToZic=Ng+;q21}38KJe zGCyjX&9m@PxlgDnID!B4;$-C74`6OFKoyu^RJ>)5J-2yfZmlBnSF&`&i%-d2Np%l5~MG6!-8$pST zb(^g&54VLd8;ccIeitPKatuJ^GnWeTRYM4}Z-%V+I_Q7^{OLV~uqNJr)!Cy!B~g!( zPJv7Q<8S83TtF8a2B483^&(!VO(eOs$O*YK`~wI@Y`+`(7KFxRtPfKXMgC$5SL(ue z^=Qas0FMS^NW?FPLZBtma2O)tT&VCC8HVc@_VvlO3Zeh-rWKa-zxAJw2CR2Lus?u; zgoWn+Q^X|Q|J1$&>1LOb*i`aI^?%^|uZg4IZI@Hxn*fjbFYWOkOo#|0{Vy_x1fTX( zxc)9FaQGky!x;pFvAtZ!a=D=)My)3y1ZWqASh4ZkQ|Vw?cz0WqvbrV(qR7!I#T)zE zdm&--1?gyK8~TZvle;e|6ulvzE?HxKzW}39W8*~7qK9d6nK^6C)%BamqpE2XQXZ$bB z_`(>R%wpA%J(keHPwzQ{z{!I;Q?B@>cqwnBsp`I`71zQIBfGWb=)G$U=)(l|#>!_uQXGNXn);!c0cQJ&Jk`du4iIGftR z9VDpau*H7xZsZ7Q(X^ibWL&#{U9 zm@UDYsamUPmU=;c?NPr@(4KhNS66wyoop$43D?l0n+GI6TK!=tVc?Qg+{$|5(B5BB zk~#{{eGYG8$+rdGd_=-Odp{BjfQ4pS0`ZId*?=xpBrq9Oh&vtk>#*ZkQ53qk%+~`f zYN53fN2@svi+7JgaG82Dl}Yk|y7x=SiT6X^HukKJHS^u&9yhccm31VD4qJ8jOH(W` zR>iLPz8d`}H#czKLrr{$7Tu={v6rm~dkS1L!S0@XC&~s&w9R;)(_T-;tuKUVcAUH= zspaz9tI?>N)ZwSv@3kI1ap9Nr0nD`z3+;|#L*6*u7HhdDKDpX%IBk0g{bh0YiC*L0 z&E?J5qif&VFILv(1HnVAw}*Ld=#^Kb@T9a{^t|nulN3EayS@5z_ow}4XT=9AcBA=O z-erBb{{Cfc5Wk;p1ISsQ#&bR5jna|R6U4}5QUNQn2cx8-FK4;SCR(Fr2J+ai4^oZ> z4x^QwphiJOMd`&h-tK*h?U(9InJjILbyMCx-n+B655v&R2Ll_L+?!p?N3otX3ZM~^ zndyv?+o;X8rFHgZ>aFxyKLvA%g*tX7_)QA~-!{DqG|i%?}s$jf$Oe8#7YJdn@p_);NLMT@YYp1d~#d~3ruJenKDan@Z$MS1gNYbLCbPuyHAZ~ zFob`j0!>1+L4Yl)v~%<}Pe9>A4NJ*v29lCB80Bu?Or_*E3oG?Y%r0PH1e=jxLdAxv z9T(mjJvBhe%WdS#G;BzVvsOtpC^h&yTqZL9UYR8}T%6|V^KJ!Ij25%XXaO;1uLz)8 z;9Wc=qQ0-Bk77vauVO1OYB7uH8gRjb#mc;8Jl7)R79UY5mopI!fE%C9r%2}acOE-D z2*O#6owUfJB8PfGdp8!47hgH{Y6%8i3|DJ10#(x3+y-e6$nKTxSbymJy%01$yjmjk z)A<~N4w5TaGe9w<+9ydjDH-9@wxoO((gh?|^AAyxFkPBW&<&FOg>PVW9rq=u?CA;u zkT_V&Z$tsr@psf+Y0YW@x_B(GX?^k4n~9I~)>C{Wj>ss>*hgJ#N2P3p*uV3ZBT12} z;+woI9C=;_xY95Y(%^32sYcVwXAH5%2O2Vd&KUrUkB>PDxr10; zA3IKQub4(V+s@krTfn-d4JW3yRF|lp-;RzkCRhE-Vg#YVbYMo8RST-=Z`PJ1B@Yt~ z*MmRn92ye&cYXpe6?(vpVN^fPO8Z&l>5(8CdQ&CO3g0@se$uCK2}MMcBH!n9H~>!xcvIy&Hs@Z8~V;^N|pii!&h z3qdV`0RaJNX=$rRD>5=Not>SIj*f+eg*`nziHV7S{`^VnPpzJ+HZn4bii#Q-7?_)z zo1LBY^YfeDojyH1jgOC)l9F0oU2SP;k&~1A{rh)iW#z`k#^mJW!^6Yy@Nj8qskym% zOl(YWaPau}_}bc)Nbbai!gadA;qRXsmH9~v6!SZuGZ zu8xk54h#&et*w3c?%l-1#Lmu6eSQ7q)n$2k`O^MUW@hH$;bB#la<*6*(N#0Wi@5VT}j>*?|*du_?+`u z8$U1z0C=zzWTZ5`=MOpq5k>=GIS<7o#o&Lh|6MV?T$TJ!&;F-+JWZ|tx_o{qg!>;p zX8}$~|1}paEwjR}c0h<30DCj9LHRAtZ&&Nlv_LIIq&O6->%Wr_0Q~rDbbikkm$Ymn zyVmGglt+H?E&MWU`27wnG}&UZ_%uMd2@lO|(bJ-ULU;_VB^mX;)Uw8XqZq(yvX>Mr zKJt7gwBVWg^BW_52rMTe>GFrc9m~V7;m9o^mew&9*M}D?!-arYU0q4GFGPVB7%SsE z-~NgOJ{hz(%anL;fe(e#C>7o}r%Sw*1U~AD^=}K9w1QzR23%WbHzRik$l#_%t(B4h zEwzH~>yZ}k>&v&vuX_!kFcOD38YK%K;fy@1SRFm>&7YSZFa3GTBI-R~Y+*uIE3~&B zG=B0`2r53(EhM3u?+?kQ52*Zj zyDOz{ih^QV{D9UJjrzj==YAWia&wZR<;DJC+)J+76HJFw*Hmj~i z(#S|*(b_mQokwn5OP0sJa?!2-D9(}mSo2H&UO`p~KuD|ky}(wyvat?4dSWVrCJ5k} z`3MyH`h2#Z-uJgAz=b6fTllCw*El2pU8I962^iZ$bJB<=)Z%tn!+S#C)5s9om7^i7 zdy#&5O}Ssla5{;4s*y)nr4V@9H+Dd3ds>j z0_AG#&@LWAddwh~3N%x3kN%bFkI6D=0N6H2BhRvNMu8mZvqX3G%ow_n4UxH zioVL4EI@Cji0IxpvXVd4NLz(tDqbV@s3#Al9e2V?c556p34)8j7J}Y9MHZ|~rdKh; zB;Oa0dty7W1X!aTtn8t`#V|k&vXuAO7D-VzE6Ie3tPN7ehmg!H55l)uY}6(tGT5o&too4q--TS$TR;E{wYnZv7TOG@{y@exbLn++zh zCup0Z^+a0{i)dk(dQN5S;M$3W>bw9(v4Nz>6yByX^WYz$(9^>t1$BSRFBJ#Kb*2J) z8jq0#ML$eJQU}vT>x!SS+u2t)a=s)g!H-mtCWVSnUE|LK~+8VG(96a@y2YU~xyxZ_*>yU8U z8bL}Z>4RiCn>d7wqt=CtXmJcXcVKK=X8fCG+ouCb`E1mj0g?>PvL!a_0mzy93g$*$ zL}K;{3cN~UoPH(wvpWx_=0*JcyO}bLx1k<*Q-2?V1d zQtUF0OG~)?+LB!Iu?>P}WOP(i{Gu{&4*y|~-vEqIc#*}|L5NzY>_ow@Pqy!y%4k^f zwa_{*V;w1q(+QmB)a}7BGdC6X%io^~WL0wrxgon+89^YD!IbmPjSguNi;J3~B?dEN z$ugn0p|;dNOAtwR+pk*<;|puYvR}D?S|x?(5J&EPuxuA&=f`SiP6NEdatBlEH|WeBJr<1}&<{-|~;h3$Hm%JZoS0 zDVmSas|xUFzk;0ejQ;j^e_$kcjQC5F)zPER?d7~u}Q`kEla`|Nkn zrdA zLF5DuD2mTnorjAKDv0^8IS@Yk0f6ip(6u&qHS8BcFz zU`WAt&Flc0^Wvs)*288H4_;F;NYf(bi+~&hM7PoV+-=^=|B|Vy`7FGG=A6=0nXkF6 zEfcS8F4XChqrnqnD5R*g$Qc{J6TyLfl79zDF~R#)lO{0sNDphJFQLYR3-1ch0nY9v z5nFG3*Nwg%H*;@bEz@ATIRP` z@chR_^#+Hj04a7q<`-nLA+O2dpE4snk#UIHNl3rNZl3N7M0^Z0ol++ii_ z5w1o2!n?)67ZAVoU{oeJPx~B*P-bvEE~$Y&CC@`*T^y9iQiy3Y89G?5q#c@^iB+lL^BLmx}W&4GaUigPpM`Cq=_O z+3dNanmk?e5{P+pWEaZq&N0suwO(IYVK1h&iw&d?25az}w3P!5frM)k;|D zJ@hJH!Gn1beJ16r(oxVnL{45(fDfavN~}`V@7356$xbNj@yh5C1O#k}2ML&eE1zWL zyW&*9MZP!B+>2JlUn6{@Fy8enIz$QO)&})tsdjs}8F?5H;Z)h&wk87}1hb7m_h$!l zh5h+up#lG>6Pd?PzI{C(t6g_MGYEK^; z_hz<_@sTP2KJY?K-#zpR37LU9FhEG+-?ovy8qdhZcW4k-JrUIU0LPUyzujxVD!~9a zJK=c2IgA-P(1 z?xS4(r67d=DZr!P4MO^w)hhvp!qXmpS(r%N0g9SonFCkde|-mN5X3%d!17_w^v2tV ztaCX4)Fep&cOsP^bH<~7*slK+eZv3)7Gqe2cWhW*4c}^A&r~Mk+zL7rZ=eHwqa<)I zynf(86uCo8%+KdT`KrYOloklx0kfW~aAI}Hg-vn*Lg{=--SaMitx8QyFd!pgGuO?R z<+vK_GXQpt6Ng#p_KQx5K2NgI0bIqic4X=?XE;q<;9|%SI8_*a)ZeXZlL=GdskDlDXu`F49xVkK7rw$4yCupB6NV2tti#uMU1xuA+Xp~b>1!5G)W2i*$dep_tK)b9a8u+|8Ek*SjqStco()GA z7<1J^-u(H*ZYbPZ@GvW&n|B-#N16mzeD8i`>f5nMNZ$pbh2b!qC!}Bpnye_AdNk@D zP*mrOEkmI2E@TYdgKnQI)vZrw&-9lY%~gFU5hIjMMf`j_{(8uEg_wIK&8a0iDZ*%` zA9#LF1B)1H)r}-tvVO;FRJOIg8@*}XUQABLtg=G`pfXm^LZ_`3lJ+H+>9!w9U=$N# zNgnEAPndABViFEvlEm6auxr@XvyGIS^-BoML7iLNAEGtd%?%hPFehQvRniP`12*}^ z$$f5R36$~b?4!jrz_yiL8gtltWresrvcLcKcm7kZN2n>G|9QLV5cpK`-NgPT2dtm8cg8?nrSerhOC;p}o#-r_S zi##3#@-740NT>@j5jH2-Ji#v&P7S_`_N8adGu>o`YVT z(ua@|{2Cd)3jm#GQ0IkvJ}wS8I%kjlA&zizJ0B5#c~N2ls{o#m+AxZyDy3}T5>nf6 z#Rqaen1ocaRKhL4q#ckL&R&$AQ%bA&fS4)Sil=b6qo}+$j*v;A?R~fV3 ziy3wrQXB4PU5Pm5)WRZ$|CtF?i^YKF1!L(oqtqE*cBXrfliyCva~#l9f?$z2sZ-6B zX^QLbYomJ)z{0ROh?|DRVC%r9E@T@BPvlo1CHhzh(qu2eEs>fw&6EFeZMi^rx`M>R z6%|Buz?MmQ7SS_?>?-q12?-Rb1sZO$CMJfb{L_MT(R1OD({8^0LB=TR0n1h7Yc8hY zBW=YgbE?{6uplJ+)fNiJ8{l`7j1qXKF8LF{eCNoIcI(&l=~dY^wPm^`16X{yJji!_7y6$O<~uU@eM?)zMCj7zZ6hj z$re;i86%G$iKHlp>)J)is<&SK+Ib7!kz#xR<_9i>tR@T+fn`(qb}2)N@_}x_^)w~j z7B?Fugt_Wyr^Xq3ZRKkp#bH-*JS-S+UXO{Nk1I&yRM~%09j}ti9YAFZ=lY#JjkUy* zlO0!?>m0SkO2DzgHaS!$@`lyCo!pOw&FsFLJzL z{?8~^p1fK-6eieSS?=XJ(Cgu}I<|T=5yNv0`50kKAt!}!5`=I6sQ&ptbFt*v&nVqo zNXC!?Ht+!i3CaG$m#NU;7aPIim6aDgDu9Bxx@Z`Yex6tM3VPp@MNRs zjG-+_sKeXVMKdX5#~qxXT4N$zhMt#q!4g9VIpwV1cxzDbsjbR30xITP8ukdt5eCoE z>D^$#2?i*^a`9N-%cKu{LA57V58D1}1leOxWgBv@JJf?VHxQS$P?%2{Kjv3uACZz54VdPby)+6v47e7 z-L-Mk{I)4ovjGDP=qW!uViRU=%&kT^JR&YZe$-%PoYSu#klEKN$YE;!c zO8j5wAd&XQ)*Fr;{Wzfd^LdiPCg~dG;Eo%nbE|Sy-aQ6dj6*q%*YKTqbiWt=Bve;QuAz?J zOtS6A1=C*X7_pUw&C>N%G5-4N0_wRL)m~8D{T`9!7|`^eNJkewk${Ba$;y2xzfIcy z^5*n08|9=2li-b2O;wE)@Q}yf|0kx>u6^bK_%Osj=R4QVMG|200ROp3A~GVv2;=HT zEOr3i*_^~WAfww z0wLU=JZIbB1%RI}DEelRKe%Yi@VPfXbUWe+b1sU7(wwH;F#DF0)R zy&{PVe=dxAG`!S1~v*nGcO_Sor-(pB1@AI*=jJGy|#d-)@XP|V>UsP$?6#h3e- z0*xmzSd-g>iDOdv)(hC(tMCugNGEa}iDb)(v(K)-H&9n;#6>XQtMne0oOD7y0Rp_a z4Xxw968;bgz^o0)hNLa2p0se`8BeHM(eFb%!#@YNMnrZmUs_Q2){3JSYF?Or=Q~vI z%cw)1e_^$Ioa$!QZjoB8-M9TMi?EZuivQi3M|(NghNDhDIm+6{rcf-v`67J1U?EAD zDqq>DHs$!xOL@HJdguw~gw;;{2j;4_gU|xX>N~|pR6%RYqv|JSRAb0ouA@bZ95Zaj zBD|L%Quwtt!hCtA1iZ-a&?P&AOEA{j;t$XFDJfVzj6h7ze?B9Rdvew9yT0jgv7Y~! zE=ls;j+VPKuyycg!&VAu?XF)*$0hI(yZuIJL}%qbmAlBOS|#+u`|OB?G1CWezbUh1~MPNz7!MF#v@ zQ!0vmy~URpQ@|?~T%Qc<#h}NoX%(9x-G=4KSwtG}$!qK;1rk%f!hsJqG*W;DpdTNG z8vDV&t!u(f44DFMqdQYRCoXQ;X#M?Hk+`5$YpD)MK9nTNgY>Rm@PRrTO_=vExb(IRgzv`jh?t_7)_f*R7?37^E zp6aeg_gW#t>#D53Ir2h)p5a_&&klR}7A^0J>XBRR>C_L1wcp*TOGzAYeoZSt8HD zujhxff11gWEpEVZc;PHPi0}`OS%B4a)i-@}0nE@JcyMLQAu`Trak=mdE-^C+7EOHJ z_l4uhq2+COa6d}}{DL|cv;H40YveJAA>dUV_z$xi<-9HTlf!u0=8G>vH^Z|dtFuiw z%{0`^$OI%@s&YLHC<~}1Fd+XrG*zLt*-T!K8~id;Dn%@^< zX~X#4=5UW;u&fXuV)J9;&FI!=g=i-wp})qg=MyaeS`IEMmanZxC<^Ci#|y*FAK-Re zocXMQoOPs?ga9?Cyn+fL1r82Xr;5@wj_RDl&u?tZ&=H+Nv3$K>aORnpk--HN*GD+t zCK-C}Qkp<*vDG~;s$a3Fzr&$@?*`VzvdBpzBp)3Ptz5Jf_&nt}hA&BnP3hG_+1{OJ z@*1_GZS|$0RZ&-7{4$LR@<+y%7p@-8Y^0GHm7O8a7I>D<6)V6Pbkj|LBNVaWk$m{G zY)(9pShqn;SVJ(TLdU7KK@F2Haer|<9QS<)UnKUBsH7g6bsq-p;y4mqnz8eu=rsPt zVK*4sY)5+gH{5*2lXY%f|N$^FjW zR6>zAZW~lJrNgGVOyDa@oK`k-5C+}9S?)?OBanP%x?5wRLQ{?-fL=ZU04x?TGq<)V9JmS79Nl#>Gw;N>s366+Yw zk+aGry!LU97Nja=^$5;l1CUt$ub|f!q!3yE^z-J*>*ZlW2 zSFYzh1=vb4l~v`aJg@mdLkSw38~xYYfOPgdLhC}1WVXiX_S%-SG&aXIr!-S9T9RTq zsFmM)?;>j0%xrL!9mbJ3$*gDZ9T+({QID`R1Xbs~XGer^VKrz55V(G>yFJOCT7K^Z zaQxIv+NcsMU-I046Sq$7RT8PtUAZ1#5gb4Cl@>Oozvbg3sEQ}gxu4S6isoFfZ>5wc=^W*a>aOAi_;Co< z#J$dR?EVLsIfI|FFLvRPNnzN19Aw5gIZ{+Rg(?&z)sl2`X3!fwoSFF3uRs>&z%+wb zxJ?9tzkWVBfSaEWlKaq4QHIRZMG9p1(VS&I+)!;{xKg2*&wocKB`Dal!TW>&k{R!543O(Z^Mfh|(cSUuG5vWzmj#QKTqlH00SK~50 zECic&SkSlpm9bVPplxq?j-8z!+6}Z5+FW|t{Xsya#By7zkN7wN(?5X+JUROqEZ%>{ z1c<_J#)HGT*$}a`YV8hx#Fjj&AZSaOV!*_ zU@*-`!X7j(CL%nnZZxfzDp_CqnPkjA#Cfcor*w+FZO(8t!el{@LLt8O^n}5BZBb5y zOOvF-ewF+u3cX}$}_l(vb9$sn!F)j;wobQ8* zaVggb4!-gD^iI^JgJQf@;BjMhBMiUX=LkgqHohXtSyM3I6|g)~y8DK1syPgSzRz}f zR%tf*%1#(e_$NooPYTT1BNg;7Pn6OAlZXR~h~0hY(unHnPya>r2|=JP4#h>E=xoJU zMYYoHvmlops}m|jt_)B?@a*iu$oDf23w{)%WOw3!q0dQ-O0M)Xm!zTPZF|#2@3#4KNV)@n zilSsp`<#*CS^_j8W&c(D5$&ITu#V_E=@*USqIrH2p~P2xCdadnl1*^1VY7-}_-W?wu0tzo`& zCi()IkU9-c%@9rUDj`r0jBSNTJ2djJ+U4#gh1m*p>i2NU>4}GH#^#xcz%_vtqP6>l`3BNyEb?lA| z3mE523-^-cP>y(;-?Yp6+ID~B_R$3HXkP2=V7L7vB6Ve(egoJ2Sx1J)GwdwwlRfXn z*P(u*N8LKyI+LBkORAvz;ZA>`vbg|^mF}5V*m^{lb57cngGD#R-MU>=uvfVy+We(o38_<1Mmp>pO zq>{l7I7v1T8Pnn-og~Q-t;S9MVTSSONEvhk;Jqr$geg(#mi=uejgra`(UFhI%IWLB z7MV%Bu@Jnys2i#;N+gp-rY~pNa#Ov0fwS!9>A|JKLXtrgM9$qSO&~0leebkA7=s@mfyrxW!(~L&DH9DSubc!c^4+C5%;JBf-}Rm zh~^H>imUvwX`wkI(jN7SlbxboNn@z411iWJNL6YxTyd|qBYd~0>J?Nzc!Lo5{}m$V z&k*GgJfC3y!xkk}e1Z4Dl}elK^=B67CMgF^>|iK5EP}9{bQP6HAwPUplzk;v@G z$AoZ$AZ`jA>B8F56ViTiPJmP|$Ohv5$~uq+#8(9JZyUe8Rw<|QN|mx&?)DZzd;-vA z1(g>I%#p<%z7XgFs6QO=xk@`AnJ~rY8oVEKJ6>c1e*~hCf!{wS?w_(=LMX`$0VqT_ z4|zo)91U)Tg3%j4LTwz1FsM<;;e|Cu+)<#HL+qs+Rv<0RI&@kPKqKdZAFt`})vd@B z&B8j6zaCm}8GJf!1}+N?k)29^jRTg=XL3eob!13YYjKBU{{hER2p6C8B+5W7=`{Ac ziZ_2LutK+kBb&4l9yi$`-yd-r`+J3*gAY4$H@3BX%*NDg)vQA%y1|p zRzYvt2r(>$cN1cFj}L#jtVe%g08Hjx5m5;EhoCp{q1+X*uO0I0tE=r@i~e&2nuc** z;ewFR%l!{%J9Eb7kvPtfZ*d-Ing&q5ng{oX8nNSa`$qtt;~(_4p^dy?=KI8hy-sBOxXMHuEQ>P@S4`siNsA;#DqlnUi6sbswyX(N7472AMASln zv_*xj+%sRSqx*=HcRSR|`Xstv1rvmXd-8-jet`yH)4>2q00aZT00;>HLjfdQ0CDVw zxFUAF1jv4-G9cVU!iBTNAQO$eF(Ch%#eHa7A>hwu)G>@k3!5L19=-k0n3nS1!>vPa zWiES&g#9NHuH>O5DEih^FNI)e_u=)EHaivu7@Fht4Um21^Ppy+;@AgWjcDD!mV#UY zpeb%bcvfpF#T#w?P3zZ5F9*mh^|WWx#e@Ssh#zlmy=frG+|>}fqjt7WYf?)>+%@}) zf$U1lGBUD1ykzk$Gv6t*zW(>%Fqx7*-{ul=Ck@=Uq7x7z`UWtc5y!R}*cMtDTd>)Y zv{rj*d%aohHc8f|`StgoNKCVMW)le_+gO4)MM~$oCYPfX(?+X2@T@J_Q$|SwuqK9=0rfHo@E}{m8;N9 zq9vC1#kTgu3l`XQ=Q34m16qh1WdMY`%L5N3u93Rr6T{EfRNZiFieN&S5cajT*{xoq}?X%2wAX)1Z3D+pu35?ZgTR$Pu9bh>#R7vX& zDNV4?oE`@7RP2K;k_*?$zx6l)LC&Pxt?$rRcXyv<`>5V{?-@I@UR~pn0=@5E!fxc& z)5nPJszx(WMu;RFAwr@?w0-|U4L_4R_x*7b#4mAq zyzD~L>+Pp1fqA}Idv|8c;h0}{1Ay{Iu zFgoM18!sMUC;*x|@)KYEZalkz0C42UYIkdk%JQFOhK`Ec;or!9=+7XwXLKJ8;Hu)r zXkg%b%Oh=n_kzZv0LDl4qpXkqyWjpOo<5%H&~`KgV6M%K{p6=f3TPH2KlX1WMo49I zQaY%$^M$r;_>Tzjoz|!-J2&xK*?}0kAtQa+wN^frjahgH3IxzFJ?W4_#eE_s0E{sa z&ScDm_{kbr(LRVH389;LWfI_nj{u-|K|;9kq}Rs&x5^GNv;c0H$NKKbJ;Dv|uRMWz zrkf8<6&(bL!oDHJDC1+zp8#;HWrN0x%~kI z34FlgWwRkdjx1-Rf|^QU^cueNlv1CV)8p&=`UNG4$tv!3b32s+bE(Ca9>NlfUl?m? z*$qo2WRg1|j`Y@(HJlhVs9@WPz-qxWHpzJuZfZ zZfRg(^` zjATZ_#eanT4pALK0U>!aNtgC>B#Q}T37@icBGbZ4*KG0_pV%>P4Tig#c#jUUCQAo1_N!fO?o J3Te|%{}26hAO-*c literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/bubble_sort.assets/bubble_operation_step7.png b/en/chapter_sorting/bubble_sort.assets/bubble_operation_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..49e1ee3b00faf6f1675ab7f663868c530af62367 GIT binary patch literal 11740 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 F{T~T#a+d%A literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/bubble_sort/index.html b/en/chapter_sorting/bubble_sort/index.html new file mode 100644 index 000000000..d58616b5e --- /dev/null +++ b/en/chapter_sorting/bubble_sort/index.html @@ -0,0 +1,4435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.3 Bubble sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.3   Bubble sort

    +

    Bubble sort achieves sorting by continuously comparing and swapping adjacent elements. This process resembles bubbles rising from the bottom to the top, hence the name bubble sort.

    +

    As shown in the following figures, the bubbling process can be simulated using element swap operations: starting from the leftmost end of the array and moving right, sequentially compare the size of adjacent elements. If "left element > right element," then swap them. After the traversal, the largest element will be moved to the far right end of the array.

    +
    +
    +
    +

    Simulating bubble process using element swap

    +
    +
    +

    bubble_operation_step2

    +
    +
    +

    bubble_operation_step3

    +
    +
    +

    bubble_operation_step4

    +
    +
    +

    bubble_operation_step5

    +
    +
    +

    bubble_operation_step6

    +
    +
    +

    bubble_operation_step7

    +
    +
    +
    +

    Figure 11-4   Simulating bubble process using element swap

    + +

    11.3.1   Algorithm process

    +

    Assuming the length of the array is \(n\), the steps of bubble sort are shown below.

    +
      +
    1. First, perform a "bubble" on \(n\) elements, swapping the largest element to its correct position.
    2. +
    3. Next, perform a "bubble" on the remaining \(n - 1\) elements, swapping the second largest element to its correct position.
    4. +
    5. Similarly, after \(n - 1\) rounds of "bubbling," the top \(n - 1\) largest elements will be swapped to their correct positions.
    6. +
    7. The only remaining element is necessarily the smallest and does not require sorting, thus the array sorting is complete.
    8. +
    +

    Bubble sort process

    +

    Figure 11-5   Bubble sort process

    + +

    Example code is as follows:

    +
    +
    +
    +
    bubble_sort.py
    def bubble_sort(nums: list[int]):
    +    """冒泡排序"""
    +    n = len(nums)
    +    # 外循环:未排序区间为 [0, i]
    +    for i in range(n - 1, 0, -1):
    +        # 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j in range(i):
    +            if nums[j] > nums[j + 1]:
    +                # 交换 nums[j] 与 nums[j + 1]
    +                nums[j], nums[j + 1] = nums[j + 1], nums[j]
    +
    +
    +
    +
    bubble_sort.cpp
    /* 冒泡排序 */
    +void bubbleSort(vector<int> &nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = nums.size() - 1; i > 0; i--) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                // 这里使用了 std::swap() 函数
    +                swap(nums[j], nums[j + 1]);
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.java
    /* 冒泡排序 */
    +void bubbleSort(int[] nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = nums.length - 1; i > 0; i--) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                int tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.cs
    /* 冒泡排序 */
    +void BubbleSort(int[] nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = nums.Length - 1; i > 0; i--) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.go
    /* 冒泡排序 */
    +func bubbleSort(nums []int) {
    +    // 外循环:未排序区间为 [0, i]
    +    for i := len(nums) - 1; i > 0; i-- {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j := 0; j < i; j++ {
    +            if nums[j] > nums[j+1] {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                nums[j], nums[j+1] = nums[j+1], nums[j]
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.swift
    /* 冒泡排序 */
    +func bubbleSort(nums: inout [Int]) {
    +    // 外循环:未排序区间为 [0, i]
    +    for i in nums.indices.dropFirst().reversed() {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j in 0 ..< i {
    +            if nums[j] > nums[j + 1] {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                nums.swapAt(j, j + 1)
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.js
    /* 冒泡排序 */
    +function bubbleSort(nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (let i = nums.length - 1; i > 0; i--) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (let j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                let tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.ts
    /* 冒泡排序 */
    +function bubbleSort(nums: number[]): void {
    +    // 外循环:未排序区间为 [0, i]
    +    for (let i = nums.length - 1; i > 0; i--) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (let j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                let tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.dart
    /* 冒泡排序 */
    +void bubbleSort(List<int> nums) {
    +  // 外循环:未排序区间为 [0, i]
    +  for (int i = nums.length - 1; i > 0; i--) {
    +    // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +    for (int j = 0; j < i; j++) {
    +      if (nums[j] > nums[j + 1]) {
    +        // 交换 nums[j] 与 nums[j + 1]
    +        int tmp = nums[j];
    +        nums[j] = nums[j + 1];
    +        nums[j + 1] = tmp;
    +      }
    +    }
    +  }
    +}
    +
    +
    +
    +
    bubble_sort.rs
    /* 冒泡排序 */
    +fn bubble_sort(nums: &mut [i32]) {
    +    // 外循环:未排序区间为 [0, i]
    +    for i in (1..nums.len()).rev() {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j in 0..i {
    +            if nums[j] > nums[j + 1] {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                let tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.c
    /* 冒泡排序 */
    +void bubbleSort(int nums[], int size) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = size - 1; i > 0; i--) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                int temp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = temp;
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.kt
    /* 冒泡排序 */
    +fun bubbleSort(nums: IntArray) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (i in nums.size - 1 downTo 1) {
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (j in 0..<i) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                val temp = nums[j]
    +                nums[j] = nums[j + 1]
    +                nums[j + 1] = temp
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.rb
    [class]{}-[func]{bubble_sort}
    +
    +
    +
    +
    bubble_sort.zig
    // 冒泡排序
    +fn bubbleSort(nums: []i32) void {
    +    // 外循环:未排序区间为 [0, i]
    +    var i: usize = nums.len - 1;
    +    while (i > 0) : (i -= 1) {
    +        var j: usize = 0;
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        while (j < i) : (j += 1) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                var tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +            }
    +        }
    +    }
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.3.2   Efficiency optimization

    +

    We find that if no swaps are performed in a round of "bubbling," the array is already sorted, and we can return the result immediately. Thus, we can add a flag flag to monitor this situation and return immediately when it occurs.

    +

    Even after optimization, the worst-case time complexity and average time complexity of bubble sort remain at \(O(n^2)\); however, when the input array is completely ordered, it can achieve the best time complexity of \(O(n)\).

    +
    +
    +
    +
    bubble_sort.py
    def bubble_sort_with_flag(nums: list[int]):
    +    """冒泡排序(标志优化)"""
    +    n = len(nums)
    +    # 外循环:未排序区间为 [0, i]
    +    for i in range(n - 1, 0, -1):
    +        flag = False  # 初始化标志位
    +        # 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j in range(i):
    +            if nums[j] > nums[j + 1]:
    +                # 交换 nums[j] 与 nums[j + 1]
    +                nums[j], nums[j + 1] = nums[j + 1], nums[j]
    +                flag = True  # 记录交换元素
    +        if not flag:
    +            break  # 此轮“冒泡”未交换任何元素,直接跳出
    +
    +
    +
    +
    bubble_sort.cpp
    /* 冒泡排序(标志优化)*/
    +void bubbleSortWithFlag(vector<int> &nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = nums.size() - 1; i > 0; i--) {
    +        bool flag = false; // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                // 这里使用了 std::swap() 函数
    +                swap(nums[j], nums[j + 1]);
    +                flag = true; // 记录交换元素
    +            }
    +        }
    +        if (!flag)
    +            break; // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.java
    /* 冒泡排序(标志优化) */
    +void bubbleSortWithFlag(int[] nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = nums.length - 1; i > 0; i--) {
    +        boolean flag = false; // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                int tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +                flag = true; // 记录交换元素
    +            }
    +        }
    +        if (!flag)
    +            break; // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.cs
    /* 冒泡排序(标志优化)*/
    +void BubbleSortWithFlag(int[] nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = nums.Length - 1; i > 0; i--) {
    +        bool flag = false; // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);
    +                flag = true;  // 记录交换元素
    +            }
    +        }
    +        if (!flag) break;     // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.go
    /* 冒泡排序(标志优化)*/
    +func bubbleSortWithFlag(nums []int) {
    +    // 外循环:未排序区间为 [0, i]
    +    for i := len(nums) - 1; i > 0; i-- {
    +        flag := false // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j := 0; j < i; j++ {
    +            if nums[j] > nums[j+1] {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                nums[j], nums[j+1] = nums[j+1], nums[j]
    +                flag = true // 记录交换元素
    +            }
    +        }
    +        if flag == false { // 此轮“冒泡”未交换任何元素,直接跳出
    +            break
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.swift
    /* 冒泡排序(标志优化)*/
    +func bubbleSortWithFlag(nums: inout [Int]) {
    +    // 外循环:未排序区间为 [0, i]
    +    for i in nums.indices.dropFirst().reversed() {
    +        var flag = false // 初始化标志位
    +        for j in 0 ..< i {
    +            if nums[j] > nums[j + 1] {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                nums.swapAt(j, j + 1)
    +                flag = true // 记录交换元素
    +            }
    +        }
    +        if !flag { // 此轮“冒泡”未交换任何元素,直接跳出
    +            break
    +        }
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.js
    /* 冒泡排序(标志优化)*/
    +function bubbleSortWithFlag(nums) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (let i = nums.length - 1; i > 0; i--) {
    +        let flag = false; // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (let j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                let tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +                flag = true; // 记录交换元素
    +            }
    +        }
    +        if (!flag) break; // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.ts
    /* 冒泡排序(标志优化)*/
    +function bubbleSortWithFlag(nums: number[]): void {
    +    // 外循环:未排序区间为 [0, i]
    +    for (let i = nums.length - 1; i > 0; i--) {
    +        let flag = false; // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (let j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                let tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +                flag = true; // 记录交换元素
    +            }
    +        }
    +        if (!flag) break; // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.dart
    /* 冒泡排序(标志优化)*/
    +void bubbleSortWithFlag(List<int> nums) {
    +  // 外循环:未排序区间为 [0, i]
    +  for (int i = nums.length - 1; i > 0; i--) {
    +    bool flag = false; // 初始化标志位
    +    // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +    for (int j = 0; j < i; j++) {
    +      if (nums[j] > nums[j + 1]) {
    +        // 交换 nums[j] 与 nums[j + 1]
    +        int tmp = nums[j];
    +        nums[j] = nums[j + 1];
    +        nums[j + 1] = tmp;
    +        flag = true; // 记录交换元素
    +      }
    +    }
    +    if (!flag) break; // 此轮“冒泡”未交换任何元素,直接跳出
    +  }
    +}
    +
    +
    +
    +
    bubble_sort.rs
    /* 冒泡排序(标志优化) */
    +fn bubble_sort_with_flag(nums: &mut [i32]) {
    +    // 外循环:未排序区间为 [0, i]
    +    for i in (1..nums.len()).rev() {
    +        let mut flag = false; // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for j in 0..i {
    +            if nums[j] > nums[j + 1] {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                let tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +                flag = true; // 记录交换元素
    +            }
    +        }
    +        if !flag {
    +            break; // 此轮“冒泡”未交换任何元素,直接跳出
    +        };
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.c
    /* 冒泡排序(标志优化)*/
    +void bubbleSortWithFlag(int nums[], int size) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (int i = size - 1; i > 0; i--) {
    +        bool flag = false;
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (int j = 0; j < i; j++) {
    +            if (nums[j] > nums[j + 1]) {
    +                int temp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = temp;
    +                flag = true;
    +            }
    +        }
    +        if (!flag)
    +            break;
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.kt
    /* 冒泡排序(标志优化) */
    +fun bubbleSortWithFlag(nums: IntArray) {
    +    // 外循环:未排序区间为 [0, i]
    +    for (i in nums.size - 1 downTo 1) {
    +        var flag = false // 初始化标志位
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        for (j in 0..<i) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                val temp = nums[j]
    +                nums[j] = nums[j + 1]
    +                nums[j + 1] = temp
    +                flag = true // 记录交换元素
    +            }
    +        }
    +        if (!flag) break // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    bubble_sort.rb
    [class]{}-[func]{bubble_sort_with_flag}
    +
    +
    +
    +
    bubble_sort.zig
    // 冒泡排序(标志优化)
    +fn bubbleSortWithFlag(nums: []i32) void {
    +    // 外循环:未排序区间为 [0, i]
    +    var i: usize = nums.len - 1;
    +    while (i > 0) : (i -= 1) {
    +        var flag = false;   // 初始化标志位
    +        var j: usize = 0;
    +        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
    +        while (j < i) : (j += 1) {
    +            if (nums[j] > nums[j + 1]) {
    +                // 交换 nums[j] 与 nums[j + 1]
    +                var tmp = nums[j];
    +                nums[j] = nums[j + 1];
    +                nums[j + 1] = tmp;
    +                flag = true;
    +            }
    +        }
    +        if (!flag) break;   // 此轮“冒泡”未交换任何元素,直接跳出
    +    }
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.3.3   Algorithm characteristics

    +
      +
    • Time complexity of \(O(n^2)\), adaptive sorting: The length of the array traversed in each round of "bubbling" decreases sequentially from \(n - 1\), \(n - 2\), \(\dots\), \(2\), \(1\), totaling \((n - 1) n / 2\). With the introduction of flag optimization, the best time complexity can reach \(O(n)\).
    • +
    • Space complexity of \(O(1)\), in-place sorting: Only a constant amount of extra space is used by pointers \(i\) and \(j\).
    • +
    • Stable sorting: As equal elements are not swapped during the "bubbling".
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/bucket_sort.assets/bucket_sort_overview.png b/en/chapter_sorting/bucket_sort.assets/bucket_sort_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..4a3886e8dc310d84b8e1cc93ab5109cac6737ae4 GIT binary patch literal 43157 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 z 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.8 Bucket sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    + +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.8   Bucket sort

    +

    The previously mentioned sorting algorithms are all "comparison-based sorting algorithms," which sort by comparing the size of elements. Such sorting algorithms cannot surpass a time complexity of \(O(n \log n)\). Next, we will discuss several "non-comparison sorting algorithms" that can achieve linear time complexity.

    +

    Bucket sort is a typical application of the divide-and-conquer strategy. It involves setting up a series of ordered buckets, each corresponding to a range of data, and then distributing the data evenly among these buckets; each bucket is then sorted individually; finally, all the data are merged in the order of the buckets.

    +

    11.8.1   Algorithm process

    +

    Consider an array of length \(n\), with elements in the range \([0, 1)\). The bucket sort process is illustrated in the Figure 11-13 .

    +
      +
    1. Initialize \(k\) buckets and distribute \(n\) elements into these \(k\) buckets.
    2. +
    3. Sort each bucket individually (using the built-in sorting function of the programming language).
    4. +
    5. Merge the results in the order from the smallest to the largest bucket.
    6. +
    +

    Bucket sort algorithm process

    +

    Figure 11-13   Bucket sort algorithm process

    + +

    The code is shown as follows:

    +
    +
    +
    +
    bucket_sort.py
    def bucket_sort(nums: list[float]):
    +    """桶排序"""
    +    # 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    k = len(nums) // 2
    +    buckets = [[] for _ in range(k)]
    +    # 1. 将数组元素分配到各个桶中
    +    for num in nums:
    +        # 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        i = int(num * k)
    +        # 将 num 添加进桶 i
    +        buckets[i].append(num)
    +    # 2. 对各个桶执行排序
    +    for bucket in buckets:
    +        # 使用内置排序函数,也可以替换成其他排序算法
    +        bucket.sort()
    +    # 3. 遍历桶合并结果
    +    i = 0
    +    for bucket in buckets:
    +        for num in bucket:
    +            nums[i] = num
    +            i += 1
    +
    +
    +
    +
    bucket_sort.cpp
    /* 桶排序 */
    +void bucketSort(vector<float> &nums) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    int k = nums.size() / 2;
    +    vector<vector<float>> buckets(k);
    +    // 1. 将数组元素分配到各个桶中
    +    for (float num : nums) {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        int i = num * k;
    +        // 将 num 添加进桶 bucket_idx
    +        buckets[i].push_back(num);
    +    }
    +    // 2. 对各个桶执行排序
    +    for (vector<float> &bucket : buckets) {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        sort(bucket.begin(), bucket.end());
    +    }
    +    // 3. 遍历桶合并结果
    +    int i = 0;
    +    for (vector<float> &bucket : buckets) {
    +        for (float num : bucket) {
    +            nums[i++] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.java
    /* 桶排序 */
    +void bucketSort(float[] nums) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    int k = nums.length / 2;
    +    List<List<Float>> buckets = new ArrayList<>();
    +    for (int i = 0; i < k; i++) {
    +        buckets.add(new ArrayList<>());
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    for (float num : nums) {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        int i = (int) (num * k);
    +        // 将 num 添加进桶 i
    +        buckets.get(i).add(num);
    +    }
    +    // 2. 对各个桶执行排序
    +    for (List<Float> bucket : buckets) {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        Collections.sort(bucket);
    +    }
    +    // 3. 遍历桶合并结果
    +    int i = 0;
    +    for (List<Float> bucket : buckets) {
    +        for (float num : bucket) {
    +            nums[i++] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.cs
    /* 桶排序 */
    +void BucketSort(float[] nums) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    int k = nums.Length / 2;
    +    List<List<float>> buckets = [];
    +    for (int i = 0; i < k; i++) {
    +        buckets.Add([]);
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    foreach (float num in nums) {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        int i = (int)(num * k);
    +        // 将 num 添加进桶 i
    +        buckets[i].Add(num);
    +    }
    +    // 2. 对各个桶执行排序
    +    foreach (List<float> bucket in buckets) {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        bucket.Sort();
    +    }
    +    // 3. 遍历桶合并结果
    +    int j = 0;
    +    foreach (List<float> bucket in buckets) {
    +        foreach (float num in bucket) {
    +            nums[j++] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.go
    /* 桶排序 */
    +func bucketSort(nums []float64) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    k := len(nums) / 2
    +    buckets := make([][]float64, k)
    +    for i := 0; i < k; i++ {
    +        buckets[i] = make([]float64, 0)
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    for _, num := range nums {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        i := int(num * float64(k))
    +        // 将 num 添加进桶 i
    +        buckets[i] = append(buckets[i], num)
    +    }
    +    // 2. 对各个桶执行排序
    +    for i := 0; i < k; i++ {
    +        // 使用内置切片排序函数,也可以替换成其他排序算法
    +        sort.Float64s(buckets[i])
    +    }
    +    // 3. 遍历桶合并结果
    +    i := 0
    +    for _, bucket := range buckets {
    +        for _, num := range bucket {
    +            nums[i] = num
    +            i++
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.swift
    /* 桶排序 */
    +func bucketSort(nums: inout [Double]) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    let k = nums.count / 2
    +    var buckets = (0 ..< k).map { _ in [Double]() }
    +    // 1. 将数组元素分配到各个桶中
    +    for num in nums {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        let i = Int(num * Double(k))
    +        // 将 num 添加进桶 i
    +        buckets[i].append(num)
    +    }
    +    // 2. 对各个桶执行排序
    +    for i in buckets.indices {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        buckets[i].sort()
    +    }
    +    // 3. 遍历桶合并结果
    +    var i = nums.startIndex
    +    for bucket in buckets {
    +        for num in bucket {
    +            nums[i] = num
    +            i += 1
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.js
    /* 桶排序 */
    +function bucketSort(nums) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    const k = nums.length / 2;
    +    const buckets = [];
    +    for (let i = 0; i < k; i++) {
    +        buckets.push([]);
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    for (const num of nums) {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        const i = Math.floor(num * k);
    +        // 将 num 添加进桶 i
    +        buckets[i].push(num);
    +    }
    +    // 2. 对各个桶执行排序
    +    for (const bucket of buckets) {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        bucket.sort((a, b) => a - b);
    +    }
    +    // 3. 遍历桶合并结果
    +    let i = 0;
    +    for (const bucket of buckets) {
    +        for (const num of bucket) {
    +            nums[i++] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.ts
    /* 桶排序 */
    +function bucketSort(nums: number[]): void {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    const k = nums.length / 2;
    +    const buckets: number[][] = [];
    +    for (let i = 0; i < k; i++) {
    +        buckets.push([]);
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    for (const num of nums) {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        const i = Math.floor(num * k);
    +        // 将 num 添加进桶 i
    +        buckets[i].push(num);
    +    }
    +    // 2. 对各个桶执行排序
    +    for (const bucket of buckets) {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        bucket.sort((a, b) => a - b);
    +    }
    +    // 3. 遍历桶合并结果
    +    let i = 0;
    +    for (const bucket of buckets) {
    +        for (const num of bucket) {
    +            nums[i++] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.dart
    /* 桶排序 */
    +void bucketSort(List<double> nums) {
    +  // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +  int k = nums.length ~/ 2;
    +  List<List<double>> buckets = List.generate(k, (index) => []);
    +
    +  // 1. 将数组元素分配到各个桶中
    +  for (double _num in nums) {
    +    // 输入数据范围为 [0, 1),使用 _num * k 映射到索引范围 [0, k-1]
    +    int i = (_num * k).toInt();
    +    // 将 _num 添加进桶 bucket_idx
    +    buckets[i].add(_num);
    +  }
    +  // 2. 对各个桶执行排序
    +  for (List<double> bucket in buckets) {
    +    bucket.sort();
    +  }
    +  // 3. 遍历桶合并结果
    +  int i = 0;
    +  for (List<double> bucket in buckets) {
    +    for (double _num in bucket) {
    +      nums[i++] = _num;
    +    }
    +  }
    +}
    +
    +
    +
    +
    bucket_sort.rs
    /* 桶排序 */
    +fn bucket_sort(nums: &mut [f64]) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    let k = nums.len() / 2;
    +    let mut buckets = vec![vec![]; k];
    +    // 1. 将数组元素分配到各个桶中
    +    for &mut num in &mut *nums {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        let i = (num * k as f64) as usize;
    +        // 将 num 添加进桶 i
    +        buckets[i].push(num);
    +    }
    +    // 2. 对各个桶执行排序
    +    for bucket in &mut buckets {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        bucket.sort_by(|a, b| a.partial_cmp(b).unwrap());
    +    }
    +    // 3. 遍历桶合并结果
    +    let mut i = 0;
    +    for bucket in &mut buckets {
    +        for &mut num in bucket {
    +            nums[i] = num;
    +            i += 1;
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.c
    /* 桶排序 */
    +void bucketSort(float nums[], int n) {
    +    int k = n / 2;                                 // 初始化 k = n/2 个桶
    +    int *sizes = malloc(k * sizeof(int));          // 记录每个桶的大小
    +    float **buckets = malloc(k * sizeof(float *)); // 动态数组的数组(桶)
    +    // 为每个桶预分配足够的空间
    +    for (int i = 0; i < k; ++i) {
    +        buckets[i] = (float *)malloc(n * sizeof(float));
    +        sizes[i] = 0;
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    for (int i = 0; i < n; ++i) {
    +        int idx = (int)(nums[i] * k);
    +        buckets[idx][sizes[idx]++] = nums[i];
    +    }
    +    // 2. 对各个桶执行排序
    +    for (int i = 0; i < k; ++i) {
    +        qsort(buckets[i], sizes[i], sizeof(float), compare);
    +    }
    +    // 3. 合并排序后的桶
    +    int idx = 0;
    +    for (int i = 0; i < k; ++i) {
    +        for (int j = 0; j < sizes[i]; ++j) {
    +            nums[idx++] = buckets[i][j];
    +        }
    +        // 释放内存
    +        free(buckets[i]);
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.kt
    /* 桶排序 */
    +fun bucketSort(nums: FloatArray) {
    +    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +    val k = nums.size / 2
    +    val buckets = mutableListOf<MutableList<Float>>()
    +    for (i in 0..<k) {
    +        buckets.add(mutableListOf())
    +    }
    +    // 1. 将数组元素分配到各个桶中
    +    for (num in nums) {
    +        // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +        val i = (num * k).toInt()
    +        // 将 num 添加进桶 i
    +        buckets[i].add(num)
    +    }
    +    // 2. 对各个桶执行排序
    +    for (bucket in buckets) {
    +        // 使用内置排序函数,也可以替换成其他排序算法
    +        bucket.sort()
    +    }
    +    // 3. 遍历桶合并结果
    +    var i = 0
    +    for (bucket in buckets) {
    +        for (num in bucket) {
    +            nums[i++] = num
    +        }
    +    }
    +}
    +
    +
    +
    +
    bucket_sort.rb
    ### 桶排序 ###
    +def bucket_sort(nums)
    +  # 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    +  k = nums.length / 2
    +  buckets = Array.new(k) { [] }
    +
    +  # 1. 将数组元素分配到各个桶中
    +  nums.each do |num|
    +    # 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
    +    i = (num * k).to_i
    +    # 将 num 添加进桶 i
    +    buckets[i] << num
    +  end
    +
    +  # 2. 对各个桶执行排序
    +  buckets.each do |bucket|
    +    # 使用内置排序函数,也可以替换成其他排序算法
    +    bucket.sort!
    +  end
    +
    +  # 3. 遍历桶合并结果
    +  i = 0
    +  buckets.each do |bucket|
    +    bucket.each do |num|
    +      nums[i] = num
    +      i += 1
    +    end
    +  end
    +end
    +
    +
    +
    +
    bucket_sort.zig
    [class]{}-[func]{bucketSort}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.8.2   Algorithm characteristics

    +

    Bucket sort is suitable for handling very large data sets. For example, if the input data includes 1 million elements, and system memory limitations prevent loading all the data at once, you can divide the data into 1,000 buckets and sort each bucket separately before merging the results.

    +
      +
    • Time complexity is \(O(n + k)\): Assuming the elements are evenly distributed across the buckets, the number of elements in each bucket is \(n/k\). Assuming sorting a single bucket takes \(O(n/k \log(n/k))\) time, sorting all buckets takes \(O(n \log(n/k))\) time. When the number of buckets \(k\) is relatively large, the time complexity tends towards \(O(n)\). Merging the results requires traversing all buckets and elements, taking \(O(n + k)\) time.
    • +
    • Adaptive sorting: In the worst case, all data is distributed into a single bucket, and sorting that bucket takes \(O(n^2)\) time.
    • +
    • Space complexity is \(O(n + k)\), non-in-place sorting: It requires additional space for \(k\) buckets and a total of \(n\) elements.
    • +
    • Whether bucket sort is stable depends on whether the algorithm used to sort elements within the buckets is stable.
    • +
    +

    11.8.3   How to achieve even distribution

    +

    The theoretical time complexity of bucket sort can reach \(O(n)\), the key is to evenly distribute the elements across all buckets, as real data is often not uniformly distributed. For example, if we want to evenly distribute all products on Taobao by price range into 10 buckets, but the distribution of product prices is uneven, with many under 100 yuan and few over 1000 yuan. If the price range is evenly divided into 10, the difference in the number of products in each bucket will be very large.

    +

    To achieve even distribution, we can initially set a rough dividing line, roughly dividing the data into 3 buckets. After the distribution is complete, the buckets with more products can be further divided into 3 buckets, until the number of elements in all buckets is roughly equal.

    +

    As shown in the Figure 11-14 , this method essentially creates a recursive tree, aiming to make the leaf node values as even as possible. Of course, you don't have to divide the data into 3 buckets each round; the specific division method can be flexibly chosen based on data characteristics.

    +

    Recursive division of buckets

    +

    Figure 11-14   Recursive division of buckets

    + +

    If we know the probability distribution of product prices in advance, we can set the price dividing line for each bucket based on the data probability distribution. It is worth noting that it is not necessarily required to specifically calculate the data distribution; it can also be approximated based on data characteristics using some probability model.

    +

    As shown in the Figure 11-15 , we assume that product prices follow a normal distribution, allowing us to reasonably set the price intervals, thereby evenly distributing the products into the respective buckets.

    +

    Dividing buckets based on probability distribution

    +

    Figure 11-15   Dividing buckets based on probability distribution

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/counting_sort.assets/counting_sort_overview.png b/en/chapter_sorting/counting_sort.assets/counting_sort_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..fff7c78141f8a1e6cd761f43d19053e867def5c4 GIT binary patch literal 30527 zcmbTeWmFtZ6fHV4xVyVca0wnXxCeI#9!StY(81l^3Blch1!r(~cMa|?Z}Q!H-;ZbO zt=l!Lr>0l;seN{xv%9LMXTnsKWzdj`kpTbznw+eZIsgC%t%4>HVW4mKzgW$oA0AZ| zH9o$*z3uMq`nUMq`>A~mS{ExgQvXvE78a(NrXeIG)X~wwsyzDCS=_nOS-iTCGj;R) z^77%shmFk*O-;?s(~a@*@%zX7ypf;FE6Y#MPjmBgMMXuXxhBIK!$w9%W@cvV8|&TO z-BwmsmzS5)($bARXTib2$H&L2s;YK&cH-jV4z1_kiog1d^m=%B)YsR0dwUNJ4b7e% zKmPQosHi9{E$!{?U0q$>+1c6N-pR_!(#g<{jEvOJ(sLUcpg7^d|96! z85xO>kN5ZYcdu}3ZEe-l)7#wIn%kdyeR-PPopf<=IZ;5qxVuP8OIuuAEFCS0iHT`y zYL4uTNXXwG7#L7gRNOh+shg^;8m~-&q{OzySmj&E$;tWp`X1fhPfkwO)YN45WqkIW zpPrs}baY(axI4H!xPG{Py*PS!dTpL-a&vP#zj}Usxb0i(tDLG(vY8f$3q8I*{@MSt zs;cVe&!1+$&%&F-@cf1$5J-N0eo9J8&vXy3=Gf}d%HrR}xbE2C-$9a+l4(WD!g>== z%{dQA_Ad)V^Q*U}T}`eL>-Vvi_d(h|@tgONrae79gM)+5qs_l(e?R_C^X$4v>`2sc zns*JKd%ZsMulGATeSFzoDC#eKED7Fk_SwF^Y#MF4y}ccqyS9e> z=^DOBFFklY-cA0KoS2vh*?#C5-1t?s@{sN_FnPJOwB*p=(Z19c7Z>+f85=)*6`8#g zmAM!`IdmUxq+EWSu`s1xd9uE9|I}B#dGQ>Wy4|t2=~O8Uhl21Y6uZecWVX!TmW)X;u`Kt z$6bEV%m9FMUrGo{K>w=$dz;DahS+~s4!r%w(tsw(|K=7X!jJi%ol9SP*#A!(c(+HC zd}f%zpyH3X3$WBw`7HbriAqiZI|eIlhoQf!dIOYwVr(-9?Kj%DlyIj`cfKk&J7w1a;ZZZFW(NWRe+j%=Hsy zOZWQDVs07sIJt!2u*eWIuuS+f>?cwAw!8g>)5JsKB|~cWpXN&iZqT#-*f&aY0&vn` zd%@9(4@iYypS|3r(MsUauv%j$-T4q)tax8>0@VD>#ALz^z%yw3JIlhh<(FJ�W+M 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/counting_sort.assets/counting_sort_step2.png b/en/chapter_sorting/counting_sort.assets/counting_sort_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..b054b7bdbdc85067609874c1f40a6556668e45ee GIT binary patch literal 21000 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/counting_sort.assets/counting_sort_step3.png b/en/chapter_sorting/counting_sort.assets/counting_sort_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..63987089b918691f77bfc74d8758170aa2a666d6 GIT binary patch literal 25992 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/counting_sort.assets/counting_sort_step4.png b/en/chapter_sorting/counting_sort.assets/counting_sort_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..afa7993d11adb5369ca347ba548af04b815f5322 GIT binary patch literal 25860 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 H5C8uF=~7HS literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/counting_sort.assets/counting_sort_step7.png b/en/chapter_sorting/counting_sort.assets/counting_sort_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..5ab818a65c3d8bedb05d78182099e5b4b9175a2e GIT binary patch literal 21272 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

    -S7OHKovQh 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 Um9i0~EBZI3qh+Xx)4)Xh2VI{DF#rGn literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/counting_sort.assets/counting_sort_step8.png b/en/chapter_sorting/counting_sort.assets/counting_sort_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..33ed7550b8ee057a6a1419f158379fe620fd9175 GIT binary patch literal 16518 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/counting_sort/index.html b/en/chapter_sorting/counting_sort/index.html new file mode 100644 index 000000000..d98e8a61b --- /dev/null +++ b/en/chapter_sorting/counting_sort/index.html @@ -0,0 +1,4703 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.9 Counting sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.9   Counting sort

    +

    Counting sort achieves sorting by counting the number of elements, typically applied to arrays of integers.

    +

    11.9.1   Simple implementation

    +

    Let's start with a simple example. Given an array nums of length \(n\), where all elements are "non-negative integers", the overall process of counting sort is illustrated in the following diagram.

    +
      +
    1. Traverse the array to find the maximum number, denoted as \(m\), then create an auxiliary array counter of length \(m + 1\).
    2. +
    3. Use counter to count the occurrence of each number in nums, where counter[num] corresponds to the occurrence of the number num. The counting method is simple, just traverse nums (suppose the current number is num), and increase counter[num] by \(1\) each round.
    4. +
    5. Since the indices of counter are naturally ordered, all numbers are essentially sorted already. Next, we traverse counter, filling nums in ascending order of occurrence.
    6. +
    +

    Counting sort process

    +

    Figure 11-16   Counting sort process

    + +

    The code is shown below:

    +
    +
    +
    +
    counting_sort.py
    def counting_sort_naive(nums: list[int]):
    +    """计数排序"""
    +    # 简单实现,无法用于排序对象
    +    # 1. 统计数组最大元素 m
    +    m = 0
    +    for num in nums:
    +        m = max(m, num)
    +    # 2. 统计各数字的出现次数
    +    # counter[num] 代表 num 的出现次数
    +    counter = [0] * (m + 1)
    +    for num in nums:
    +        counter[num] += 1
    +    # 3. 遍历 counter ,将各元素填入原数组 nums
    +    i = 0
    +    for num in range(m + 1):
    +        for _ in range(counter[num]):
    +            nums[i] = num
    +            i += 1
    +
    +
    +
    +
    counting_sort.cpp
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +void countingSortNaive(vector<int> &nums) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    for (int num : nums) {
    +        m = max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    vector<int> counter(m + 1, 0);
    +    for (int num : nums) {
    +        counter[num]++;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    int i = 0;
    +    for (int num = 0; num < m + 1; num++) {
    +        for (int j = 0; j < counter[num]; j++, i++) {
    +            nums[i] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.java
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +void countingSortNaive(int[] nums) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    for (int num : nums) {
    +        m = Math.max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    int[] counter = new int[m + 1];
    +    for (int num : nums) {
    +        counter[num]++;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    int i = 0;
    +    for (int num = 0; num < m + 1; num++) {
    +        for (int j = 0; j < counter[num]; j++, i++) {
    +            nums[i] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.cs
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +void CountingSortNaive(int[] nums) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    foreach (int num in nums) {
    +        m = Math.Max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    int[] counter = new int[m + 1];
    +    foreach (int num in nums) {
    +        counter[num]++;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    int i = 0;
    +    for (int num = 0; num < m + 1; num++) {
    +        for (int j = 0; j < counter[num]; j++, i++) {
    +            nums[i] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.go
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +func countingSortNaive(nums []int) {
    +    // 1. 统计数组最大元素 m
    +    m := 0
    +    for _, num := range nums {
    +        if num > m {
    +            m = num
    +        }
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    counter := make([]int, m+1)
    +    for _, num := range nums {
    +        counter[num]++
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    for i, num := 0, 0; num < m+1; num++ {
    +        for j := 0; j < counter[num]; j++ {
    +            nums[i] = num
    +            i++
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.swift
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +func countingSortNaive(nums: inout [Int]) {
    +    // 1. 统计数组最大元素 m
    +    let m = nums.max()!
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    var counter = Array(repeating: 0, count: m + 1)
    +    for num in nums {
    +        counter[num] += 1
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    var i = 0
    +    for num in 0 ..< m + 1 {
    +        for _ in 0 ..< counter[num] {
    +            nums[i] = num
    +            i += 1
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.js
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +function countingSortNaive(nums) {
    +    // 1. 统计数组最大元素 m
    +    let m = 0;
    +    for (const num of nums) {
    +        m = Math.max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    const counter = new Array(m + 1).fill(0);
    +    for (const num of nums) {
    +        counter[num]++;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    let i = 0;
    +    for (let num = 0; num < m + 1; num++) {
    +        for (let j = 0; j < counter[num]; j++, i++) {
    +            nums[i] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.ts
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +function countingSortNaive(nums: number[]): void {
    +    // 1. 统计数组最大元素 m
    +    let m = 0;
    +    for (const num of nums) {
    +        m = Math.max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    const counter: number[] = new Array<number>(m + 1).fill(0);
    +    for (const num of nums) {
    +        counter[num]++;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    let i = 0;
    +    for (let num = 0; num < m + 1; num++) {
    +        for (let j = 0; j < counter[num]; j++, i++) {
    +            nums[i] = num;
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.dart
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +void countingSortNaive(List<int> nums) {
    +  // 1. 统计数组最大元素 m
    +  int m = 0;
    +  for (int _num in nums) {
    +    m = max(m, _num);
    +  }
    +  // 2. 统计各数字的出现次数
    +  // counter[_num] 代表 _num 的出现次数
    +  List<int> counter = List.filled(m + 1, 0);
    +  for (int _num in nums) {
    +    counter[_num]++;
    +  }
    +  // 3. 遍历 counter ,将各元素填入原数组 nums
    +  int i = 0;
    +  for (int _num = 0; _num < m + 1; _num++) {
    +    for (int j = 0; j < counter[_num]; j++, i++) {
    +      nums[i] = _num;
    +    }
    +  }
    +}
    +
    +
    +
    +
    counting_sort.rs
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +fn counting_sort_naive(nums: &mut [i32]) {
    +    // 1. 统计数组最大元素 m
    +    let m = *nums.into_iter().max().unwrap();
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    let mut counter = vec![0; m as usize + 1];
    +    for &num in &*nums {
    +        counter[num as usize] += 1;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    let mut i = 0;
    +    for num in 0..m + 1 {
    +        for _ in 0..counter[num as usize] {
    +            nums[i] = num;
    +            i += 1;
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.c
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +void countingSortNaive(int nums[], int size) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    for (int i = 0; i < size; i++) {
    +        if (nums[i] > m) {
    +            m = nums[i];
    +        }
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    int *counter = calloc(m + 1, sizeof(int));
    +    for (int i = 0; i < size; i++) {
    +        counter[nums[i]]++;
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    int i = 0;
    +    for (int num = 0; num < m + 1; num++) {
    +        for (int j = 0; j < counter[num]; j++, i++) {
    +            nums[i] = num;
    +        }
    +    }
    +    // 4. 释放内存
    +    free(counter);
    +}
    +
    +
    +
    +
    counting_sort.kt
    /* 计数排序 */
    +// 简单实现,无法用于排序对象
    +fun countingSortNaive(nums: IntArray) {
    +    // 1. 统计数组最大元素 m
    +    var m = 0
    +    for (num in nums) {
    +        m = max(m, num)
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    val counter = IntArray(m + 1)
    +    for (num in nums) {
    +        counter[num]++
    +    }
    +    // 3. 遍历 counter ,将各元素填入原数组 nums
    +    var i = 0
    +    for (num in 0..<m + 1) {
    +        var j = 0
    +        while (j < counter[num]) {
    +            nums[i] = num
    +            j++
    +            i++
    +        }
    +    }
    +}
    +
    +
    +
    +
    counting_sort.rb
    [class]{}-[func]{counting_sort_naive}
    +
    +
    +
    +
    counting_sort.zig
    [class]{}-[func]{countingSortNaive}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +
    +

    Connection between counting sort and bucket sort

    +

    From the perspective of bucket sort, we can consider each index of the counting array counter in counting sort as a bucket, and the process of counting as distributing elements into the corresponding buckets. Essentially, counting sort is a special case of bucket sort for integer data.

    +
    +

    11.9.2   Complete implementation

    +

    Astute readers might have noticed, if the input data is an object, the above step 3. becomes ineffective. Suppose the input data is a product object, we want to sort the products by their price (a class member variable), but the above algorithm can only provide the sorting result for the price.

    +

    So how can we get the sorting result for the original data? First, we calculate the "prefix sum" of counter. As the name suggests, the prefix sum at index i, prefix[i], equals the sum of the first i elements of the array:

    +
    \[ +\text{prefix}[i] = \sum_{j=0}^i \text{counter[j]} +\]
    +

    The prefix sum has a clear meaning, prefix[num] - 1 represents the last occurrence index of element num in the result array res. This information is crucial, as it tells us where each element should appear in the result array. Next, we traverse the original array nums for each element num in reverse order, performing the following two steps in each iteration.

    +
      +
    1. Fill num into the array res at the index prefix[num] - 1.
    2. +
    3. Reduce the prefix sum prefix[num] by \(1\), thus obtaining the next index to place num.
    4. +
    +

    After the traversal, the array res contains the sorted result, and finally, res replaces the original array nums. The complete counting sort process is shown in the figures below.

    +
    +
    +
    +

    Counting sort process

    +
    +
    +

    counting_sort_step2

    +
    +
    +

    counting_sort_step3

    +
    +
    +

    counting_sort_step4

    +
    +
    +

    counting_sort_step5

    +
    +
    +

    counting_sort_step6

    +
    +
    +

    counting_sort_step7

    +
    +
    +

    counting_sort_step8

    +
    +
    +
    +

    Figure 11-17   Counting sort process

    + +

    The implementation code of counting sort is shown below:

    +
    +
    +
    +
    counting_sort.py
    def counting_sort(nums: list[int]):
    +    """计数排序"""
    +    # 完整实现,可排序对象,并且是稳定排序
    +    # 1. 统计数组最大元素 m
    +    m = max(nums)
    +    # 2. 统计各数字的出现次数
    +    # counter[num] 代表 num 的出现次数
    +    counter = [0] * (m + 1)
    +    for num in nums:
    +        counter[num] += 1
    +    # 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    # 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for i in range(m):
    +        counter[i + 1] += counter[i]
    +    # 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    # 初始化数组 res 用于记录结果
    +    n = len(nums)
    +    res = [0] * n
    +    for i in range(n - 1, -1, -1):
    +        num = nums[i]
    +        res[counter[num] - 1] = num  # 将 num 放置到对应索引处
    +        counter[num] -= 1  # 令前缀和自减 1 ,得到下次放置 num 的索引
    +    # 使用结果数组 res 覆盖原数组 nums
    +    for i in range(n):
    +        nums[i] = res[i]
    +
    +
    +
    +
    counting_sort.cpp
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +void countingSort(vector<int> &nums) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    for (int num : nums) {
    +        m = max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    vector<int> counter(m + 1, 0);
    +    for (int num : nums) {
    +        counter[num]++;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (int i = 0; i < m; i++) {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    int n = nums.size();
    +    vector<int> res(n);
    +    for (int i = n - 1; i >= 0; i--) {
    +        int num = nums[i];
    +        res[counter[num] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num]--;              // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    nums = res;
    +}
    +
    +
    +
    +
    counting_sort.java
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +void countingSort(int[] nums) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    for (int num : nums) {
    +        m = Math.max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    int[] counter = new int[m + 1];
    +    for (int num : nums) {
    +        counter[num]++;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (int i = 0; i < m; i++) {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    int n = nums.length;
    +    int[] res = new int[n];
    +    for (int i = n - 1; i >= 0; i--) {
    +        int num = nums[i];
    +        res[counter[num] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for (int i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +
    +
    +
    counting_sort.cs
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +void CountingSort(int[] nums) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    foreach (int num in nums) {
    +        m = Math.Max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    int[] counter = new int[m + 1];
    +    foreach (int num in nums) {
    +        counter[num]++;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (int i = 0; i < m; i++) {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    int n = nums.Length;
    +    int[] res = new int[n];
    +    for (int i = n - 1; i >= 0; i--) {
    +        int num = nums[i];
    +        res[counter[num] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for (int i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +
    +
    +
    counting_sort.go
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +func countingSort(nums []int) {
    +    // 1. 统计数组最大元素 m
    +    m := 0
    +    for _, num := range nums {
    +        if num > m {
    +            m = num
    +        }
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    counter := make([]int, m+1)
    +    for _, num := range nums {
    +        counter[num]++
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for i := 0; i < m; i++ {
    +        counter[i+1] += counter[i]
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    n := len(nums)
    +    res := make([]int, n)
    +    for i := n - 1; i >= 0; i-- {
    +        num := nums[i]
    +        // 将 num 放置到对应索引处
    +        res[counter[num]-1] = num
    +        // 令前缀和自减 1 ,得到下次放置 num 的索引
    +        counter[num]--
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    copy(nums, res)
    +}
    +
    +
    +
    +
    counting_sort.swift
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +func countingSort(nums: inout [Int]) {
    +    // 1. 统计数组最大元素 m
    +    let m = nums.max()!
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    var counter = Array(repeating: 0, count: m + 1)
    +    for num in nums {
    +        counter[num] += 1
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for i in 0 ..< m {
    +        counter[i + 1] += counter[i]
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    var res = Array(repeating: 0, count: nums.count)
    +    for i in nums.indices.reversed() {
    +        let num = nums[i]
    +        res[counter[num] - 1] = num // 将 num 放置到对应索引处
    +        counter[num] -= 1 // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for i in nums.indices {
    +        nums[i] = res[i]
    +    }
    +}
    +
    +
    +
    +
    counting_sort.js
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +function countingSort(nums) {
    +    // 1. 统计数组最大元素 m
    +    let m = 0;
    +    for (const num of nums) {
    +        m = Math.max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    const counter = new Array(m + 1).fill(0);
    +    for (const num of nums) {
    +        counter[num]++;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (let i = 0; i < m; i++) {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    const n = nums.length;
    +    const res = new Array(n);
    +    for (let i = n - 1; i >= 0; i--) {
    +        const num = nums[i];
    +        res[counter[num] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for (let i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +
    +
    +
    counting_sort.ts
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +function countingSort(nums: number[]): void {
    +    // 1. 统计数组最大元素 m
    +    let m = 0;
    +    for (const num of nums) {
    +        m = Math.max(m, num);
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    const counter: number[] = new Array<number>(m + 1).fill(0);
    +    for (const num of nums) {
    +        counter[num]++;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (let i = 0; i < m; i++) {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    const n = nums.length;
    +    const res: number[] = new Array<number>(n);
    +    for (let i = n - 1; i >= 0; i--) {
    +        const num = nums[i];
    +        res[counter[num] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for (let i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +
    +
    +
    counting_sort.dart
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +void countingSort(List<int> nums) {
    +  // 1. 统计数组最大元素 m
    +  int m = 0;
    +  for (int _num in nums) {
    +    m = max(m, _num);
    +  }
    +  // 2. 统计各数字的出现次数
    +  // counter[_num] 代表 _num 的出现次数
    +  List<int> counter = List.filled(m + 1, 0);
    +  for (int _num in nums) {
    +    counter[_num]++;
    +  }
    +  // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +  // 即 counter[_num]-1 是 _num 在 res 中最后一次出现的索引
    +  for (int i = 0; i < m; i++) {
    +    counter[i + 1] += counter[i];
    +  }
    +  // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +  // 初始化数组 res 用于记录结果
    +  int n = nums.length;
    +  List<int> res = List.filled(n, 0);
    +  for (int i = n - 1; i >= 0; i--) {
    +    int _num = nums[i];
    +    res[counter[_num] - 1] = _num; // 将 _num 放置到对应索引处
    +    counter[_num]--; // 令前缀和自减 1 ,得到下次放置 _num 的索引
    +  }
    +  // 使用结果数组 res 覆盖原数组 nums
    +  nums.setAll(0, res);
    +}
    +
    +
    +
    +
    counting_sort.rs
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +fn counting_sort(nums: &mut [i32]) {
    +    // 1. 统计数组最大元素 m
    +    let m = *nums.into_iter().max().unwrap();
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    let mut counter = vec![0; m as usize + 1];
    +    for &num in &*nums {
    +        counter[num as usize] += 1;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for i in 0..m as usize {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    let n = nums.len();
    +    let mut res = vec![0; n];
    +    for i in (0..n).rev() {
    +        let num = nums[i];
    +        res[counter[num as usize] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num as usize] -= 1; // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for i in 0..n {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +
    +
    +
    counting_sort.c
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +void countingSort(int nums[], int size) {
    +    // 1. 统计数组最大元素 m
    +    int m = 0;
    +    for (int i = 0; i < size; i++) {
    +        if (nums[i] > m) {
    +            m = nums[i];
    +        }
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    int *counter = calloc(m, sizeof(int));
    +    for (int i = 0; i < size; i++) {
    +        counter[nums[i]]++;
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (int i = 0; i < m; i++) {
    +        counter[i + 1] += counter[i];
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    int *res = malloc(sizeof(int) * size);
    +    for (int i = size - 1; i >= 0; i--) {
    +        int num = nums[i];
    +        res[counter[num] - 1] = num; // 将 num 放置到对应索引处
    +        counter[num]--;              // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    memcpy(nums, res, size * sizeof(int));
    +    // 5. 释放内存
    +    free(counter);
    +}
    +
    +
    +
    +
    counting_sort.kt
    /* 计数排序 */
    +// 完整实现,可排序对象,并且是稳定排序
    +fun countingSort(nums: IntArray) {
    +    // 1. 统计数组最大元素 m
    +    var m = 0
    +    for (num in nums) {
    +        m = max(m, num)
    +    }
    +    // 2. 统计各数字的出现次数
    +    // counter[num] 代表 num 的出现次数
    +    val counter = IntArray(m + 1)
    +    for (num in nums) {
    +        counter[num]++
    +    }
    +    // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引”
    +    // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引
    +    for (i in 0..<m) {
    +        counter[i + 1] += counter[i]
    +    }
    +    // 4. 倒序遍历 nums ,将各元素填入结果数组 res
    +    // 初始化数组 res 用于记录结果
    +    val n = nums.size
    +    val res = IntArray(n)
    +    for (i in n - 1 downTo 0) {
    +        val num = nums[i]
    +        res[counter[num] - 1] = num // 将 num 放置到对应索引处
    +        counter[num]-- // 令前缀和自减 1 ,得到下次放置 num 的索引
    +    }
    +    // 使用结果数组 res 覆盖原数组 nums
    +    for (i in 0..<n) {
    +        nums[i] = res[i]
    +    }
    +}
    +
    +
    +
    +
    counting_sort.rb
    [class]{}-[func]{counting_sort}
    +
    +
    +
    +
    counting_sort.zig
    [class]{}-[func]{countingSort}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.9.3   Algorithm characteristics

    +
      +
    • Time complexity is \(O(n + m)\), non-adaptive sort: Involves traversing nums and counter, both using linear time. Generally, \(n \gg m\), and the time complexity tends towards \(O(n)\).
    • +
    • Space complexity is \(O(n + m)\), non-in-place sort: Utilizes arrays res and counter of lengths \(n\) and \(m\) respectively.
    • +
    • Stable sort: Since elements are filled into res in a "right-to-left" order, reversing the traversal of nums can prevent changing the relative position between equal elements, thereby achieving a stable sort. Actually, traversing nums in order can also produce the correct sorting result, but the outcome is unstable.
    • +
    +

    11.9.4   Limitations

    +

    By now, you might find counting sort very clever, as it can achieve efficient sorting merely by counting quantities. However, the prerequisites for using counting sort are relatively strict.

    +

    Counting sort is only suitable for non-negative integers. If you want to apply it to other types of data, you need to ensure that these data can be converted to non-negative integers without changing the relative sizes of the elements. For example, for an array containing negative integers, you can first add a constant to all numbers, converting them all to positive numbers, and then convert them back after sorting is complete.

    +

    Counting sort is suitable for large data volumes but small data ranges. For example, in the above example, \(m\) should not be too large, otherwise, it will occupy too much space. And when \(n \ll m\), counting sort uses \(O(m)\) time, which may be slower than \(O(n \log n)\) sorting algorithms.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step1.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..ecea70a3d3573e37db2d15aeb34a1249cf3ca6d1 GIT binary patch literal 23764 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 YfKn)LwPnO$+&=|M^6F2^WRZdY1)vr@^Z)<= literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step10.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step10.png new file mode 100644 index 0000000000000000000000000000000000000000..e3997706aa584fc5c8355ff6954a9c9d2f5bcc55 GIT binary patch literal 18100 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 TORVcE<3IwQu6{1-oD!M<(dz36 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step11.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step11.png new file mode 100644 index 0000000000000000000000000000000000000000..a857ddca4feeeb86eb498e04b118f7a31fd6695f GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step12.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step12.png new file mode 100644 index 0000000000000000000000000000000000000000..ee9c1a062e5176049d5399cdfe73e4cfb24241ff GIT binary patch literal 21022 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step3.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..ec761049e94fea22751dec7b447c084cfc72e057 GIT binary patch literal 22261 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 P|F+lFG}Ne4!$$oFH)Hnx literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step4.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..fea98499d557c2df28f3739233dbd0fb692682ad GIT binary patch literal 20159 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�q~1Cov=R4C#v6ZKKDEv&f#hl9Dwf)MKVH-| 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 Q`ku5H=o+Job?n3c4b`C@{v`mQJr=>^Fv#QM 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step6.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..61656286b23a0c8a6a9b6a6ab8d9b49b9bd205b9 GIT binary patch literal 19357 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 C4qR&h literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort.assets/heap_sort_step7.png b/en/chapter_sorting/heap_sort.assets/heap_sort_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..9b938dd6e662dc92606d8066cf90a4c5d2b0c5dd GIT binary patch literal 20906 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
    88@h+z>xc$)V2K!7!_OU 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/heap_sort/index.html b/en/chapter_sorting/heap_sort/index.html new file mode 100644 index 000000000..904c27081 --- /dev/null +++ b/en/chapter_sorting/heap_sort/index.html @@ -0,0 +1,4455 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.7 Heap sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.7   Heap sort

    +
    +

    Tip

    +

    Before reading this section, please make sure you have completed the "Heap" chapter.

    +
    +

    Heap sort is an efficient sorting algorithm based on the heap data structure. We can implement heap sort using the "heap creation" and "element extraction" operations we have already learned.

    +
      +
    1. Input the array and establish a min-heap, where the smallest element is at the heap's top.
    2. +
    3. Continuously perform the extraction operation, recording the extracted elements in sequence to obtain a sorted list from smallest to largest.
    4. +
    +

    Although the above method is feasible, it requires an additional array to save the popped elements, which is somewhat space-consuming. In practice, we usually use a more elegant implementation.

    +

    11.7.1   Algorithm flow

    +

    Suppose the array length is \(n\), the heap sort process is as follows.

    +
      +
    1. Input the array and establish a max-heap. After completion, the largest element is at the heap's top.
    2. +
    3. Swap the top element of the heap (the first element) with the heap's bottom element (the last element). After the swap, reduce the heap's length by \(1\) and increase the sorted elements count by \(1\).
    4. +
    5. Starting from the heap top, perform the sift-down operation from top to bottom. After the sift-down, the heap's property is restored.
    6. +
    7. Repeat steps 2. and 3. Loop for \(n - 1\) rounds to complete the sorting of the array.
    8. +
    +
    +

    Tip

    +

    In fact, the element extraction operation also includes steps 2. and 3., with the addition of a popping element step.

    +
    +
    +
    +
    +

    Heap sort process

    +
    +
    +

    heap_sort_step2

    +
    +
    +

    heap_sort_step3

    +
    +
    +

    heap_sort_step4

    +
    +
    +

    heap_sort_step5

    +
    +
    +

    heap_sort_step6

    +
    +
    +

    heap_sort_step7

    +
    +
    +

    heap_sort_step8

    +
    +
    +

    heap_sort_step9

    +
    +
    +

    heap_sort_step10

    +
    +
    +

    heap_sort_step11

    +
    +
    +

    heap_sort_step12

    +
    +
    +
    +

    Figure 11-12   Heap sort process

    + +

    In the code implementation, we used the sift-down function sift_down() from the "Heap" chapter. It is important to note that since the heap's length decreases as the maximum element is extracted, we need to add a length parameter \(n\) to the sift_down() function to specify the current effective length of the heap. The code is shown below:

    +
    +
    +
    +
    heap_sort.py
    def sift_down(nums: list[int], n: int, i: int):
    +    """堆的长度为 n ,从节点 i 开始,从顶至底堆化"""
    +    while True:
    +        # 判断节点 i, l, r 中值最大的节点,记为 ma
    +        l = 2 * i + 1
    +        r = 2 * i + 2
    +        ma = i
    +        if l < n and nums[l] > nums[ma]:
    +            ma = l
    +        if r < n and nums[r] > nums[ma]:
    +            ma = r
    +        # 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if ma == i:
    +            break
    +        # 交换两节点
    +        nums[i], nums[ma] = nums[ma], nums[i]
    +        # 循环向下堆化
    +        i = ma
    +
    +def heap_sort(nums: list[int]):
    +    """堆排序"""
    +    # 建堆操作:堆化除叶节点以外的其他所有节点
    +    for i in range(len(nums) // 2 - 1, -1, -1):
    +        sift_down(nums, len(nums), i)
    +    # 从堆中提取最大元素,循环 n-1 轮
    +    for i in range(len(nums) - 1, 0, -1):
    +        # 交换根节点与最右叶节点(交换首元素与尾元素)
    +        nums[0], nums[i] = nums[i], nums[0]
    +        # 以根节点为起点,从顶至底进行堆化
    +        sift_down(nums, i, 0)
    +
    +
    +
    +
    heap_sort.cpp
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +void siftDown(vector<int> &nums, int n, int i) {
    +    while (true) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        int l = 2 * i + 1;
    +        int r = 2 * i + 2;
    +        int ma = i;
    +        if (l < n && nums[l] > nums[ma])
    +            ma = l;
    +        if (r < n && nums[r] > nums[ma])
    +            ma = r;
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma == i) {
    +            break;
    +        }
    +        // 交换两节点
    +        swap(nums[i], nums[ma]);
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +void heapSort(vector<int> &nums) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (int i = nums.size() / 2 - 1; i >= 0; --i) {
    +        siftDown(nums, nums.size(), i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (int i = nums.size() - 1; i > 0; --i) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        swap(nums[0], nums[i]);
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.java
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +void siftDown(int[] nums, int n, int i) {
    +    while (true) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        int l = 2 * i + 1;
    +        int r = 2 * i + 2;
    +        int ma = i;
    +        if (l < n && nums[l] > nums[ma])
    +            ma = l;
    +        if (r < n && nums[r] > nums[ma])
    +            ma = r;
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma == i)
    +            break;
    +        // 交换两节点
    +        int temp = nums[i];
    +        nums[i] = nums[ma];
    +        nums[ma] = temp;
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +void heapSort(int[] nums) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (int i = nums.length / 2 - 1; i >= 0; i--) {
    +        siftDown(nums, nums.length, i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (int i = nums.length - 1; i > 0; i--) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        int tmp = nums[0];
    +        nums[0] = nums[i];
    +        nums[i] = tmp;
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.cs
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +void SiftDown(int[] nums, int n, int i) {
    +    while (true) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        int l = 2 * i + 1;
    +        int r = 2 * i + 2;
    +        int ma = i;
    +        if (l < n && nums[l] > nums[ma])
    +            ma = l;
    +        if (r < n && nums[r] > nums[ma])
    +            ma = r;
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma == i)
    +            break;
    +        // 交换两节点
    +        (nums[ma], nums[i]) = (nums[i], nums[ma]);
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +void HeapSort(int[] nums) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (int i = nums.Length / 2 - 1; i >= 0; i--) {
    +        SiftDown(nums, nums.Length, i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (int i = nums.Length - 1; i > 0; i--) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        (nums[i], nums[0]) = (nums[0], nums[i]);
    +        // 以根节点为起点,从顶至底进行堆化
    +        SiftDown(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.go
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +func siftDown(nums *[]int, n, i int) {
    +    for true {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        l := 2*i + 1
    +        r := 2*i + 2
    +        ma := i
    +        if l < n && (*nums)[l] > (*nums)[ma] {
    +            ma = l
    +        }
    +        if r < n && (*nums)[r] > (*nums)[ma] {
    +            ma = r
    +        }
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if ma == i {
    +            break
    +        }
    +        // 交换两节点
    +        (*nums)[i], (*nums)[ma] = (*nums)[ma], (*nums)[i]
    +        // 循环向下堆化
    +        i = ma
    +    }
    +}
    +
    +/* 堆排序 */
    +func heapSort(nums *[]int) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for i := len(*nums)/2 - 1; i >= 0; i-- {
    +        siftDown(nums, len(*nums), i)
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for i := len(*nums) - 1; i > 0; i-- {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        (*nums)[0], (*nums)[i] = (*nums)[i], (*nums)[0]
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0)
    +    }
    +}
    +
    +
    +
    +
    heap_sort.swift
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +func siftDown(nums: inout [Int], n: Int, i: Int) {
    +    var i = i
    +    while true {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        let l = 2 * i + 1
    +        let r = 2 * i + 2
    +        var ma = i
    +        if l < n, nums[l] > nums[ma] {
    +            ma = l
    +        }
    +        if r < n, nums[r] > nums[ma] {
    +            ma = r
    +        }
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if ma == i {
    +            break
    +        }
    +        // 交换两节点
    +        nums.swapAt(i, ma)
    +        // 循环向下堆化
    +        i = ma
    +    }
    +}
    +
    +/* 堆排序 */
    +func heapSort(nums: inout [Int]) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for i in stride(from: nums.count / 2 - 1, through: 0, by: -1) {
    +        siftDown(nums: &nums, n: nums.count, i: i)
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for i in nums.indices.dropFirst().reversed() {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        nums.swapAt(0, i)
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums: &nums, n: i, i: 0)
    +    }
    +}
    +
    +
    +
    +
    heap_sort.js
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +function siftDown(nums, n, i) {
    +    while (true) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        let l = 2 * i + 1;
    +        let r = 2 * i + 2;
    +        let ma = i;
    +        if (l < n && nums[l] > nums[ma]) {
    +            ma = l;
    +        }
    +        if (r < n && nums[r] > nums[ma]) {
    +            ma = r;
    +        }
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma === i) {
    +            break;
    +        }
    +        // 交换两节点
    +        [nums[i], nums[ma]] = [nums[ma], nums[i]];
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +function heapSort(nums) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {
    +        siftDown(nums, nums.length, i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (let i = nums.length - 1; i > 0; i--) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        [nums[0], nums[i]] = [nums[i], nums[0]];
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.ts
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +function siftDown(nums: number[], n: number, i: number): void {
    +    while (true) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        let l = 2 * i + 1;
    +        let r = 2 * i + 2;
    +        let ma = i;
    +        if (l < n && nums[l] > nums[ma]) {
    +            ma = l;
    +        }
    +        if (r < n && nums[r] > nums[ma]) {
    +            ma = r;
    +        }
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma === i) {
    +            break;
    +        }
    +        // 交换两节点
    +        [nums[i], nums[ma]] = [nums[ma], nums[i]];
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +function heapSort(nums: number[]): void {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {
    +        siftDown(nums, nums.length, i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (let i = nums.length - 1; i > 0; i--) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        [nums[0], nums[i]] = [nums[i], nums[0]];
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.dart
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +void siftDown(List<int> nums, int n, int i) {
    +  while (true) {
    +    // 判断节点 i, l, r 中值最大的节点,记为 ma
    +    int l = 2 * i + 1;
    +    int r = 2 * i + 2;
    +    int ma = i;
    +    if (l < n && nums[l] > nums[ma]) ma = l;
    +    if (r < n && nums[r] > nums[ma]) ma = r;
    +    // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +    if (ma == i) break;
    +    // 交换两节点
    +    int temp = nums[i];
    +    nums[i] = nums[ma];
    +    nums[ma] = temp;
    +    // 循环向下堆化
    +    i = ma;
    +  }
    +}
    +
    +/* 堆排序 */
    +void heapSort(List<int> nums) {
    +  // 建堆操作:堆化除叶节点以外的其他所有节点
    +  for (int i = nums.length ~/ 2 - 1; i >= 0; i--) {
    +    siftDown(nums, nums.length, i);
    +  }
    +  // 从堆中提取最大元素,循环 n-1 轮
    +  for (int i = nums.length - 1; i > 0; i--) {
    +    // 交换根节点与最右叶节点(交换首元素与尾元素)
    +    int tmp = nums[0];
    +    nums[0] = nums[i];
    +    nums[i] = tmp;
    +    // 以根节点为起点,从顶至底进行堆化
    +    siftDown(nums, i, 0);
    +  }
    +}
    +
    +
    +
    +
    heap_sort.rs
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +fn sift_down(nums: &mut [i32], n: usize, mut i: usize) {
    +    loop {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        let l = 2 * i + 1;
    +        let r = 2 * i + 2;
    +        let mut ma = i;
    +        if l < n && nums[l] > nums[ma] {
    +            ma = l;
    +        }
    +        if r < n && nums[r] > nums[ma] {
    +            ma = r;
    +        }
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if ma == i {
    +            break;
    +        }
    +        // 交换两节点
    +        let temp = nums[i];
    +        nums[i] = nums[ma];
    +        nums[ma] = temp;
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +fn heap_sort(nums: &mut [i32]) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for i in (0..=nums.len() / 2 - 1).rev() {
    +        sift_down(nums, nums.len(), i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for i in (1..=nums.len() - 1).rev() {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        let tmp = nums[0];
    +        nums[0] = nums[i];
    +        nums[i] = tmp;
    +        // 以根节点为起点,从顶至底进行堆化
    +        sift_down(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.c
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +void siftDown(int nums[], int n, int i) {
    +    while (1) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        int l = 2 * i + 1;
    +        int r = 2 * i + 2;
    +        int ma = i;
    +        if (l < n && nums[l] > nums[ma])
    +            ma = l;
    +        if (r < n && nums[r] > nums[ma])
    +            ma = r;
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma == i) {
    +            break;
    +        }
    +        // 交换两节点
    +        int temp = nums[i];
    +        nums[i] = nums[ma];
    +        nums[ma] = temp;
    +        // 循环向下堆化
    +        i = ma;
    +    }
    +}
    +
    +/* 堆排序 */
    +void heapSort(int nums[], int n) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (int i = n / 2 - 1; i >= 0; --i) {
    +        siftDown(nums, n, i);
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (int i = n - 1; i > 0; --i) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        int tmp = nums[0];
    +        nums[0] = nums[i];
    +        nums[i] = tmp;
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0);
    +    }
    +}
    +
    +
    +
    +
    heap_sort.kt
    /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */
    +fun siftDown(nums: IntArray, n: Int, li: Int) {
    +    var i = li
    +    while (true) {
    +        // 判断节点 i, l, r 中值最大的节点,记为 ma
    +        val l = 2 * i + 1
    +        val r = 2 * i + 2
    +        var ma = i
    +        if (l < n && nums[l] > nums[ma]) 
    +            ma = l
    +        if (r < n && nums[r] > nums[ma]) 
    +            ma = r
    +        // 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +        if (ma == i) 
    +            break
    +        // 交换两节点
    +        val temp = nums[i]
    +        nums[i] = nums[ma]
    +        nums[ma] = temp
    +        // 循环向下堆化
    +        i = ma
    +    }
    +}
    +
    +/* 堆排序 */
    +fun heapSort(nums: IntArray) {
    +    // 建堆操作:堆化除叶节点以外的其他所有节点
    +    for (i in nums.size / 2 - 1 downTo 0) {
    +        siftDown(nums, nums.size, i)
    +    }
    +    // 从堆中提取最大元素,循环 n-1 轮
    +    for (i in nums.size - 1 downTo 1) {
    +        // 交换根节点与最右叶节点(交换首元素与尾元素)
    +        val temp = nums[0]
    +        nums[0] = nums[i]
    +        nums[i] = temp
    +        // 以根节点为起点,从顶至底进行堆化
    +        siftDown(nums, i, 0)
    +    }
    +}
    +
    +
    +
    +
    heap_sort.rb
    ### 堆的长度为 n ,从节点 i 开始,从顶至底堆化 ###
    +def sift_down(nums, n, i)
    +  while true
    +    # 判断节点 i, l, r 中值最大的节点,记为 ma
    +    l = 2 * i + 1
    +    r = 2 * i + 2
    +    ma = i
    +    ma = l if l < n && nums[l] > nums[ma]
    +    ma = r if r < n && nums[r] > nums[ma]
    +    # 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出
    +    break if ma == i
    +    # 交换两节点
    +    nums[i], nums[ma] = nums[ma], nums[i]
    +    # 循环向下堆化
    +    i = ma
    +  end
    +end
    +
    +### 堆排序 ###
    +def heap_sort(nums)
    +  # 建堆操作:堆化除叶节点以外的其他所有节点
    +  (nums.length / 2 - 1).downto(0) do |i|
    +    sift_down(nums, nums.length, i)
    +  end
    +  # 从堆中提取最大元素,循环 n-1 轮
    +  (nums.length - 1).downto(1) do |i|
    +    # 交换根节点与最右叶节点(交换首元素与尾元素)
    +    nums[0], nums[i] = nums[i], nums[0]
    +    # 以根节点为起点,从顶至底进行堆化
    +    sift_down(nums, i, 0)
    +  end
    +end
    +
    +
    +
    +
    heap_sort.zig
    [class]{}-[func]{siftDown}
    +
    +[class]{}-[func]{heapSort}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.7.2   Algorithm characteristics

    +
      +
    • Time complexity is \(O(n \log n)\), non-adaptive sort: The heap creation uses \(O(n)\) time. Extracting the largest element from the heap takes \(O(\log n)\) time, looping for \(n - 1\) rounds.
    • +
    • Space complexity is \(O(1)\), in-place sort: A few pointer variables use \(O(1)\) space. The element swapping and heapifying operations are performed on the original array.
    • +
    • Non-stable sort: The relative positions of equal elements may change during the swapping of the heap's top and bottom elements.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/index.html b/en/chapter_sorting/index.html new file mode 100644 index 000000000..4e56a91ac --- /dev/null +++ b/en/chapter_sorting/index.html @@ -0,0 +1,3800 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Chapter 11.   Sorting - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    Chapter 11.   Sorting

    +

    Sorting

    +
    +

    Abstract

    +

    Sorting is like a magical key that turns chaos into order, enabling us to understand and handle data in a more efficient manner.

    +

    Whether it's simple ascending order or complex categorical arrangements, sorting reveals the harmonious beauty of data.

    +
    +

    Chapter contents

    + + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/insertion_sort.assets/insertion_operation.png b/en/chapter_sorting/insertion_sort.assets/insertion_operation.png new file mode 100644 index 0000000000000000000000000000000000000000..c6806c0ea78f8205cf9133ded4758a9c94a225b2 GIT binary patch literal 27207 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.4 Insertion sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.4   Insertion sort

    +

    Insertion sort is a simple sorting algorithm that works very much like the process of manually sorting a deck of cards.

    +

    Specifically, we select a pivot element from the unsorted interval, compare it with the elements in the sorted interval to its left, and insert the element into the correct position.

    +

    The Figure 11-6 shows the process of inserting an element into an array. Assuming the pivot element is base, we need to move all elements between the target index and base one position to the right, then assign base to the target index.

    +

    Single insertion operation

    +

    Figure 11-6   Single insertion operation

    + +

    11.4.1   Algorithm process

    +

    The overall process of insertion sort is shown in the following figure.

    +
      +
    1. Initially, the first element of the array is sorted.
    2. +
    3. The second element of the array is taken as base, and after inserting it into the correct position, the first two elements of the array are sorted.
    4. +
    5. The third element is taken as base, and after inserting it into the correct position, the first three elements of the array are sorted.
    6. +
    7. And so on, in the last round, the last element is taken as base, and after inserting it into the correct position, all elements are sorted.
    8. +
    +

    Insertion sort process

    +

    Figure 11-7   Insertion sort process

    + +

    Example code is as follows:

    +
    +
    +
    +
    insertion_sort.py
    def insertion_sort(nums: list[int]):
    +    """插入排序"""
    +    # 外循环:已排序区间为 [0, i-1]
    +    for i in range(1, len(nums)):
    +        base = nums[i]
    +        j = i - 1
    +        # 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while j >= 0 and nums[j] > base:
    +            nums[j + 1] = nums[j]  # 将 nums[j] 向右移动一位
    +            j -= 1
    +        nums[j + 1] = base  # 将 base 赋值到正确位置
    +
    +
    +
    +
    insertion_sort.cpp
    /* 插入排序 */
    +void insertionSort(vector<int> &nums) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for (int i = 1; i < nums.size(); i++) {
    +        int base = nums[i], j = i - 1;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > base) {
    +            nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
    +            j--;
    +        }
    +        nums[j + 1] = base; // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.java
    /* 插入排序 */
    +void insertionSort(int[] nums) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for (int i = 1; i < nums.length; i++) {
    +        int base = nums[i], j = i - 1;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > base) {
    +            nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
    +            j--;
    +        }
    +        nums[j + 1] = base;        // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.cs
    /* 插入排序 */
    +void InsertionSort(int[] nums) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for (int i = 1; i < nums.Length; i++) {
    +        int bas = nums[i], j = i - 1;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > bas) {
    +            nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
    +            j--;
    +        }
    +        nums[j + 1] = bas;         // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.go
    /* 插入排序 */
    +func insertionSort(nums []int) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for i := 1; i < len(nums); i++ {
    +        base := nums[i]
    +        j := i - 1
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        for j >= 0 && nums[j] > base {
    +            nums[j+1] = nums[j] // 将 nums[j] 向右移动一位
    +            j--
    +        }
    +        nums[j+1] = base // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.swift
    /* 插入排序 */
    +func insertionSort(nums: inout [Int]) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for i in nums.indices.dropFirst() {
    +        let base = nums[i]
    +        var j = i - 1
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while j >= 0, nums[j] > base {
    +            nums[j + 1] = nums[j] // 将 nums[j] 向右移动一位
    +            j -= 1
    +        }
    +        nums[j + 1] = base // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.js
    /* 插入排序 */
    +function insertionSort(nums) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for (let i = 1; i < nums.length; i++) {
    +        let base = nums[i],
    +            j = i - 1;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > base) {
    +            nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
    +            j--;
    +        }
    +        nums[j + 1] = base; // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.ts
    /* 插入排序 */
    +function insertionSort(nums: number[]): void {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for (let i = 1; i < nums.length; i++) {
    +        const base = nums[i];
    +        let j = i - 1;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > base) {
    +            nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
    +            j--;
    +        }
    +        nums[j + 1] = base; // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.dart
    /* 插入排序 */
    +void insertionSort(List<int> nums) {
    +  // 外循环:已排序区间为 [0, i-1]
    +  for (int i = 1; i < nums.length; i++) {
    +    int base = nums[i], j = i - 1;
    +    // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +    while (j >= 0 && nums[j] > base) {
    +      nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
    +      j--;
    +    }
    +    nums[j + 1] = base; // 将 base 赋值到正确位置
    +  }
    +}
    +
    +
    +
    +
    insertion_sort.rs
    /* 插入排序 */
    +fn insertion_sort(nums: &mut [i32]) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for i in 1..nums.len() {
    +        let (base, mut j) = (nums[i], (i - 1) as i32);
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while j >= 0 && nums[j as usize] > base {
    +            nums[(j + 1) as usize] = nums[j as usize]; // 将 nums[j] 向右移动一位
    +            j -= 1;
    +        }
    +        nums[(j + 1) as usize] = base; // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.c
    /* 插入排序 */
    +void insertionSort(int nums[], int size) {
    +    // 外循环:已排序区间为 [0, i-1]
    +    for (int i = 1; i < size; i++) {
    +        int base = nums[i], j = i - 1;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > base) {
    +            // 将 nums[j] 向右移动一位
    +            nums[j + 1] = nums[j];
    +            j--;
    +        }
    +        // 将 base 赋值到正确位置
    +        nums[j + 1] = base;
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.kt
    /* 插入排序 */
    +fun insertionSort(nums: IntArray) {
    +    //外循环: 已排序元素为 1, 2, ..., n
    +    for (i in nums.indices) {
    +        val base = nums[i]
    +        var j = i - 1
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 0 && nums[j] > base) {
    +            nums[j + 1] = nums[j] // 将 nums[j] 向右移动一位
    +            j--
    +        }
    +        nums[j + 1] = base        // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    insertion_sort.rb
    ### 插入排序 ###
    +def insertion_sort(nums)
    +  n = nums.length
    +  # 外循环:已排序区间为 [0, i-1]
    +  for i in 1...n
    +    base = nums[i]
    +    j = i - 1
    +    # 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +    while j >= 0 && nums[j] > base
    +      nums[j + 1] = nums[j] # 将 nums[j] 向右移动一位
    +      j -= 1
    +    end
    +    nums[j + 1] = base # 将 base 赋值到正确位置
    +  end
    +end
    +
    +
    +
    +
    insertion_sort.zig
    // 插入排序
    +fn insertionSort(nums: []i32) void {
    +    // 外循环:已排序区间为 [0, i-1]
    +    var i: usize = 1;
    +    while (i < nums.len) : (i += 1) {
    +        var base = nums[i];
    +        var j: usize = i;
    +        // 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
    +        while (j >= 1 and nums[j - 1] > base) : (j -= 1) {
    +            nums[j] = nums[j - 1];  // 将 nums[j] 向右移动一位
    +        }
    +        nums[j] = base;             // 将 base 赋值到正确位置
    +    }
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.4.2   Algorithm characteristics

    +
      +
    • Time complexity is \(O(n^2)\), adaptive sorting: In the worst case, each insertion operation requires \(n - 1\), \(n-2\), ..., \(2\), \(1\) loops, summing up to \((n - 1) n / 2\), thus the time complexity is \(O(n^2)\). In the case of ordered data, the insertion operation will terminate early. When the input array is completely ordered, insertion sort achieves the best time complexity of \(O(n)\).
    • +
    • Space complexity is \(O(1)\), in-place sorting: Pointers \(i\) and \(j\) use a constant amount of extra space.
    • +
    • Stable sorting: During the insertion operation, we insert elements to the right of equal elements, not changing their order.
    • +
    +

    11.4.3   Advantages of insertion sort

    +

    The time complexity of insertion sort is \(O(n^2)\), while the time complexity of quicksort, which we will study next, is \(O(n \log n)\). Although insertion sort has a higher time complexity, it is usually faster in cases of small data volumes.

    +

    This conclusion is similar to that for linear and binary search. Algorithms like quicksort that have a time complexity of \(O(n \log n)\) and are based on the divide-and-conquer strategy often involve more unit operations. In cases of small data volumes, the numerical values of \(n^2\) and \(n \log n\) are close, and complexity does not dominate, with the number of unit operations per round playing a decisive role.

    +

    In fact, many programming languages (such as Java) use insertion sort in their built-in sorting functions. The general approach is: for long arrays, use sorting algorithms based on divide-and-conquer strategies, such as quicksort; for short arrays, use insertion sort directly.

    +

    Although bubble sort, selection sort, and insertion sort all have a time complexity of \(O(n^2)\), in practice, insertion sort is used significantly more frequently than bubble sort and selection sort, mainly for the following reasons.

    +
      +
    • Bubble sort is based on element swapping, which requires the use of a temporary variable, involving 3 unit operations; insertion sort is based on element assignment, requiring only 1 unit operation. Therefore, the computational overhead of bubble sort is generally higher than that of insertion sort.
    • +
    • The time complexity of selection sort is always \(O(n^2)\). Given a set of partially ordered data, insertion sort is usually more efficient than selection sort.
    • +
    • Selection sort is unstable and cannot be applied to multi-level sorting.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_overview.png b/en/chapter_sorting/merge_sort.assets/merge_sort_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..7e71adce4e4aa74869d3a2c6d188262ff636ef96 GIT binary patch literal 25986 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 BoUQ-> literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step1.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..34d567f0cbb7bcad2c7e62a5133d5116cc3025ff GIT binary patch literal 8581 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 S{KU>*bF_-4a_MbM@P7fXL%28q literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step10.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step10.png new file mode 100644 index 0000000000000000000000000000000000000000..c870f0466de546356c50c9d337625df0e9239b5f GIT binary patch literal 14895 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 Yke|nM)2aq{TmOz#m9>;g6_Bt02l}J4_y7O^ literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step2.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..4e8d1e809504c0e95fc4f2ed1d6cdadb6d6f3a82 GIT binary patch literal 9346 zcmc(EXH-;8v+mv#$OA|c0Tsze6pR7&1tZBsmKR5=3%l00GH4 zN><6pkTcxzeeYfCu66G@XPxiI`Sy>Q-c{ArwY#gUx}FZzP*Xq<(GdXvfKXDD(*yuG zt_c|=fa3m+Kk!%p07$2ys`cpV>dLRq_xSi&TwFXfH1zA&uZxR|A3uI^`Qc`kdWhE;s>-_w@tE;QOzyImerz$Ec zMn*=LmzR5cdz+h^)z#JJ=H}|^>e|}c4<9}(D=Qlw9v&PVjE;_e_wJpksi}>PO>1jw zPfyS1&!2sKe4L$~_4M=-5)z!8oaE%>!o$OJb93wK>*M0$e*gYGIyxF09IU9Qn39sx z(b18fp6>4M-qzMuSXk)g68Wm6w5X3}-n#UlazR@#_j$=#!^r=O`)UrA+!cFA^ zNZ})Zkg?R@|KGfi&;R|Mt!(`CrdPwWx$&|(FOv6__t0a1-Q7RMk0!_%w?0d(k{-@89w z;+V}N8ZRv5n`?hEG+ z25E!v#*}tPf+Ib?)fml*0!2gG6gci4K2~f~W%B60K!G6Qf%vb=U#ic3wJF5) z|51Dn&XC>OB{_bjS@fc)` z6&Z^2po-ggpsz+@<0F3QjnijhPm33+f89@E{KH*PvbEP=&zY;fO%$jQmT|q~dHWrbG+&c2p$@5G>Zef%w`Y;-?cqMw+fy zi<@Aa&Ftp7f6n>j?p=nc>{{sRr|Be!i1o!g;R}|_u?cGFARx!)5a3cxCeEcbI;^=<|W zE7#>W1V0_wqhb>ruh30I)R;WV?%CBgJYynV&;X`{Dc#a_rN0A@~r+{pmV<|ha?S_Z)Hp!yEb#m;Gm0H@5#fXZJpZ6pMY z03Ro;lpg^hz^D*`al>{mZo$wQED$|@020Ed1_XlSNUvy!o&fHZR}&z1n1YiV=K#uG z00G933FO8pa14b-dHRBK*Ll!TJS31FLx^et2r^&P8-$fNNr=Xb_nE)oCQB>U+5Y8r zb<$5)w^$jIPH zxGHllImo#v9@<};mb}nc>-2@{6_6JJir@Man@`yK1III5ADkWhZU*8Vk4oD0>mN&5 zU+e{c+grr0dIQf4Hn^e}U5^YOLiHT+D-1{rt60btd$z3U3wNyc9&N03XlrCR&@k;< zlqYRNL`FO*Uo0E=Fw{B9>+W_{Vod;3?pfOx%GFyFXz;wJztM&Dn!FjU_kvl_eOd%# zcn;c929JWAip?+Zy^B=Q`qkCDWlP3~eO8JUR$Cjyy!wXCv(K%B8q6k649{v zDpPp*pi^HPxUsv|4$f%257W^%cmfvn!<-a%f%s$Isc>Uc;PY0iDmA$b!2mYl+fr=9 zuAklV-ZKbo&*M0@EaK?r$m(>%*+jAhu#3q1LNB~6I`i^Ko2V_GM1f&bptY1ofNJLv zV*oZB>~jH?!)BnpCxH1~Y0}xWl^bRHrW-@MC?T}RJ3-CTo6!=Sm{1J01n|0+kWg0N znuAlgMaC`Eha7$@IsS2(O>zS_`eDC^2qnhQGUkS=oU4+QvnGDgr-l3Y<;ftmEzxW!nWliz7z zlD7;Ih#2jTA}QiHWkEl;AjqBKamoTVW5|ZsA`V7?)8`FHtU*)c@?P!Zq!=S>MF>Yg zuquT1SLzT8+EO!xEOVIMaF*=`#s+vYDHNP~|C2MrzIuHD5Okd`1|V9zvoqL3BRaE` ziqpmh|klua`UQ^` zh!{(yvde^j8+MYS-u^5;;VF&D)QmJCM?Q%5x3rGS>BJ8P+9K&|Jggr?En?z{a00kCmuw3h*>Xwjmkov7-}vPlImO`98D^ z5OU|gj`3vssD3%jlF{-6WJSw_(8utOROxSTZVS_$CCO)+@*n^~MbhYnaKy}~k?f!# zYJnhbB5iTB;SbmK7c<_a<+!X8M44RG00fynZhUbKH0`SI+vUh?Km(lH$T!fkA=@SbC z*y^xU%U0fLAjI+U)C$;?Qw#s9YB2pR(lo_5(~!y3P67Ptsr9?{hGb0zaOoy}*zy=K zh3;(MmWC3j0D;&#w;iFleY5%@F){b)y7_Og2YPgOTN3Ws_)Z`KodZ0G<;GoST21I%!iUo?6IFUEan zFx41^gbZkS!=)bjDh;Q2C$>?%;{`chE62HbTB8ha?b8r`KbG#2nk!Kk-6wR4_jQQm zy-j5wY!zDdMt%mYYy|PJDn3Nd`GGks73N9zxJuNF(mF8+EB$d7?OHIYzSuEYXiCV4 zM(BcG`*qs05Ct1XG$3RI$8saIL5AEw05XZ|*`qY;stv@xX2bC$;7(ETD58ZQCMF4t zp*a3aDol#t6huTtC3#p|>;)kN)u|4Iy+%|4q-p6^G+E%L2+_h|0WFj^Z$>HEN9Paa zgb-B|{y=?6-R75)7qIO{#CQb*ovd*Qu^g8Wt#Apk50^2MaT!w(mocqz8FR3R49*Wv z(Rv^UfDHWTdy`*3-GLA+puye;U@wdu-8BSBl=1cs=Pab}zC#F*Qetv^T4Xe5HAtQS z-cyx-X&3nNleGD`kXkd*rTpS}o89*?%wPV=S9#0!?z85by0S!E`etVF+wRF!NzHGP zx&qW7B4lk|OYSZ=k3VP4lcCihH4dP9&B$bYhL{DE;PrJ3UDe%)AN$);5wGmkZqXV0 z0&n0>Cd6(odxDby;Q51o$KU!1vh-8Es}KFfO6i=KeT#>-L}}0P?;A zAYX9DAXYSz8-$q?GLowRzIqUXuecLs{Qm&!%=sAWrdxQ{Qznt$*C^(3`Fm{Z@_6}B z|H9JMZLi?dp)}dqw3lhTIGkXiy~cZZx-Y(Ae7bGA!TV~-P|~*eO;JkqR;Pop_tAP? zWK)HUwswZ0XYF^qrmDjV0BoRbo~*AeNqZ~WhgD`I%U;cil%ycAiBOjwMIrr;%!{kYVhY{6{8P?f|l(~&2nG;0`N3A5erXh zgU!uJbOkP`N;c`N$$}qnkQg6Tb~w>qkG{T8YwR?I%+fexz}R_z{0M5{RNDz7_p%@( z-&SzD4d4A5q4sLx(hYEBcUKg>`&|Z_ABV?37|z=~mZwo?d1LF88PhEc#(gwp(yTN_ z+l$j7a|O`~YZ6dZZiZ*{7`=>8!3!sZZks9_bTY}+W=d)2;U5)PMazY{-U?T8%&QlY zAYy87@F-^>^ZReWUfoL?{Uu=g(cc3tC}TA(8ZYUPrua^EhKHxxa^r5j6f^9582w?& zJt%Epw$U1QsU{tU`AO^1EzBnFJe06$;{$X0#_leSX61MeydMT`MKl7p0yY}Dn(kk_ zH$TU~uj>`F51sVO`+ItZYWzk78c#DItJOuWE-o~1oh2@``^|_$tlWnormq*kVJ7ob z)VA_J_Ao{5vp;;9(ubF5FC;l7!0u){K~WEX=?PNlk783*stE2$qiOALZC5yF~aMSr52)k-oOzL)Wrt0C|TnyK70#Vg*DJ*8doKr|AfA$z&;U zgX`Vsq8mk<+wq~awyi-_R^jYh8nd`)D?-- zRVKFRr?=^v=i%N7u<2p0%}Lw>?$e1(@^Vjm14oZ?@GJf*7`E$*ynl;DE^kvy-6P4w z@ffS;coY^`q*w=0dD>CO5U(jl=EY)wWwcDxC|oShWG-`27BF2(Qe8QAh#=KU7xEgS zsl{!TA>i(T0=vgG1|(NJA?MQo_wqrzqms+F^pvTu2y-8$ztCp77j1z*kY=RzE$rMt zeR6{09`WGK&;Uo5*OJKG!+=UOC}?o>$U)6f?8xS%c*pv!qvg8{k||{)=hWH|lI5j) zFZo7Jtr|sbNN(RYAlwdccyPxPuWFVmceH;k)C7*Nq1xmc{a!L_tDvKr=W&SUdM9k1 zLxb}`np!Gim0yE1S1LfAsqW%giqyLtt;_%@dEnJZUYw>fXYS=T9jmOw&goKb)Mxo0 zJ8mqd0o#TXcTUz>ISoI5{Fuj)tA$NMT~X-L+cKZrCH(s9{s)rrB(LaTnO4=XQ8RAk z0>0L3X>ih1&&01Tx%Cn9AHsf0!};s+ifW$;U5Shb8`idakK-n&^L#Cv-Mm2q z+ce7`D*zq+;b?CoB|h_lDl~u8x0LkKj|0*l`0XUw_24!%k+guy9jg+XSdfU&=tZjNwrDHs z`V&@&QAMyBOT-@2N4ZN6OA}-cwOc~_CPWuzLih~v*sUfv^}{rkC!i!HE36WHSk+G& zPMJ0gFf3amHAVFO;BFi1$j_*5HN5<80FkK~tak8{BSe#?$>Y1w57LrWMN&x39!tqb z`QBN5vqI|c#GGSx*TzG?(oGZUD#vN2hmZo$f&rZ=ehP~9h4rohFfQ!8wA)eV>P~`G zLZW{m9h|FZ0KA)P8YoVx+ux1H&dXGL*YE=C3ZAR5j1(+vkfv;oE(>&Ozpr;N6htep z2}eizo8_=;#0+MK7m9%KX(O8}K=K!!YinN~)DG~_5SQz={FSCOxh|tCQy|AdWs4E} zc~6cr_bFq``@0^M0zEZF1<|WNUM|h|K{^?1`#Q?+*euADEoVO|c_7CU8{iN!p!0Xw z)@dLS8Eg(zt4O_(R!tNYyA9zuX%-+$zs3J%vhH5hRnDK7>Sok^tkYGQv@T#->d+pn$58;q#OkTzx39lOM9Sw(iYQ!UBx-PAR3J4RezOG=FI!@p7X-V z3efSg)?l_EF^Y4w^pGOzyNAb%SXc z_9+M#q?)H{UB?0-jBm63t4EQlBtjibWCR6%dSB(_N{3pnu5MD-zGtfP7`J`4-lxTk z7GB*ryV~2yGEo2iaHQzd`q5UZ(wLLz?C8!$PyXShR380xMuG+7)#CY1XQiXuPaXbN zmwQI|VJ4Lz!`P4<@DOkud2XEbs_en$k@%LA&;|_-X_WYP97O($Lyx%2`rn{3GOGE2 z@w%KHA^9W)V<{^VrGm!91HL>U#1I0jf)V_;8H$@TTMol0+Tb1WdLe!@=7zWyj&-!( z2U@3W(r3aeCW&X5lZ?oU4@mX}K{nL+m6THgWzDWcZ5GoN4_rg;(vT=K#4csx#(gfM zl$%Bk98(nSFS=t$P4@R_x=fAdInhjIzYfn?=aO?jeH7h5w)eNFKVY^=IWuZsV~JgB zon)#;Du7hcTjS=T=}BaB`f%GrLMiG{qsd-1;nQ>{Xv3F5aVO0`gH&sSGtz-WvyxhM zB2!GT7IUnLD>zfd)9o=>85#pMeGR9H=9z$0zsJ%ddtBFM4quSnocWF~!pjZgpI}@% zup3gy_fGGn#FqWhR!gJB)8fnV{BtBLPVs(p_7N8TDJ=oV8X79@@4H$r$$mzm(R0;=#`<2h-< z-XwbIEUQGdBG9kwDbEg8Yfbrkco3Nm7^brJbl6}D9{=@)oAJ%Z>^Bw1Y#o;Xnr-)= z@{n7`hPC{QveK!yvu^aC-#`5b#o4LMfOO=i9bEzKgwftF(kTP(?oug-!~Vw@RSnn_E5alP%a0#vp2%8Tv#EK9uN|WkB<(OGE7H zwZV!6)7y457$OPPYD@yP=iTQ%beP79&=5OJ9U$Kdcw1-%I1cXr;BhKQdyS%uh=Q7k zNHV65g%`&TU+BsSagt_!-#7>g1@gLe*z;R~NN@=_RO+4%XcPFX)5(`M_juzvZrQJG zRAVSV9_)!d4PLe^JI2wMEvmtcK>4`uB_xV_hQbaY%ri=j-h?F308TDq(WnV7ELzQ2N( zv_wxKD*9X`I+{sQ4lv^sxCWdG=L~-Gcg?8arNG0fm!!W{%5li406Lcqi%kIqd1T}) zpySPCrOvIgtCL=9kyakLFgfPs9k&AI3llm&_*>fxtS!vA?9J z!b4h;Y<@9ovuh-m?*m~e+!%Z&y|qhWOV~9(US!S6=u@Ben+pSvaW%b%AIXHawyXE3 zg-?xET0;HPH$s?2`}>i9ner9>YW%DZ6r(XdhSlR^s?Y6>Uwv~M_TmX0WI-b*=+XJ#LF+PKUtVec!Gmy=)S0se3;_I)Smx>GFApaXEewOUJd7G# zKj6?xfhWGmg1)YQZu$P(S8;AG8|Y~h3W zo~?O5=%hA2H}v%`9M+%2C8jS5^e0j`j!FV^7oGrf72IpG+J8(w3s>g14J4?wP?-A( zI4s!(5JZHbBk)x7En?4_vqW{oZ9;;wo_6pz49E;Zc}=nB3cyv!Wq$&1x{0kjbob*uF=}7@yVQEx( zWi#$RC*rQ|kM}qiPAi&Mjri7^mn1O2P3kAtFGk=uX)t$w;^vj^KAuW=|pg-(w_sW?6^yrysrCd!fP?7neGX|K&hm!lUo|&!0FORxK`; zZCRQsd7*lh#;UAo{@2&J%gw%|BK|1QZ!VboIW<#Hin3R0h>k7!sdZ@yJg9ycotpf| zBs*kwf1YI3QR(-wm$zK&XJbVjU1J>t%eEnj@?mXTn3KTNkUw&Gvd)9`URD!NQPK&o z`O7uctZ7^diACSfl5DgvqXBt#`Z9^!6^IGG6B|2ms+Q(7+{wmjt@uu-Tm&3H3k+8m z>YWd^rJex8Uz@p;qF6sRd;#+xG`E5^P#l)9E$k z2o06^jzIwMoN-N9W~#7c25h=$DF@F*NG8sXrey&Tg7&^R-JbJ)_kB@y-n}o^{frELqw7Z-Ym{S$u&kS~#Q6SqU>SGGGn0~2C{aDC zR-aqI(VseebHiCH;wjtQPwj=Am($Er)TBTg%ddKgb4-ZgA4<$+y#I`km>U5j#%BO;a96af&3P{^Eg?+0bR3Wu zy@8{@TDDcEP1h+m6DM4#U4Lz!hjcbp2?O`*Fcba7OI|-?!oHxlDxXh>3jy>>qH2k;rKDDE4yVExm9IvJl6+>a zchE0x_kJkQeL|+%;}W>-;!#FKm zCIqN1U-DbQt;F~&kiMb~8-TbZQmU|P_uGmb?I8hfuoSM8A|9^d`pJg1)Dl|KG2MDNY_ zE^+)tAufqv{PMP8)?!Ku{(_CfGXUp8eXPBPd)nM2GO0-yHUQMP&_3T^%E-uJHtlA< z3q`Y#0&_xJ_OI!3@rTC3xzlf7Oi2ZD)b9MnPWR4%67yJ<%O8NuJn7$jwESF(I1L;!EUuHQruz_Z#k#_x z-q&OxMv@os$QRl}#DqQ}XQE%}J%;=^F1-d|HFHkxF}*O2WY#q=e*ymw(#d~9##A3J lME&6-2d^fY_`!cfO9@aJ@xtn~awLD=l^&_dmB^s{{udJt2J`>` literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step3.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..c25844dca9bb85e8dd731ec143ea4798afa02f8c GIT binary patch literal 9922 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step4.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..890a0e4977c82f0c94cfe9fdafa344dac60b1bf2 GIT binary patch literal 10210 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step5.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step5.png new file mode 100644 index 0000000000000000000000000000000000000000..67a3d88080689405b56c0988abbbdd9061c0a7fb GIT binary patch literal 11245 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step6.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa7dcfca8df54810f624805c84cfc18d24348f4 GIT binary patch literal 11992 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step7.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d94c13bfe4bd251d0c9dc570d500a367a38b32 GIT binary patch literal 12223 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step8.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..a25be5c344bdbee219cf736f8ec2d5195ee7f276 GIT binary patch literal 12346 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
    o zFP(`8{lN=2x!h;p3-2l>hQRqSSEQ*MMBtDS1^(wa;NL=-lNmsF_srrKDHINAMfCAMeWUcjUG}WESRt>fJ@nkmQ}mH(W7prf4hw}jk^0IfKsK{p)YU}~YbI$z@l9Wsd3S172A0OmOtQh9xZ@qmWgV0NBt&(>F>ktckTtQ)#Ofu2**RPW z(eCO>Uu0rDp={z3J=*#@&hF;%#G2a9#FnCi%-~!Qz-Oa zFOXnb43m4aNS*7KW&medv19)I{$+0gID}7P3iUAb+|6=FP*!L@TMl%w~>b?`uTGakMUv5K+>2?d-stc2D6|FMJYHuQJ90 z`}{}0rb#dbhBs?8HKqr|3Y&NeI~&Hnh5Vx~U11^@ZCBWdkz?UB*uf2;6|B8?SJRUf z1v*$gbxOH4lU_sJGepDe!LhT9TcL&m=hA9mO$4}nw(G4whTAF@MoKF9Yft5pcmrvM z|9Rw7l<}73Hx0XAr4(fCzPnc`ug!$Xlen_f3$`z%)ZMENB4(Q`bmnkSp3#Ry@>4yy zkUopeIk`pH$%cU83m$q74xJnvY)H7XwL&R#-I?cpk_)8ojQ&O<@%)BTU(fpN8_XHgTj*^TP z%6E^`7+`yRr)1vX%!4OM8A$hks(qbM>@w$BwHo}o31f`{ zPL5HJR`!)ti)?uY=MhhY;#0InaEH!Ha~P{JdVj@K9jQ4AG@k#|a<^HYN#YN5;9#>U zOUSJGP^ZG39xGx>CMDPB`IM!q*^#O2#NLVXJSH}87ytau zEkytY$7~yNNoeX=`LXK9);+i^DO#J4rfSw332Ci+v=7tUp4_5Y3TJ|#??fE3oq!*M zW>B;=47)fTBJ9sXMS|9k>1lmsZz^gYX*gCm@2Bm*Qf)|h&-sK5z44D|O< zK))Nr8&Y;(42&mnYfYzUUVH+pVeiHo_@$-K6n+lhscFy~$gEXQ1=(1wK-?pkZcS{m zUry1J)!Z{lt!&#>qxJYkbS~@ooJ&P_s3LXjz31Qq0*QKO)TfnT`K*1kWr&o)dNjp3 zdc~@Pm6pJC(&=-xe9F*r-eOI4xv6l!2lci1nH%NWhA#4-Jo@cov79lFekaHDS)zwc zCl8?sflMnJv|^MFL64wR2iie-l6C3go7;9X=H*24al$m*ts^G#uQ*liObBD|52ESf zp@~a2_i0;=!4f?gk=T@-*|kT|1ZT$fmhrp!j}3cUISFDmwpC6U+6%8;>?dBOOODXu zM}Oe>JK5aMR^^lMoi;wy3n@i;=yN@yCwosQI?1n3^Ci{Mql3yh7aOW)6{igjOMC$o z-9N=zE+Tm9L`8s!i|*mTvJoWsx+^_aU#t~J!}UD+@SuLW4is7GfQ2Powx4SrWM4EQaDV{bJzwF%<3SE0nR zc8Ss6pfd0Kud#IzL%R%yL)bW{nyuRyfjjkzq2qa2@n*+ry@cwdb9F9PE5s*+dbKTv}~asODLN$Ew$Ux1>V+QVX5)A#=a77)^V literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/merge_sort.assets/merge_sort_step9.png b/en/chapter_sorting/merge_sort.assets/merge_sort_step9.png new file mode 100644 index 0000000000000000000000000000000000000000..129d4506fb3c424467bfedd043271d7cfd1e7c6d GIT binary patch literal 13181 zcmc(`bx@p7uqgVi;O?H_4k5U+xJz&dfhEC$1rN@W1PcTWENaq&vf^6_xH_qPfu@@o{lO3E-fwq00io4O8NkRf$oBb zu_5TMivm6y004>TX&EZt-`~G!3ca|vh>D7ml9KA`>RMi2{`~nfavquApNHCCYHx49 zzP`S_yEQU0%FD}JSy`#CuU}YL=;-Je7#P^z-X0qpv#_w3oSdAUogE$?K07>b zcQU&D_=rFtG&MCgMLAudgpFD|>o++S}Xv;>C-?!orO1^q82K)x(v_ z(TcFJu#4-9{r&xjh=`z|ptZF%KR>^Xjg6l_e<~>{$;il@pPw)6E{t!Cr=_KpmX;o! zA4RrBgy)AXEiJ`�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 Q + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.6 Merge sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.6   Merge sort

    +

    Merge sort is a sorting algorithm based on the divide-and-conquer strategy, involving the "divide" and "merge" phases shown in the following figure.

    +
      +
    1. Divide phase: Recursively split the array from the midpoint, transforming the sorting problem of a long array into that of shorter arrays.
    2. +
    3. Merge phase: Stop dividing when the length of the sub-array is 1, start merging, and continuously combine two shorter ordered arrays into one longer ordered array until the process is complete.
    4. +
    +

    The divide and merge phases of merge sort

    +

    Figure 11-10   The divide and merge phases of merge sort

    + +

    11.6.1   Algorithm workflow

    +

    As shown in the Figure 11-11 , the "divide phase" recursively splits the array from the midpoint into two sub-arrays from top to bottom.

    +
      +
    1. Calculate the midpoint mid, recursively divide the left sub-array (interval [left, mid]) and the right sub-array (interval [mid + 1, right]).
    2. +
    3. Continue with step 1. recursively until the sub-array interval length is 1 to stop.
    4. +
    +

    The "merge phase" combines the left and right sub-arrays into a single ordered array from bottom to top. Note that merging starts with sub-arrays of length 1, and each sub-array is ordered during the merge phase.

    +
    +
    +
    +

    Merge sort process

    +
    +
    +

    merge_sort_step2

    +
    +
    +

    merge_sort_step3

    +
    +
    +

    merge_sort_step4

    +
    +
    +

    merge_sort_step5

    +
    +
    +

    merge_sort_step6

    +
    +
    +

    merge_sort_step7

    +
    +
    +

    merge_sort_step8

    +
    +
    +

    merge_sort_step9

    +
    +
    +

    merge_sort_step10

    +
    +
    +
    +

    Figure 11-11   Merge sort process

    + +

    It is observed that the order of recursion in merge sort is consistent with the post-order traversal of a binary tree.

    +
      +
    • Post-order traversal: First recursively traverse the left subtree, then the right subtree, and finally handle the root node.
    • +
    • Merge sort: First recursively handle the left sub-array, then the right sub-array, and finally perform the merge.
    • +
    +

    The implementation of merge sort is shown in the following code. Note that the interval to be merged in nums is [left, right], while the corresponding interval in tmp is [0, right - left].

    +
    +
    +
    +
    merge_sort.py
    def merge(nums: list[int], left: int, mid: int, right: int):
    +    """合并左子数组和右子数组"""
    +    # 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    # 创建一个临时数组 tmp ,用于存放合并后的结果
    +    tmp = [0] * (right - left + 1)
    +    # 初始化左子数组和右子数组的起始索引
    +    i, j, k = left, mid + 1, 0
    +    # 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while i <= mid and j <= right:
    +        if nums[i] <= nums[j]:
    +            tmp[k] = nums[i]
    +            i += 1
    +        else:
    +            tmp[k] = nums[j]
    +            j += 1
    +        k += 1
    +    # 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while i <= mid:
    +        tmp[k] = nums[i]
    +        i += 1
    +        k += 1
    +    while j <= right:
    +        tmp[k] = nums[j]
    +        j += 1
    +        k += 1
    +    # 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for k in range(0, len(tmp)):
    +        nums[left + k] = tmp[k]
    +
    +def merge_sort(nums: list[int], left: int, right: int):
    +    """归并排序"""
    +    # 终止条件
    +    if left >= right:
    +        return  # 当子数组长度为 1 时终止递归
    +    # 划分阶段
    +    mid = (left + right) // 2  # 计算中点
    +    merge_sort(nums, left, mid)  # 递归左子数组
    +    merge_sort(nums, mid + 1, right)  # 递归右子数组
    +    # 合并阶段
    +    merge(nums, left, mid, right)
    +
    +
    +
    +
    merge_sort.cpp
    /* 合并左子数组和右子数组 */
    +void merge(vector<int> &nums, int left, int mid, int right) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    vector<int> tmp(right - left + 1);
    +    // 初始化左子数组和右子数组的起始索引
    +    int i = left, j = mid + 1, k = 0;
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j])
    +            tmp[k++] = nums[i++];
    +        else
    +            tmp[k++] = nums[j++];
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++];
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++];
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (k = 0; k < tmp.size(); k++) {
    +        nums[left + k] = tmp[k];
    +    }
    +}
    +
    +/* 归并排序 */
    +void mergeSort(vector<int> &nums, int left, int right) {
    +    // 终止条件
    +    if (left >= right)
    +        return; // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    int mid = (left + right) / 2;    // 计算中点
    +    mergeSort(nums, left, mid);      // 递归左子数组
    +    mergeSort(nums, mid + 1, right); // 递归右子数组
    +    // 合并阶段
    +    merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.java
    /* 合并左子数组和右子数组 */
    +void merge(int[] nums, int left, int mid, int right) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    int[] tmp = new int[right - left + 1];
    +    // 初始化左子数组和右子数组的起始索引
    +    int i = left, j = mid + 1, k = 0;
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j])
    +            tmp[k++] = nums[i++];
    +        else
    +            tmp[k++] = nums[j++];
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++];
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++];
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (k = 0; k < tmp.length; k++) {
    +        nums[left + k] = tmp[k];
    +    }
    +}
    +
    +/* 归并排序 */
    +void mergeSort(int[] nums, int left, int right) {
    +    // 终止条件
    +    if (left >= right)
    +        return; // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    int mid = (left + right) / 2; // 计算中点
    +    mergeSort(nums, left, mid); // 递归左子数组
    +    mergeSort(nums, mid + 1, right); // 递归右子数组
    +    // 合并阶段
    +    merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.cs
    /* 合并左子数组和右子数组 */
    +void Merge(int[] nums, int left, int mid, int right) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    int[] tmp = new int[right - left + 1];
    +    // 初始化左子数组和右子数组的起始索引
    +    int i = left, j = mid + 1, k = 0;
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j])
    +            tmp[k++] = nums[i++];
    +        else
    +            tmp[k++] = nums[j++];
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++];
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++];
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (k = 0; k < tmp.Length; ++k) {
    +        nums[left + k] = tmp[k];
    +    }
    +}
    +
    +/* 归并排序 */
    +void MergeSort(int[] nums, int left, int right) {
    +    // 终止条件
    +    if (left >= right) return;       // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    int mid = (left + right) / 2;    // 计算中点
    +    MergeSort(nums, left, mid);      // 递归左子数组
    +    MergeSort(nums, mid + 1, right); // 递归右子数组
    +    // 合并阶段
    +    Merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.go
    /* 合并左子数组和右子数组 */
    +func merge(nums []int, left, mid, right int) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    tmp := make([]int, right-left+1)
    +    // 初始化左子数组和右子数组的起始索引
    +    i, j, k := left, mid+1, 0
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    for i <= mid && j <= right {
    +        if nums[i] <= nums[j] {
    +            tmp[k] = nums[i]
    +            i++
    +        } else {
    +            tmp[k] = nums[j]
    +            j++
    +        }
    +        k++
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    for i <= mid {
    +        tmp[k] = nums[i]
    +        i++
    +        k++
    +    }
    +    for j <= right {
    +        tmp[k] = nums[j]
    +        j++
    +        k++
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for k := 0; k < len(tmp); k++ {
    +        nums[left+k] = tmp[k]
    +    }
    +}
    +
    +/* 归并排序 */
    +func mergeSort(nums []int, left, right int) {
    +    // 终止条件
    +    if left >= right {
    +        return
    +    }
    +    // 划分阶段
    +    mid := (left + right) / 2
    +    mergeSort(nums, left, mid)
    +    mergeSort(nums, mid+1, right)
    +    // 合并阶段
    +    merge(nums, left, mid, right)
    +}
    +
    +
    +
    +
    merge_sort.swift
    /* 合并左子数组和右子数组 */
    +func merge(nums: inout [Int], left: Int, mid: Int, right: Int) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    var tmp = Array(repeating: 0, count: right - left + 1)
    +    // 初始化左子数组和右子数组的起始索引
    +    var i = left, j = mid + 1, k = 0
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while i <= mid, j <= right {
    +        if nums[i] <= nums[j] {
    +            tmp[k] = nums[i]
    +            i += 1
    +        } else {
    +            tmp[k] = nums[j]
    +            j += 1
    +        }
    +        k += 1
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while i <= mid {
    +        tmp[k] = nums[i]
    +        i += 1
    +        k += 1
    +    }
    +    while j <= right {
    +        tmp[k] = nums[j]
    +        j += 1
    +        k += 1
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for k in tmp.indices {
    +        nums[left + k] = tmp[k]
    +    }
    +}
    +
    +/* 归并排序 */
    +func mergeSort(nums: inout [Int], left: Int, right: Int) {
    +    // 终止条件
    +    if left >= right { // 当子数组长度为 1 时终止递归
    +        return
    +    }
    +    // 划分阶段
    +    let mid = (left + right) / 2 // 计算中点
    +    mergeSort(nums: &nums, left: left, right: mid) // 递归左子数组
    +    mergeSort(nums: &nums, left: mid + 1, right: right) // 递归右子数组
    +    // 合并阶段
    +    merge(nums: &nums, left: left, mid: mid, right: right)
    +}
    +
    +
    +
    +
    merge_sort.js
    /* 合并左子数组和右子数组 */
    +function merge(nums, left, mid, right) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    const tmp = new Array(right - left + 1);
    +    // 初始化左子数组和右子数组的起始索引
    +    let i = left,
    +        j = mid + 1,
    +        k = 0;
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j]) {
    +            tmp[k++] = nums[i++];
    +        } else {
    +            tmp[k++] = nums[j++];
    +        }
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++];
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++];
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (k = 0; k < tmp.length; k++) {
    +        nums[left + k] = tmp[k];
    +    }
    +}
    +
    +/* 归并排序 */
    +function mergeSort(nums, left, right) {
    +    // 终止条件
    +    if (left >= right) return; // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    let mid = Math.floor((left + right) / 2); // 计算中点
    +    mergeSort(nums, left, mid); // 递归左子数组
    +    mergeSort(nums, mid + 1, right); // 递归右子数组
    +    // 合并阶段
    +    merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.ts
    /* 合并左子数组和右子数组 */
    +function merge(nums: number[], left: number, mid: number, right: number): void {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    const tmp = new Array(right - left + 1);
    +    // 初始化左子数组和右子数组的起始索引
    +    let i = left,
    +        j = mid + 1,
    +        k = 0;
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j]) {
    +            tmp[k++] = nums[i++];
    +        } else {
    +            tmp[k++] = nums[j++];
    +        }
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++];
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++];
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (k = 0; k < tmp.length; k++) {
    +        nums[left + k] = tmp[k];
    +    }
    +}
    +
    +/* 归并排序 */
    +function mergeSort(nums: number[], left: number, right: number): void {
    +    // 终止条件
    +    if (left >= right) return; // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    let mid = Math.floor((left + right) / 2); // 计算中点
    +    mergeSort(nums, left, mid); // 递归左子数组
    +    mergeSort(nums, mid + 1, right); // 递归右子数组
    +    // 合并阶段
    +    merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.dart
    /* 合并左子数组和右子数组 */
    +void merge(List<int> nums, int left, int mid, int right) {
    +  // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +  // 创建一个临时数组 tmp ,用于存放合并后的结果
    +  List<int> tmp = List.filled(right - left + 1, 0);
    +  // 初始化左子数组和右子数组的起始索引
    +  int i = left, j = mid + 1, k = 0;
    +  // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +  while (i <= mid && j <= right) {
    +    if (nums[i] <= nums[j])
    +      tmp[k++] = nums[i++];
    +    else
    +      tmp[k++] = nums[j++];
    +  }
    +  // 将左子数组和右子数组的剩余元素复制到临时数组中
    +  while (i <= mid) {
    +    tmp[k++] = nums[i++];
    +  }
    +  while (j <= right) {
    +    tmp[k++] = nums[j++];
    +  }
    +  // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +  for (k = 0; k < tmp.length; k++) {
    +    nums[left + k] = tmp[k];
    +  }
    +}
    +
    +/* 归并排序 */
    +void mergeSort(List<int> nums, int left, int right) {
    +  // 终止条件
    +  if (left >= right) return; // 当子数组长度为 1 时终止递归
    +  // 划分阶段
    +  int mid = (left + right) ~/ 2; // 计算中点
    +  mergeSort(nums, left, mid); // 递归左子数组
    +  mergeSort(nums, mid + 1, right); // 递归右子数组
    +  // 合并阶段
    +  merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.rs
    /* 合并左子数组和右子数组 */
    +fn merge(nums: &mut [i32], left: usize, mid: usize, right: usize) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    let tmp_size = right - left + 1;
    +    let mut tmp = vec![0; tmp_size];
    +    // 初始化左子数组和右子数组的起始索引
    +    let (mut i, mut j, mut k) = (left, mid + 1, 0);
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while i <= mid && j <= right {
    +        if nums[i] <= nums[j] {
    +            tmp[k] = nums[i];
    +            i += 1;
    +        } else {
    +            tmp[k] = nums[j];
    +            j += 1;
    +        }
    +        k += 1;
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while i <= mid {
    +        tmp[k] = nums[i];
    +        k += 1;
    +        i += 1;
    +    }
    +    while j <= right {
    +        tmp[k] = nums[j];
    +        k += 1;
    +        j += 1;
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for k in 0..tmp_size {
    +        nums[left + k] = tmp[k];
    +    }
    +}
    +
    +/* 归并排序 */
    +fn merge_sort(nums: &mut [i32], left: usize, right: usize) {
    +    // 终止条件
    +    if left >= right {
    +        return; // 当子数组长度为 1 时终止递归
    +    }
    +
    +    // 划分阶段
    +    let mid = (left + right) / 2; // 计算中点
    +    merge_sort(nums, left, mid); // 递归左子数组
    +    merge_sort(nums, mid + 1, right); // 递归右子数组
    +
    +    // 合并阶段
    +    merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.c
    /* 合并左子数组和右子数组 */
    +void merge(int *nums, int left, int mid, int right) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    int tmpSize = right - left + 1;
    +    int *tmp = (int *)malloc(tmpSize * sizeof(int));
    +    // 初始化左子数组和右子数组的起始索引
    +    int i = left, j = mid + 1, k = 0;
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j]) {
    +            tmp[k++] = nums[i++];
    +        } else {
    +            tmp[k++] = nums[j++];
    +        }
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++];
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++];
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (k = 0; k < tmpSize; ++k) {
    +        nums[left + k] = tmp[k];
    +    }
    +    // 释放内存
    +    free(tmp);
    +}
    +
    +/* 归并排序 */
    +void mergeSort(int *nums, int left, int right) {
    +    // 终止条件
    +    if (left >= right)
    +        return; // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    int mid = (left + right) / 2;    // 计算中点
    +    mergeSort(nums, left, mid);      // 递归左子数组
    +    mergeSort(nums, mid + 1, right); // 递归右子数组
    +    // 合并阶段
    +    merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    merge_sort.kt
    /* 合并左子数组和右子数组 */
    +fun merge(nums: IntArray, left: Int, mid: Int, right: Int) {
    +    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +    // 创建一个临时数组 tmp ,用于存放合并后的结果
    +    val tmp = IntArray(right - left + 1)
    +    // 初始化左子数组和右子数组的起始索引
    +    var i = left
    +    var j = mid + 1
    +    var k = 0
    +    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +    while (i <= mid && j <= right) {
    +        if (nums[i] <= nums[j])
    +            tmp[k++] = nums[i++]
    +        else 
    +            tmp[k++] = nums[j++]
    +    }
    +    // 将左子数组和右子数组的剩余元素复制到临时数组中
    +    while (i <= mid) {
    +        tmp[k++] = nums[i++]
    +    }
    +    while (j <= right) {
    +        tmp[k++] = nums[j++]
    +    }
    +    // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +    for (l in tmp.indices) {
    +        nums[left + l] = tmp[l]
    +    }
    +}
    +
    +/* 归并排序 */
    +fun mergeSort(nums: IntArray, left: Int, right: Int) {
    +    // 终止条件
    +    if (left >= right) return  // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    val mid = (left + right) / 2 // 计算中点
    +    mergeSort(nums, left, mid) // 递归左子数组
    +    mergeSort(nums, mid + 1, right) // 递归右子数组
    +    // 合并阶段
    +    merge(nums, left, mid, right)
    +}
    +
    +
    +
    +
    merge_sort.rb
    ### 合并左子数组和右子数组 ###
    +def merge(nums, left, mid, right)
    +  # 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    +  # 创建一个临时数组 tmp,用于存放合并后的结果
    +  tmp = Array.new(right - left + 1, 0)
    +  # 初始化左子数组和右子数组的起始索引
    +  i, j, k = left, mid + 1, 0
    +  # 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    +  while i <= mid && j <= right
    +    if nums[i] <= nums[j]
    +      tmp[k] = nums[i]
    +      i += 1
    +    else
    +      tmp[k] = nums[j]
    +      j += 1
    +    end
    +    k += 1
    +  end
    +  # 将左子数组和右子数组的剩余元素复制到临时数组中
    +  while i <= mid
    +    tmp[k] = nums[i]
    +    i += 1
    +    k += 1
    +  end
    +  while j <= right
    +    tmp[k] = nums[j]
    +    j += 1
    +    k += 1
    +  end
    +  # 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间
    +  (0...tmp.length).each do |k|
    +    nums[left + k] = tmp[k]
    +  end
    +end
    +
    +### 归并排序 ###
    +def merge_sort(nums, left, right)
    +  # 终止条件
    +  # 当子数组长度为 1 时终止递归
    +  return if left >= right
    +  # 划分阶段
    +  mid = (left + right) / 2 # 计算中点
    +  merge_sort(nums, left, mid) # 递归左子数组
    +  merge_sort(nums, mid + 1, right) # 递归右子数组
    +  # 合并阶段
    +  merge(nums, left, mid, right)
    +end
    +
    +
    +
    +
    merge_sort.zig
    // 合并左子数组和右子数组
    +// 左子数组区间 [left, mid]
    +// 右子数组区间 [mid + 1, right]
    +fn merge(nums: []i32, left: usize, mid: usize, right: usize) !void {
    +    // 初始化辅助数组
    +    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    +    defer mem_arena.deinit();
    +    const mem_allocator = mem_arena.allocator();
    +    var tmp = try mem_allocator.alloc(i32, right + 1 - left);
    +    std.mem.copy(i32, tmp, nums[left..right+1]);
    +    // 左子数组的起始索引和结束索引  
    +    var leftStart = left - left;
    +    var leftEnd = mid - left;
    +    // 右子数组的起始索引和结束索引       
    +    var rightStart = mid + 1 - left;
    +    var rightEnd = right - left;
    +    // i, j 分别指向左子数组、右子数组的首元素
    +    var i = leftStart;
    +    var j = rightStart;
    +    // 通过覆盖原数组 nums 来合并左子数组和右子数组
    +    var k = left;
    +    while (k <= right) : (k += 1) {
    +        // 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
    +        if (i > leftEnd) {
    +            nums[k] = tmp[j];
    +            j += 1;
    +        // 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
    +        } else if  (j > rightEnd or tmp[i] <= tmp[j]) {
    +            nums[k] = tmp[i];
    +            i += 1;
    +        // 否则,若“左右子数组都未全部合并完”且“左子数组元素 > 右子数组元素”,则选取右子数组元素,并且 j++
    +        } else {
    +            nums[k] = tmp[j];
    +            j += 1;
    +        }
    +    }
    +}
    +
    +// 归并排序
    +fn mergeSort(nums: []i32, left: usize, right: usize) !void {
    +    // 终止条件
    +    if (left >= right) return;              // 当子数组长度为 1 时终止递归
    +    // 划分阶段
    +    var mid = (left + right) / 2;           // 计算中点
    +    try mergeSort(nums, left, mid);         // 递归左子数组
    +    try mergeSort(nums, mid + 1, right);    // 递归右子数组
    +    // 合并阶段
    +    try merge(nums, left, mid, right);
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.6.2   Algorithm characteristics

    +
      +
    • Time complexity of \(O(n \log n)\), non-adaptive sort: The division creates a recursion tree of height \(\log n\), with each layer merging a total of \(n\) operations, resulting in an overall time complexity of \(O(n \log n)\).
    • +
    • Space complexity of \(O(n)\), non-in-place sort: The recursion depth is \(\log n\), using \(O(\log n)\) stack frame space. The merging operation requires auxiliary arrays, using an additional space of \(O(n)\).
    • +
    • Stable sort: During the merging process, the order of equal elements remains unchanged.
    • +
    +

    11.6.3   Linked List sorting

    +

    For linked lists, merge sort has significant advantages over other sorting algorithms, optimizing the space complexity of the linked list sorting task to \(O(1)\).

    +
      +
    • Divide phase: "Iteration" can be used instead of "recursion" to perform the linked list division work, thus saving the stack frame space used by recursion.
    • +
    • Merge phase: In linked lists, node addition and deletion operations can be achieved by changing references (pointers), so no extra lists need to be created during the merge phase (combining two short ordered lists into one long ordered list).
    • +
    +

    Detailed implementation details are complex, and interested readers can consult related materials for learning.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step1.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..242ff0d0aaf2a32d200c7c2ea74b1f91b859ea4f GIT binary patch literal 31804 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 z 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step2.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..27a829600de45a4b53d9a9b4300ccf40956373b8 GIT binary patch literal 31803 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 axB~!oeh_n+avJ^vP?pztRU>N_`hNgx%V-Ax literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step3.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..44a80612d19d06e8d5fc8a78fd6d4261c3c8a771 GIT binary patch literal 31739 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step4.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..41af011229998ceca0ce23ca3a1faf39bef0f7c2 GIT binary patch literal 32538 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step6.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..546d67a58ce633306e8fd1b478703509e29fb4a3 GIT binary patch literal 31883 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 Op(v{+Q!Ql@@_zslE3XFt literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step7.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..44975cc8272ccb8d187353183a4402191750f145 GIT binary patch literal 31756 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 Kt(LY3{(k`M$+BPo literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step8.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..ad2014f8d29f7c8e5d4611288ac5d9e99954448f GIT binary patch literal 32688 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 Q|CytTvT8D4q|8J92bG#(!~g&Q literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort.assets/pivot_division_step9.png b/en/chapter_sorting/quick_sort.assets/pivot_division_step9.png new file mode 100644 index 0000000000000000000000000000000000000000..e226b88bed54eb90fa9dfd5a1b67f946f865916f GIT binary patch literal 14662 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 d{=eT?K%PntIguw4ef$TPlU9{e0GoRo0 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 EKNW;~g8%>k literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/quick_sort/index.html b/en/chapter_sorting/quick_sort/index.html new file mode 100644 index 000000000..c5380303f --- /dev/null +++ b/en/chapter_sorting/quick_sort/index.html @@ -0,0 +1,5199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.5 Quick sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.5   Quick sort

    +

    Quick sort is a sorting algorithm based on the divide and conquer strategy, known for its efficiency and wide application.

    +

    The core operation of quick sort is "pivot partitioning," aiming to: select an element from the array as the "pivot," move all elements smaller than the pivot to its left, and move elements greater than the pivot to its right. Specifically, the pivot partitioning process is illustrated as follows.

    +
      +
    1. Select the leftmost element of the array as the pivot, and initialize two pointers i and j at both ends of the array.
    2. +
    3. Set up a loop where each round uses i (j) to find the first element larger (smaller) than the pivot, then swap these two elements.
    4. +
    5. Repeat step 2. until i and j meet, finally swap the pivot to the boundary between the two sub-arrays.
    6. +
    +
    +
    +
    +

    Pivot division process

    +
    +
    +

    pivot_division_step2

    +
    +
    +

    pivot_division_step3

    +
    +
    +

    pivot_division_step4

    +
    +
    +

    pivot_division_step5

    +
    +
    +

    pivot_division_step6

    +
    +
    +

    pivot_division_step7

    +
    +
    +

    pivot_division_step8

    +
    +
    +

    pivot_division_step9

    +
    +
    +
    +

    Figure 11-8   Pivot division process

    + +

    After the pivot partitioning, the original array is divided into three parts: left sub-array, pivot, and right sub-array, satisfying "any element in the left sub-array \(\leq\) pivot \(\leq\) any element in the right sub-array." Therefore, we only need to sort these two sub-arrays next.

    +
    +

    Quick sort's divide and conquer strategy

    +

    The essence of pivot partitioning is to simplify a longer array's sorting problem into two shorter arrays' sorting problems.

    +
    +
    +
    +
    +
    quick_sort.py
    def partition(self, nums: list[int], left: int, right: int) -> int:
    +    """哨兵划分"""
    +    # 以 nums[left] 为基准数
    +    i, j = left, right
    +    while i < j:
    +        while i < j and nums[j] >= nums[left]:
    +            j -= 1  # 从右向左找首个小于基准数的元素
    +        while i < j and nums[i] <= nums[left]:
    +            i += 1  # 从左向右找首个大于基准数的元素
    +        # 元素交换
    +        nums[i], nums[j] = nums[j], nums[i]
    +    # 将基准数交换至两子数组的分界线
    +    nums[i], nums[left] = nums[left], nums[i]
    +    return i  # 返回基准数的索引
    +
    +
    +
    +
    quick_sort.cpp
    /* 元素交换 */
    +void swap(vector<int> &nums, int i, int j) {
    +    int tmp = nums[i];
    +    nums[i] = nums[j];
    +    nums[j] = tmp;
    +}
    +
    +/* 哨兵划分 */
    +int partition(vector<int> &nums, int left, int right) {
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--; // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j); // 交换这两个元素
    +    }
    +    swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i;            // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.java
    /* 元素交换 */
    +void swap(int[] nums, int i, int j) {
    +    int tmp = nums[i];
    +    nums[i] = nums[j];
    +    nums[j] = tmp;
    +}
    +
    +/* 哨兵划分 */
    +int partition(int[] nums, int left, int right) {
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--;          // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j); // 交换这两个元素
    +    }
    +    swap(nums, i, left);  // 将基准数交换至两子数组的分界线
    +    return i;             // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.cs
    /* 元素交换 */
    +void Swap(int[] nums, int i, int j) {
    +    (nums[j], nums[i]) = (nums[i], nums[j]);
    +}
    +
    +/* 哨兵划分 */
    +int Partition(int[] nums, int left, int right) {
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--;          // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        Swap(nums, i, j); // 交换这两个元素
    +    }
    +    Swap(nums, i, left);  // 将基准数交换至两子数组的分界线
    +    return i;             // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.go
    /* 哨兵划分 */
    +func (q *quickSort) partition(nums []int, left, right int) int {
    +    // 以 nums[left] 为基准数
    +    i, j := left, right
    +    for i < j {
    +        for i < j && nums[j] >= nums[left] {
    +            j-- // 从右向左找首个小于基准数的元素
    +        }
    +        for i < j && nums[i] <= nums[left] {
    +            i++ // 从左向右找首个大于基准数的元素
    +        }
    +        // 元素交换
    +        nums[i], nums[j] = nums[j], nums[i]
    +    }
    +    // 将基准数交换至两子数组的分界线
    +    nums[i], nums[left] = nums[left], nums[i]
    +    return i // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.swift
    /* 哨兵划分 */
    +func partition(nums: inout [Int], left: Int, right: Int) -> Int {
    +    // 以 nums[left] 为基准数
    +    var i = left
    +    var j = right
    +    while i < j {
    +        while i < j, nums[j] >= nums[left] {
    +            j -= 1 // 从右向左找首个小于基准数的元素
    +        }
    +        while i < j, nums[i] <= nums[left] {
    +            i += 1 // 从左向右找首个大于基准数的元素
    +        }
    +        nums.swapAt(i, j) // 交换这两个元素
    +    }
    +    nums.swapAt(i, left) // 将基准数交换至两子数组的分界线
    +    return i // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.js
    /* 元素交换 */
    +swap(nums, i, j) {
    +    let tmp = nums[i];
    +    nums[i] = nums[j];
    +    nums[j] = tmp;
    +}
    +
    +/* 哨兵划分 */
    +partition(nums, left, right) {
    +    // 以 nums[left] 为基准数
    +    let i = left,
    +        j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left]) {
    +            j -= 1; // 从右向左找首个小于基准数的元素
    +        }
    +        while (i < j && nums[i] <= nums[left]) {
    +            i += 1; // 从左向右找首个大于基准数的元素
    +        }
    +        // 元素交换
    +        this.swap(nums, i, j); // 交换这两个元素
    +    }
    +    this.swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i; // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.ts
    /* 元素交换 */
    +swap(nums: number[], i: number, j: number): void {
    +    let tmp = nums[i];
    +    nums[i] = nums[j];
    +    nums[j] = tmp;
    +}
    +
    +/* 哨兵划分 */
    +partition(nums: number[], left: number, right: number): number {
    +    // 以 nums[left] 为基准数
    +    let i = left,
    +        j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left]) {
    +            j -= 1; // 从右向左找首个小于基准数的元素
    +        }
    +        while (i < j && nums[i] <= nums[left]) {
    +            i += 1; // 从左向右找首个大于基准数的元素
    +        }
    +        // 元素交换
    +        this.swap(nums, i, j); // 交换这两个元素
    +    }
    +    this.swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i; // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.dart
    /* 元素交换 */
    +void _swap(List<int> nums, int i, int j) {
    +  int tmp = nums[i];
    +  nums[i] = nums[j];
    +  nums[j] = tmp;
    +}
    +
    +/* 哨兵划分 */
    +int _partition(List<int> nums, int left, int right) {
    +  // 以 nums[left] 为基准数
    +  int i = left, j = right;
    +  while (i < j) {
    +    while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
    +    while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
    +    _swap(nums, i, j); // 交换这两个元素
    +  }
    +  _swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +  return i; // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.rs
    /* 哨兵划分 */
    +fn partition(nums: &mut [i32], left: usize, right: usize) -> usize {
    +    // 以 nums[left] 为基准数
    +    let (mut i, mut j) = (left, right);
    +    while i < j {
    +        while i < j && nums[j] >= nums[left] {
    +            j -= 1; // 从右向左找首个小于基准数的元素
    +        }
    +        while i < j && nums[i] <= nums[left] {
    +            i += 1; // 从左向右找首个大于基准数的元素
    +        }
    +        nums.swap(i, j); // 交换这两个元素
    +    }
    +    nums.swap(i, left); // 将基准数交换至两子数组的分界线
    +    i // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.c
    /* 元素交换 */
    +void swap(int nums[], int i, int j) {
    +    int tmp = nums[i];
    +    nums[i] = nums[j];
    +    nums[j] = tmp;
    +}
    +
    +/* 哨兵划分 */
    +int partition(int nums[], int left, int right) {
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left]) {
    +            j--; // 从右向左找首个小于基准数的元素
    +        }
    +        while (i < j && nums[i] <= nums[left]) {
    +            i++; // 从左向右找首个大于基准数的元素
    +        }
    +        // 交换这两个元素
    +        swap(nums, i, j);
    +    }
    +    // 将基准数交换至两子数组的分界线
    +    swap(nums, i, left);
    +    // 返回基准数的索引
    +    return i;
    +}
    +
    +
    +
    +
    quick_sort.kt
    /* 元素交换 */
    +fun swap(nums: IntArray, i: Int, j: Int) {
    +    val temp = nums[i]
    +    nums[i] = nums[j]
    +    nums[j] = temp
    +}
    +
    +/* 哨兵划分 */
    +fun partition(nums: IntArray, left: Int, right: Int): Int {
    +    // 以 nums[left] 为基准数
    +    var i = left
    +    var j = right
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--           // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++           // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j)  // 交换这两个元素
    +    }
    +    swap(nums, i, left)   // 将基准数交换至两子数组的分界线
    +    return i              // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.rb
    [class]{QuickSort}-[func]{partition}
    +
    +
    +
    +
    quick_sort.zig
    // 元素交换
    +fn swap(nums: []i32, i: usize, j: usize) void {
    +    var tmp = nums[i];
    +    nums[i] = nums[j];
    +    nums[j] = tmp;
    +}
    +
    +// 哨兵划分
    +fn partition(nums: []i32, left: usize, right: usize) usize {
    +    // 以 nums[left] 为基准数
    +    var i = left;
    +    var j = right;
    +    while (i < j) {
    +        while (i < j and nums[j] >= nums[left]) j -= 1; // 从右向左找首个小于基准数的元素
    +        while (i < j and nums[i] <= nums[left]) i += 1; // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j);   // 交换这两个元素
    +    }
    +    swap(nums, i, left);    // 将基准数交换至两子数组的分界线
    +    return i;               // 返回基准数的索引
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.5.1   Algorithm process

    +

    The overall process of quick sort is shown in the following figure.

    +
      +
    1. First, perform a "pivot partitioning" on the original array to obtain the unsorted left and right sub-arrays.
    2. +
    3. Then, recursively perform "pivot partitioning" on both the left and right sub-arrays.
    4. +
    5. Continue recursively until the sub-array length reaches 1, thus completing the sorting of the entire array.
    6. +
    +

    Quick sort process

    +

    Figure 11-9   Quick sort process

    + +
    +
    +
    +
    quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):
    +    """快速排序"""
    +    # 子数组长度为 1 时终止递归
    +    if left >= right:
    +        return
    +    # 哨兵划分
    +    pivot = self.partition(nums, left, right)
    +    # 递归左子数组、右子数组
    +    self.quick_sort(nums, left, pivot - 1)
    +    self.quick_sort(nums, pivot + 1, right)
    +
    +
    +
    +
    quick_sort.cpp
    /* 快速排序 */
    +void quickSort(vector<int> &nums, int left, int right) {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right)
    +        return;
    +    // 哨兵划分
    +    int pivot = partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    quickSort(nums, left, pivot - 1);
    +    quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.java
    /* 快速排序 */
    +void quickSort(int[] nums, int left, int right) {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right)
    +        return;
    +    // 哨兵划分
    +    int pivot = partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    quickSort(nums, left, pivot - 1);
    +    quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.cs
    /* 快速排序 */
    +void QuickSort(int[] nums, int left, int right) {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right)
    +        return;
    +    // 哨兵划分
    +    int pivot = Partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    QuickSort(nums, left, pivot - 1);
    +    QuickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.go
    /* 快速排序 */
    +func (q *quickSort) quickSort(nums []int, left, right int) {
    +    // 子数组长度为 1 时终止递归
    +    if left >= right {
    +        return
    +    }
    +    // 哨兵划分
    +    pivot := q.partition(nums, left, right)
    +    // 递归左子数组、右子数组
    +    q.quickSort(nums, left, pivot-1)
    +    q.quickSort(nums, pivot+1, right)
    +}
    +
    +
    +
    +
    quick_sort.swift
    /* 快速排序 */
    +func quickSort(nums: inout [Int], left: Int, right: Int) {
    +    // 子数组长度为 1 时终止递归
    +    if left >= right {
    +        return
    +    }
    +    // 哨兵划分
    +    let pivot = partition(nums: &nums, left: left, right: right)
    +    // 递归左子数组、右子数组
    +    quickSort(nums: &nums, left: left, right: pivot - 1)
    +    quickSort(nums: &nums, left: pivot + 1, right: right)
    +}
    +
    +
    +
    +
    quick_sort.js
    /* 快速排序 */
    +quickSort(nums, left, right) {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right) return;
    +    // 哨兵划分
    +    const pivot = this.partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    this.quickSort(nums, left, pivot - 1);
    +    this.quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.ts
    /* 快速排序 */
    +quickSort(nums: number[], left: number, right: number): void {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right) {
    +        return;
    +    }
    +    // 哨兵划分
    +    const pivot = this.partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    this.quickSort(nums, left, pivot - 1);
    +    this.quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.dart
    /* 快速排序 */
    +void quickSort(List<int> nums, int left, int right) {
    +  // 子数组长度为 1 时终止递归
    +  if (left >= right) return;
    +  // 哨兵划分
    +  int pivot = _partition(nums, left, right);
    +  // 递归左子数组、右子数组
    +  quickSort(nums, left, pivot - 1);
    +  quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.rs
    /* 快速排序 */
    +pub fn quick_sort(left: i32, right: i32, nums: &mut [i32]) {
    +    // 子数组长度为 1 时终止递归
    +    if left >= right {
    +        return;
    +    }
    +    // 哨兵划分
    +    let pivot = Self::partition(nums, left as usize, right as usize) as i32;
    +    // 递归左子数组、右子数组
    +    Self::quick_sort(left, pivot - 1, nums);
    +    Self::quick_sort(pivot + 1, right, nums);
    +}
    +
    +
    +
    +
    quick_sort.c
    /* 快速排序 */
    +void quickSort(int nums[], int left, int right) {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right) {
    +        return;
    +    }
    +    // 哨兵划分
    +    int pivot = partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    quickSort(nums, left, pivot - 1);
    +    quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    quick_sort.kt
    /* 快速排序 */
    +fun quickSort(nums: IntArray, left: Int, right: Int) {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right) return
    +    // 哨兵划分
    +    val pivot = partition(nums, left, right)
    +    // 递归左子数组、右子数组
    +    quickSort(nums, left, pivot - 1)
    +    quickSort(nums, pivot + 1, right)
    +}
    +
    +
    +
    +
    quick_sort.rb
    [class]{QuickSort}-[func]{quick_sort}
    +
    +
    +
    +
    quick_sort.zig
    // 快速排序
    +fn quickSort(nums: []i32, left: usize, right: usize) void {
    +    // 子数组长度为 1 时终止递归
    +    if (left >= right) return;
    +    // 哨兵划分
    +    var pivot = partition(nums, left, right);
    +    // 递归左子数组、右子数组
    +    quickSort(nums, left, pivot - 1);
    +    quickSort(nums, pivot + 1, right);
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.5.2   Algorithm features

    +
      +
    • Time complexity of \(O(n \log n)\), adaptive sorting: In average cases, the recursive levels of pivot partitioning are \(\log n\), and the total number of loops per level is \(n\), using \(O(n \log n)\) time overall. In the worst case, each round of pivot partitioning divides an array of length \(n\) into two sub-arrays of lengths \(0\) and \(n - 1\), reaching \(n\) recursive levels, and using \(O(n^2)\) time overall.
    • +
    • Space complexity of \(O(n)\), in-place sorting: In completely reversed input arrays, reaching the worst recursion depth of \(n\), using \(O(n)\) stack frame space. The sorting operation is performed on the original array without the aid of additional arrays.
    • +
    • Non-stable sorting: In the final step of pivot partitioning, the pivot may be swapped to the right of equal elements.
    • +
    +

    11.5.3   Why is quick sort fast

    +

    From its name, it is apparent that quick sort should have certain efficiency advantages. Although the average time complexity of quick sort is the same as "merge sort" and "heap sort," quick sort is generally more efficient, mainly for the following reasons.

    +
      +
    • Low probability of worst-case scenarios: Although the worst time complexity of quick sort is \(O(n^2)\), less stable than merge sort, in most cases, quick sort can operate under a time complexity of \(O(n \log n)\).
    • +
    • High cache usage efficiency: During the pivot partitioning operation, the system can load the entire sub-array into the cache, thus accessing elements more efficiently. In contrast, algorithms like "heap sort" need to access elements in a jumping manner, lacking this feature.
    • +
    • Small constant coefficient of complexity: Among the mentioned algorithms, quick sort has the fewest total number of comparisons, assignments, and swaps. This is similar to why "insertion sort" is faster than "bubble sort."
    • +
    +

    11.5.4   Pivot optimization

    +

    Quick sort's time efficiency may decrease under certain inputs. For example, if the input array is completely reversed, since we select the leftmost element as the pivot, after the pivot partitioning, the pivot is swapped to the array's right end, causing the left sub-array length to be \(n - 1\) and the right sub-array length to be \(0\). If this recursion continues, each round of pivot partitioning will have a sub-array length of \(0\), and the divide and conquer strategy fails, degrading quick sort to a form similar to "bubble sort."

    +

    To avoid this situation, we can optimize the strategy for selecting the pivot in the pivot partitioning. For instance, we can randomly select an element as the pivot. However, if luck is not on our side, and we keep selecting suboptimal pivots, the efficiency is still not satisfactory.

    +

    It's important to note that programming languages usually generate "pseudo-random numbers". If we construct a specific test case for a pseudo-random number sequence, the efficiency of quick sort may still degrade.

    +

    For further improvement, we can select three candidate elements (usually the first, last, and midpoint elements of the array), and use the median of these three candidate elements as the pivot. This significantly increases the probability that the pivot is "neither too small nor too large". Of course, we can also select more candidate elements to further enhance the algorithm's robustness. Using this method significantly reduces the probability of time complexity degradation to \(O(n^2)\).

    +

    Sample code is as follows:

    +
    +
    +
    +
    quick_sort.py
    def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:
    +    """选取三个候选元素的中位数"""
    +    l, m, r = nums[left], nums[mid], nums[right]
    +    if (l <= m <= r) or (r <= m <= l):
    +        return mid  # m 在 l 和 r 之间
    +    if (m <= l <= r) or (r <= l <= m):
    +        return left  # l 在 m 和 r 之间
    +    return right
    +
    +def partition(self, nums: list[int], left: int, right: int) -> int:
    +    """哨兵划分(三数取中值)"""
    +    # 以 nums[left] 为基准数
    +    med = self.median_three(nums, left, (left + right) // 2, right)
    +    # 将中位数交换至数组最左端
    +    nums[left], nums[med] = nums[med], nums[left]
    +    # 以 nums[left] 为基准数
    +    i, j = left, right
    +    while i < j:
    +        while i < j and nums[j] >= nums[left]:
    +            j -= 1  # 从右向左找首个小于基准数的元素
    +        while i < j and nums[i] <= nums[left]:
    +            i += 1  # 从左向右找首个大于基准数的元素
    +        # 元素交换
    +        nums[i], nums[j] = nums[j], nums[i]
    +    # 将基准数交换至两子数组的分界线
    +    nums[i], nums[left] = nums[left], nums[i]
    +    return i  # 返回基准数的索引
    +
    +
    +
    +
    quick_sort.cpp
    /* 选取三个候选元素的中位数 */
    +int medianThree(vector<int> &nums, int left, int mid, int right) {
    +    int l = nums[left], m = nums[mid], r = nums[right];
    +    if ((l <= m && m <= r) || (r <= m && m <= l))
    +        return mid; // m 在 l 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m))
    +        return left; // l 在 m 和 r 之间
    +    return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +int partition(vector<int> &nums, int left, int right) {
    +    // 选取三个候选元素的中位数
    +    int med = medianThree(nums, left, (left + right) / 2, right);
    +    // 将中位数交换至数组最左端
    +    swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--; // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j); // 交换这两个元素
    +    }
    +    swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i;            // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.java
    /* 选取三个候选元素的中位数 */
    +int medianThree(int[] nums, int left, int mid, int right) {
    +    int l = nums[left], m = nums[mid], r = nums[right];
    +    if ((l <= m && m <= r) || (r <= m && m <= l))
    +        return mid; // m 在 l 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m))
    +        return left; // l 在 m 和 r 之间
    +    return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +int partition(int[] nums, int left, int right) {
    +    // 选取三个候选元素的中位数
    +    int med = medianThree(nums, left, (left + right) / 2, right);
    +    // 将中位数交换至数组最左端
    +    swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--;          // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j); // 交换这两个元素
    +    }
    +    swap(nums, i, left);  // 将基准数交换至两子数组的分界线
    +    return i;             // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.cs
    /* 选取三个候选元素的中位数 */
    +int MedianThree(int[] nums, int left, int mid, int right) {
    +    int l = nums[left], m = nums[mid], r = nums[right];
    +    if ((l <= m && m <= r) || (r <= m && m <= l))
    +        return mid; // m 在 l 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m))
    +        return left; // l 在 m 和 r 之间
    +    return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +int Partition(int[] nums, int left, int right) {
    +    // 选取三个候选元素的中位数
    +    int med = MedianThree(nums, left, (left + right) / 2, right);
    +    // 将中位数交换至数组最左端
    +    Swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--;          // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        Swap(nums, i, j); // 交换这两个元素
    +    }
    +    Swap(nums, i, left);  // 将基准数交换至两子数组的分界线
    +    return i;             // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.go
    /* 选取三个候选元素的中位数 */
    +func (q *quickSortMedian) medianThree(nums []int, left, mid, right int) int {
    +    l, m, r := nums[left], nums[mid], nums[right]
    +    if (l <= m && m <= r) || (r <= m && m <= l) {
    +        return mid // m 在 l 和 r 之间
    +    }
    +    if (m <= l && l <= r) || (r <= l && l <= m) {
    +        return left // l 在 m 和 r 之间
    +    }
    +    return right
    +}
    +
    +/* 哨兵划分(三数取中值)*/
    +func (q *quickSortMedian) partition(nums []int, left, right int) int {
    +    // 以 nums[left] 为基准数
    +    med := q.medianThree(nums, left, (left+right)/2, right)
    +    // 将中位数交换至数组最左端
    +    nums[left], nums[med] = nums[med], nums[left]
    +    // 以 nums[left] 为基准数
    +    i, j := left, right
    +    for i < j {
    +        for i < j && nums[j] >= nums[left] {
    +            j-- //从右向左找首个小于基准数的元素
    +        }
    +        for i < j && nums[i] <= nums[left] {
    +            i++ //从左向右找首个大于基准数的元素
    +        }
    +        //元素交换
    +        nums[i], nums[j] = nums[j], nums[i]
    +    }
    +    //将基准数交换至两子数组的分界线
    +    nums[i], nums[left] = nums[left], nums[i]
    +    return i //返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.swift
    /* 选取三个候选元素的中位数 */
    +func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
    +    let l = nums[left]
    +    let m = nums[mid]
    +    let r = nums[right]
    +    if (l <= m && m <= r) || (r <= m && m <= l) {
    +        return mid // m 在 l 和 r 之间
    +    }
    +    if (m <= l && l <= r) || (r <= l && l <= m) {
    +        return left // l 在 m 和 r 之间
    +    }
    +    return right
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +func partitionMedian(nums: inout [Int], left: Int, right: Int) -> Int {
    +    // 选取三个候选元素的中位数
    +    let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)
    +    // 将中位数交换至数组最左端
    +    nums.swapAt(left, med)
    +    return partition(nums: &nums, left: left, right: right)
    +}
    +
    +
    +
    +
    quick_sort.js
    /* 选取三个候选元素的中位数 */
    +medianThree(nums, left, mid, right) {
    +    let l = nums[left],
    +        m = nums[mid],
    +        r = nums[right];
    +    // m 在 l 和 r 之间
    +    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;
    +    // l 在 m 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;
    +    return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +partition(nums, left, right) {
    +    // 选取三个候选元素的中位数
    +    let med = this.medianThree(
    +        nums,
    +        left,
    +        Math.floor((left + right) / 2),
    +        right
    +    );
    +    // 将中位数交换至数组最左端
    +    this.swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    let i = left,
    +        j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
    +        this.swap(nums, i, j); // 交换这两个元素
    +    }
    +    this.swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i; // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.ts
    /* 选取三个候选元素的中位数 */
    +medianThree(
    +    nums: number[],
    +    left: number,
    +    mid: number,
    +    right: number
    +): number {
    +    let l = nums[left],
    +        m = nums[mid],
    +        r = nums[right];
    +    // m 在 l 和 r 之间
    +    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;
    +    // l 在 m 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;
    +    return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +partition(nums: number[], left: number, right: number): number {
    +    // 选取三个候选元素的中位数
    +    let med = this.medianThree(
    +        nums,
    +        left,
    +        Math.floor((left + right) / 2),
    +        right
    +    );
    +    // 将中位数交换至数组最左端
    +    this.swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    let i = left,
    +        j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left]) {
    +            j--; // 从右向左找首个小于基准数的元素
    +        }
    +        while (i < j && nums[i] <= nums[left]) {
    +            i++; // 从左向右找首个大于基准数的元素
    +        }
    +        this.swap(nums, i, j); // 交换这两个元素
    +    }
    +    this.swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i; // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.dart
    /* 选取三个候选元素的中位数 */
    +int _medianThree(List<int> nums, int left, int mid, int right) {
    +  int l = nums[left], m = nums[mid], r = nums[right];
    +  if ((l <= m && m <= r) || (r <= m && m <= l))
    +    return mid; // m 在 l 和 r 之间
    +  if ((m <= l && l <= r) || (r <= l && l <= m))
    +    return left; // l 在 m 和 r 之间
    +  return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +int _partition(List<int> nums, int left, int right) {
    +  // 选取三个候选元素的中位数
    +  int med = _medianThree(nums, left, (left + right) ~/ 2, right);
    +  // 将中位数交换至数组最左端
    +  _swap(nums, left, med);
    +  // 以 nums[left] 为基准数
    +  int i = left, j = right;
    +  while (i < j) {
    +    while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
    +    while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
    +    _swap(nums, i, j); // 交换这两个元素
    +  }
    +  _swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +  return i; // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.rs
    /* 选取三个候选元素的中位数 */
    +fn median_three(nums: &mut [i32], left: usize, mid: usize, right: usize) -> usize {
    +    let (l, m, r) = (nums[left], nums[mid], nums[right]);
    +    if (l <= m && m <= r) || (r <= m && m <= l) {
    +        return mid; // m 在 l 和 r 之间
    +    }
    +    if (m <= l && l <= r) || (r <= l && l <= m) {
    +        return left; // l 在 m 和 r 之间
    +    }
    +    right
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +fn partition(nums: &mut [i32], left: usize, right: usize) -> usize {
    +    // 选取三个候选元素的中位数
    +    let med = Self::median_three(nums, left, (left + right) / 2, right);
    +    // 将中位数交换至数组最左端
    +    nums.swap(left, med);
    +    // 以 nums[left] 为基准数
    +    let (mut i, mut j) = (left, right);
    +    while i < j {
    +        while i < j && nums[j] >= nums[left] {
    +            j -= 1; // 从右向左找首个小于基准数的元素
    +        }
    +        while i < j && nums[i] <= nums[left] {
    +            i += 1; // 从左向右找首个大于基准数的元素
    +        }
    +        nums.swap(i, j); // 交换这两个元素
    +    }
    +    nums.swap(i, left); // 将基准数交换至两子数组的分界线
    +    i // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.c
    /* 选取三个候选元素的中位数 */
    +int medianThree(int nums[], int left, int mid, int right) {
    +    int l = nums[left], m = nums[mid], r = nums[right];
    +    if ((l <= m && m <= r) || (r <= m && m <= l))
    +        return mid; // m 在 l 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m))
    +        return left; // l 在 m 和 r 之间
    +    return right;
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +int partitionMedian(int nums[], int left, int right) {
    +    // 选取三个候选元素的中位数
    +    int med = medianThree(nums, left, (left + right) / 2, right);
    +    // 将中位数交换至数组最左端
    +    swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    int i = left, j = right;
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--; // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++;          // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j); // 交换这两个元素
    +    }
    +    swap(nums, i, left); // 将基准数交换至两子数组的分界线
    +    return i;            // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.kt
    /* 选取三个候选元素的中位数 */
    +fun medianThree(nums: IntArray, left: Int, mid: Int, right: Int): Int {
    +    val l = nums[left]
    +    val m = nums[mid]
    +    val r = nums[right]
    +    if ((m in l..r) || (m in r..l))
    +        return mid  // m 在 l 和 r 之间
    +    if ((l in m..r) || (l in r..m))
    +        return left // l 在 m 和 r 之间
    +    return right
    +}
    +
    +/* 哨兵划分(三数取中值) */
    +fun partitionMedian(nums: IntArray, left: Int, right: Int): Int {
    +    // 选取三个候选元素的中位数
    +    val med = medianThree(nums, left, (left + right) / 2, right)
    +    // 将中位数交换至数组最左端
    +    swap(nums, left, med)
    +    // 以 nums[left] 为基准数
    +    var i = left
    +    var j = right
    +    while (i < j) {
    +        while (i < j && nums[j] >= nums[left])
    +            j--                      // 从右向左找首个小于基准数的元素
    +        while (i < j && nums[i] <= nums[left])
    +            i++                      // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j)             // 交换这两个元素
    +    }
    +    swap(nums, i, left)              // 将基准数交换至两子数组的分界线
    +    return i                         // 返回基准数的索引
    +}
    +
    +
    +
    +
    quick_sort.rb
    [class]{QuickSortMedian}-[func]{median_three}
    +
    +[class]{QuickSortMedian}-[func]{partition}
    +
    +
    +
    +
    quick_sort.zig
    // 选取三个候选元素的中位数
    +fn medianThree(nums: []i32, left: usize, mid: usize, right: usize) usize {
    +    var l = nums[left];
    +    var m = nums[mid];
    +    var r = nums[right];
    +    if ((l <= m && m <= r) || (r <= m && m <= l))
    +        return mid; // m 在 l 和 r 之间
    +    if ((m <= l && l <= r) || (r <= l && l <= m))
    +        return left; // l 在 m 和 r 之间
    +    return right;
    +}
    +
    +// 哨兵划分(三数取中值)
    +fn partition(nums: []i32, left: usize, right: usize) usize {
    +    // 选取三个候选元素的中位数
    +    var med = medianThree(nums, left, (left + right) / 2, right);
    +    // 将中位数交换至数组最左端
    +    swap(nums, left, med);
    +    // 以 nums[left] 为基准数
    +    var i = left;
    +    var j = right;
    +    while (i < j) {
    +        while (i < j and nums[j] >= nums[left]) j -= 1; // 从右向左找首个小于基准数的元素
    +        while (i < j and nums[i] <= nums[left]) i += 1; // 从左向右找首个大于基准数的元素
    +        swap(nums, i, j);   // 交换这两个元素
    +    }
    +    swap(nums, i, left);    // 将基准数交换至两子数组的分界线
    +    return i;               // 返回基准数的索引
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.5.5   Tail recursion optimization

    +

    Under certain inputs, quick sort may occupy more space. For a completely ordered input array, assume the sub-array length in recursion is \(m\), each round of pivot partitioning produces a left sub-array of length \(0\) and a right sub-array of length \(m - 1\), meaning the problem size reduced per recursive call is very small (only one element), and the height of the recursion tree can reach \(n - 1\), requiring \(O(n)\) stack frame space.

    +

    To prevent the accumulation of stack frame space, we can compare the lengths of the two sub-arrays after each round of pivot sorting, and only recursively sort the shorter sub-array. Since the length of the shorter sub-array will not exceed \(n / 2\), this method ensures that the recursion depth does not exceed \(\log n\), thus optimizing the worst space complexity to \(O(\log n)\). The code is as follows:

    +
    +
    +
    +
    quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):
    +    """快速排序(尾递归优化)"""
    +    # 子数组长度为 1 时终止
    +    while left < right:
    +        # 哨兵划分操作
    +        pivot = self.partition(nums, left, right)
    +        # 对两个子数组中较短的那个执行快速排序
    +        if pivot - left < right - pivot:
    +            self.quick_sort(nums, left, pivot - 1)  # 递归排序左子数组
    +            left = pivot + 1  # 剩余未排序区间为 [pivot + 1, right]
    +        else:
    +            self.quick_sort(nums, pivot + 1, right)  # 递归排序右子数组
    +            right = pivot - 1  # 剩余未排序区间为 [left, pivot - 1]
    +
    +
    +
    +
    quick_sort.cpp
    /* 快速排序(尾递归优化) */
    +void quickSort(vector<int> &nums, int left, int right) {
    +    // 子数组长度为 1 时终止
    +    while (left < right) {
    +        // 哨兵划分操作
    +        int pivot = partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            quickSort(nums, left, pivot - 1); // 递归排序左子数组
    +            left = pivot + 1;                 // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            quickSort(nums, pivot + 1, right); // 递归排序右子数组
    +            right = pivot - 1;                 // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.java
    /* 快速排序(尾递归优化) */
    +void quickSort(int[] nums, int left, int right) {
    +    // 子数组长度为 1 时终止
    +    while (left < right) {
    +        // 哨兵划分操作
    +        int pivot = partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            quickSort(nums, left, pivot - 1); // 递归排序左子数组
    +            left = pivot + 1; // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            quickSort(nums, pivot + 1, right); // 递归排序右子数组
    +            right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.cs
    /* 快速排序(尾递归优化) */
    +void QuickSort(int[] nums, int left, int right) {
    +    // 子数组长度为 1 时终止
    +    while (left < right) {
    +        // 哨兵划分操作
    +        int pivot = Partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            QuickSort(nums, left, pivot - 1);  // 递归排序左子数组
    +            left = pivot + 1;  // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            QuickSort(nums, pivot + 1, right); // 递归排序右子数组
    +            right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.go
    /* 快速排序(尾递归优化)*/
    +func (q *quickSortTailCall) quickSort(nums []int, left, right int) {
    +    // 子数组长度为 1 时终止
    +    for left < right {
    +        // 哨兵划分操作
    +        pivot := q.partition(nums, left, right)
    +        // 对两个子数组中较短的那个执行快速排序
    +        if pivot-left < right-pivot {
    +            q.quickSort(nums, left, pivot-1) // 递归排序左子数组
    +            left = pivot + 1                 // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            q.quickSort(nums, pivot+1, right) // 递归排序右子数组
    +            right = pivot - 1                 // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.swift
    /* 快速排序(尾递归优化) */
    +func quickSortTailCall(nums: inout [Int], left: Int, right: Int) {
    +    var left = left
    +    var right = right
    +    // 子数组长度为 1 时终止
    +    while left < right {
    +        // 哨兵划分操作
    +        let pivot = partition(nums: &nums, left: left, right: right)
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left) < (right - pivot) {
    +            quickSortTailCall(nums: &nums, left: left, right: pivot - 1) // 递归排序左子数组
    +            left = pivot + 1 // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            quickSortTailCall(nums: &nums, left: pivot + 1, right: right) // 递归排序右子数组
    +            right = pivot - 1 // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.js
    /* 快速排序(尾递归优化) */
    +quickSort(nums, left, right) {
    +    // 子数组长度为 1 时终止
    +    while (left < right) {
    +        // 哨兵划分操作
    +        let pivot = this.partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            this.quickSort(nums, left, pivot - 1); // 递归排序左子数组
    +            left = pivot + 1; // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            this.quickSort(nums, pivot + 1, right); // 递归排序右子数组
    +            right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.ts
    /* 快速排序(尾递归优化) */
    +quickSort(nums: number[], left: number, right: number): void {
    +    // 子数组长度为 1 时终止
    +    while (left < right) {
    +        // 哨兵划分操作
    +        let pivot = this.partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            this.quickSort(nums, left, pivot - 1); // 递归排序左子数组
    +            left = pivot + 1; // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            this.quickSort(nums, pivot + 1, right); // 递归排序右子数组
    +            right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.dart
    /* 快速排序(尾递归优化) */
    +void quickSort(List<int> nums, int left, int right) {
    +  // 子数组长度为 1 时终止
    +  while (left < right) {
    +    // 哨兵划分操作
    +    int pivot = _partition(nums, left, right);
    +    // 对两个子数组中较短的那个执行快速排序
    +    if (pivot - left < right - pivot) {
    +      quickSort(nums, left, pivot - 1); // 递归排序左子数组
    +      left = pivot + 1; // 剩余未排序区间为 [pivot + 1, right]
    +    } else {
    +      quickSort(nums, pivot + 1, right); // 递归排序右子数组
    +      right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1]
    +    }
    +  }
    +}
    +
    +
    +
    +
    quick_sort.rs
    /* 快速排序(尾递归优化) */
    +pub fn quick_sort(mut left: i32, mut right: i32, nums: &mut [i32]) {
    +    // 子数组长度为 1 时终止
    +    while left < right {
    +        // 哨兵划分操作
    +        let pivot = Self::partition(nums, left as usize, right as usize) as i32;
    +        // 对两个子数组中较短的那个执行快速排序
    +        if pivot - left < right - pivot {
    +            Self::quick_sort(left, pivot - 1, nums); // 递归排序左子数组
    +            left = pivot + 1; // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            Self::quick_sort(pivot + 1, right, nums); // 递归排序右子数组
    +            right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.c
    /* 快速排序(尾递归优化) */
    +void quickSortTailCall(int nums[], int left, int right) {
    +    // 子数组长度为 1 时终止
    +    while (left < right) {
    +        // 哨兵划分操作
    +        int pivot = partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            // 递归排序左子数组
    +            quickSortTailCall(nums, left, pivot - 1);
    +            // 剩余未排序区间为 [pivot + 1, right]
    +            left = pivot + 1;
    +        } else {
    +            // 递归排序右子数组
    +            quickSortTailCall(nums, pivot + 1, right);
    +            // 剩余未排序区间为 [left, pivot - 1]
    +            right = pivot - 1;
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.kt
    /* 快速排序(尾递归优化) */
    +fun quickSortTailCall(nums: IntArray, left: Int, right: Int) {
    +    // 子数组长度为 1 时终止
    +    var l = left
    +    var r = right
    +    while (l < r) {
    +        // 哨兵划分操作
    +        val pivot = partition(nums, l, r)
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - l < r - pivot) {
    +            quickSort(nums, l, pivot - 1) // 递归排序左子数组
    +            l = pivot + 1 // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            quickSort(nums, pivot + 1, r) // 递归排序右子数组
    +            r = pivot - 1 // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    quick_sort.rb
    [class]{QuickSortTailCall}-[func]{quick_sort}
    +
    +
    +
    +
    quick_sort.zig
    // 快速排序(尾递归优化)
    +fn quickSort(nums: []i32, left_: usize, right_: usize) void {
    +    var left = left_;
    +    var right = right_;
    +    // 子数组长度为 1 时终止递归
    +    while (left < right) {
    +        // 哨兵划分操作
    +        var pivot = partition(nums, left, right);
    +        // 对两个子数组中较短的那个执行快速排序
    +        if (pivot - left < right - pivot) {
    +            quickSort(nums, left, pivot - 1);   // 递归排序左子数组
    +            left = pivot + 1;                   // 剩余未排序区间为 [pivot + 1, right]
    +        } else {
    +            quickSort(nums, pivot + 1, right);  // 递归排序右子数组
    +            right = pivot - 1;                  // 剩余未排序区间为 [left, pivot - 1]
    +        }
    +    }
    +}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/radix_sort.assets/radix_sort_overview.png b/en/chapter_sorting/radix_sort.assets/radix_sort_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..e123cb73b3cd233115082effbb1b4f91118ff0aa GIT binary patch literal 46860 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/radix_sort/index.html b/en/chapter_sorting/radix_sort/index.html new file mode 100644 index 000000000..d72b6ce50 --- /dev/null +++ b/en/chapter_sorting/radix_sort/index.html @@ -0,0 +1,4575 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.10 Radix sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.10   Radix sort

    +

    The previous section introduced counting sort, which is suitable for scenarios where the data volume \(n\) is large but the data range \(m\) is small. Suppose we need to sort \(n = 10^6\) student IDs, where each ID is an \(8\)-digit number. This means the data range \(m = 10^8\) is very large, requiring a significant amount of memory space for counting sort, while radix sort can avoid this situation.

    +

    Radix sort shares the core idea with counting sort, which also sorts by counting the frequency of elements. Building on this, radix sort utilizes the progressive relationship between the digits of numbers, sorting each digit in turn to achieve the final sorted order.

    +

    11.10.1   Algorithm process

    +

    Taking the student ID data as an example, assuming the least significant digit is the \(1^{st}\) and the most significant is the \(8^{th}\), the radix sort process is illustrated in the following diagram.

    +
      +
    1. Initialize digit \(k = 1\).
    2. +
    3. Perform "counting sort" on the \(k^{th}\) digit of the student IDs. After completion, the data will be sorted from smallest to largest based on the \(k^{th}\) digit.
    4. +
    5. Increment \(k\) by \(1\), then return to step 2. and continue iterating until all digits have been sorted, then the process ends.
    6. +
    +

    Radix sort algorithm process

    +

    Figure 11-18   Radix sort algorithm process

    + +

    Below we dissect the code implementation. For a number \(x\) in base \(d\), to obtain its \(k^{th}\) digit \(x_k\), the following calculation formula can be used:

    +
    \[ +x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d +\]
    +

    Where \(\lfloor a \rfloor\) denotes rounding down the floating point number \(a\), and \(\bmod \: d\) denotes taking the modulus of \(d\). For student ID data, \(d = 10\) and \(k \in [1, 8]\).

    +

    Additionally, we need to slightly modify the counting sort code to allow sorting based on the \(k^{th}\) digit:

    +
    +
    +
    +
    radix_sort.py
    def digit(num: int, exp: int) -> int:
    +    """获取元素 num 的第 k 位,其中 exp = 10^(k-1)"""
    +    # 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num // exp) % 10
    +
    +def counting_sort_digit(nums: list[int], exp: int):
    +    """计数排序(根据 nums 第 k 位排序)"""
    +    # 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    counter = [0] * 10
    +    n = len(nums)
    +    # 统计 0~9 各数字的出现次数
    +    for i in range(n):
    +        d = digit(nums[i], exp)  # 获取 nums[i] 第 k 位,记为 d
    +        counter[d] += 1  # 统计数字 d 的出现次数
    +    # 求前缀和,将“出现个数”转换为“数组索引”
    +    for i in range(1, 10):
    +        counter[i] += counter[i - 1]
    +    # 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    res = [0] * n
    +    for i in range(n - 1, -1, -1):
    +        d = digit(nums[i], exp)
    +        j = counter[d] - 1  # 获取 d 在数组中的索引 j
    +        res[j] = nums[i]  # 将当前元素填入索引 j
    +        counter[d] -= 1  # 将 d 的数量减 1
    +    # 使用结果覆盖原数组 nums
    +    for i in range(n):
    +        nums[i] = res[i]
    +
    +def radix_sort(nums: list[int]):
    +    """基数排序"""
    +    # 获取数组的最大元素,用于判断最大位数
    +    m = max(nums)
    +    # 按照从低位到高位的顺序遍历
    +    exp = 1
    +    while exp <= m:
    +        # 对数组元素的第 k 位执行计数排序
    +        # k = 1 -> exp = 1
    +        # k = 2 -> exp = 10
    +        # 即 exp = 10^(k-1)
    +        counting_sort_digit(nums, exp)
    +        exp *= 10
    +
    +
    +
    +
    radix_sort.cpp
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +int digit(int num, int exp) {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num / exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +void countingSortDigit(vector<int> &nums, int exp) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    vector<int> counter(10, 0);
    +    int n = nums.size();
    +    // 统计 0~9 各数字的出现次数
    +    for (int i = 0; i < n; i++) {
    +        int d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++;                // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (int i = 1; i < 10; i++) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    vector<int> res(n, 0);
    +    for (int i = n - 1; i >= 0; i--) {
    +        int d = digit(nums[i], exp);
    +        int j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i];       // 将当前元素填入索引 j
    +        counter[d]--;           // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (int i = 0; i < n; i++)
    +        nums[i] = res[i];
    +}
    +
    +/* 基数排序 */
    +void radixSort(vector<int> &nums) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    int m = *max_element(nums.begin(), nums.end());
    +    // 按照从低位到高位的顺序遍历
    +    for (int exp = 1; exp <= m; exp *= 10)
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, exp);
    +}
    +
    +
    +
    +
    radix_sort.java
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +int digit(int num, int exp) {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num / exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +void countingSortDigit(int[] nums, int exp) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    int[] counter = new int[10];
    +    int n = nums.length;
    +    // 统计 0~9 各数字的出现次数
    +    for (int i = 0; i < n; i++) {
    +        int d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++;                // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (int i = 1; i < 10; i++) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    int[] res = new int[n];
    +    for (int i = n - 1; i >= 0; i--) {
    +        int d = digit(nums[i], exp);
    +        int j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i];       // 将当前元素填入索引 j
    +        counter[d]--;           // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (int i = 0; i < n; i++)
    +        nums[i] = res[i];
    +}
    +
    +/* 基数排序 */
    +void radixSort(int[] nums) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    int m = Integer.MIN_VALUE;
    +    for (int num : nums)
    +        if (num > m)
    +            m = num;
    +    // 按照从低位到高位的顺序遍历
    +    for (int exp = 1; exp <= m; exp *= 10) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, exp);
    +    }
    +}
    +
    +
    +
    +
    radix_sort.cs
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +int Digit(int num, int exp) {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num / exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +void CountingSortDigit(int[] nums, int exp) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    int[] counter = new int[10];
    +    int n = nums.Length;
    +    // 统计 0~9 各数字的出现次数
    +    for (int i = 0; i < n; i++) {
    +        int d = Digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++;                // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (int i = 1; i < 10; i++) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    int[] res = new int[n];
    +    for (int i = n - 1; i >= 0; i--) {
    +        int d = Digit(nums[i], exp);
    +        int j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i];       // 将当前元素填入索引 j
    +        counter[d]--;           // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (int i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +/* 基数排序 */
    +void RadixSort(int[] nums) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    int m = int.MinValue;
    +    foreach (int num in nums) {
    +        if (num > m) m = num;
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    for (int exp = 1; exp <= m; exp *= 10) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        CountingSortDigit(nums, exp);
    +    }
    +}
    +
    +
    +
    +
    radix_sort.go
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +func digit(num, exp int) int {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num / exp) % 10
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +func countingSortDigit(nums []int, exp int) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    counter := make([]int, 10)
    +    n := len(nums)
    +    // 统计 0~9 各数字的出现次数
    +    for i := 0; i < n; i++ {
    +        d := digit(nums[i], exp) // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++             // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for i := 1; i < 10; i++ {
    +        counter[i] += counter[i-1]
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    res := make([]int, n)
    +    for i := n - 1; i >= 0; i-- {
    +        d := digit(nums[i], exp)
    +        j := counter[d] - 1 // 获取 d 在数组中的索引 j
    +        res[j] = nums[i]    // 将当前元素填入索引 j
    +        counter[d]--        // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for i := 0; i < n; i++ {
    +        nums[i] = res[i]
    +    }
    +}
    +
    +/* 基数排序 */
    +func radixSort(nums []int) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    max := math.MinInt
    +    for _, num := range nums {
    +        if num > max {
    +            max = num
    +        }
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    for exp := 1; max >= exp; exp *= 10 {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, exp)
    +    }
    +}
    +
    +
    +
    +
    radix_sort.swift
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +func digit(num: Int, exp: Int) -> Int {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    (num / exp) % 10
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +func countingSortDigit(nums: inout [Int], exp: Int) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    var counter = Array(repeating: 0, count: 10)
    +    // 统计 0~9 各数字的出现次数
    +    for i in nums.indices {
    +        let d = digit(num: nums[i], exp: exp) // 获取 nums[i] 第 k 位,记为 d
    +        counter[d] += 1 // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for i in 1 ..< 10 {
    +        counter[i] += counter[i - 1]
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    var res = Array(repeating: 0, count: nums.count)
    +    for i in nums.indices.reversed() {
    +        let d = digit(num: nums[i], exp: exp)
    +        let j = counter[d] - 1 // 获取 d 在数组中的索引 j
    +        res[j] = nums[i] // 将当前元素填入索引 j
    +        counter[d] -= 1 // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for i in nums.indices {
    +        nums[i] = res[i]
    +    }
    +}
    +
    +/* 基数排序 */
    +func radixSort(nums: inout [Int]) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    var m = Int.min
    +    for num in nums {
    +        if num > m {
    +            m = num
    +        }
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    for exp in sequence(first: 1, next: { m >= ($0 * 10) ? $0 * 10 : nil }) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums: &nums, exp: exp)
    +    }
    +}
    +
    +
    +
    +
    radix_sort.js
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +function digit(num, exp) {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return Math.floor(num / exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +function countingSortDigit(nums, exp) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    const counter = new Array(10).fill(0);
    +    const n = nums.length;
    +    // 统计 0~9 各数字的出现次数
    +    for (let i = 0; i < n; i++) {
    +        const d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++; // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (let i = 1; i < 10; i++) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    const res = new Array(n).fill(0);
    +    for (let i = n - 1; i >= 0; i--) {
    +        const d = digit(nums[i], exp);
    +        const j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i]; // 将当前元素填入索引 j
    +        counter[d]--; // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (let i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +/* 基数排序 */
    +function radixSort(nums) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    let m = Number.MIN_VALUE;
    +    for (const num of nums) {
    +        if (num > m) {
    +            m = num;
    +        }
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    for (let exp = 1; exp <= m; exp *= 10) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, exp);
    +    }
    +}
    +
    +
    +
    +
    radix_sort.ts
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +function digit(num: number, exp: number): number {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return Math.floor(num / exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +function countingSortDigit(nums: number[], exp: number): void {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    const counter = new Array(10).fill(0);
    +    const n = nums.length;
    +    // 统计 0~9 各数字的出现次数
    +    for (let i = 0; i < n; i++) {
    +        const d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++; // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (let i = 1; i < 10; i++) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    const res = new Array(n).fill(0);
    +    for (let i = n - 1; i >= 0; i--) {
    +        const d = digit(nums[i], exp);
    +        const j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i]; // 将当前元素填入索引 j
    +        counter[d]--; // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (let i = 0; i < n; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +/* 基数排序 */
    +function radixSort(nums: number[]): void {
    +    // 获取数组的最大元素,用于判断最大位数
    +    let m = Number.MIN_VALUE;
    +    for (const num of nums) {
    +        if (num > m) {
    +            m = num;
    +        }
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    for (let exp = 1; exp <= m; exp *= 10) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, exp);
    +    }
    +}
    +
    +
    +
    +
    radix_sort.dart
    /* 获取元素 _num 的第 k 位,其中 exp = 10^(k-1) */
    +int digit(int _num, int exp) {
    +  // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +  return (_num ~/ exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +void countingSortDigit(List<int> nums, int exp) {
    +  // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +  List<int> counter = List<int>.filled(10, 0);
    +  int n = nums.length;
    +  // 统计 0~9 各数字的出现次数
    +  for (int i = 0; i < n; i++) {
    +    int d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +    counter[d]++; // 统计数字 d 的出现次数
    +  }
    +  // 求前缀和,将“出现个数”转换为“数组索引”
    +  for (int i = 1; i < 10; i++) {
    +    counter[i] += counter[i - 1];
    +  }
    +  // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +  List<int> res = List<int>.filled(n, 0);
    +  for (int i = n - 1; i >= 0; i--) {
    +    int d = digit(nums[i], exp);
    +    int j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +    res[j] = nums[i]; // 将当前元素填入索引 j
    +    counter[d]--; // 将 d 的数量减 1
    +  }
    +  // 使用结果覆盖原数组 nums
    +  for (int i = 0; i < n; i++) nums[i] = res[i];
    +}
    +
    +/* 基数排序 */
    +void radixSort(List<int> nums) {
    +  // 获取数组的最大元素,用于判断最大位数
    +  // dart 中 int 的长度是 64 位的
    +  int m = -1 << 63;
    +  for (int _num in nums) if (_num > m) m = _num;
    +  // 按照从低位到高位的顺序遍历
    +  for (int exp = 1; exp <= m; exp *= 10)
    +    // 对数组元素的第 k 位执行计数排序
    +    // k = 1 -> exp = 1
    +    // k = 2 -> exp = 10
    +    // 即 exp = 10^(k-1)
    +    countingSortDigit(nums, exp);
    +}
    +
    +
    +
    +
    radix_sort.rs
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +fn digit(num: i32, exp: i32) -> usize {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return ((num / exp) % 10) as usize;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +fn counting_sort_digit(nums: &mut [i32], exp: i32) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    let mut counter = [0; 10];
    +    let n = nums.len();
    +    // 统计 0~9 各数字的出现次数
    +    for i in 0..n {
    +        let d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d] += 1; // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for i in 1..10 {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    let mut res = vec![0; n];
    +    for i in (0..n).rev() {
    +        let d = digit(nums[i], exp);
    +        let j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i]; // 将当前元素填入索引 j
    +        counter[d] -= 1; // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for i in 0..n {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +/* 基数排序 */
    +fn radix_sort(nums: &mut [i32]) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    let m = *nums.into_iter().max().unwrap();
    +    // 按照从低位到高位的顺序遍历
    +    let mut exp = 1;
    +    while exp <= m {
    +        counting_sort_digit(nums, exp);
    +        exp *= 10;
    +    }
    +}
    +
    +
    +
    +
    radix_sort.c
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +int digit(int num, int exp) {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num / exp) % 10;
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +void countingSortDigit(int nums[], int size, int exp) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    int *counter = (int *)malloc((sizeof(int) * 10));
    +    // 统计 0~9 各数字的出现次数
    +    for (int i = 0; i < size; i++) {
    +        // 获取 nums[i] 第 k 位,记为 d
    +        int d = digit(nums[i], exp);
    +        // 统计数字 d 的出现次数
    +        counter[d]++;
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (int i = 1; i < 10; i++) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    int *res = (int *)malloc(sizeof(int) * size);
    +    for (int i = size - 1; i >= 0; i--) {
    +        int d = digit(nums[i], exp);
    +        int j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i];       // 将当前元素填入索引 j
    +        counter[d]--;           // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (int i = 0; i < size; i++) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +/* 基数排序 */
    +void radixSort(int nums[], int size) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    int max = INT32_MIN;
    +    for (size_t i = 0; i < size - 1; i++) {
    +        if (nums[i] > max) {
    +            max = nums[i];
    +        }
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    for (int exp = 1; max >= exp; exp *= 10)
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, size, exp);
    +}
    +
    +
    +
    +
    radix_sort.kt
    /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */
    +fun digit(num: Int, exp: Int): Int {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return (num / exp) % 10
    +}
    +
    +/* 计数排序(根据 nums 第 k 位排序) */
    +fun countingSortDigit(nums: IntArray, exp: Int) {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    val counter = IntArray(10)
    +    val n = nums.size
    +    // 统计 0~9 各数字的出现次数
    +    for (i in 0..<n) {
    +        val d = digit(nums[i], exp) // 获取 nums[i] 第 k 位,记为 d
    +        counter[d]++                // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    for (i in 1..9) {
    +        counter[i] += counter[i - 1]
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    val res = IntArray(n)
    +    for (i in n - 1 downTo 0) {
    +        val d = digit(nums[i], exp)
    +        val j = counter[d] - 1 // 获取 d 在数组中的索引 j
    +        res[j] = nums[i]       // 将当前元素填入索引 j
    +        counter[d]--           // 将 d 的数量减 1
    +    }
    +    // 使用结果覆盖原数组 nums
    +    for (i in 0..<n)
    +        nums[i] = res[i]
    +}
    +
    +/* 基数排序 */
    +fun radixSort(nums: IntArray) {
    +    // 获取数组的最大元素,用于判断最大位数
    +    var m = Int.MIN_VALUE
    +    for (num in nums) if (num > m) m = num
    +    var exp = 1
    +    // 按照从低位到高位的顺序遍历
    +    while (exp <= m) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        countingSortDigit(nums, exp)
    +        exp *= 10
    +    }
    +}
    +
    +
    +
    +
    radix_sort.rb
    [class]{}-[func]{digit}
    +
    +[class]{}-[func]{counting_sort_digit}
    +
    +[class]{}-[func]{radix_sort}
    +
    +
    +
    +
    radix_sort.zig
    // 获取元素 num 的第 k 位,其中 exp = 10^(k-1)
    +fn digit(num: i32, exp: i32) i32 {
    +    // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
    +    return @mod(@divFloor(num, exp), 10);
    +}
    +
    +// 计数排序(根据 nums 第 k 位排序)
    +fn countingSortDigit(nums: []i32, exp: i32) !void {
    +    // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组
    +    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    +    // defer mem_arena.deinit();
    +    const mem_allocator = mem_arena.allocator();
    +    var counter = try mem_allocator.alloc(usize, 10);
    +    @memset(counter, 0);
    +    var n = nums.len;
    +    // 统计 0~9 各数字的出现次数
    +    for (nums) |num| {
    +        var d: u32 = @bitCast(digit(num, exp)); // 获取 nums[i] 第 k 位,记为 d
    +        counter[d] += 1; // 统计数字 d 的出现次数
    +    }
    +    // 求前缀和,将“出现个数”转换为“数组索引”
    +    var i: usize = 1;
    +    while (i < 10) : (i += 1) {
    +        counter[i] += counter[i - 1];
    +    }
    +    // 倒序遍历,根据桶内统计结果,将各元素填入 res
    +    var res = try mem_allocator.alloc(i32, n);
    +    i = n - 1;
    +    while (i >= 0) : (i -= 1) {
    +        var d: u32 = @bitCast(digit(nums[i], exp));
    +        var j = counter[d] - 1; // 获取 d 在数组中的索引 j
    +        res[j] = nums[i];       // 将当前元素填入索引 j
    +        counter[d] -= 1;        // 将 d 的数量减 1
    +        if (i == 0) break;
    +    }
    +    // 使用结果覆盖原数组 nums
    +    i = 0;
    +    while (i < n) : (i += 1) {
    +        nums[i] = res[i];
    +    }
    +}
    +
    +// 基数排序
    +fn radixSort(nums: []i32) !void {
    +    // 获取数组的最大元素,用于判断最大位数
    +    var m: i32 = std.math.minInt(i32);
    +    for (nums) |num| {
    +        if (num > m) m = num;
    +    }
    +    // 按照从低位到高位的顺序遍历
    +    var exp: i32 = 1;
    +    while (exp <= m) : (exp *= 10) {
    +        // 对数组元素的第 k 位执行计数排序
    +        // k = 1 -> exp = 1
    +        // k = 2 -> exp = 10
    +        // 即 exp = 10^(k-1)
    +        try countingSortDigit(nums, exp);    
    +    }
    +} 
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +
    +

    Why start sorting from the least significant digit?

    +

    In consecutive sorting rounds, the result of a later round will override the result of an earlier round. For example, if the result of the first round is \(a < b\) and the result of the second round is \(a > b\), the result of the second round will replace the first round's result. Since the significance of higher digits is greater than that of lower digits, it makes sense to sort lower digits before higher digits.

    +
    +

    11.10.2   Algorithm characteristics

    +

    Compared to counting sort, radix sort is suitable for larger numerical ranges, but it assumes that the data can be represented in a fixed number of digits, and the number of digits should not be too large. For example, floating-point numbers are not suitable for radix sort, as their digit count \(k\) may be large, potentially leading to a time complexity \(O(nk) \gg O(n^2)\).

    +
      +
    • Time complexity is \(O(nk)\), non-adaptive sorting: Assuming the data size is \(n\), the data is in base \(d\), and the maximum number of digits is \(k\), then sorting a single digit takes \(O(n + d)\) time, and sorting all \(k\) digits takes \(O((n + d)k)\) time. Generally, both \(d\) and \(k\) are relatively small, leading to a time complexity approaching \(O(n)\).
    • +
    • Space complexity is \(O(n + d)\), non-in-place sorting: Like counting sort, radix sort relies on arrays res and counter of lengths \(n\) and \(d\) respectively.
    • +
    • Stable sorting: When counting sort is stable, radix sort is also stable; if counting sort is unstable, radix sort cannot guarantee a correct sorting outcome.
    • +
    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_instability.png b/en/chapter_sorting/selection_sort.assets/selection_sort_instability.png new file mode 100644 index 0000000000000000000000000000000000000000..e3c1de0db1b8782ada05feb1f9d38c44db88d8bd GIT binary patch literal 15511 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 KqVgTg@BacgsScL_ literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step1.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step1.png new file mode 100644 index 0000000000000000000000000000000000000000..f540c6d5452a739804f235e11128b70ce673eec4 GIT binary patch literal 11421 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 bZ#*urS&GQqwtP literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step10.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step10.png new file mode 100644 index 0000000000000000000000000000000000000000..d99b293700481a1318a92c2c3ea1b5ae3aa497e1 GIT binary patch literal 16798 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 aoB}i_&f~N-pHuqVSCmtc{rK4I&3^$OTda-% literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step2.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step2.png new file mode 100644 index 0000000000000000000000000000000000000000..e8958492535002a232d3c47abcf883538881bc1c GIT binary patch literal 16574 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 E4>?pjX#fBK literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step3.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step3.png new file mode 100644 index 0000000000000000000000000000000000000000..31a5db2dafed8c97bfece4285fc49a0fccd7b397 GIT binary patch literal 11707 zcmb_?Wl)^W^6#?(i@OI1?y|TB2^Inbf_rc$xQDPvkl>!+A-KEC26qo`2^u7j;1(`< z&;4-f-c$9zb?Wwq-F~{df78=F)3eX?MyS0|z{a4!00016@tLeT0H8du;0ZLy!`J0! zPK$>JYc*v}x%>P3t*xz~mcYx)%ZP{wF)=Z%kD5I_J(qzmrSkVXJ39}RFxJ1V_xJZ# zR#p}k7T*22o0yomzP|qb`*&AY7jhXnH8rKEsQCT+_x${Pb#?XP;^O4wWN~rvgM)+3 z&CT82-QnS3;=tjsurOI!+4S^uNlD4vkxw%-Ge$;6$H&LHxw!}gqQ1WV)vH&xx3{CC zqp7K>OG`_orKO)feX_N+jf{*O92|^~k6-_}zOuR^EiL^nBqSgpz}eZ^!NFm1aWOhN zdU<)dwzl@{{A_=Je_>&vt*tFFF|o0+v8=4@^z<|?HrCtA%fP@OEiKK{#bthezNMvQ zZEa0OMdeTxH!CYkOG|5RZcaZ#?~R|IuCDI+#pTe@PfBrNxGn<{At*)*%H#Z+%ANtUjs;Q|tIXRhw z%yBMsGR-jwZFv_Q9PI1sySlnMu{DvInVH;{>{04|aeYxXUM3+SAulg~gDff-&Hvn= zdvt!ZxVNx(vez`)l$4Yd*BX~Sb+&S_(zn*v+}vDIQL)pI8{QtKlcxRq^7mDLZ8S1! zY+>xvmz?WQ{zpegC4I%2{h7WMzRqpOjkArWRSoS~w(&jNwKFwIJ&D%2R@uXQ3u_B) zi*1I6hKGi<1DnU2T1B%wag(m~8QG;CKP|bu8@@#~MINO4)eKedmM72t zIG&;~Uhcjqjk3?PJ9LxzbN+j4Wnp`$qhqrDN38u)oKffU@&4)c?bg!G*WSyf zY>Ctv)wUZa0AR;el$F->UOe~`_^=ECM9y6?X)*XO``?kt`MT6UmIL?o_?iz{{4eR< z6Jfl6aDE3kLjOyQzh7*7rXc^n<3@-hpDCc@NQdd4w{Wuzo?I%|heUF==$#&)= zc%va$6j}R2%;%l!ECF3EKVM)jgBHU4*B0UcUo9CsmHQAJIB_uglWFmSOV8;6~<6aQ45E54A$)XQBuJ~=Qff^UCZWaLSqt#Q<;N)1r zKnDU13(|nm$2o?iFpXLUcUuX?r|}?$+@$%(NJ~nj!FVKO*T>i!Rl5Juo2eyH{Q1g!{t zzd=2fU7^vo0wP#Ej9W3<9wBc|gb|)F!3Outjp2%n3+`CmyQ?w zHXO?enJWpJ(5%79c}5agTuqEjuyOo5@y%YKq;aAx6EFs=;J3y~T|Bj*N4R3FML3{1 zCwyi4>%hP&@HSpGnhV^pFCp)SsMsg1KtIK;i-N6feUWY`m<92>9+wYwi9F0%gdLtu z3r{xy71OR0A0EoZndd}sKB321pMLT*QtV;8Kd{i?@XritF%rZS(WqSjm-4hY!4JU4 zp*b0j(6$HXc+DU@>+z*3bISk5klZiSI)+oi<4y!ZIgBpo8B{0R0gy_vcd)9JYmy*z za3S9Ff!apzO;J%c>Co`=jXpt<4!d*o2rb$x%JsQJVDXrqMEFEi__Xr@KX&51TW7W$ zV8x4Iv281H=%3^mb)O+XS#BNce^fNLFQ*Ksv0uDLa*r%{yC;{ApSnxI))s| z52!m2X&NoN$gc|c_5#oHDLa)e_fIG}2wM@V_LDkwJoZabqf!K!Uh+JKP^5>$-`LXO zzS8J5_@+tNQAQSw4_`&k*#ps|3v4{?1Mx>Lp_&4O9Hrd=!Amw47>ob&pC}UgKLXk1 zZ0<4vYQUSBF16G|o;ww7UE(YgX!w+gjz8Hcgb<`Qrq zS(mwNeb@)<&j$=&jkDhAYm0599YEDOD)e*7jezNR{jj?F*l(~ZPITs1i!YSI!>24v zmY$!xCf6*VoJhMHd#5<=e_=1WGDOF}GaHXlp+Pkv16trkJl^+?ox@O7^~;JW=u?`1 zipsx#tRJZZ3Lc>4q%5#7Yb%QLFzcZ=MkMN&D@5vpEr9N`{g1eJX#V*m{?|?Y?(L(OIL4=DwY?CTeIT7ecieTaBgz zTDHImgl|i#a|6{=gi_r9?(<(hd!bL)$L7=#^tQ6HZHm;>^N>c%lm-oKGYOr-4k{Jt z&Y-;*79<^D`cNOVOC>(1(_i_McclV#?=U?`ifvjsd{NLMexy6f;CY!;?kwZ%8h191 zglKNcFQSuR26EY%vT^pd{fm_p|24>3%(R(7ifvaTt>r?JMpxss@P2_0Wu_t{i$v1Z z6^-58vGMnFqfF{oB&B@c=oKo+tjhUO69~FwAgLy~o{Wm#^B!lO-XduW-{=guV0>a7 zkLFCJT-3jwv87j(mSlkyA-OUimEbRH|L8Q0LAb4~i{0Qdv|KEjPU^N=(G0Yr{8d0i z8e>pc$I1MLZB6iu=n}!z7JS2WMyq7S9f!eEHcVDZ){%hqZl{+0&RV^a^=_cqt16ixIN>2Q+IGO zdRZYK&e(8tG9ilO@w6l~FNbBF=X}16DT|K);g0|-Up0c{LStz0I$5HU$|l_0e6`|>{t`oO5CwfkJYayz zsX$q>iPHRD1pEvjw|9WX0lc&GXfz;;vTA%O@PMv4Jpvk6-RFscYz%Alvjh%RL^Yuk zb=w_hRHa}Wm~{0E^}{zp0ur zzytHW9$3h8zKLRBo#NS7;PkZKuv=t388!i90|~#pg^^(jF9@PIJa}vLvEU;e88#{( zNRQ1LB<#BMDIGg&pJKYlqa6oPQEgPVykOxb0R)!DGJ62@yQcX{anPzE$b4`|gFR3s z&^Fje^bDQG+~eyUzhjSu-_J|wNxde{vhEI%pp{t`HsZAQ+&bOw|G6f08Y)FzU zFy!zqyn3z1h~VfVWiF+fZn1qkXo@E94~5pd~h58&QX zz<*`i2q`m8PG0ZbG>}jrTZmxN29*w=14p^H0gp!{5XQ}uJTT|fIUrDkBDJ!lhxDic zc%3x;xc%4KnwpsM8M}Jzr(V=59*IF=jcyVoeg5L0A$T`a4ww-A zH@L9ua+$rkTtoKle^x&hn-fj73R9L#+E1ux^1c7 z#sSiNlA*iA#?6oTteDW!0Qk1+a|l>bAd3TM;3!pdNp!2|V6qWDMDmwHXEXm#po8b1 z^~<%j8U^dJz+NqTW6TH{)&?m2m*aLj67j_l!lEV5y%uKd6$nyx-xwj1s^rABek`TB zC;)}qD!DubK*8kDWA(i?YUG}q;^^5#tllO@l?bg?8mAjDuK9Ds8pUQ2%*@I9(^-fN zX+i=rtdu=+!Zx`&v@2();uJ^d3>C})uxJ-!L%m;7jYzKN6)`2SkB|>_`JP>eRY0&G z?z+6Ni#@OwQe0mTuU~Ad1SEW}Pk)%R-d&m%fW#Bhf_?97G$<@_O`NQ)t!e5#J+D7P z<}2+QwJU}4hTv|%QUa=gQzQUJy&y-HuR*J>c{3<>JHVI9a~QLLHYezyx8*n605y`+ zh@JT%3Cmw)dr>|@ii){FP^_Qyh{sc5vQt(B1%mn;-0YUg+yb|QL|`c5A0Y7CGH*_OoIs~!;=CY$_1DP0mTDA3<%(%YCxrcCtx%LKp+K3 z!ko7PN8hW5<)6^Bo=kmWASDw~yy=ZZuIDyon==)P2cywcjWDG;eG62PE^eRdr)iDN zf1>!(gh+9biyDU7-+M^OCpW|w4uFRpT(2ZX2$6)-)J^<2CK=3#!iFc#E|f@NRlppK zcB@*!wMOiBe@lH?YYW;H@iTqkN*zHq*{tdn(oj5IE3R-$3Dn7C^=*~o9d$**zzC-I z3qoIBMfQsGu^#2HID@M)4A(7IpprAmiRx*{lXb40$J1+K@fNF=eQCm+1?X)9&VO7o z{(QHM`DnI9MT8O$a1?s`{vyRqYAQ8(FMFdC@(ZEsykdm}9h5&v4Z`{9U@PDQ^=1w?T zL=UMz;2gkM3RKdf1V4|`6~X6lY8UQf8x5yd;3}xAH-WGR^JC5pvSA8UfU#7I!(JSu zX?S#D&tWSLN)qSGuFm@fRjZb;%$nty^9Hl{Y;6*|MKdE3{9l~^6%@^HcRIeYd(h1| z@ouI(q0D~3Ax>9_>4tBc6CV8q?evKpu8D*<2?RR*qC_q*ePha*^b|@b5&yyE! zp9H{YzynWB{P@sp=6L}iQD|!i1=8&|zUL*2gB+gzCITGBL=mqlcW8k5RdK9fQ()L2 z?al~T@9yP7^z)aff)IqBptev80>Imp7%9gMICpa){MX6w5bT~HhZcTOPa0quZWzQ* z+l&EFdYA5B6C)ccl(y=iYK{C?#Fz+7nOnD6{VbW?tn8N{VG}ATs^$>TdWa8jWaP_! zP6Hrb{r`H0ZNIruSLAU)ij}py~vDaeOx*tav zl_lYmDP@XN$#lL8!;Q_g7fenI4Ik+Ad~XNX~4bfA-XXdc@C5B4KB%Pj;+1iAlS0E&eX5m~Z)%{fm|Nf>P#UmbQ zfo++zECW&FygdZ`Y_@83Lu4nDE< zK6UKXF;TG?IOUajm`Ogk9B(JsW+$@beUhk99wG3=9?j>LauVN36uXXu>U zLp>fK!9Kd8(&zg#H`dYYj7>*Jt4CS;eY1t?L=t^nEp3y@w>M=#Os-(xwm^~8nM5LA zLKYM&e+L7#wTsG_x4QaTj4^(k)Uv@xH@Zos4lKt`*ylOb|3&sp=fx6G!BMTDD=UOJ z3JnYM8fbLkec~XC=znb66uoyQw>kJ@>qmkR3VwW*R)7G)jbDDkDLs&XC{OG?p%dLg~v#3if#mpN>X~d}J%)S@|fZ?<60Fi`pz49hI>##g)4yf1Ck!u{x9x|0$5>?txyauF|pMW zY?E#6{q=1R>!#;52to@UUWL{E#o%=cZVglvus8HpH zEkx0C#8dAmkmqkT46u?~=S=#>b@?_kBqNZzdLR4%{CH=J;jQ1a`hJ$fj7Oj6(iB|H zM^a^C?XkT5`iJr`H{g-K?tpDC#SXX|vvldUJ4AT=$Pfk3MbQi8A#V}eiUos$Q7H=4 z3YE3D+fd)0_wGs-bl{}HIzq}1%4xJ-fqCh#VUJ>x?F=HO=x-Sis%IL)_~@~GuB|e^ z7pkz=e@-n?{Ghti1H^bvMLP&6g8;<@oflc+>hxZtY^rNx{R_K8uAAGJJ)gT4yTkyO zN5}xREr@uj&v?s$5WpgW!c(?8lrbZ@25-}GI=#Tf zXLMKKKyi`i3f;_)G7sBL#v$UsFii?i$|2t2#X9ahK;aS_7-n_UFqjeS8Ug!y0I8~8 zd@NO({4V^N@atK1ChxaEI+LUfd+aX-f>k|T=1>Kv<)&&+>b^L?!NB+oyUiob6}#Mq zIWA7%B`;5eKcjj89y8s2DC8BxNAdTajyz$3DVdNHZFVsJ|2xHVA1n+%-&Z3F`*r(6 zk4U^cESO+FpXgUmZg_)@TpjVJ+4n5QsNbb9t^u5kaG5paobw*!(q>jSny0+Z7%$;S z2!mtbcqy_S^l!)MzgWatd=c79%^z;S8x~qwQgo<9*Ey*p5uQz@YIwtY2;xt#Ru^a@ z0nZ-?AVD^np+M1099%Hbj-iwWP`q^vcn2i_g;!7lMlk0NolJI;DU2qrna#n%!p*F0 z;-r1Ra>vG=#hHPJv&QS9}am8cTi$=Or8xh}g`XgOSET(7=%6?}Cz z+qh#}G{Cg8w?sZS779Bo(gL_gg;qZ^2d8A7S~{wN47BGAn&U6dzs99GF4i}vj^AG! zS1jl?8&>QMcHgb68CQDL=JVbFx_4PtU+_cza_0D8nerj}(*Ln|$~2)2}L z;(S!q#!KZiAriBi>ylDt)pqo1HRqzn#1T4?JUdV)waxbxc>RgiRU24w@apE^7CZa) zrg=bKW6kfv2p_3!Oe`hm)%GFvDfS=2r&(D>9>QkmM$4||ml z(lle`h2JIn)qnM49M|VWjGWwCKX=Y>YIo75_i4HYz;s(Q6Y0Whbg6kWy&S9RdG`b> z040_jxnk4WYX=x{Y05oSD*EBJ&JD$5HCj7gv-EVYLrxSq0}MOc1T)*)DS@=1xlQ>l zqzPgDKTyjRfboVTxQ`Eu7u{|SxQOMRX}9lNNHAth+EWAIO4Qc&j+#TPgcUFr}O1S2&(Ld*#=(|eo+5Jwa$%#x32^5xg?u#$DNo9ukGye zreQdDzGif0Yu3eG-=07ntHR@d_pF&v2KErfD?joXJ6EWN$mQp6)i zF5#A14VVzs19Y_t6;JtJudPr@G25fAaUm|H-URG$RKXkaBM)#aX*gpWTF_XZua?4& zLto&&;1SmU%ww>onmZas%4O*N=NHPi?!9ArBwL@*uZU{me&g_Ok2-yHeSZ~M0|CBs zf77u;Accu7QRX(dI-!HTj%6^~AqS)$p68My={I0cics;K8L7v>cg9wZHc-4jK=T&$ z&aWqRs8ti(lv(7+g}2>gZ7ovjLLz%0!(RuxSb7OJc_eycNV|P2a43LT1jDmG)dxA? zcx^oGWO_Fcr%if@WwPR7Zw;hB={<`6QfdskRS|Fd%oRwyWeE1J*5#N8V@+9rd3@#5F%7`#yEq9x z#2r6FRe-lQS)peU&s&>kv*2Bf_+Rgb1-3ghY4n1ESLU}cv+OX|bH*qU@YZVS8XT%= zKa_ba!;l$H#9Zg4CP~E-d5-X@d$wSBjU@i0c zxCWG4zVEAp32>>0fNdYlE>2%sVIM4$S}(lokB{}p^su4NtpKG!#1;ra@EIOb804zo z#EGa18{oWM0YuI7`3dntZTr#Y)Xc3tnW-a1tO8q=!Tu>hgm>`*sPy>F<@<^C&0mS6 z%6QU26GA3ci7z*3`=q9yfR_!pHBLmFu*y)$YtFFN&(ghFBj*?qu~9Ow#w7^-yk9|o zF(TGfeNm2a%}-XH>FMo@ExZuYy(?_iu0ih*+?KrK*qH)t|kuhx)U4&Yt z#@c*1YJxS5?=otPDfJyi`m8gLf(&uu!z#{!J!4vTUm)M|3Z^gPE{Nj1n95WvwyfPP zk=hFh!Tqqdyj)jJxmrQt++8I*x`LJ?j^Z#Q%9So063VSd+7f_kG!yAH#fK2erU3N_ z(ILz@VgfE(9+vU$TB~G97YxZR^inHO)!1%y z%|UR#k^ET?L_{CvIedj2IqFbMM$SlH7t-BpbioR$>(ByTz3Qa#zpk?f@{eYC$>c=V zfY-H}wyiLm@-d&LVP)y6+K?7j>LWgq9kvqnQzl`IQy+0^5p;F_?dU=frP~OzPqT>w zBoFrtxE_$Ty7{nBt-&2Qj$^_!{?QKTygf$`eH!tE3((~x`#wUk)NTjVOVPl`T|4LI z`3Bf8$wRx!L3N2sadgY}*g5V;)v3#mKLUdMKgI5CfnUGxFsJ&tTVcn3FOij+z{3WC zkgeOjYrJU^po&y2906L$!s0C85ZZpal3O<{oDnxRIaC@I9P*`pU+eGs;>0#%DDK&}HS_h&$R7VEx!01NIH52lS zr`N!791qZdw=+Q@RoW*8Zx)EDgH8DM3O(o5#L|2p(fUJ}-0)8!2%7blc5dX&UidnC86S-Yy|W=CnakwTG5ZT+vZ4 zHc=NLyT>?#>xIpT0^qs{lg3Q%LiRv#POu$0FIe?RIg=PU-n+4%EqO?dOr4W#|Dmwm z%L?k@&P8H@b z`USelJHAm6RPfQTNrr+-ZD*nl^my@&N)tXZ;(3P7xn{reXy=#6{(+k;-kO5kZl z$jgV6o}ih8WQ5#(7$Kq8=;$v^X&y2zR_l?YHYg{_T;-W;3GYp?CJ%)?ao+)@fx{Py z!4tiz>rrxIT~8x6VKsj}rRrQ%YrU z=luCJ;>~Q)s~ll1C=)U=;*Z(Y4RE03*(V8UPGBZ4{%Z#E4Qh(zL<$ku4~g0nH#Y-O zqk+w#&DC6c--#EMyT==N0%D8)T##LoLJw}xhxnW81za;0$Ym|hjy>wJSH>+3q4%8( zyD#do4iE0{)k-$RdsiF~2M-u2uwhwCt|^Qw=3_y^EFb(9Kghpqqa7LS2`DhoXM&;z zt*-%3h9R2otE}E_k_DRsl1W_8OV!ttI$j``;cr4#X zz-(>e>c=_|KU2wPJnpGpXp8$j*UKC7AyvlIA-h{UV{3C#NXSoe`2OUx6LtGJ8}(L z*$v{CAs;AF9?zc8^I|eGhp<*Q#vM1m-0||{!Q|Lsw`m|{9|Ab}{LnMCOJBJg4Lxaq za(G$2k)bcPN2)nkTajqlFJRYU>?n09BJ@3(c%rR<>t^K7GrimKkdp$279X_%Oi%Z}Rp8zbNdEay zRplO*GDwr?;kP2nvFiCj2$~5Q6hWiRkb{1oVn-7V%oDqGL%cFa=0Irc>cq%i#ce_< zXQ&}NK)r_{QQ3X6=R|gC>Z?O1MJP_cdX1A@PED8{SSi2e$F)isBGRZqLuvj z)J08+_7Bcgr(n>34^vWQ(9Z;P!vQEZ23eGJ{p_zlGM0fe@*%CXS%2@I{{taHJ-4TO zG9c?&Wp232I@AlrhrB$j ztV|N5jFxB1GNt8U_WV170aGWRJs8>}fjC8PaXlP9kK+6Co=<&hBL4RsN%uQ3x0J_N z7k}t$sAK>T(d9kF#uo+fL8Ad4IvX?yKnegM05AZ80{`3>1Aq7tlU>HMUqB#e6}`nf zlF#xq9x+R#}{jIfP=MiD44)>A0PRfqMa>ZfKmMO=EuRUuB*d7-%^KLr4k^diNnq({c0_zb||cp1T19^_S#+)RwQ^%{)^ zF*W%6td2iRwNel=51+%@{2pV-u8*5jkW%?r8ivcU$bhXx;_y)4srIT-jddFi+ug{ByK359}7|<$vw)K*W0fFQ`|5?~;OM?Zu zOd>~Xb9eZIuWmTCNfYwE?!E4UMzpP*LEM3{uZMEGUV zKTm>RuWtG)o}b38C>k{Je+e*Ub8USN=+j;Neo+EB-c!r?t-@jer2z~Vf5^qHe!65! zGQ~%@T$R&N8MA;Vd_Fa(`b6gtA@IR?0GG;ZBLuqhUdlAMe%sDF3aOJe{U9o`U@$R$_}5^ z^ycuN;A1V%d6zPKoqpIv;io4YwasdzQzA0Z38rke^GUQZA{%&zO)S+ zw)t~1p@K|4UWv>GUA0`oL$U)%m5i-D-5Adg`{%rw(ExtLIy2|e>OeSiTiLyjjkjai zV~3i7V|`m&V&S?d?{3vAi4<-72yQtrLLTo{bpkYid8w}q*a$zwZ`lA%3b<4mgPZj8 zj-NDfm6UWxBLFC3jYw@E#?nPL<{t^oW%d;D$;Ap02<>=n8dP*PFxhMSm7MRc9PVHT zh~ntrA%J_{fI5rkqWYTe6#JZbLPy3eMn!AwhpTAYZVNia&RUHgBl1Q^K1#%@peN!F8$JXgV-S%L$3ofanGYYn zhuo5zNt~q&$K9p@$}E;_G)o-L7cRYgy9Wn&~omc5Y@0n$q+;e6ixj^v&4B*)W5SH5) z2hA&bchdkME*tqe_wXsZYE_B31t%sSV2n&DOg3pjdC)LduNVz0*QSsEC;s604Ew0V z_mzo!W1ceZFR0ZN)l<0wG}&_0ehq&*A#qr!0JbGA+i+j8&zushAEj}DCw<3yg0Edo zONnCd+i%8^H?oamxhq?vQ*r=!nXvki=$9mt16R?Wbf^#lxCo_JTv#{=ih6BM2Ul#N zLIp0~{cyO>FiJ5E58ZWN#QF~>+5aedTL%mKrxhCXr}O+B`oHu^K*m4CO8Xd}ocw)O NlzSmt@zf;fe*uFL@kamv literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step4.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step4.png new file mode 100644 index 0000000000000000000000000000000000000000..ff5e1d719edce0c232700315957ac554e8f7c42c GIT binary patch literal 16781 zcmb{ZWmsG>_csdfnZe!N-Jw8nhvM#9+zO?*78o1~6f4EGXmR&4l;Z9VQ>3_Si@n_U zD<9r-p65E(|D1ft&d$zS*~!XUS@|W2(NtH!L?c53002`-QBE5G5MPquNfgM-Wrva;pn z<=WcX)z#I)!otPHMHmdGsHj*`QSs)@o6XJ5r>CdG!$T+(dUbVWZf@S+-yawl7#|;> znwlyjBeT7|U0hu3@9!@qC3SIeF*!N8zP=t66{V}ID=8^CJUrac(D3QgClwWyzyJPy z|Ni~v=4NbcY;bU}XBC!`lG4=Fl%AfRm6c^{Yy0p1Uq?qrPEL-!z5US8kh8P1hK2@V z$cSO4fsT$&TU%Q~Lc+tty_=ic-rnBC#6(wD*YWXjQc{wMiOJ*RL*ZzFx3_mjMuwrG zp_Z1GpP!$Znc2+D%;@N-zP^4~SeTWSRZB~YgoK2LhevO3@6VqEg3a7RZ+ zH8r*K^Yi)n`MJ5dyu7@Ep8Vk8;Dv>S+1c5uswx*3moHzwh>MHY*Vpgw@7GLK$Hm3D zmVUUqzbh&#I@ZAc+L`KA;ptcDJHI<$HC}agc4nUUb{IY!(h%G_*1CGQ`g6L+roj60 z^77laZxIm@e+L@=!OGm--A@cD4leie2lG#^&l1`{8)q9G92_L|Bt=9HpC+6X9nlbRV$Qg+xzWGTUouvF<|2Ca_jc!O zyK%OmZm90tK;hql!1dqj<4fZzSt*~oWAdi2e=K)p!?K@lueMH49(FgDH|I-(+L>~wC^9d}yRH1}+IjYPy5F%hKeIA@ zzc@TNKbSS}Go|;3Wo@(c*Z7`@_ZPw1r?y;7pT^F86~ddB3PuJD3NtTa%vFn~|4sau z*!wrRv$YK0`r5tHH`~`a(HYa#>eiTD92GFXHt$(iQQTY9IJU7@l{yTE->*(MRD{j0 zZ8?6Q6HAHF{2IO*X8vdV*Pp%?r_c4iO`%_l-&Mw$b$*nbv1Q!tDEEu?Doi(>4KtDH z;Y$Jl2^A$dXdv87aE{)k+n%i`9cov+nvNWN|4{x06mOSR&QX^km*f-R{|n%ShrnOFk!9y z42Q*TPW)CRQlI6&T~I>|_dClm9v8^O5T`pkj5GdQvQ8AbfN`BW$O8?r#ev1tIg%nw zMg)dU5+2^_ghwv3;~C>g(aI?wVZnv4@?A3Z38ZHDd(ELDyzI!xSWq75Lg4r6GOnYnG;kb-E$=xV#qAa4vI&03=BPG7Y^~a zIno8Qge&GGoPa+dyJ~)hEb=IRcApU$LT3Og{)bN>mBbs2iya+jLRdvmo+VHfwDH1( zjSy+fm{pYSuN6HO%@_3vP9;im(5!d~f+k85UEqm@JZKgz>hCtwAOZ~aFFp&lVuLW< zlAa+VP8ko+$_k1FVQ%h!i=HA){-sbg0Z}BISu8c~HMql!fuwKTvGKrXw%nxu77>N` z##LIrnsi>=Yn!AiQU?${)^n*%?Yq4lq#NS5sIh;q0wqrlhh((U>sQif*9$` z?jHCI8s2S|^~A_$Ua&+z1`vVF1Ga8X5_1HMHPEZnf&{4-$jmG`h9LRDFhza>L@V^k zDS=@{UM)mY4R9mH|HyErbtkKo@#BHBr0k!hon@s&0aw*OSll1^>Vw@ZlmB>;z>Hn< zo=B9@(O9x*WTG3{b(P+67YQ)8u`uL8#FjBE!h(K*)1DAtCliK)vS()MK|-9##=KDd zIqUyO-f=T~>KkjkbDLkXzI+up+8i6(m<0B=K+}*;L83hd5Ex2xB#?Stx)gM;Q^jfo zA&@Crx~e6+;TA*Pbhy$DCfE>1b(bMiM8HwFJYTWq8Q*P#kH|OpHzt?y6@Lr( zE^M0^=zUXLSjr4;9l6#A0>=;{U7Epn;{M&%G?xn?ipX2S z7fo@+omQlzMYLEI{BygAM)R5Iz3-Pd?%sts4J#cil2CC5n}mRCfp8o;wc+^4pX$}x zIxVKnxV4mbUsXQb0Rzp1;W*t(4c7S4AQB`f7Y1A0t@&+->RAZ%lueBW;s0pgp12TQ zb%|kW`>fEEdJ}+HEddo}wXr-M3VWlZS4B@EWba+UPvfd7qM;oEBOcpE?C8=-xcWm# z^_5!GCvJrW2hrkg$apAXC)c{jEfvz*c$z4?O~xMp_w_0O0rx3f^AaCnonov4SCC(w;7`XN+g5)XI+%gEF}0n z!^l>nZu#L;@o8qyc=31DEio0k^L4SecHld(O~>rB zk$HZ=edbafEw9zr38_2`O5Q3YK39Y9@+W^OHyP#Szt8H%RsE%L6bjr$=Nu0&I-8_OrN z(gSdIGh$KF`05oY1`I@?GbOH5KGw8&<$?u(lUG&79r{X8VLAlUUF(y z%AjP0b$H&7=LkFZ@9L-9Xbq+xb>1F!i8*ysQLmB;*cwLRsqknuDMy6ONa6m>$+C}= zQk6r*KW*WiAqn}aR*PkeM5EO-T(Kb(&-i({*3DxrV*G5x5;bkT#Im(%f>qey&#f^1yvPZh$5eaMD#U4_EsUNzvBomDj zYNJ%UiRU>njs2&|R66nN4{eCR1hu;YnA_%`w0qp+E(#6Erm_xK3Os0NO%Fv#tm~Ht zP-(2=;{iOWezFx2-~;#gXB%LdmKOTXlT!ct7qHPnbL^=Ekgl}pgMHm0gFvIKHXtr#&?^8> zr2{;qVnErEv72h3Q860Q@zL)uwTmvW0k;Vu)fiHu42ZQ3!RfEDLZrYJN3=`$5JQw_ zkUUxH(lEjx3XQc_@fYPJg~y;GOXaaglJtzRzBVH-_`S=8@L3oUv|5z3^Df1zT^tDM zoq>=-y%kaNk5S7QfFGa}bFf2fKrAPs_DjpnyeJ0RJpQaP-*_W*W*vjpAIjTA5!peVFzh`BcB8E)j(V?UH7%pw;9e1-N*ta#_NLu0-|Vm zf%n~rJXj&Q0F3IaZ~d`T0JGnX;`xlmBzA4d_l6rME{)P>ukJ7P1vf&hq!ufc@w7f` z>eraQSE8}vo_fPreQ2TNM>Hbdnm#jG%+e2_P$jaQ@$$d@MNU_jBF^l`y^ydUez{^! z-f!njI2{2K`C=+MXduiAh+*o*hPMSQto}SEhaH}foqfHB44-U~|J%%PLPunH1%0i; z4Z&t8h3&4r)z81)E`=?B%N2s!zJ)Mk<|DRz6kc_WZ7~NX9LIHhej{9Ppz(cHrYe(= zp@S@jeA6UGs4XctBCKMnnTAO z&2)nPbi1A&J--GbhKE>dfan>77p`cL49Y$g+7P$LBaMn;Ty_NEb1mh#xw#=w(7Ch4=*#R7ngpj01S6zi^}| zTU&ww4>e$pkMAV?7t$G)dsjZ_$UxjL-{|!(cBvtv#Z&52Bv}R=FMzv!WyLShasznR z6swPKsA>m@Vt1bC@uyF(SYF#M0GMm&OOSkg4rtIbn%6p3tRl??kehRUObqK-2Sxjk zx)zY>0ST0nK@TYKkK&{(&;VpaOgNq9aiejpUq1B*fZgazmHr`!#~htP3SVl#-OK`r zK`6w4M{FSQ`1supVHKjmwLZQk|9?|jjD?>je-eaN@%I10Bou<)l?=T!Ne&m5HQquF zTnO4x*iQst?-H*9xo+;eNM|CoAK&$RR6_^Bz6jc5Q^-IXr6&VGZn&ml{Ru$oGR08Zm4v?c^;6e9LU@9>y(sp9WO7sgcbUbMUo}v;u zMx4aJhfyw33GMtRC6xkV_?O3mxRBi$EG77;-wGha;TZk&KZtM!vE(T!lu2XIXeE;l zhu@JP{P2XUovnD1St}!0m&3E*#O1o_893gF)fhNhyrjcWPyCN0Kbjg-U<<(#&%Otp zE|}IOcs#F~Q{3_H*kFGL@OL9bY3+D%Uno3ZC^FXX4c&2gqfWm}_jvwJ$>t|nY|2D) z5dWo$B!hJk94z-mv%{oyX{k+e;lmA2kS3egvuXGAa)Qo*JoLvN(~p++_T1&ewT`Z9 zleMI=Z4H8;#2&<#pMCR8G;S$FCHV_9)<lKcd*Tg*r)l0^?ZC#!j&BT-WO61nGpDUPl>=JwdbX5-h$uIbI$Hjs|^cDtR)+ zDy4SiUK4XZR}K6T)Xa-@EPSdXIM%H|KGOV)FPx&ql1LKXT(a9*dH&r#DEx`NNTJ%m zG;P{B2lPL|6W|H|Pr(4EPeI9O|A7Ir?<>`aWN4K#Bb3qPHJcwo5M4;M5gKZL78Qc# z{#h!Om|0wuqD;|YB3^i`@KG?i$7n-;og`}MxANi%z{r`oFXTPQfe(TbL z_;Sb{eL1@uccsddj-bxoPVn8CkjS5JQ;5;g4^9Jv^*Js{_;>VF?iBi|&biH7WzQc` z`fYyqawBGJk7~F0{Nsw#1gMVllnT?LC}Dd-@i1ngx5<^enx>33Z2qH2EUZJh|srBaFY|V@1v2$OBS^pu8>@-mE2uixT1GaFMpv7 zsW=GR{g@#>LW2VZi&Q6UgP=J^)G0Iu!E^@ubnwt+X9O zuB|^6g(#Sg89!4E2+}J+XAzU5rVc6MNs_Y|CcwEUM&kwV;Q|X#@hqB}?=4^(_&lda zUWd9hGpbWazkr;asaw)o)Y z4w)2h#_f$ObWVS#$0hc>da0dGV$D4_PRMBuskR$6*<{ZR+G%Lz{6ofl6D{sd{fYF) zg><9M+lw6F#Jt$LP-@_gC+=@m3i6Av@HXPM82!eKoFq}$>*a+|{K`4LJrRU~UIdMkuDasp2lyF=HRO)ACZlHj`wo>ETHvKW zE#V0k66NP7pf4>Qg~-a|2|dQiThY7CN0GJhG$;NhfBD<0rwWj1ksCsn%M4nt3Q}Yk z|H7+XNG$oyfY%bxw&}LHC)8kSITB`h`N@a~nD zTHt7n*bQRa!DWxip)naJy8slO0ofRIM*z}#=QZpGmzIVK; zliy+pD*8o&gxuwc@ThcznO~}Yl1~Wpz1-SDqWlmNfR-Qqpu>LThS4>j$?)yXRVt+- zvSG}5eVWa-71dWv_?~8{4O!G^9un~oq4UJDHP7ExEvA-HUTj?47Bky~N6Ebnqbn~4 z{ess=jA6pSdY?QqbY{+5=d!Ug=cO?6XE*n{*BC!h{u0~M(rtb=cw2MJK#5pGFI8Qz zA`qXW!nw3=4b^XOU07M)TO1hF6@~6DC{n%lsFPFhYs8oGSQ3!QE>mSha~Q!wL=Y) zm$k<^b~&|TC4sUED*+qEaB*!jy9cKaQ5!)Uzvkk$h#+!GbY-nyg8JBIdYWIXmSB$j z*6V+Y@#i7uc=&mDs#}n)JUI35wnp(TEWww|du8wO)1%76@vttB@xM7lwBa}}=+pm= z$c^%5Euy=oX(1G&XC2GIbZ4%t+LboN;~R0X3W4D8>q&5L#yZg|3Ul>HzqarbV~^z+ z$;H0X34zQikHKS%?yEulqIAwSRi4#fJiHXPg8ao4(&_Po>uTs2Qx;tK1c6V72l`&c zRH`W-I!Z&|k~n8WCOf}+?tuAsTI>$wBBK_=4__&ukt+OTndaANpq7ayZ&vRh zMaBJ>s6Ao|d8UC14LOn+rymLt)J)ff=$AOjNmuI$IIbP-{C3C%K2O1g(Db661rv)0 zEq3^)g{zjvrE$*~XD@u+4I6Jk6sAT-jv)tW*m>PM*d*YYVXhbW_Ic1D{1x%ZMVaEe zLn3i#-PRJD3k|eb4Ygt0)M~LD$#o?6z2-f#num8)Q%`N5Jc0fKtOrVTYGURyd8mC& z0us|XWOmZC8U2C+ui&}!Mu)RBWHepyrrDlC9Qdz)o4B;?klJLV0cht5m6&x%z1imfPljj(CmWb`m@1{nxFPx7RLG-m?URtdJZF%{kMK(itGzsc~|4OnntW#WUxF46El=8`fPMY>UfevO${ zyXJ2HJ~?6aZ`T`ueojiFZWZCx22)tvOJ|>ze&&%2sOmANfp%mWP5F|}Am2h>fcGbl z$bs5lZN)|OMxeMle8=Gr(`t1BuiDY2n7steO$~*r5nbIZEqe+PCnLYU?QJF#7l-aV z&E4m>g>~}1%%l9SW*|97bhiB^WW&8TKV{{!bKX0rI~ypp-Y}l|DtNF#4U|t|Tz`(p zu*qicw}UYB!AP z^Kw%Gv^wHXSZw{8{X;rPI&{!K)@;Zs369FyttU!2;!ws^)WafcUsU@b1evin`MOgi@Cwv7;^UT$x5u3K^_MQ%>IMcM|u!}75A);!|@ zkyF0ppHk)$5=EriWm$p79KYgsjXs~YX}+c>s7b@76{&!7m)_g<_(Va(q;&c+y}py3i07Oj}Yf{Ql!>&%2My(-u=s9(0`0 zvfq~Y&`&yOS&UzP7)@Lf^;;Z4H$clyp^ zjywr$_`pa6_%5T~_f8`N0oO_cvN-0LsTOD56QVB;m0g8?kE@Zj{fz^p=n}FK_UG$Jva`r)$mx*vKsv-EUojPo)38y^t+iWoR8Db;TfCv}Um8nhYc=eD_U5M>?xZ zNCh_4IH7q&6;y!_+C4^aK^LtDh6b3-ks}ZwhDl7?;$G`k*Y&Czd9o)^GrpGUyZSs` z-+swEkW%UhgSf}aoG>VRQ`*i*fELC6g*}=^P{Fi-_qwAl>Tvy% zStf89c|9*H7LCI$#xx{)As&KNCm;wlutQ$E^-1xZ)lgksnF}-B?^_XvQcG%81{`m7 zf@Zsz6M9hUT0oU>3zK7 zUj-ah)*t*4F6F>Z5>-TWjWT`peo@%OOEwKA52(GmVFdeLZsrJ0{@DCO0j*|z12IUo zeX#;hzG5d^lYwum*}f?~q6OvT#*6~XgP40KrJ{mRSh~C7(S|oDC&-)laR%6YFzIV& z9^b`=*SrJeCA}DwQczq&MLZ*6=OUS-1LXqPHNl6edJH>O=1HX66hN2z4 z>K}umc|WuCGL)(wSwwII>JW}=&kLPnFX})p(?q))b^)1sOsrFL62PRwKgY-cve_Yr zp%UnoqC+4CHJ(52ZKD)F)9wEfXbz!3FT6j~@Il3cA`3{bJw!#JAzyP`l8;Y@1a60i zmXW5lE;Jx0A0Hx~Mn}>ALhg1v0NPo=%cLJ*7kSWaywy4Oa`&1}&q-W>n$L$*V)uFy3hi ztSx*$y>ei_x#Gol@ZyAGJ>nVOQ$;gz+vi7r^`aAns;oo&&zyv#8iA8qbSU>*vWunR z3EfHbqZOe2XsZM94BzYVJho;B8~&I1Z2-q7@j^*V%H*fDN#lUr z4pzsXDDa48B;zD@xo7X~NiyB>s6TW``#9Plv3nd+)*fC^MSJN0%0BR0x3hUgz} zco|;!Fk7IrZ6V7-&d%9Elp}U{)jPK6aEKrE; zKU0j*iXwO0q@VL61^zz!{{_phRCT*$3Ej9 z09}PYT)9Z0=X>}@oBZ(TKsvj?UqFGU^p97hp(EmKY!u$9|HpElCE3<44e7OTJ2!dH zB{a5aXtYhK1kh+|_}`XSUCs?yXGd%<)-zMc83VW&E!+#Bub;VYc9C4ugQ~d4h(n2A zulGnv8jI`6 z53;ZNt zD3n7#e%uD?=iHn~Tu-QN+IeZ@d9%r3fyIJ(nUl-BjX!P8U#q%dFCnXW=6;tT`OMWo zn|cg7$b{;6b9sX$*j6?5ye@r#j<$#6tOW6Bne4P5ftM>PS~P?(ydCLdyKTOATBFJ@ zt|u~6rmCj!DJk~~YLxxI%HphobA!nlA8gHK^myBbMz;ovjCQMH#Toah7SeFL{Xr~c z>-%ds29Y%3&A3LD;WtG$qMhI11FQFnyPsRHfmGKf;8oYPM7nJk`JI!$XH@t`8siae=LevUeBJV1Wu0xFD`BmbxImlOm*0RyV?XlRp? zg{+GtpiC)AQe!$s?N|85xqllcFfFN`pT? zv+t5k)|FC4_MTH;oXKJhth?PvQarPctJU_l0iF-R!f8;fUDW)o;1SgP-v2(^kiCTx z0Lo_*b$~Je`L!RHf1MfsB6{kr6q*lhNQe7R%D%v4_ljl90b8#5d4z!BcbYu{PjEWj zfkNd?Ibx2?)o+XOa^TmVek%p<#PjpDOF-=dk*2k0wyuH%E#$Yc8=PL>j#}~vNz~J0 z^|6I1ZY80Cad|xgI?mzz^72}=A{}cu&5plOPUMlP2LdlR^rZI)bk8)e@!p*inrAE7 zTO49II*x&{WeKfPV%=cvA4v(df4oD3?oDl>9Z_zwZkcF&`-zXS*QRH;h#kx70_VCD zO1Ni~cSMS;$@M>o%`51TV~t{aY2H1almYXKGbCMTc!;(qE3_n4HER&n`BG>>lXc2! z4xxu|euwl`4E9dL8PBIiO!w{|$<@lDdVMBkzwd++9D) zg1`MaCQhF6Y979=^E>A%sH9bA;wzg}jm1=?tgMd|C$c7IdniGk-1Y|VwN7X<4!sNc z1mwnf98VXkxDh}bqaV04s>(;IB_}M=^3Dt)P#tIl1gJBu;FATiZ+-s=w^oXv zj!yM6U@${QV`u+avI&^@(zc0ZI!=G{u>4>IiQaevbbEmJ7B$N7lnvMcOfN4)u35wm zFoiB)5WW;n3hQLGAcmPaj(aKJ z$mqNN+J#EcuL<)^A7pdf{9ZSTVuv07j~g{2g*)E^k$ zJb2p0O7D51*|6UNCSUb*Y@Ch00ehwIrdM9v9d1Y~7gFy#fO(35zs&%&2g2}JvK>Vt zEW1#Wv>=yiIU}-GX6}`COn#fL&UX^lr{b1-0a8n`LHFLoc2vBK{FpEV7z=|uk1EI> z+1+?S1@Y(kLH`5=#@)Wx39HR8@36y!Q~VIql`lMnq3@4$Z!C!K?q81RW=ZCX2LFEW zvTjFYQTa*PNz0VC-s-w_GryAcVI$miclGZW`fiOg>oX3_T;l0&%iJ5qV(Rc(qKB$x z(jKYyhEM7g2E(vNrfL#{%z}NBQ<;WAo~2702*2qd_QTJ45ZE_Lks4AM4g$BeOQcxh zykU5vgQo4$M!r`5xpN{q>keYgCMm-`^-8Rn#d*2;z~O>`V9i>HtJ!EU!n!8*Cpzq* zss{TO7jxkNZ&naZo!3?>y8VaMc1L1Zjpu)K7S;Q6s;>=h@~)8Z;rCU<8z$kYWo3cp zW>V16XXjfM{-~iFcc5cX{~@e8x*)3fq7@~!_}{;OE!?vzEm!+SaB<;a$nLMhip_-f z9~p@w?dUZN7;tXnh#c_ZP(2YJRP;mWBGOqKsFy}KnGG37mX>NCku2Ftn-nH+&|d-e zZHpSy#B|4y`9wse7^C2^or$higkDY3_Vg9G$xF^tVJO-XqOTE~aAVwcb?`p$pU7;l zD;4z~@|NSZgEPoS;LvM9q6`bJlgXV8h}_^i`$9Ox(AN-1jmlAI+zFg)(5l`6W?G_D zD3sZ9!cY=>X(p?kvK&VW6o+XW5l!z!CTL{oMgw~OK2s16vq=;9F6!ewhA6^WVr!UM z@}^hYsS9|Kor{zel1>zc?+--8u)b3AO8mge1BrHs34yQ+d&BTxsNHAbYJkdqb`9k; z1^E^5Rv>;4boFNl)`!ptfVsa6QVE{jX_5EB6s2T&H3b}qrFuC#fJ_&l<_mMyrOcy8r4Jbqnd%Bq-dbS zt)SV)pkYw>DIV$RPu};Y0)jHF>qz;c^9Vx{&>GV=HgtP(n8Eh+iaS*F+P&55ad}1~ z_|pOK^mKo^A@rhEg1SS=@5@=oWezM7*i*LSs9;O7uU}m}Z5)xLuop4rgBo-Xl)gJZ0^hY8`v1F0 zrjX9{Bi>%R={+_EeN^b|d|>v*g}EhP%6?;sDD_WUQs zkUBO8DEvdB>aEo-P_GcphotHtd14AD6^B}v6cS00M=86Av`oXDCQ{01y^ccc)YT*QZBXT209k9{L3XVR!(EZ}k7IdgSW(KdpMx(YQ22q%m;`qA<0N9e% z!pgLT8u}nl%r7h)#(5wjzXLfO)yKuJA=$#*ab3rfg)kSdyEKlB%v9t|hI z=EeRDVdT%zXX?4?Wj3mlnUya1>f!u-kfBzUe*|0*>RSZ6KR>NL=8R-zReqk`p zXf}H0pQ6!?qdrw^13vswTi&swiOMq2?6$E(83c}AOPUIj`|7u6oKb@XS9Wxzr=TUR zF)^k1ps(4-v0nYMjDOel=Rs`+c(>l?0w(!GfZoedsf#q}%Bw_66`{_mwO2X9G7lhS z%`sZ709J zg-r!u(Nxbmy){#Q8FykdnzA2~ds`LT3$oxz6y#Od@uBYk$boEab~lXbm49s9%Zh)$ z?-+EI%sebC?1D5o`}Bb8UOffDKok=6uL1okts!MzE4=}Iyv;xR%?0+g5{KJM@9&1H z0SYRn^a|mxTkXQL~diiAQ5@R%%;2UPiJ>D&u)J`dSKUeLGIe>th5Qdic?JW&s zzGu;#*ji@W1R1^4ge>k~{%uc}4e(#X#&88m@sFu2Qb`%Wgz8cOZez&aaHE`JiQxLD zz+~~%gp`7l0E~Rs%TM0(IStrw?hoGsXhe}FUk`m{Hj)Z($QOYoT)SFlUQyVVqi2?B ztRPtKFrk!&*kQ@e^icsB*Vh;fSemzp{#)u0C@?>E0C<0CR zj#!o+$nzS#>lz#_2c~L@BB~ey{y8DK^0l3!wnQ3$_t+`HkQ4sXgnGiz6EZ1V;P~5GqLmTWPdu2w z7UxsR@91v7i6tFg{vjQyic_m^KoD)tnitP(-LOuvei)d=JGe=4m69mT8XQ^2?`qVbWc5=b9AkYtd@%-w1! zq&oHwd=Mtpmn%VW+Q=6@z17w8Ged1Djr6Njy_)TC7Xnz+#hHGdq$VHqw>|a*H!$IZ z%=7T{7(fr*EJe$|Sjlf*{Ef5Jkn-la?K^NH(W5VvFjJET5dx2TO)vb0aw?Zx`3uTU z_U>SRda2~d;sa}Y3I=21Hj9`95!kg*3;6J!M-S1pjvx0o)DOk<1I?9a;4vWL-PD7T zf9-A9%(q?iO$=vQTq#%hWq)9RbgmK$tnXavJa71!|mGDzNf>lUy%L9)jT3dO-J)V4yxoH;8yP zc`q3saoLUIO(d09|4UblB?tY@#0lsJUHSYqic?^{o;YSnc1+VJlwyy{i?euf3vtjo zQKS-lh5gCof!>?O=$Z~ofY{{)Lo&f0YePnV86c%u;et-cIG{B=*j_ph8)Q#H**dR= zLTV3LNy2Rb6VBsNi=fF1G3>#BXZnP(q7L}AP{1lmG9p2vrNW!0Punk^4ncyf;yN?6 zV=>?&scgq3hy_1<4JP?vDe)JT4LZC5N^N}T(n{7bQ%4zdOco8eVFD%!UailW>4;5X zI>J=U4=Lyf3eSg_3)4kqFxEyAJC-SU_HuF{f9C{)7wkK?5tNyPUW>k}OQle#6jaOg zjJsvd%mC$^eVSg0Q_fQc&F*xsn*c3wU7Z@(+r8QVabHj*E)4tbuJQ{ks>VFu1+cyl z8Ejg_Uc+RX?>#D*)A@~MyHra1bs~Y+oKz~K+!7^oWq;HFVKS@SvqS`{v|{!z4v6F; zQwK#;VRZ!*nFWM7Kw^r_nP*DT)`tlq}D!9?_ti$ANV2?^E^7)L}(VzTgO zM~9aaHyLjR^WW#F;W*+CQNU@YXSlG($^jMs^5dJSP31C2I0h^3ZWWLXM_Eu`k zuFRpptUpA6C&v_82A$Og{?3WHVq(+03T0({j>b}C{i{F+DsOxUK6+)1;?c2YygCG-JN8Byka< zMj$(2K(dbGnVPjLgJ>yh%hsc13&oaVL_}iMH>D?U3R`ytT;&}neS?!J730iAUr5Xl zDqN04^ddgt8jayd0fbL4Oa660iWH0jAm9KfG{8$H4HS?9Ku`b-fDoYFm=^VoRcLr% zlzc9m)USf21)iea4$Jc&MI6<@FPTI(dSn~d&dYV9>nCYGkC1?vq@v4c09*z!ib(jU zCdTi>y3k1MFxb=z0+%5gwK3@b@unI!TlNMoCOf@U)|7wHk=b!GWA)w9Mt}mt-`yvy z$HGCQ@I3Hz^T%(U7DLSCwe=k@iyaZ>WO-Z=f+l*syN`RrAn!4U!@Y6rrDCKp=_5~? zvVW`ApUX+*suHti7;qr1?@~G1`)x-6EL1B|bRJ*~pvq z`I{A>F@`DIcBfyR=ZvIj&3-OjO`Owq`*KU9B8Bih68A$p|3a>+vHJ(+6s48b11CZA zc+X3qe*xJscd$^lt?Tn@C;;~Lsz*yO@b{jr-6RsqP-?&E)jXNx7%Lrc4`hEgQtYh? zfM&xgm0dlGRx6D#EOcCg2W-3h`~XPaFC)IHGG-sU4HO!vf1+N%QHehu5yZCyvquCP z*tSU}WE8<$%k|P`?0QME?FE=RE!6D2;ykD`d4)CDm^W)ew$1Y?1$eSL{r}!%+(AY7 zQ8YddNqJ<&(KvwC*J@d_~_>i1jo}TjZFSQ zaO?1MnWC&sJ>bH<{al0aGKBPeIG`ui$2$hJO)d?mhch$#VHDH8?`J0BxiM%t1&siw z`?N@Ixt@oc@dzffRXQl(sy_fB`Js4f$p6+P$Lu-x#JE*?V1@aE`BD3=gU^}UtH8i= zL`lebwd6_mnt@QLp9Qpt>P85q7Eq&GkIaC>6gi3FEO(7 zUcdFysf7JIG)*uH#Q)3f1FjTMhNMO@6?o}F-NNlvM~sx_bLyXi!W!i6Mm)H?#4X!; z-|5Q|L<~cC8TJh`zqBj^MWzil4C@L3z_750mx%fR3s1yGy;P?lvT)O#@kN==q9~qJqej(WX0Hhd)7XEXBG!I0 z`*Hg6Q^+%{X#dP1}kCO=}dzBP+981TzVGvEPcm4t!nG`LK6!gBjKj!!z zKPoGNmRjn^ySIn#neIIBBr`mi5=^k-iiHn#ULNM=QtIS4MkvVKx8rH+;Gb=yfZO1B zK8yaMnL%!Sp8`gPCyF_yn7Afx8ih(vK+0l0(=6$gjA;RZ7ks}DRrF0 zyNjwlDf8Ddy%WCldY1Pl81g}oc>N+NA<_@l7~;KosTh4gW~cQR1lM8Qq!FgJKk9k^ zWShb4)KXE8Mg51X?j`-Nlnzi{1eRigV2~9d+0Kf^2s(0OPg+d|s*P|s+tf)@0&vH4 zfnr3ygw=Z6s1>;b5nn_U;2G)`xW?yM@s<~-ttUSZJHMCHYi9GXM{`%`aiCz7@OFp_ z(?c}SX$|vuwca1C$AF=n{>4J7bJ=-MD-21^T37EtNa8szJv>Nor@j)akLZWhUbPBP zzxm?mHe*yr_&vwLWsFF0gT+K&Ls}=d$=_d4R74FRk1QiWz=6k^{;6fBW`t;2jkRs9jg`!H zK6OJJ_7MO=!uWk+YoCkDQA%nox9MGK8ZP-tL~ zx{QI9U)!&9G}RcBt9S1mqO2&3hfReI005rcTWM7QKu1-< zBbaEY+hz7kQ&huO`JMWkhlhuajg7DMewUY*At50mA|e`z>Kz>&;yJsQekv_3E&B@C z-QC@HcXxStc?AUprKP2uam4-@kwF@9!5C6+JyYg~Q>G z{Q8fNkENxhCnqNn3y75DWHB+Z;o;$rS#`1p8JQ`7G5?(*{T`}gmsr>C`(wSNEp-QM2b*Vl(YAVx+;yuG~*3=DE} zb2D2rU=_ZuE-v==_E%R|fByUl3kxe9EipGYS5i`H8*kIl(9qY{|NQy0rl#h_^@YE` zzq-2m_V)JZ=%_>9r-_M)K4f2PW9-Sv$4A-rq3D|av_v?WA8RWE()Y-n~U zvMpk9Z}FPhcSOF<;->FEvsxz@;^ z9N!!tpC4}=Zgi|nNiTHSOZGgl<~_c=T|Zj;Qyk|~g}f*XySls_-8{QLKi*iJ?U?8& z>n+=ku$hn4-*b~k9$dC89DQwE+aGSVCAh)To8+azdEmi%eiz(+ zagzJeo6aq`wV$I`NJy316zU%!y&uSoe{xkG^X@+K(N2bt7t^pq6mLK<%g{SICY7rr zX{xseASUegH zo0xb4H^#s)8!K*xnf5)6kq)s!Vi@rtj!|7e1I?&Cu%IX{($Z)fOc6mL{xmcys}wz< zb%gBs^sYW|_P1IHQAt;zgNrr;=A;fGZ4loItZhcqSBb~e=Y&aZa%ptr5@5^zGa@D^+K`7=|K7l&$_Gwtmj>2hSp0aH~sIb3g zpy!|tFrL&25UYg6mIXe799bNA5$Z#>LwnedWPU267YV!q_?Y^EP{tL?gCg`YdYx1d zV-|%wH*6a0aS`*A7>p;_|19-|6cmFe;Egq8js%+UW&vO1tD|Lol zLtr7O;^Rx>)+)i*iUx%!pjNe;D!twPdjB3jHOB?W7 zeWk)4#mn`RcU_p3v2N^0s=^eXeo7zU*-DAa9&Vl&_~%2XCzSH;U>zRbbg znS8GwD;+>)(a)KP#p~*J#hRhn2Iov=G3rsp4wK5BeJJwYnIa4F9avKeTH|8nRv;9% z5M>uX{lAlKl0hI|wOwoz%-h!>WKMc&@C>qIGAm7Da=5a z7-84<7*r%>gH1HrvNd55E{(>bSYI-%p3$^~iL61MkfwDQVw7z^u%nj4%qma(#b@~^ zcdDKaFCT+qOHV>AWAI@sCDD;;v*xSNGIk<(`p#M?AyKDXrj~knTyd;1Ikuv*@I%42 zIzgI*(6#W>>&`TqWN};sC*W+Xyw!Dcc&-2JQXKIm?inE%^nZmn-*~WK0S+?vlnf!4 z_#F1FdKv<;Pf~v;j?DU5&_#rsQo*A^MJULU%A7Bb{N{S{H8HJN*5eqPpg$s2q#8sB z$pWlx|5zr#=o32bzNqMuV87$_XsiM1HrtpNKwsjrl{QXcswK=hvZnD0M#>qsRGCnu zw-Eeo{rh)eN63kI`uiLbbu{N0 zjVCQs{{{VJWN}rTM6o^2k*CYXkNUC-n{Gk;HgVD*Sq4UPs-zSI{7BA=O~;xlAhK3m z6@lmUs|uW4RNcyx&(>7>@R*Udniy7}(?ji;z=Z=M!BlR5UEOSs`^jP`^Q4$G6ABUo z>bob{%X1}lV^uFxZ%4fo*2j2pPd{KsadZ;i%Wej3`b@BXTpm~G*h0%N*!B+DP2zq@ zvoOjS2)zzYTV~42&Q$5A#z}C%g8up-xO}gxb|8}|Q2(u`{BMpOQPhoRE?zW)ymOL< z%i>jEbHUC#?G7f244sw_wOwDiKQSI7CBI?P%yf{9%ANI^X=?NlLkTl@Sh{d6y0V zJQ0>y-qrUwq%7oZ_{;!_N^T!n0R`g8`CdYfF$;G45nQU;`Ohjcc2b3qSwMe5zhksB zOxs$4(bS zcX0X%b@+7)735~wj|vo51Ssb}G#`GTI2BG!^D8d@f;OQ?9Zw74}RXB}vYaqYW zPvLg;6tqUdL*)i##UGHKH>^_V8Eo4i(o|7A81%sM0+4@=BogmBj|5nlT0pnjPZ9)G z^O~B{>0SUiEno`YiZ9(o?*kmEyM0At6~Ho?`1p#$3J!v+tB)O;iYw?A65gO_B1sDe+%$K*OBX=9+A^&v;ujlDH(Va?yo0aOPJiMTBqj6fI~D0Z;w$SGAFiPaF$WTtbWgfa(a5jvxiTQ0sQ_G=MB?%aXhd?-LoRt6`l@J`FKO7~<=@(0FFpHL;%d{I7U!*pSQGTj4$$gsa*hW4x3u zz%x4$^&GYszFtQH;nXq(;^9yHSqqu)j8qdXJW@npQu&nKe-n9UI5EnY-~0foIdXUo z(4n|wRO0zuZbYU!W_TI93Qdimg|QA#8z6Op3sSZipT!S?ux&mO=kQLXMRf7V6;INo zKDPrnG!8fMkQs4S^2M5#c*wWHJhnk)iRTfEMu5LNhJ%Ry68nvjHLzPa@2DWmZUMk$ zwJ*9{-c0S6L90K*GKVEy8Sze*vBu)B?W)_sxSO;H0SR*tU>O=xRYmukyN2m#9D{&X zG&;I_OQD7`$Q*K{WsOH5+x_0kp$0@PFcCsP5b<-v-~c#h!dshwf*`n?l!))kkh1%y zwL~@sAg?T&xSV-hDIW05x6^i;FDM}wXEPz^I<#MpUxG0y1{h#ZqMtBFCoxN`4w|3u z9?Mf9R0wg$fde_+(ys$cxtnAN*?QMc+x+b#1D|33KYn&?{BBqS>d!S5R4blP*#~;& z+7N*t_essmJAdMnl9xX5_t!J|d=a(hFju&>ckB6a3EbxZ$6^w|x)drl0H|mHA`}N> z!cZXsKm`Rb9SrL~S~X~HzP+11qnUR*bv%Nl2MXA!DhYVA7L~dUoMCzsu2^)+=0nd_ zw9E5JY3A~MoS^9iBGHXJ$LK+g#Jg3)K~ck1E?~^q#Lx1gmDNRmM)K|O^ajBckFbo? z8DSW?d=B3M@Wy7!UjJ+;Ho^Xf7AgW@zhB$XsE4&e_r_cpV1$V$2C}PK_e!d+WLn?9 zIhwZC_>dwOMSrK<--LOuS@?WKp9R<;tyi8p+mn(Dgew-xfrl60ZKX#Gr0vMB<7V|n zy31fxG5V3)|M)iCdxKvB{)3*8l9f#0+v$X^_2PA<+Mtyo$@%2Wz&!0gY`p< zjGxaGYUMZX_aZfDt+S9LLqk5{*ZV0u7E5p;`OR!ysVU0h(!-&Wzh^+BL6|7Y6>!c$2oo?(SnP)^jDn%M@v|=C=mopgFX|^At<|P zIgYIn?~SW?M_z{2VTHNeQpfCc|NFT{Ud%+UfOwoTr9ov z>OVof{CF6yLV}qE;I{DNTJ2p>8w@YuXlb))SsTa6lam%_K}D6#M+2#i$e#^dJmL|! zOuk4!?U52Dwl>HBzWV*-P1aC80$9Fi(jM`fYr*PmW&o-NIih`|^D|Zx#2KY~u-rW2 z%ZyH#pjp#IJ|_l(>@dL)&g>2Gl5jdHAbsn^of7ys$Hy_xGA07+k9~!fQ4iQ(?=k=~ zE@G*QIT#K;0~Vfmu+e=S0;KShZ|?zVbuxrh-w-HLgA8Ht7-;GPyS@7X@{=$F=~bK4 zAu`H=k{{1SAc$IX{pmB%g3BUX-^m=>tzseub9_lQX})Gioarq z->R5rQiH4LnQ=X#R5`t_R)riRHwWQ02O-BD-u>(0aht@YXTd1~EyLeD59H>yHUzd8 zKYt+lF9l2AV`GL`$HQXSpu;dEZCD*Ck`|0BO~mVdyiVkd%S@b2NOZNV7=u?y+UtHB zMn>r5R0`XEb$;yM@6o65H!YBB0oqq3*PJ!zb@f zWh`qAjZ&-L6t`+KEHl4-{gz@o6)gc4{I(}NO0OE^A-|>?U6d{+7RtVjcim?N>6iiG z-o;j6_SUsFER+Pb&CLAFUzwTFvW?RVZ+aeWZ?R}e`t)h$%+o}d=IF%N(ee9@q*68h zF0LJ(UqSEO8P)P9Fd7|tg_4`rEQRc*8l(5Hk+ju|tt9bYB1#@jNAD+N4(Xl}2d%)_ z$RmwKV_q*5<@q(%_@FJOKxSud?8CcWLz)XgJghoFgm^>}6a{)a zD_3j@=(=9%=%$X1X?+cTOMzX%7MH|E`O~+@2o5&S-n7JV!|lEB+YMa zSy=oTJmX5jsLxjaQr?=uvRP@KIf)WHzb6}|*RQK{o+k3iFsk>>Lc z>3)Znra~re>%GB~CwI@@t}NAe|EQ|qFrs-E)hiJk9AIM8%%qgNr}gj#h^S?}A#{jp zB;49`h*`gNr_e6X{E@$tJt(N@u_D^Wb1&JFh z$P*!f_$q72&0~aC8~O3G7c>=U-rnC|p_%3^iPSalW}JvVDtW*=i?Mo@y!&)bm&HO`shCI z{9B4Cn(f;V&bD+t(9sOjB07rBb@epU^3>`A*(K~|?k>w8mhZE4E2V4pTApQ&HOo-Y zM` zN8eNBVC_|a!bV>(AcW?xQv~8$!-YX%&t`uVm~=5EE?XX3z$4uZxl;o;l)|$Zgoh^# zQ26PS7?R`h+X(2U-j*cI;*X&v=2#)8K^+Vc%`xWtS-mO#@`>|&uwCAuub|2TE0n~? zBkeXw=_7w(m&-9pNP>ifV}Lz{Dz!#0@eN0{G)d_# z5yymY&q>PXx$*Rm$rOX<-b^B|Ea3QBNa973fU@^li(w-0F=!(z+_EDP6BbJV zL>aRV{c_Jk5tAO|rTL0Ez-`>&IiMfPD? zNu|Y)B03_NUFe&k^Cr7gX#oTgX6+jtE$f?j?Jm4yOQ$~}%E7XD$X_3e^>CdaW~ndF zoXQ426Kf1P0YQ(3jH9J~y(+FkY^LYO``gc*Xf5jO^ZO^_C|&CQ2^<_W_7-W-E4OEw zbuXSH|8@Kt{#Ov(80_2o6fZI8fp1`pGf0?NoSv2srY5=*z|`s<`|`KJ?Gp&0+yP>$ z+oM!6-mDCdp@=si*IbmEzkasQD;qG#d+A2jM^+X2ehs@oZyo=|l}Xi*lmJCFn)eSYZ zs!>8$#+iB{zO`)Z=+0<1E*P+x^_*<(yPILdi0mPH<c?H5#s`+OwGQ2*GB%5(EBY zQQR-%u3d_rXA@PKd_7wCdF!<-UgI#2Z;%827oSOhw7Kvk`^`3dw*6< zt5PD|L}~fKwHb#lptluEKd_O7zZ}NzsmU8BJ9U-egJ*%YfU|Yw;%~HH>2g+-fDQe= znHK1DZ?=&cT9!S<7OT?F*KEJ9FHVD%LHNL6Y4jead3BXno|q4$XTtGf!KfG?(8urQ ze1#8J%T`2Jp5+G55Eb*;pgTA|`r+^kjp-%3s0EedXsT6$Fh{5cjfYe?PpS z$1yUfOlm{xim2?&W=hVJ1C*ws_}$!%4gypZz$_gP*i?>9U~;%V6PypUpdrG))o7Kj zFqPJ@`orK^@?f(y=?_;5a^Ko=F1r z1vIba@QP0{`Qkl$%TjPe;-#$+YjUO?kTOE3?-9aIJ4V{q#-`e|Zs)=j`#_*&HD13=okq64M|$l2b`?)awo zWt@>=()ybj&?%#x>;|wY85WC{uu<|rYVPM-=d{tczjoMsk6bL3hx>x=S?h1y*81WM z51U*s=GR)9n{UqS{v5R2oh>#P`W_cP(1UKb;ZJ-nToGH~DP@2d|GZe!qI!+L%ld_&U$hkMj|+=^z++F2@Fe|H8zvI9RKnR3 zQv+$lb9C3DWdy9j2?6EKCcv<2yv#8YN%v;h51x;v-$;s>But#s)7!tOIf!9HbjmD@ z?0+tQ3QJAmqVxIoUC`M2@O4&=(y%EKN>y+2^DySiU>jdOSUvAxX;OgTsQ7v&!uRfA zkf)UIG5E%JqGtJ)4Me&sm*I!s6}bU?;C`p~;z+dv7s)=IQ8bE^1DCyaZE`0Za{6N8 zW+F_;LIGlffbm_>wTwvXOL{YeUh0vE*Gid^DN!NPq>V$YSUzlbLCBR?&3%~T-qxDK z7}vzVt(9SLz{x3a;opmkJBtQ&-T=Q5Uijh)$wTjD&fpNVM;Dk5-Z^iTing5Qog?Wj z#)0NjoP)$p8$txfWd0hfH9=|q%F!!;ARI-nfcMF0IyctSj(n&COr$a8BQQ%RGXRjy zLd_O-6mY&>^M4sV6^_H-wWLXKxA3dKs`rG+$>`z{aU|B~9xjA@fF7k1x|eA^79T7O z*aP^dZG8Ov>6=xF5K%M4a)TRBCYWXmKh0-4JNkNiFZP;D2jvWYy61Ddbp-|$#2cob zSA;B!yjXHXfpyg7U~EnF~%R<$YmhH2tzhM7$fiP5u}@GG~)ATx(3`r zT-aVK#^qb-P{IoXk&oA>25W%NXT^&;RF+V~GlGpL@7WoCj~1)qiAd$}%^u}=NFjkb90j46hgKcAjpW4>fhjYx0i+7xGmNv4b;AN!%JC!RyMTesf*-9NH282KEbfe!qDv^!lr|28JMKxV2`ti%8S~mP^xSRq z0kq*PH*p|6`q?Q)Sd+pnC-!8sUxi)Qmc$8=6pEm35)kpAgKpiC;p z%wQeKSyj*7Ac)!Cr?D=P#X{;MYvq6l&?T)`LE5+}afcTAW%55%;%2N_6K??37nC5c zW$Lr4XpZT|r*`X+N%J}wf{F(bqR#ZEka3j$7LN%mR#?BgM;7NBzIsJ1Od1AC8)}5( zG0VrLU%aRBXtnBR`~u|P0q7uo+27ZM?FO#mTTdRqRUl{ghCw8UBgG?77^M=Hh-P)0 z{nje9N&EpiLNt&Kq`H4htU zbpKS?70nc`QmA`f&C?^4aGvOA@4(V&l-o!sOk%pDc|Z?ZSXVa#{9HUK2Uu|mSscH& z<0G%GqS-}Y*~!lhq?@=ro)P<*u{2-6NkUS&Q2FeX6ITQiqPTV#d}G%F5*%lO& zeJ&e;9BpE^~wn|^yqRN4mnb|SzlZ;2L;p-%ls?Ha=r_1_mJ04y) z*wnVduj4+kbTIN~|3fj32z3LS;u{)NW@F4ac5L4wO*Vv8Ml$;(=Y92^liL2pn#UuQ^`@FXLrd0lu0ibWiU7Nj{`tEhDYv z5=D1yE9~SHc(NX6XiSD;1E_P+@InWvSmWp-9kh#W$U$^U5rNTzd~R{Sr2^Oc_fL$ssGmFa6{JpIAJ|#&<@U{n+wkH_ z;dzw$fCkiREbe>dn&-k}sKqXKzDw|~H9Q~-F)qBz*rJ=RCHJ*?SHJ9p{KJ}@jTE<=o96p_AviOC2%kQ9LXabiF z=jyfk?%c~$Tf-pk`6eX%xl=7Kr>Od)Uyj|veZu-gsay-L)dh-Gq{QtpuQa3dzW2L& zh>>C)OGO2^$@sFD`I+3-6N6k}J8^G)O3XrkI!ED@{ZM7y* zA%#0`+-B0XR@c5&5Dyx`vdZ`|XaAKEcM3#qEJ?oo>^00C279beVfa*kOQPwEurcP^ z_ouBP8#gZx>vkhNg&u-!hY7_2kdhcI*8(_Vg%ARmbO5S{4hEpQVE`BaK>#o&;7f&Y zGi#9oK(~3O5{11hIlNxAmqsE{iVD*ZLh*f5dI7OY{(A1i$=0))bI%*yM0p%AW`=7y zOf5h5=ce;U*cW0%{68ZlL185B?QjJl{dsL5MlT)!|I%lH)f^8E*fvi%8T~NVmL0PC zVV3`jO1j&SBm5J_=HQ7$#prfgRU1gu91Cn@XgN>d#?M*0?a#0A{P)73WL-m@khffF zNTa}W5Txt@rC{B~L^rv>*<$HLT9vY~SzZB*Y4i{X7W`me9R{5QXp>^t*BPaR_T6}3 zp^_lmi|Cb6_ird5>1;*?ZL8ybDdwa!eeOhWRK`=HQv6N$##q1!Dc*Yz6x$fEHf zQdmF8SA;W}=bkvciA+;}kRENn9|>=$;+g;X^5wWbD-l^NW>Xdge? z#9?_L}%SIHdjL{1MI8gM}+gA4z*!j0W3Y-*RmZl&8@#->rD z^(9lK@>Ru+`2T1txC5n7iP-*rq{q|j!5EO>{JmrMm>)LR5Y*#l^|SW!HEN8o)cS6V z!p7j>!W9h;eOEnfan2sVc-kKky~ZrnNQw`H4-Bp!(C2y8h5*eavK_pH2L%+r()(c0h~KIU0+%+ZWpuPG34oB~8p)vj9k?;eX=I%KYb+GG zw^?L{UdxqL{Ti=K&El2X4snpI**B|?z?ese$@u1? z^84xxR~cQeSSzSYdz#njgq#v?h~Q2^DC7C@)*`t)AElW>#U3H@-=LlU;h7Fjb7W

    77{WTYt<^`?PiFzWBj|Kn0`;TQ^=X2Y)B{#7S@2tkua z>^Jw(tg}Fu_s`)1gO?)J^yOcjRsWW)YoCAIz#Fo)cz>^~Y8Mv6<}C$29= z)*(k>tbVH-5QjcVv50SHR|E7PFqA2|KhO8;+B+t`HN+T3S&G2T)yIdQb6<5xe0?zK zn=`2*|MxAYgGHM=^@kqM@_Ulw~4(O{IUd{d<^6~ z=lYPvO!IW^$U*h@DV^n)HI;wl`!(?fSA4~Awdul{4Ka4hNIZSY;J8pNL+C4wh%xT@@=gT0X{u&jbDv}A! z_sRYL%(GKuw^`S$2xnanIz`?t;~SY011T(dQp?+JQ#CxL6(X2hH@+{cKa7ZML?wCI z?`)h(Y0W?Kb|%b$uU3jmqkN0R#?Tf z7C34tVDQ+xwXXRFPTN0XcX P$jQA?lrE7p`ue{B_AqS% literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step6.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step6.png new file mode 100644 index 0000000000000000000000000000000000000000..1f33c582b6949f12bbf9a29071a367f53dcdae18 GIT binary patch literal 17086 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 OfUKm#yE1Y8AO8b4-#D89 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step7.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step7.png new file mode 100644 index 0000000000000000000000000000000000000000..647b0b75574e083f88a219f83983af9992671abb GIT binary patch literal 11636 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 XIXSPy={x5C?x-niD^)zOc=`VTPIe4* literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort.assets/selection_sort_step8.png b/en/chapter_sorting/selection_sort.assets/selection_sort_step8.png new file mode 100644 index 0000000000000000000000000000000000000000..0cf6653e793fc29b18a6a00eb62c95232f8dfba2 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/selection_sort/index.html b/en/chapter_sorting/selection_sort/index.html new file mode 100644 index 000000000..aee4057ea --- /dev/null +++ b/en/chapter_sorting/selection_sort/index.html @@ -0,0 +1,4131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.2 Selection sort - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.2   Selection sort

    +

    Selection sort works on a very simple principle: it starts a loop where each iteration selects the smallest element from the unsorted interval and moves it to the end of the sorted interval.

    +

    Suppose the length of the array is \(n\), the algorithm flow of selection sort is as shown below.

    +
      +
    1. Initially, all elements are unsorted, i.e., the unsorted (index) interval is \([0, n-1]\).
    2. +
    3. Select the smallest element in the interval \([0, n-1]\) and swap it with the element at index \(0\). After this, the first element of the array is sorted.
    4. +
    5. Select the smallest element in the interval \([1, n-1]\) and swap it with the element at index \(1\). After this, the first two elements of the array are sorted.
    6. +
    7. Continue in this manner. After \(n - 1\) rounds of selection and swapping, the first \(n - 1\) elements are sorted.
    8. +
    9. The only remaining element is necessarily the largest element and does not need sorting, thus the array is sorted.
    10. +
    +
    +
    +
    +

    Selection sort process

    +
    +
    +

    selection_sort_step2

    +
    +
    +

    selection_sort_step3

    +
    +
    +

    selection_sort_step4

    +
    +
    +

    selection_sort_step5

    +
    +
    +

    selection_sort_step6

    +
    +
    +

    selection_sort_step7

    +
    +
    +

    selection_sort_step8

    +
    +
    +

    selection_sort_step9

    +
    +
    +

    selection_sort_step10

    +
    +
    +

    selection_sort_step11

    +
    +
    +
    +

    Figure 11-2   Selection sort process

    + +

    In the code, we use \(k\) to record the smallest element within the unsorted interval:

    +
    +
    +
    +
    selection_sort.py
    def selection_sort(nums: list[int]):
    +    """选择排序"""
    +    n = len(nums)
    +    # 外循环:未排序区间为 [i, n-1]
    +    for i in range(n - 1):
    +        # 内循环:找到未排序区间内的最小元素
    +        k = i
    +        for j in range(i + 1, n):
    +            if nums[j] < nums[k]:
    +                k = j  # 记录最小元素的索引
    +        # 将该最小元素与未排序区间的首个元素交换
    +        nums[i], nums[k] = nums[k], nums[i]
    +
    +
    +
    +
    selection_sort.cpp
    /* 选择排序 */
    +void selectionSort(vector<int> &nums) {
    +    int n = nums.size();
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (int i = 0; i < n - 1; i++) {
    +        // 内循环:找到未排序区间内的最小元素
    +        int k = i;
    +        for (int j = i + 1; j < n; j++) {
    +            if (nums[j] < nums[k])
    +                k = j; // 记录最小元素的索引
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        swap(nums[i], nums[k]);
    +    }
    +}
    +
    +
    +
    +
    selection_sort.java
    /* 选择排序 */
    +void selectionSort(int[] nums) {
    +    int n = nums.length;
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (int i = 0; i < n - 1; i++) {
    +        // 内循环:找到未排序区间内的最小元素
    +        int k = i;
    +        for (int j = i + 1; j < n; j++) {
    +            if (nums[j] < nums[k])
    +                k = j; // 记录最小元素的索引
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        int temp = nums[i];
    +        nums[i] = nums[k];
    +        nums[k] = temp;
    +    }
    +}
    +
    +
    +
    +
    selection_sort.cs
    /* 选择排序 */
    +void SelectionSort(int[] nums) {
    +    int n = nums.Length;
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (int i = 0; i < n - 1; i++) {
    +        // 内循环:找到未排序区间内的最小元素
    +        int k = i;
    +        for (int j = i + 1; j < n; j++) {
    +            if (nums[j] < nums[k])
    +                k = j; // 记录最小元素的索引
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        (nums[k], nums[i]) = (nums[i], nums[k]);
    +    }
    +}
    +
    +
    +
    +
    selection_sort.go
    /* 选择排序 */
    +func selectionSort(nums []int) {
    +    n := len(nums)
    +    // 外循环:未排序区间为 [i, n-1]
    +    for i := 0; i < n-1; i++ {
    +        // 内循环:找到未排序区间内的最小元素
    +        k := i
    +        for j := i + 1; j < n; j++ {
    +            if nums[j] < nums[k] {
    +                // 记录最小元素的索引
    +                k = j
    +            }
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        nums[i], nums[k] = nums[k], nums[i]
    +
    +    }
    +}
    +
    +
    +
    +
    selection_sort.swift
    /* 选择排序 */
    +func selectionSort(nums: inout [Int]) {
    +    // 外循环:未排序区间为 [i, n-1]
    +    for i in nums.indices.dropLast() {
    +        // 内循环:找到未排序区间内的最小元素
    +        var k = i
    +        for j in nums.indices.dropFirst(i + 1) {
    +            if nums[j] < nums[k] {
    +                k = j // 记录最小元素的索引
    +            }
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        nums.swapAt(i, k)
    +    }
    +}
    +
    +
    +
    +
    selection_sort.js
    /* 选择排序 */
    +function selectionSort(nums) {
    +    let n = nums.length;
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (let i = 0; i < n - 1; i++) {
    +        // 内循环:找到未排序区间内的最小元素
    +        let k = i;
    +        for (let j = i + 1; j < n; j++) {
    +            if (nums[j] < nums[k]) {
    +                k = j; // 记录最小元素的索引
    +            }
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        [nums[i], nums[k]] = [nums[k], nums[i]];
    +    }
    +}
    +
    +
    +
    +
    selection_sort.ts
    /* 选择排序 */
    +function selectionSort(nums: number[]): void {
    +    let n = nums.length;
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (let i = 0; i < n - 1; i++) {
    +        // 内循环:找到未排序区间内的最小元素
    +        let k = i;
    +        for (let j = i + 1; j < n; j++) {
    +            if (nums[j] < nums[k]) {
    +                k = j; // 记录最小元素的索引
    +            }
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        [nums[i], nums[k]] = [nums[k], nums[i]];
    +    }
    +}
    +
    +
    +
    +
    selection_sort.dart
    /* 选择排序 */
    +void selectionSort(List<int> nums) {
    +  int n = nums.length;
    +  // 外循环:未排序区间为 [i, n-1]
    +  for (int i = 0; i < n - 1; i++) {
    +    // 内循环:找到未排序区间内的最小元素
    +    int k = i;
    +    for (int j = i + 1; j < n; j++) {
    +      if (nums[j] < nums[k]) k = j; // 记录最小元素的索引
    +    }
    +    // 将该最小元素与未排序区间的首个元素交换
    +    int temp = nums[i];
    +    nums[i] = nums[k];
    +    nums[k] = temp;
    +  }
    +}
    +
    +
    +
    +
    selection_sort.rs
    /* 选择排序 */
    +fn selection_sort(nums: &mut [i32]) {
    +    if nums.is_empty() {
    +        return;
    +    }
    +    let n = nums.len();
    +    // 外循环:未排序区间为 [i, n-1]
    +    for i in 0..n - 1 {
    +        // 内循环:找到未排序区间内的最小元素
    +        let mut k = i;
    +        for j in i + 1..n {
    +            if nums[j] < nums[k] {
    +                k = j; // 记录最小元素的索引
    +            }
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        nums.swap(i, k);
    +    }
    +}
    +
    +
    +
    +
    selection_sort.c
    /* 选择排序 */
    +void selectionSort(int nums[], int n) {
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (int i = 0; i < n - 1; i++) {
    +        // 内循环:找到未排序区间内的最小元素
    +        int k = i;
    +        for (int j = i + 1; j < n; j++) {
    +            if (nums[j] < nums[k])
    +                k = j; // 记录最小元素的索引
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        int temp = nums[i];
    +        nums[i] = nums[k];
    +        nums[k] = temp;
    +    }
    +}
    +
    +
    +
    +
    selection_sort.kt
    /* 选择排序 */
    +fun selectionSort(nums: IntArray) {
    +    val n = nums.size
    +    // 外循环:未排序区间为 [i, n-1]
    +    for (i in 0..<n - 1) {
    +        var k = i
    +        // 内循环:找到未排序区间内的最小元素
    +        for (j in i + 1..<n) {
    +            if (nums[j] < nums[k])
    +                k = j // 记录最小元素的索引
    +        }
    +        // 将该最小元素与未排序区间的首个元素交换
    +        val temp = nums[i]
    +        nums[i] = nums[k]
    +        nums[k] = temp
    +    }
    +}
    +
    +
    +
    +
    selection_sort.rb
    [class]{}-[func]{selection_sort}
    +
    +
    +
    +
    selection_sort.zig
    [class]{}-[func]{selectionSort}
    +
    +
    +
    +
    +
    +Code Visualization +

    +

    +
    +

    11.2.1   Algorithm characteristics

    +
      +
    • Time complexity of \(O(n^2)\), non-adaptive sort: There are \(n - 1\) rounds in the outer loop, with the unsorted interval length starting at \(n\) in the first round and decreasing to \(2\) in the last round, i.e., the outer loops contain \(n\), \(n - 1\), \(\dots\), \(3\), \(2\) inner loops respectively, summing up to \(\frac{(n - 1)(n + 2)}{2}\).
    • +
    • Space complexity of \(O(1)\), in-place sort: Uses constant extra space with pointers \(i\) and \(j\).
    • +
    • Non-stable sort: As shown in the Figure 11-3 , an element nums[i] may be swapped to the right of an equal element, causing their relative order to change.
    • +
    +

    Selection sort instability example

    +

    Figure 11-3   Selection sort instability example

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/sorting_algorithm.assets/sorting_examples.png b/en/chapter_sorting/sorting_algorithm.assets/sorting_examples.png new file mode 100644 index 0000000000000000000000000000000000000000..aec33cb1f9e465dc7410d57d08c9bb65604d5d6f GIT binary patch literal 16395 zcmbWebzIcXw?F>cU0~^!F6mC`5b0F9!4(i`kp_uHr356T8$`NWa*^)t25FG)`l9d8 zjoUIb%dM@g1qB6L$6HOajloSpS$*G3O-;+jN@r$f z27V0`j}*zv%YXXxX=rHZ`1m+?Fn9fMyguSdsJXeh@y+ocKYq;b&X<;!CU+-0IXStyy3X#*R83TV`SK+^JlxjS_WQv1 zz`(%D@rt6NqSVyXg@uLX{be*F#1H^T1S!fq({i8LZSi~1E&xxz%_GhO|Ed1(3hZnn zo*{!99dZz|h#SXj)g}83=`ooU6l#Z-;fN|289)@b{V;7y`7$-+LY>Dd&;j9trvF`6 z0B{g)q%}BAjzcWm?o}Zs);HojF`qSFeVp+1B;Ve;!0zd7H!IfHZQYOkH{2@kebPBGUNc?ffP-L%*6 zjhgm&1~sLdVvDVPpceVbu^I_YRh|j*ukAXqMU>LZX0XtXQG$7$ZN|R5O5O0gaN(-w zg@-~pxKa)1OA-1U>0LbB--Cl%k>SEFGK@1G3NB`+ejITM(_T;HY!kucc}{D_ct zxKMhh$YIBYb2D=&2Z+mNR2T=QsB`PV$4F&hbm*0Qm17B3u8JKcZ{fIrQEXV86Z&H$ z4RXc~OwfEW&B`2#!>cmjdtrPb@bMRYoX&~fiN`o#%SqKEAQ#ZdZ~w^9E(^py$XIL1 z6GfrqAGg*;==n_!!z!o)2F2rBew@i&R(}ss! za^DeaNc{4b&|5wFkDQz{REjn_AEbyp8zZh$Bas|*E3XtK;?+RIKnXl<_IB)m)@*v~`QE8Vfuz-pE4NpY$pcjqC<40Mb-LE^7NidemdxggnTf-Eo;1H%- zRwFwF8@S$GLBfHeNPhttExBic4O~F?(iR~9VI+>dBox<6IthTQ=1VaeiY&k2+MLU4 zM@{4{B6Ekx|11#p$6eup^K(dPD0{sw2F;k~WArJ`l4!JF->58BE#O(A*f%CPzaQij zpo&~mA4DoGIpiak6s$+f1oRvMSTPT3=dZFbw)Pykr!a4H=}Co&S$Bz?WB}uFDzbyj zBm>8!3x}NYDI?rpksTX0$&zU|yNGy?=!pL)cvY)T{?(QAT<646^>CF~xEl#qKy{T2 zv7K3=)_Q;oJ-`jf04*UHj*n(M11H6TIL}^^avCswfkR?VUp0_}SY>zG-`3Wr=WeV?}YnhzteK!L1g@d>uk?v(C&dA?(%ksjQEB2zjv=vtMSKqXlX`5Gm67_=%!l|jpXcW93iJ*g%Be;0X8EK=aDs*QT-C6TyvaYoG{-d z0k}t;NcLhkW7p;S^9Z^KrelS%OSI_NZlo?O0&KU*akRghCciv+!)-TDyXV)zVftu4 zbjmzMuW$05U!t?T`{Jc;_k+ z$*`;dT(!7IL959CIO(JRi~FV?u@%7TA({VsZRlwgz@X*#*^u9XN3c6ZkunlRac_?r zk{jjf$+%nfPW{SuSpq&gesGGDK|J>cqIdRDq8MFk6|fHGcu;^K7~`=C3a(y+bItTq zD&tWULhIMj^G|FqGnK6ufh$mwfbOU->Qb^1*%mJc%>ga~|3CyTpIQMz>Z!$nxlr5u z<8fl}=IyK>v^Yvebb$ig890ay+$oKn60;kmoO zdx)2t{tqk~DsV3Csp<1+D3R3MrYlAvq-Qrh^0YjovmY3!BuwuB5Xs7b@)g2)w#>3W zyFY#8aSA6ly5*xtwFS>c2A7+7`zMZ18-*#ekNx!W)UC8*cWKPVG}4eAl+P(6&niWY zEx;G9VpIhuncs*hH9!6nIyJ+xu;b~^ztu`=m-_{Gkiy+~aYA!Rz!ak%M$B~7jGeo$?HjacN z3vkzKab&CBqDeTle0;A35EfPCHmu^4H zTp<(T1lfvwewvd=v@U9d0E}kiEzC79Q6&i?V*a1yN;5IP_^enRJLzP9i&*MYw> z*d0o$_Fowv7)iO(zmP+Vl7);nC8#%(Elx;((1W^q?kraPsK5_CpK&rKw1I#JK|8sjjXNs4)g7i$oz^ zv@c9ouws8wzv#|HDQEdm#sfothF2Du8%C{QTTDwd8-!{QcRao)YXfxHw~@(5TwiC_ip3?C{?1^Xxnt`AK*fY+dOKERyI z4WuUNV0i2H4iy}p~;odin;I9s9x)N-p*{{eLeI>MUpxCe};(E3L6Fuv{vDYoq7;J|Vo zI#|dfD8*G-q@8-cF+^N0vIECPoQ+v>fE?C&*Lx-4=Es7oPN4#X)(!V`WSDRXk@6(hpXkur=fQSl8Kb? z1BEYZ05@!egBTtQ7XbtJ-yj52gEfzy*F`!00&8i+e{ zKE}-LW1=nDhll`_-x^_RI9JV{0{A*?Hk~X`xG0J68h8j_4GM$W2Pir8Yk<7D?-_qf z3fR5#M&@y9C?x^5x4h>g9s$abC9*_Eom&iwUxjre)(lIvbNr(&%rcuWgIw7IU~P5{ zymZvC9qfGvZ`)$%#eW!oF602IX%*_6p8e#VJ-`Y3mbg8nhN~I)ZI!7Emo;O;!1JY` z`6*xg5m4)&8aw_rX@){Wc!^xd;)OJEHXg9En@zc!CjMS^*{}s@gM3Ijv7s3)!jfb7 zOL&Q5QiYKx>pS3p9c*qeuNm%|Nn?Qy-2nJn=*J9{_ICmb0X;Hchx<{5C$i9`HR2Y) zo*v~!f$<`_Ca7}MK7Bty-BN1_m^u>#Jm&8#XW+p5tJGPf!OW_rmP$-uVL2;-7LKz< zQ2=#v0x=P)NEOBWQR{Z#&>H9f?7~w(?Z=Q#co3Oa=*Zj2B2X*-T43+h@vi;`>V_1^ zorJx^$MM;Zj}lI3ecy+8|LVix=a35H<76cOHWyH4VXXq3OV?Mpx+I4Ik{J`Gf7F4D z7y(FHjRv=EkKtN;RWxdxL4~jder51Xf~rkzO^{a(q!A3VT*GER&@Q8l)Xcf5Joy`2B<~N*?TGzbCO zE%)^DDY!=~20d@7JS01lg$y-I(&^&k^l&7Cnq5W#=1GGWC3X)M`yJ!}f-n&S*Y3Tx zjJ?e%7vFM&iY{$YLxPGicCk>ezXPR^#=g|092mZlM2qnfS-gGn&wK^I;LgQ~;V?Tn z?Kk9`08$HUh+@e<>|8%)JONPLGl=SKtZUui@~)%(?Tx~;0GES62pZ?KDy7O`wgVR- z{B8+m&svA%*z1{C? zYO0E+HvFp&`B{Rh3(iQGda^hcHSXR|Z5r`FHRwJO4&u?k3!IwSJ+HM2X4yagSjj%a%cJ)7mignJep=S&KiS5ebEbi|R| z?ordi6;_^P4RawLaX|W(O&6a?;?YBgEL~`wfYaUjJL2RwaHC`bbb#c-i`77{xr<8i z2g-gISJ6Lz1&rCGJZ-Fg%m#qhfT6{axU@IMn4q__j?O@4k&Ot+rL z{H0{(0x8t%z5FR|P+00btZ=0X`qfM~SF*SzwA30k2{n~b(it=5Cy+ZS;_GQAts^QW zeF#*dOM~D#y{*$+Z+sn|>id^>2kR~>O-G354K8>o-`re-3@!r?eHWkJRk4`(GuQ@~ z{CT>y6ugv{zkqg>y?1`Mk9676yq!X`@2)T|`s^+b9sV|Y`~?=GWL!CN;popArundj zF&Ctf!p9Aln=0H;gs~xyagoq!`|j`Sdx{-hkk0VMitB!j{iGDxb0=hx=1_+Rs=+^& zixdHuFPE^SWIjfZwv=CWT7#9WOqztA*O;F4g>??l9n>z5)a{0a^XT15T^z= zdw5uO8+kM4d{#c^nVjL3BZxD>08Sq88BC$d;X1+KXhjgi?t*p1hT-u2sB8me-5?(; z6Br~+x5D4SPl%TN%CQDD)`PRfg^LSvPiolVBD-e;(qCoby0TQqtXP^JL~E}7BUV_A;e+C_gp?=NSynQrhN$d) z02^I;+1B|bTK*nSNR&+MdMfMQ6@sF!5SKfzVX2cvwt?ZG{fC)_K|YRWqa>B?p!oav zhRZjR%HMJqqpYNyhp~KOj>>jW*7aGjS1^`H7oMT>-F~X~Z(s@OyQ%1s@|5w8{lec# zs~NMOZe4GmuB=7v{LyPJRqZ$BDB275U@x&R4zXIDTH``bD+Y;llFqY%1;I^vIX)go}gF|2xlhQwoLt&9zD1m4v0||99no-txag$!C2? zUD>RtkpwIgr}-NMNBPUCsRh%}c4T16%p*OU^(Q14(?Ie65|na(kFowMzB)L;Tmt4g zSQTXD-n+G(EiSJt^G`WxCRv02*mkox%K2QCk~P2Avu)7ygx*dg_LJNX#+g+oWrMGs zyO%dEVUDuJu7gnmEH}8cnJ?MCap)qmH!EemoDhkLdm(=L1mYPr@>9o{@`PaxqqNq8 zo5(I~U!zlV!0UINF{bQJ3zcFIp#7Nk${3Ir5J`K%Ul962I#{@+7Xvm!(m4mL_iYr- z)*KdPo~#9>XP%Nu(q4rCWGN9L89sKOUL;-LvK4MvSBV7V6ho6`%@;%2{p_5tvuDq< z#$FW^gjrv-uO!yIY6AyEn#cis8%`6(biDj{WiBN3x~lHO#xH|{eDDy$E1t`vFK#+LI|SQT#QBvm%mi~+j2Vy-*EG=Xsi!d|!mrNeb^n_Z!*@%#Pp?B!tUBb^-R{`zH%&DG_+p5ZYd%h6ND3*+Hetc0qgkOf~u) zFPxm5frmA~KM{LLE=p-1bb|jLz84M<{mQtp`X)Nos{N|Uz(WL{T4!k9_on1MNJOKO z`@N))nr-F@o}_3Kbn49?K+_6R#H?-p!E19mDoMdPh%+ZuDXV}j(5p_E>9Qr=c+Lb8 zqv@~;B5N@6(u)hhTZHr_51Q0iH0FN~w|_N8xm{XqgGqyTJ5L3(Q;Vfc7FACj7#-AH zBB&yhmI3*^RO@u(4IG93 z^x!EL!Wj{GfmFs&SJI0T^24%1dPtWvF74GZP_2Rt_c$e+g-|TDD&RNiIWT6fC4-@; zhNtGHTP1L(mr)?+l|UM~4zGo}BU@8rDwzOyT|ge2#7oLj&xs4a2awkQu>%Fdm7+7C zu80w==Q(5#o-zP^{M-hfdJ@W2irK1XYD&_{3}`0A8|#^Q zjWJcSZ81s^ss0A}JNaLg>({sgDnIsROknvt-?~t(G#^~#Numn}aF(Q1);MbD;6sQ= zA7#mb2$jf*g%(7*m;lCO4z0;ObC@p!lXS%3)5i%r3ssK2(;de%?ME zGL_nI@sxMHVloAy9glx^5jP76M5Q4=m?(4i;_v1i%_XL#1NQPj?ND&-9_#6>bc74b zimB0OBbg>-&e&(%0hCA}2lNjNb1+T~q|f-DquhyUa32*?PfADBv@ty!AU&Sm`7+mt zXz(#=hdr3-Tf)Ufl+lt|1k7SZwleXWai;aR^>HN|VHDwf4UP!#?{WU;Dj*kH|+nKvT zo3lN#D+vlzW(Rl0w7LeloJdQ*E8)R+9CBndk`lrcmWByi6lfp?oAPkul z*bG0>-#RkrIUdTzWE*u|PNKC0YZo)9ffIBtd%yP=chg#oX z&53b4g=?4hOh_le4G>SnQwo0Z<4GuzqgQ(rvD?G(wOF*k5ScCR+QZNJ9S5`&7Bs( zz0ZBwyHa=YGF4vqV-kc!T>Y9i-S$E0(2!Ga70zAMbJXrdBYf*$utQJB5Si21-@O?lNZ!YK!g>v;kho<`~1!09taADV65dTmd0fvDyj{zXtxBt$7U8<#b z4P(e)JFQ22tgmI|ls=APdbp_p4!;k}ZEgK2J;*-E>8|)VXI^@qg56}0DA*E+BR*iW zm!YI0BJ;HPA(4YpigK_F+O0qt`l$iYgSgu^90Ooeg74sW-HeeItkt_LigN~e8@ zgUK<@$?@WphEH$9maLa<$)C|J)*ydnTyTPLAD=r@TsFZn=S}KPi5wGtYk0k^IxL01 z5x`cs-Om~cbQ>btsN(>z;xAiJyxysvLt!4^1vfbqg^C}{Y>oZD1!y^AemcQk3xbwV z)i``X2k1Z&YRtEZ8h{4A*N2p>{*Rgn*$WU(JANe*ZT@w*+b> zumdh-jrqZuENwmcF>(w*^A=h%{l#|1xPj!mr9LvyOK>2;w=$m;_({jxGCXj6wr~Y+ z3pADEs_3!6Q<@o{P(}ed910}n%yJw1BPaqkHHl<4ezxI~+F@}v#VMVI74I~CGIriXgLu7zm z6(QOmYskFm*bidLvEDkPJ}%SVJlQ~$YhwO6Q| zyX1xxxFGsDcQA20|2)?AlcbFSCfrE`U#dHs2aEJMB*N^uBs$cQSz}^J4HR8%F!%)S z7csJK1$I!S7<*)#&Ju@NA_OGSRM{%g%WimNCL)gnapj@{9-{93v@SGjKKh}CAV8Vm zpouT@xB8;z%#f1;7RF5B$b&9xp$m4;3_eCr$;+NE=pFn7%yrA$y+}KWEMlI5fKjCQ zmyy*^ zx6%yUDM`~?b_eFTsFT1oVLQ_(rD_~JvFaF8$@FBOP;FLTz=td_MgZL5XOxIH58Bks z&E7i&oon#)3#l$?0f-T#hRIMNKo_AwJVQ0H>ugQSZdt)9p9O_2eyF(V6MYWFLd3~3 z@xMp4)&F|3j;N zKMRju;vhaQa8;)6pDFyl#EdtA(olBBsVqJ{neMV&uNpQb$@D&XNcJEB(uJR*1aQJ? z*-XtYe$YZD(uDv+l36GR?oFCPyk#0a+0Sz1TMK@3j1ka~7%F^lw#DXb?2>4X>oe&* z2HX?8U?WEXw?m8uep$bBK*sz${nvMdh%^{6e+Vc)Qf)Uyd>}@qVGHgw>s=zcE4*O= zEHj8xY95%OElooc4nhD24^sFEhZQv~F$AUohI82ZM{(kW#eev^5c$ihI+GhP^XkzF z-b9)GD#P~4xsuxggY}5wj}Lo5`^JA?WyW7V1PZ35MvFF(5Xypc2Gm9Y>w!nlgWXvQ zArxrIr`Y5?v?^(50+6}TB~9={I%8WnZuBqt0B#C!u=j*#)2y*%o<0(sbg04nNohD7l3@StD~^H|RpFV63cYj4;+acuPtGJ#(VW$w15=F3dTF#E3^ zRy%_rOQlEPC6f4Um1Y#{U+w$gA;5Y~a1x({6V}lVQh0eR^9%2sJ`#iNDJIbT1kiu* zH|Ml0S7NSps2I4=RIcIuTOy0PAyTy*q8KFDDcwpYAx3(P5-e}ARZ72d`*qL1PXLU_ zM*zsiK4>u>Y1Jvt&HTDz zTfQwzqmbq$KYB!$mJ6#VV~DHPLDXN*weLp^*)B}y9s1RAW(l*~$;4<#z{T;QE2UhlU>BRYyFjo1hu4qe6)y=JsQ z)!1@|SB!PoeVg>d>Chaua@^-eRPYAMhIKa>y$Byd{J{WDUcE#vc926U4P8f5o17{9 znua$@Rmx&f@%fLp&w+`eeyP3+f4W#b^8A=OO#fg9NdD>{x64Wt&hgRkVhe~jTO=)= zNc(+8)CYmO?YG(h^!i5@e9Yg?8;mflBn7u8Jg3uVY(7um> z!Pg>y;t0eJV1zSP$#fIv1Y`c7VIx=rbv-!K@5Bg4WVQg06P`t=-f}3W0z>MA#R*pT z12O9dVl>F*)+YgCdJ`KTAuLRo z>p6xbZw}EctbrRehO@Du1=)~|eQCiz;OKxw2~61L^p7IV8ku5+w(|o`(s|O4@gKI& zy^TN0;jxePXh-B1(yxpx9+Zm{?~KX)W>2WVgSYp6nYM>JkMY`Y=Z$g%`kRx;K)WKQ zNn4_R0O@W>sb{+I3hx~-@Gb%Q-7OYxCl`jEFS*I)`PN=xjWD?&}b8)d{kasG?-!EendC~9b&n)it6nX zOIF>1Fas52WQLb9bfAhLE+~h9M-SU(Tgb&_DUI=bb`?QCePzU>FG9fLQRo@8+XQSaNWi|uu zhIh-leVfRV*~9>K_GwLb89?Fbbq!uBx(s~D^NkotFaf;cCl(py$L7#RFyJ-oe~|!l zPtd_DgL{m-)v0jgrJd%Vx1ZR#fF|Igbot(F-^7s~>PG|r5M6qByDv&zma9S6uLqvB zYIK8R^2>am9}n?a0H65!aY$lt4-YplwZ=GusM^7O5vHJpAAsR}f%j{3@~4%`Qbb&c z)%*IG`!Cs~!W!$+Y5K+2V~Ho5t88?$7mqp7^y`7}qiAH3OPjNVDAUdGh+T}*aTC+d zypt;q{SK05{XS``>0zhqx6W+0l&XA=S$%;L6-MV)RV7cqoA`v(X+{r*+O7uHveH|# z8^Ak%*uQT6W+nF}dTS^rc1J>eHul@%&DDI*8@cL3>3T--?}OF-YqYstts6yMI44G zVTpU^-Q{EymFU3(?Ri*q?{rgh8}y?eVb8Awx;3nv4~@oIGc`vKaU4Zs{O2Rl|4-eg z?0=lP{7FTD`WNl8S>VI}H#^DtuWN@u#Jvq&?msft-LZ!hr6kaC2u=H#ow<^sNCUz` zQ(*3(MXn-d+4N*?43c-3Zbu9N{n)QzHIwjBzET5X!(p`PlulD)pKvs zjxKFuE5Q^#o;kI&Lh%f9mm|@vF+F6u6AXcMX>6$ozQ-w+lC^6jBXlp{^)vk%6QEYB zqG>!*mQtX)CD#g_^3S$fl*L1kr+qZlF2^L2BBYvfQ+uOG%x}L1#Z4u$z?1wDxdT}8 zO@bM_+d*ydOk?h=_|(V}zSWwb=W|uxC827gO>Cry0m*ot=x;1Kd#i^kY+J7NW}Kt@ z7{1R?DITv+sndu(gtn#v3L5u$i-{Z}4JSu+^d;8lE@2?>Hi59rpJneJ<$y*q+u^u&bG+oZp-1t+&Vnem^#zgbp1yWMD2arw9WkdMU3=vIgh0``$3n=hHZzz4_UHgtovXkkl4`M-nRJy;7aFl52V)KYyAjwIrW+m zaFWHDy12pe>rrst+vdL`M2sF~6G}3Dk(PUxtcD9B#O8(1o9NSkFBUF$yQ;+O1=EBf z3tNN3nRc{%4DWxE8}pEezJmTm3G{|(*=0m=xMyElVmYpvp~OT0tCKvGVHCEdDWxjLP&U8D@-6l zT*>1iia@~`6-mQ|aE*81*XI?iAi@=bQ5*QU37(B7L$VlUKpcxhpW16{uXydA3u%DO zr>vu}bt;YS7*CCSm}h|;agO!O8IWHcb8|HCFYk|O!E_Sp!vbnwzM76hciT#abcwc` z8Q%uc!==1XSm6e3s%MsBWP6s2)YdV&mrvl;zUoXI^w!x@BU+w9Y(u}L%C^Op3j0r+ zp`|gs{Mx{2)VCNETuT`<;tTwdRP#G~YiSX>WDa5eVhFP|?qdnIM~Dt#;~9wxl&RH( z>v|T4iB$eM2Rk{26ou!b`Jt`c$s-u8k}mz<&ldpC>BkDBh|l?UFBo%rNj)}K!ngz) zK?Bu{8|^0BU&QS8LBDE(gDQ#`xjvyDqU8e5H$AdeJyKgo?blf0{?I*q#IDzAF9W>8 z@_GkYX&Hk;8Pg*5c-QiZW44-^;HT~LndL?uBJe}UAC*9x?K5LtCxzleIWxI4%w&B~ zzgL*97S+Bcp5Ruh7npEmm2CujO3p1`n$Ln#i4jg`$>{qOY1kFhhd{Ego8q@!afBmz zm>fd=+pso>g1Zhqz4NynFh3E>v?pi-_tpuS;h|4yOoX^al;zC-l$D@WovYChP0ZP& zTRJLwxD`d6AZk5JpR%7zUojKZ`vhK~Q*iMDRQN9YBLP<>)cna7rq>LX`P5D7!ZZ~r zP6gKu|o;oG5oqA)?wiT)av6KW`19{g6x8aq01`y9yc-QkyvE4=QB{!$X@NWk9K zIkBPWZNB_2zkXe0Hw&cY49pIa4T3NeiMiqcx#S%n+oH>1hd#&9T#T`%uytIpu!|A9 z;Q9$1rEwM@B5f+gQJL6rc>ygICJWQb$fh8|f4m)bioFOgHm@_aL z`WA9=K}Y(*>y0a_BXDF+m9XKY#8&LU%a!GIhLK0NbVWX-V)B+n8SuZDJ1Plpakjyp zCQq1qR&ceLAznxjlH($=*Vp7yCIKx~5D8l>1ZA#8I)CZ1JpO^$Qrl0k1s8LU7?Zmt zlQR#9G{=M8VoRhWmK=n3;b`LKkSPmG8k<2ZUaCkWTs*Uf0i>m(r;kh}(VI0`UkPJ| zQ>Hf*0@@|^%i%U~Jk^fNmncKlUzcg=UxxPjf3c!5o&Oo+Wl9hq-#M9Z*fG7ei=Q$zH=3+M4o z-O<8RM1-9Vr|28;G|1)P%T?-UQ`bKk4iVtc*GJ&`+((grt_6o6_PHU>714tAQ(Zr9HeEo;AkFnC%oC1oZN9)njtFXJa zuzQB-cjR^Dhs_@$!bcF_-fjWEg`luDOllsc_ut)+4hlNAU4X*{V4cGpZ0Wzy&*9L> z8Qy|=*z&{vS$mFHxN5nT9{<+?Fv3lo-qIl-O3wzcp)^x}&?}Shon_j(cvs==7#}v2 z>z?JrOvj@inQY%fBDA~pTT2B6g|RYi(%TgttGa;!Psw|3`N*kVjmdr_?}imF>iP2B zh_^Gf?pv_l9WP0t-n9#`jLrC!g7Q+y>mh#d!?pcO6`NF?zipdi;4p3gO;H{&sZkBX z^(dgDD&(yqVDrRKZ6dO@0%V<~%i~a%lJE;`hGNf)_G%EBJ&CEwpJJLzx;sIhW+nI% z6((1HD*!L?IL@tfD2foi5`a^(`XQ+Wy(ri?pGAoX>BOQhl*XD8&}B$&*yV5;nbR(t znOik~8}2Y1W~OXB<|UW^#Bwinqlct4^9{x%S=C#BNDhA~H_;@z*To13%)!T(28uR| zb;*~0y_%3P7;?QMSU*LMb~Fmmz}WH8VqP{7-0W<8M>V-EQK>Pv-^|`yTYVD#|Gds9 zbz_c$jr3`|==g)hKnWD$Wy#W?1B%!lvwg*y z)l%y|Ll<|w($d{M6qH5n__f{r#Z#TXA)x4_3yF|z6~LL1CUTvQK&H?u&`yJuHhf4u%7c}gLG7*MSu~2|8!&#J z1TUzqXW9(V;%s)J?GbwvPn#@8{Eld_ikz5<0dJCb!L12Nf;GTxO0BhWtJ2~J1*pG1o`F7nv zuF=e@9q5{n7%`7XY2&ja`h;eEv(MR@Vv!dB1Lya7uDS4%z_}5p@&s70=+zWl2?b%2+ zjpxR|)Q@%p#T+p38Etbm>rI>%z0OfaTw(+Pz_AcrF$IuRIs!rsb!1>6av_FOOhh0F zT;&-WP_JtY#P_W9|JJ}p=^NJR%|oq;;@? zv>?k=V3Jd@5emPGueL^4xki=+yy!iz^S}9&=?3%g)JH=~pUd2m4%OkMmAyb@O3TFU zTOrpV9KlxtThk1Wf*%Qb(J%^u>*6seTZLgO?L6o+E z4t}!aB@{tIn_h#Mo&yaI$V-EbN)5q_-znhUFlKSHr{(?HD3Zb;@1&F6sD$#Tz%g5F zd_>yf}tA4LC!pd!uX7h z+_q0%uc>hd;ULW*{RZ7GfaHriP+k7RwQTq_lD*IG$uV}43}jc!Ohx6HFfjbBQ7QB< z+UyD&LYTVPh@6_t^{1D^bc&{2A#3;Fj~Y702H7>UceQujtu-lGWoYrW8JE)F_;_4m*2Ub z$65vdi=!i`R-?Q_CZ~D0tbUs4fQKy1dfJSz|59U8`T8hLu%nHT&==zdU2IR=RHctI z1>}y=#tWDL^O7Y%0;70+7H!!|fKTobJ}+oMUKzCci`bNC{}C?`Kt}|hM1(w9@V4cT z_D1_jNC=5=WG!R-Gr>*c@OQ;5#Fb3Xd{Dah|HEwKBJip`ySduftGS+ic!YtVa$r*3 z=8p)~*#R8gW#hU6KmcO zEO^Uj$dV#P(09eX%!#=io)2V!$vXt57#b8;1Z8kWT?rQ&ByCFP%P4$mjxuR)@=_1Or`!(Ezu1yo@gJT=sC? zl?6&emA0>QN_$EA9tu0-y|jj?lQg3_HvDJUhPTx1NGt=YJ7BvR;H)6eZgeBu62Amfo9RM$tdni!h7 z?HT&O(#AD_KHZB8)|3Ej=BKk1N3xo}`Ba1~hO|9Q9{AuUPY}0hFKqsMpUmEFmhs8+ zHjdYxMgYPA4|*sN|MZ^;i1FHd&0r2>&F=A@qt2PWr_{+Ex%+txdl~FI+B{h7BIQoK zMEz;ic!uq8&l|qn1LU41JN!z!RmBbCAO&KS-#1{vdHHw4Y4dFVEv(P=+_BCrhR1*o zUVc4uzwZPpn=uNxbWjk!s(+$BAy5kXk06gCsk3Iz;Qtf|Rt?o<*zqsrKykdrb2EMo7-#5$d zJU0Fu&=W%aD7j)$HZI+~_D6kEXky{(Gil+Oz@CISPDFu@>&{nUSYZz-M(KmFYIx@} zRO&%EAxgZY&0c@nO~I|x`;f_`mAiGKu}Qd9`vQ>~@56Wya?~GpQ}F1FhaykSg}S(D z@z@{kWxSKIr2ESAvJ@!soDO@j9$GfTo|J9Tr+!PNXQst_ox%SF)y|yvXb0n9hPi&f zn}Sy->GkN?RY5lM%@nJ-tF#jZ0jtGt&HH?tg57K;ry)JN7*$>B{o}sNdkv?sr|1c$ zn{-ZUx$z19g3r>*->Y`*N0d)zr`2=^9SZkIm|P)`%zlnf-NZ5AlV}cz_O9k{O&K+k zlVRO@Y%}2+QI1ocjj@45D#k4DS3bC2F5J>XDrVYrE1SOSd+GNY@@Gr-KP(8Y|MA~m z{@eYXwm+q)TqH%n2jD8NZAp$26WJ+v3wo& zLPK!zZlO^E<>W54NVAwrI>|ckw?8-y&tWgs>Yizy;u%jkExOviBkii1QxLhX5`EE# zZNRo4jf*EP-J-2Jc(|-DV7bHl493m z8xF|i_y=v0LdL-CXlM8;eDG)H?X+BNbW=&7MXgQs7nt^9)|sSO+9!NU!@oIrG8U$lSoHH$*1?h$$9W~jIC3GmWflx|Qf<>jgfC-xh zPrUd7UwL?$%pS!-y1f3-0)T{e!Rd40MFb_^S%?A81~xxG? za?7_fph}ktLX($LA|hxy&ynS1cCyWI1Ijoia=i5q2`O5ynInf(A-K#*EiyNRdjSbAq@m$n zAJ1R>3zg)iIq|~};icFIAzImh{YPt&50Y~poCp?hXVlTv_F1jAN^UdB_OY+(E zUHmeJGTN<6ZE?S2BcJyTc` + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.1 Sorting algorithms - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.1   Sorting algorithms

    +

    Sorting algorithms (sorting algorithm) are used to arrange a set of data in a specific order. Sorting algorithms have a wide range of applications because ordered data can usually be searched, analyzed, and processed more efficiently.

    +

    As shown in the following figure, the data types in sorting algorithms can be integers, floating point numbers, characters, or strings, etc. Sorting rules can be set according to needs, such as numerical size, character ASCII order, or custom rules.

    +

    Data types and comparator examples

    +

    Figure 11-1   Data types and comparator examples

    + +

    11.1.1   Evaluation dimensions

    +

    Execution efficiency: We expect the time complexity of sorting algorithms to be as low as possible, with a lower number of overall operations (reduction in the constant factor of time complexity). For large data volumes, execution efficiency is particularly important.

    +

    In-place property: As the name implies, in-place sorting is achieved by directly manipulating the original array, without the need for additional auxiliary arrays, thus saving memory. Generally, in-place sorting involves fewer data movement operations and is faster.

    +

    Stability: Stable sorting ensures that the relative order of equal elements in the array does not change after sorting.

    +

    Stable sorting is a necessary condition for multi-level sorting scenarios. Suppose we have a table storing student information, with the first and second columns being name and age, respectively. In this case, unstable sorting might lead to a loss of orderedness in the input data:

    +
    # Input data is sorted by name
    +# (name, age)
    +  ('A', 19)
    +  ('B', 18)
    +  ('C', 21)
    +  ('D', 19)
    +  ('E', 23)
    +
    +# Assuming an unstable sorting algorithm is used to sort the list by age,
    +# the result changes the relative position of ('D', 19) and ('A', 19),
    +# and the property of the input data being sorted by name is lost
    +  ('B', 18)
    +  ('D', 19)
    +  ('A', 19)
    +  ('C', 21)
    +  ('E', 23)
    +
    +

    Adaptability: Adaptive sorting has a time complexity that depends on the input data, i.e., the best time complexity, worst time complexity, and average time complexity are not exactly equal.

    +

    Adaptability needs to be assessed according to the specific situation. If the worst time complexity is worse than the average, it suggests that the performance of the sorting algorithm might deteriorate under certain data, hence it is seen as a negative attribute; whereas, if the best time complexity is better than the average, it is considered a positive attribute.

    +

    Comparison-based: Comparison-based sorting relies on comparison operators (\(<\), \(=\), \(>\)) to determine the relative order of elements and thus sort the entire array, with the theoretical optimal time complexity being \(O(n \log n)\). Meanwhile, non-comparison sorting does not use comparison operators and can achieve a time complexity of \(O(n)\), but its versatility is relatively poor.

    +

    11.1.2   Ideal sorting algorithm

    +

    Fast execution, in-place, stable, positively adaptive, and versatile. Clearly, no sorting algorithm that combines all these features has been found to date. Therefore, when selecting a sorting algorithm, it is necessary to decide based on the specific characteristics of the data and the requirements of the problem.

    +

    Next, we will learn about various sorting algorithms together and analyze the advantages and disadvantages of each based on the above evaluation dimensions.

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_sorting/summary.assets/sorting_algorithms_comparison.png b/en/chapter_sorting/summary.assets/sorting_algorithms_comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..6a6559d0886745eca4030469a5e25519f3f3f77b GIT binary patch literal 59466 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 XmbHKBa>1If{vA+N)PhvVTL=FS0Lu{& literal 0 HcmV?d00001 diff --git a/en/chapter_sorting/summary/index.html b/en/chapter_sorting/summary/index.html new file mode 100644 index 000000000..91d39f84e --- /dev/null +++ b/en/chapter_sorting/summary/index.html @@ -0,0 +1,3878 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.11 Summary - Hello Algo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + +

    11.11   Summary

    +

    1.   Key review

    +
      +
    • Bubble sort works by swapping adjacent elements. By adding a flag to enable early return, we can optimize the best-case time complexity of bubble sort to \(O(n)\).
    • +
    • Insertion sort sorts each round by inserting elements from the unsorted interval into the correct position in the sorted interval. Although the time complexity of insertion sort is \(O(n^2)\), it is very popular in sorting small amounts of data due to relatively fewer operations per unit.
    • +
    • Quick sort is based on sentinel partitioning operations. In sentinel partitioning, it's possible to always pick the worst pivot, leading to a time complexity degradation to \(O(n^2)\). Introducing median or random pivots can reduce the probability of such degradation. Tail recursion can effectively reduce the recursion depth, optimizing the space complexity to \(O(\log n)\).
    • +
    • Merge sort includes dividing and merging two phases, typically embodying the divide-and-conquer strategy. In merge sort, sorting an array requires creating auxiliary arrays, resulting in a space complexity of \(O(n)\); however, the space complexity for sorting a list can be optimized to \(O(1)\).
    • +
    • Bucket sort consists of three steps: data bucketing, sorting within buckets, and merging results. It also embodies the divide-and-conquer strategy, suitable for very large datasets. The key to bucket sort is the even distribution of data.
    • +
    • Counting sort is a special case of bucket sort, which sorts by counting the occurrences of each data point. Counting sort is suitable for large datasets with a limited range of data and requires that data can be converted to positive integers.
    • +
    • Radix sort sorts data by sorting digit by digit, requiring data to be represented as fixed-length numbers.
    • +
    • Overall, we hope to find a sorting algorithm that has high efficiency, stability, in-place operation, and positive adaptability. However, like other data structures and algorithms, no sorting algorithm can meet all these conditions simultaneously. In practical applications, we need to choose the appropriate sorting algorithm based on the characteristics of the data.
    • +
    • The following figure compares mainstream sorting algorithms in terms of efficiency, stability, in-place nature, and adaptability.
    • +
    +

    Sorting Algorithm Comparison

    +

    Figure 11-19   Sorting Algorithm Comparison

    + +

    2.   Q & A

    +

    Q: When is the stability of sorting algorithms necessary?

    +

    In reality, we might sort based on one attribute of an object. For example, students have names and heights as attributes, and we aim to implement multi-level sorting: first by name to get (A, 180) (B, 185) (C, 170) (D, 170); then by height. Because the sorting algorithm is unstable, we might end up with (D, 170) (C, 170) (A, 180) (B, 185).

    +

    It can be seen that the positions of students D and C have been swapped, disrupting the orderliness of the names, which is undesirable.

    +

    Q: Can the order of "searching from right to left" and "searching from left to right" in sentinel partitioning be swapped?

    +

    No, when using the leftmost element as the pivot, we must first "search from right to left" then "search from left to right". This conclusion is somewhat counterintuitive, so let's analyze the reason.

    +

    The last step of the sentinel partition partition() is to swap nums[left] and nums[i]. After the swap, the elements to the left of the pivot are all <= the pivot, which requires that nums[left] >= nums[i] must hold before the last swap. Suppose we "search from left to right" first, then if no element larger than the pivot is found, we will exit the loop when i == j, possibly with nums[j] == nums[i] > nums[left]. In other words, the final swap operation will exchange an element larger than the pivot to the left end of the array, causing the sentinel partition to fail.

    +

    For example, given the array [0, 0, 0, 0, 1], if we first "search from left to right", the array after the sentinel partition is [1, 0, 0, 0, 0], which is incorrect.

    +

    Upon further consideration, if we choose nums[right] as the pivot, then exactly the opposite, we must first "search from left to right".

    +

    Q: Regarding tail recursion optimization, why does choosing the shorter array ensure that the recursion depth does not exceed \(\log n\)?

    +

    The recursion depth is the number of currently unreturned recursive methods. Each round of sentinel partition divides the original array into two subarrays. With tail recursion optimization, the length of the subarray to be recursively followed is at most half of the original array length. Assuming the worst case always halves the length, the final recursion depth will be \(\log n\).

    +

    Reviewing the original quicksort, we might continuously recursively process larger arrays, in the worst case from \(n\), \(n - 1\), ..., \(2\), \(1\), with a recursion depth of \(n\). Tail recursion optimization can avoid this scenario.

    +

    Q: When all elements in the array are equal, is the time complexity of quicksort \(O(n^2)\)? How should this degenerate case be handled?

    +

    Yes. For this situation, consider using sentinel partitioning to divide the array into three parts: less than, equal to, and greater than the pivot. Only recursively proceed with the less than and greater than parts. In this method, an array where all input elements are equal can be sorted in just one round of sentinel partitioning.

    +

    Q: Why is the worst-case time complexity of bucket sort \(O(n^2)\)?

    +

    In the worst case, all elements are placed in the same bucket. If we use an \(O(n^2)\) algorithm to sort these elements, the time complexity will be \(O(n^2)\).

    + + + + + + + + + + + + + + + + + + + +
    Feel free to drop your insights, questions or suggestions
    + + + + + + + +
    +
    + + + + + +
    + + + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/chapter_stack_and_queue/deque/index.html b/en/chapter_stack_and_queue/deque/index.html index 3db3baaf5..b3579acdb 100644 --- a/en/chapter_stack_and_queue/deque/index.html +++ b/en/chapter_stack_and_queue/deque/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1677,7 +1677,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2086,6 +2086,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_stack_and_queue/index.html b/en/chapter_stack_and_queue/index.html index 1b8789d18..87acaba88 100644 --- a/en/chapter_stack_and_queue/index.html +++ b/en/chapter_stack_and_queue/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -1995,6 +1995,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_stack_and_queue/queue/index.html b/en/chapter_stack_and_queue/queue/index.html index 7d767bf79..24f0445c1 100644 --- a/en/chapter_stack_and_queue/queue/index.html +++ b/en/chapter_stack_and_queue/queue/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1677,7 +1677,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2086,6 +2086,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_stack_and_queue/stack/index.html b/en/chapter_stack_and_queue/stack/index.html index a26a715e7..2b530767e 100644 --- a/en/chapter_stack_and_queue/stack/index.html +++ b/en/chapter_stack_and_queue/stack/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1686,7 +1686,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2095,6 +2095,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_stack_and_queue/summary/index.html b/en/chapter_stack_and_queue/summary/index.html index b70bc26e4..806c11d39 100644 --- a/en/chapter_stack_and_queue/summary/index.html +++ b/en/chapter_stack_and_queue/summary/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1644,7 +1644,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2053,6 +2053,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_tree/array_representation_of_tree/index.html b/en/chapter_tree/array_representation_of_tree/index.html index 16db62f93..7b313497c 100644 --- a/en/chapter_tree/array_representation_of_tree/index.html +++ b/en/chapter_tree/array_representation_of_tree/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2062,6 +2062,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + @@ -3469,7 +4926,7 @@ aria-label="Footer" @@ -3594,7 +5051,7 @@ aria-label="Footer" diff --git a/en/chapter_tree/binary_search_tree/index.html b/en/chapter_tree/binary_search_tree/index.html index f2600006f..623e6f7b9 100644 --- a/en/chapter_tree/binary_search_tree/index.html +++ b/en/chapter_tree/binary_search_tree/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1586,7 +1586,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2104,6 +2104,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + diff --git a/en/chapter_tree/binary_tree/index.html b/en/chapter_tree/binary_tree/index.html index b0408b59c..8486cef4d 100644 --- a/en/chapter_tree/binary_tree/index.html +++ b/en/chapter_tree/binary_tree/index.html @@ -1139,7 +1139,7 @@ - 4.4 Memory and cache + 4.4 Memory and cache * @@ -1728,7 +1728,7 @@ - 7.2 Binary tree Traversal + 7.2 Binary tree traversal @@ -2137,6 +2137,1463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • + + + @@ -2951,7 +4408,7 @@ aria-label="Footer" @@ -2076,7 +3533,7 @@

    Chapter contents

    diff --git a/en/index.html b/en/index.html index 148e7d3a4..fb24550b9 100644 --- a/en/index.html +++ b/en/index.html @@ -957,7 +957,7 @@
  • - 4.4 Memory and cache + 4.4 Memory and cache *
  • @@ -1115,7 +1115,7 @@
  • - 7.2 Binary tree Traversal + 7.2 Binary tree traversal
  • @@ -1260,6 +1260,512 @@ +
  • + + + +
  • +
  • + + + +
  • +
  • + + + +
  • +
  • + + + +
  • +
  • + + + +
  • +
  • + + + +
  • +
  • + + + +
  • +
  • + + + +
  • diff --git a/en/search/search_index.json b/en/search/search_index.json index b36d4b372..44418fda7 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"chapter_array_and_linkedlist/","title":"Chapter 4. \u00a0 Arrays and linked lists","text":"

    Abstract

    The world of data structures resembles a sturdy brick wall.

    In arrays, envision bricks snugly aligned, each resting seamlessly beside the next, creating a unified formation. Meanwhile, in linked lists, these bricks disperse freely, embraced by vines gracefully knitting connections between them.

    "},{"location":"chapter_array_and_linkedlist/#chapter-contents","title":"Chapter contents","text":"
    • 4.1 \u00a0 Array
    • 4.2 \u00a0 Linked list
    • 4.3 \u00a0 List
    • 4.4 \u00a0 Memory and cache
    • 4.5 \u00a0 Summary
    "},{"location":"chapter_array_and_linkedlist/array/","title":"4.1 \u00a0 Array","text":"

    An \"array\" is a linear data structure that operates as a lineup of similar items, stored together in a computer's memory in contiguous spaces. It's like a sequence that maintains organized storage. Each item in this lineup has its unique 'spot' known as an \"index\". Please refer to the Figure 4-1 to observe how arrays work and grasp these key terms.

    Figure 4-1 \u00a0 Array definition and storage method

    "},{"location":"chapter_array_and_linkedlist/array/#411-common-operations-on-arrays","title":"4.1.1 \u00a0 Common operations on arrays","text":""},{"location":"chapter_array_and_linkedlist/array/#1-initializing-arrays","title":"1. \u00a0 Initializing arrays","text":"

    Arrays can be initialized in two ways depending on the needs: either without initial values or with specified initial values. When initial values are not specified, most programming languages will set the array elements to \\(0\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig array.py
    # Initialize array\narr: list[int] = [0] * 5  # [ 0, 0, 0, 0, 0 ]\nnums: list[int] = [1, 3, 2, 5, 4]\n
    array.cpp
    /* Initialize array */\n// Stored on stack\nint arr[5];\nint nums[5] = { 1, 3, 2, 5, 4 };\n// Stored on heap (manual memory release needed)\nint* arr1 = new int[5];\nint* nums1 = new int[5] { 1, 3, 2, 5, 4 };\n
    array.java
    /* Initialize array */\nint[] arr = new int[5]; // { 0, 0, 0, 0, 0 }\nint[] nums = { 1, 3, 2, 5, 4 };\n
    array.cs
    /* Initialize array */\nint[] arr = new int[5]; // [ 0, 0, 0, 0, 0 ]\nint[] nums = [1, 3, 2, 5, 4];\n
    array.go
    /* Initialize array */\nvar arr [5]int\n// In Go, specifying the length ([5]int) denotes an array, while not specifying it ([]int) denotes a slice.\n// Since Go's arrays are designed to have compile-time fixed length, only constants can be used to specify the length.\n// For convenience in implementing the extend() method, the Slice will be considered as an Array here.\nnums := []int{1, 3, 2, 5, 4}\n
    array.swift
    /* Initialize array */\nlet arr = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]\nlet nums = [1, 3, 2, 5, 4]\n
    array.js
    /* Initialize array */\nvar arr = new Array(5).fill(0);\nvar nums = [1, 3, 2, 5, 4];\n
    array.ts
    /* Initialize array */\nlet arr: number[] = new Array(5).fill(0);\nlet nums: number[] = [1, 3, 2, 5, 4];\n
    array.dart
    /* Initialize array */\nList<int> arr = List.filled(5, 0); // [0, 0, 0, 0, 0]\nList<int> nums = [1, 3, 2, 5, 4];\n
    array.rs
    /* Initialize array */\nlet arr: Vec<i32> = vec![0; 5]; // [0, 0, 0, 0, 0]\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    array.c
    /* Initialize array */\nint arr[5] = { 0 }; // { 0, 0, 0, 0, 0 }\nint nums[5] = { 1, 3, 2, 5, 4 };\n
    array.kt
    \n
    array.zig
    // Initialize array\nvar arr = [_]i32{0} ** 5; // { 0, 0, 0, 0, 0 }\nvar nums = [_]i32{ 1, 3, 2, 5, 4 };\n
    "},{"location":"chapter_array_and_linkedlist/array/#2-accessing-elements","title":"2. \u00a0 Accessing elements","text":"

    Elements in an array are stored in contiguous memory spaces, making it simpler to compute each element's memory address. The formula shown in the Figure below aids in determining an element's memory address, utilizing the array's memory address (specifically, the first element's address) and the element's index. This computation streamlines direct access to the desired element.

    Figure 4-2 \u00a0 Memory address calculation for array elements

    As observed in the above illustration, array indexing conventionally begins at \\(0\\). While this might appear counterintuitive, considering counting usually starts at \\(1\\), within the address calculation formula, an index is essentially an offset from the memory address. For the first element's address, this offset is \\(0\\), validating its index as \\(0\\).

    Accessing elements in an array is highly efficient, allowing us to randomly access any element in \\(O(1)\\) time.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def random_access(nums: list[int]) -> int:\n    \"\"\"\u968f\u673a\u8bbf\u95ee\u5143\u7d20\"\"\"\n    # \u5728\u533a\u95f4 [0, len(nums)-1] \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    random_index = random.randint(0, len(nums) - 1)\n    # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    random_num = nums[random_index]\n    return random_num\n
    array.cpp
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.java
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int[] nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = ThreadLocalRandom.current().nextInt(0, nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.cs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint RandomAccess(int[] nums) {\n    Random random = new();\n    // \u5728\u533a\u95f4 [0, nums.Length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = random.Next(nums.Length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.go
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums []int) (randomNum int) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    randomIndex := rand.Intn(len(nums))\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    randomNum = nums[randomIndex]\n    return\n}\n
    array.swift
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums: [Int]) -> Int {\n    // \u5728\u533a\u95f4 [0, nums.count) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let randomIndex = nums.indices.randomElement()!\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.js
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.ts
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums: number[]): number {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.dart
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(List<int> nums) {\n  // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  int randomIndex = Random().nextInt(nums.length);\n  // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  int randomNum = nums[randomIndex];\n  return randomNum;\n}\n
    array.rs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfn random_access(nums: &[i32]) -> i32 {\n    // \u5728\u533a\u95f4 [0, nums.len()) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let random_index = rand::thread_rng().gen_range(0..nums.len());\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let random_num = nums[random_index];\n    random_num\n}\n
    array.c
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.kt
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfun randomAccess(nums: IntArray): Int {\n    // \u5728\u533a\u95f4 [0, nums.size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    val randomIndex = ThreadLocalRandom.current().nextInt(0, nums.size)\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    val randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.rb
    ### \u968f\u673a\u8bbf\u95ee\u5143\u7d20 ###\ndef random_access(nums)\n  # \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  random_index = Random.rand(0...nums.length)\n\n  # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  nums[random_index]\nend\n
    array.zig
    // \u968f\u673a\u8bbf\u95ee\u5143\u7d20\nfn randomAccess(nums: []i32) i32 {\n    // \u5728\u533a\u95f4 [0, nums.len) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6574\u6570\n    var randomIndex = std.crypto.random.intRangeLessThan(usize, 0, nums.len);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    var randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#3-inserting-elements","title":"3. \u00a0 Inserting elements","text":"

    Array elements are tightly packed in memory, with no space available to accommodate additional data between them. Illustrated in Figure below, inserting an element in the middle of an array requires shifting all subsequent elements back by one position to create room for the new element.

    Figure 4-3 \u00a0 Array element insertion example

    It's important to note that due to the fixed length of an array, inserting an element will unavoidably result in the loss of the last element in the array. Solutions to address this issue will be explored in the \"List\" chapter.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def insert(nums: list[int], num: int, index: int):\n    \"\"\"\u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\"\"\"\n    # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in range(len(nums) - 1, index, -1):\n        nums[i] = nums[i - 1]\n    # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n
    array.cpp
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid Insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.Length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums []int, num int, index int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i := len(nums) - 1; i > index; i-- {\n        nums[i] = nums[i-1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums: inout [Int], num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).reversed() {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums, num, index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums: number[], num: number, index: number): void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 _num */\nvoid insert(List<int> nums, int _num, int index) {\n  // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for (var i = nums.length - 1; i > index; i--) {\n    nums[i] = nums[i - 1];\n  }\n  // \u5c06 _num \u8d4b\u7ed9 index \u5904\u5143\u7d20\n  nums[index] = _num;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfn insert(nums: &mut Vec<i32>, num: i32, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in (index + 1..nums.len()).rev() {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfun insert(nums: IntArray, num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (i in nums.size - 1 downTo index + 1) {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num ###\ndef insert(nums, num, index)\n  # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for i in (nums.length - 1).downto(index + 1)\n    nums[i] = nums[i - 1]\n  end\n\n  # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n  nums[index] = num\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\nfn insert(nums: []i32, num: i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    var i = nums.len - 1;\n    while (i > index) : (i -= 1) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#4-deleting-elements","title":"4. \u00a0 Deleting elements","text":"

    Similarly, as depicted in the Figure 4-4 , to delete an element at index \\(i\\), all elements following index \\(i\\) must be moved forward by one position.

    Figure 4-4 \u00a0 Array element deletion example

    Please note that after deletion, the former last element becomes \"meaningless,\" hence requiring no specific modification.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def remove(nums: list[int], index: int):\n    \"\"\"\u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\"\"\"\n    # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in range(index, len(nums) - 1):\n        nums[i] = nums[i + 1]\n
    array.cpp
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.java
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.cs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid Remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.Length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.go
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums []int, index int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i := index; i < len(nums)-1; i++ {\n        nums[i] = nums[i+1]\n    }\n}\n
    array.swift
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums: inout [Int], index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).dropLast() {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.js
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums, index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.ts
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums: number[], index: number): void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.dart
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(List<int> nums, int index) {\n  // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for (var i = index; i < nums.length - 1; i++) {\n    nums[i] = nums[i + 1];\n  }\n}\n
    array.rs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfn remove(nums: &mut Vec<i32>, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in index..nums.len() - 1 {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.c
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.kt
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfun remove(nums: IntArray, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (i in index..<nums.size - 1) {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.rb
    ### \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 ###\ndef remove(nums, index)\n  # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for i in index...(nums.length - 1)\n    nums[i] = nums[i + 1]\n  end\nend\n
    array.zig
    // \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\nfn remove(nums: []i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    var i = index;\n    while (i < nums.len - 1) : (i += 1) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    Code Visualization

    Full Screen >

    In summary, the insertion and deletion operations in arrays present the following disadvantages:

    • High time complexity: Both insertion and deletion in an array have an average time complexity of \\(O(n)\\), where \\(n\\) is the length of the array.
    • Loss of elements: Due to the fixed length of arrays, elements that exceed the array's capacity are lost during insertion.
    • Waste of memory: Initializing a longer array and utilizing only the front part results in \"meaningless\" end elements during insertion, leading to some wasted memory space.
    "},{"location":"chapter_array_and_linkedlist/array/#5-traversing-arrays","title":"5. \u00a0 Traversing arrays","text":"

    In most programming languages, we can traverse an array either by using indices or by directly iterating over each element:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def traverse(nums: list[int]):\n    \"\"\"\u904d\u5386\u6570\u7ec4\"\"\"\n    count = 0\n    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in range(len(nums)):\n        count += nums[i]\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums:\n        count += num\n    # \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num in enumerate(nums):\n        count += nums[i]\n        count += num\n
    array.cpp
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.java
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (int num : nums) {\n        count += num;\n    }\n}\n
    array.cs
    /* \u904d\u5386\u6570\u7ec4 */\nvoid Traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    foreach (int num in nums) {\n        count += num;\n    }\n}\n
    array.go
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums []int) {\n    count := 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i := 0; i < len(nums); i++ {\n        count += nums[i]\n    }\n    count = 0\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for _, num := range nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num := range nums {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.swift
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums: [Int]) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in nums.indices {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for (i, num) in nums.enumerated() {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.js
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums) {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.ts
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums: number[]): void {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.dart
    /* \u904d\u5386\u6570\u7ec4\u5143\u7d20 */\nvoid traverse(List<int> nums) {\n  int count = 0;\n  // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n  }\n  // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for (int _num in nums) {\n    count += _num;\n  }\n  // \u901a\u8fc7 forEach \u65b9\u6cd5\u904d\u5386\u6570\u7ec4\n  nums.forEach((_num) {\n    count += _num;\n  });\n}\n
    array.rs
    /* \u904d\u5386\u6570\u7ec4 */\nfn traverse(nums: &[i32]) {\n    let mut _count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in 0..nums.len() {\n        _count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        _count += num;\n    }\n}\n
    array.c
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.kt
    /* \u904d\u5386\u6570\u7ec4 */\nfun traverse(nums: IntArray) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (i in nums.indices) {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (j in nums) {\n        count += j\n    }\n}\n
    array.rb
    ### \u904d\u5386\u6570\u7ec4 ###\ndef traverse(nums)\n  count = 0\n\n  # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for i in 0...nums.length\n    count += nums[i]\n  end\n\n  # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for num in nums\n    count += num\n  end\nend\n
    array.zig
    // \u904d\u5386\u6570\u7ec4\nfn traverse(nums: []i32) void {\n    var count: i32 = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    var i: i32 = 0;\n    while (i < nums.len) : (i += 1) {\n        count += nums[i];\n    }\n    count = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (nums) |num| {\n        count += num;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#6-finding-elements","title":"6. \u00a0 Finding elements","text":"

    Locating a specific element within an array involves iterating through the array, checking each element to determine if it matches the desired value.

    Because arrays are linear data structures, this operation is commonly referred to as \"linear search.\"

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def find(nums: list[int], target: int) -> int:\n    \"\"\"\u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\"\"\"\n    for i in range(len(nums)):\n        if nums[i] == target:\n            return i\n    return -1\n
    array.cpp
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int[] nums, int target) {\n    for (int i = 0; i < nums.length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint Find(int[] nums, int target) {\n    for (int i = 0; i < nums.Length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums []int, target int) (index int) {\n    index = -1\n    for i := 0; i < len(nums); i++ {\n        if nums[i] == target {\n            index = i\n            break\n        }\n    }\n    return\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums: [Int], target: Int) -> Int {\n    for i in nums.indices {\n        if nums[i] == target {\n            return i\n        }\n    }\n    return -1\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums, target) {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) return i;\n    }\n    return -1;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums: number[], target: number): number {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(List<int> nums, int target) {\n  for (var i = 0; i < nums.length; i++) {\n    if (nums[i] == target) return i;\n  }\n  return -1;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfn find(nums: &[i32], target: i32) -> Option<usize> {\n    for i in 0..nums.len() {\n        if nums[i] == target {\n            return Some(i);\n        }\n    }\n    None\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfun find(nums: IntArray, target: Int): Int {\n    for (i in nums.indices) {\n        if (nums[i] == target)\n            return i\n    }\n    return -1\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 ###\ndef find(nums, target)\n  for i in 0...nums.length\n    return i if nums[i] == target\n  end\n\n  -1\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\nfn find(nums: []i32, target: i32) i32 {\n    for (nums, 0..) |num, i| {\n        if (num == target) return @intCast(i);\n    }\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#7-expanding-arrays","title":"7. \u00a0 Expanding arrays","text":"

    In complex system environments, ensuring the availability of memory space after an array for safe capacity extension becomes challenging. Consequently, in most programming languages, the length of an array is immutable.

    To expand an array, it's necessary to create a larger array and then copy the elements from the original array. This operation has a time complexity of \\(O(n)\\) and can be time-consuming for large arrays. The code are as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def extend(nums: list[int], enlarge: int) -> list[int]:\n    \"\"\"\u6269\u5c55\u6570\u7ec4\u957f\u5ea6\"\"\"\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res = [0] * (len(nums) + enlarge)\n    # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in range(len(nums)):\n        res[i] = nums[i]\n    # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n
    array.cpp
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = new int[size + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    delete[] nums;\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.java
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.cs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] Extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.Length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.go
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums []int, enlarge int) []int {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res := make([]int, len(nums)+enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i, num := range nums {\n        res[i] = num\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.swift
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums: [Int], enlarge: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = Array(repeating: 0, count: nums.count + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in nums.indices {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.js
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cJavaScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums, enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.ts
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cTypeScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums: number[], enlarge: number): number[] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.dart
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nList<int> extend(List<int> nums, int enlarge) {\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  List<int> res = List.filled(nums.length + enlarge, 0);\n  // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    res[i] = nums[i];\n  }\n  // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  return res;\n}\n
    array.rs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfn extend(nums: Vec<i32>, enlarge: usize) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    let mut res: Vec<i32> = vec![0; nums.len() + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\n    for i in 0..nums.len() {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    res\n}\n
    array.c
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = (int *)malloc(sizeof(int) * (size + enlarge));\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u521d\u59cb\u5316\u6269\u5c55\u540e\u7684\u7a7a\u95f4\n    for (int i = size; i < size + enlarge; i++) {\n        res[i] = 0;\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.kt
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfun extend(nums: IntArray, enlarge: Int): IntArray {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    val res = IntArray(nums.size + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (i in nums.indices) {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.rb
    ### \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 ###\n# \u8bf7\u6ce8\u610f\uff0cRuby \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n# \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\ndef extend(nums, enlarge)\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  res = Array.new(nums.length + enlarge, 0)\n\n  # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for i in 0...nums.length\n    res[i] = nums[i]\n  end\n\n  # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  res\nend\n
    array.zig
    // \u6269\u5c55\u6570\u7ec4\u957f\u5ea6\nfn extend(mem_allocator: std.mem.Allocator, nums: []i32, enlarge: usize) ![]i32 {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = try mem_allocator.alloc(i32, nums.len + enlarge);\n    @memset(res, 0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    std.mem.copy(i32, res, nums);\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#412-advantages-and-limitations-of-arrays","title":"4.1.2 \u00a0 Advantages and limitations of arrays","text":"

    Arrays are stored in contiguous memory spaces and consist of elements of the same type. This approach provides substantial prior information that systems can leverage to optimize the efficiency of data structure operations.

    • High space efficiency: Arrays allocate a contiguous block of memory for data, eliminating the need for additional structural overhead.
    • Support for random access: Arrays allow \\(O(1)\\) time access to any element.
    • Cache locality: When accessing array elements, the computer not only loads them but also caches the surrounding data, utilizing high-speed cache to enchance subsequent operation speeds.

    However, continuous space storage is a double-edged sword, with the following limitations:

    • Low efficiency in insertion and deletion: As arrays accumulate many elements, inserting or deleting elements requires shifting a large number of elements.
    • Fixed length: The length of an array is fixed after initialization. Expanding an array requires copying all data to a new array, incurring significant costs.
    • Space wastage: If the allocated array size exceeds the what is necessary, the extra space is wasted.
    "},{"location":"chapter_array_and_linkedlist/array/#413-typical-applications-of-arrays","title":"4.1.3 \u00a0 Typical applications of arrays","text":"

    Arrays are fundamental and widely used data structures. They find frequent application in various algorithms and serve in the implementation of complex data structures.

    • Random access: Arrays are ideal for storing data when random sampling is required. By generating a random sequence based on indices, we can achieve random sampling efficiently.
    • Sorting and searching: Arrays are the most commonly used data structure for sorting and searching algorithms. Techniques like quick sort, merge sort, binary search, etc., are primarily operate on arrays.
    • Lookup tables: Arrays serve as efficient lookup tables for quick element or relationship retrieval. For instance, mapping characters to ASCII codes becomes seamless by using the ASCII code values as indices and storing corresponding elements in the array.
    • Machine learning: Within the domain of neural networks, arrays play a pivotal role in executing crucial linear algebra operations involving vectors, matrices, and tensors. Arrays serve as the primary and most extensively used data structure in neural network programming.
    • Data structure implementation: Arrays serve as the building blocks for implementing various data structures like stacks, queues, hash tables, heaps, graphs, etc. For instance, the adjacency matrix representation of a graph is essentially a two-dimensional array.
    "},{"location":"chapter_array_and_linkedlist/linked_list/","title":"4.2 \u00a0 Linked list","text":"

    Memory space is a shared resource among all programs. In a complex system environment, available memory can be dispersed throughout the memory space. We understand that the memory allocated for an array must be continuous. However, for very large arrays, finding a sufficiently large contiguous memory space might be challenging. This is where the flexible advantage of linked lists becomes evident.

    A \"linked list\" is a linear data structure in which each element is a node object, and the nodes are interconnected through \"references\". These references hold the memory addresses of subsequent nodes, enabling navigation from one node to the next.

    The design of linked lists allows for their nodes to be distributed across memory locations without requiring contiguous memory addresses.

    Figure 4-5 \u00a0 Linked list definition and storage method

    As shown in the figure, we see that the basic building block of a linked list is the \"node\" object. Each node comprises two key components: the node's \"value\" and a \"reference\" to the next node.

    • The first node in a linked list is the \"head node\", and the final one is the \"tail node\".
    • The tail node points to \"null\", designated as null in Java, nullptr in C++, and None in Python.
    • In languages that support pointers, like C, C++, Go, and Rust, this \"reference\" is typically implemented as a \"pointer\".

    As the code below illustrates, a ListNode in a linked list, besides holding a value, must also maintain an additional reference (or pointer). Therefore, a linked list occupies more memory space than an array when storing the same quantity of data..

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    class ListNode:\n    \"\"\"Linked list node class\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val               # Node value\n        self.next: ListNode | None = None # Reference to the next node\n
    /* Linked list node structure */\nstruct ListNode {\n    int val;         // Node value\n    ListNode *next;  // Pointer to the next node\n    ListNode(int x) : val(x), next(nullptr) {}  // Constructor\n};\n
    /* Linked list node class */\nclass ListNode {\n    int val;        // Node value\n    ListNode next;  // Reference to the next node\n    ListNode(int x) { val = x; }  // Constructor\n}\n
    /* Linked list node class */\nclass ListNode(int x) {  // Constructor\n    int val = x;         // Node value\n    ListNode? next;      // Reference to the next node\n}\n
    /* Linked list node structure */\ntype ListNode struct {\n    Val  int       // Node value\n    Next *ListNode // Pointer to the next node\n}\n\n// NewListNode Constructor, creates a new linked list\nfunc NewListNode(val int) *ListNode {\n    return &ListNode{\n        Val:  val,\n        Next: nil,\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n    var val: Int // Node value\n    var next: ListNode? // Reference to the next node\n\n    init(x: Int) { // Constructor\n        val = x\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n    constructor(val, next) {\n        this.val = (val === undefined ? 0 : val);       // Node value\n        this.next = (next === undefined ? null : next); // Reference to the next node\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    constructor(val?: number, next?: ListNode | null) {\n        this.val = val === undefined ? 0 : val;        // Node value\n        this.next = next === undefined ? null : next;  // Reference to the next node\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n  int val; // Node value\n  ListNode? next; // Reference to the next node\n  ListNode(this.val, [this.next]); // Constructor\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n/* Linked list node class */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // Node value\n    next: Option<Rc<RefCell<ListNode>>>, // Pointer to the next node\n}\n
    /* Linked list node structure */\ntypedef struct ListNode {\n    int val;               // Node value\n    struct ListNode *next; // Pointer to the next node\n} ListNode;\n\n/* Constructor */\nListNode *newListNode(int val) {\n    ListNode *node;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    return node;\n}\n
    \n
    // Linked list node class\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // Node value\n        next: ?*Self = null, // Pointer to the next node\n\n        // Constructor\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n        }\n    };\n}\n
    "},{"location":"chapter_array_and_linkedlist/linked_list/#421-common-operations-on-linked-lists","title":"4.2.1 \u00a0 Common operations on linked lists","text":""},{"location":"chapter_array_and_linkedlist/linked_list/#1-initializing-a-linked-list","title":"1. \u00a0 Initializing a linked list","text":"

    Constructing a linked list is a two-step process: first, initializing each node object, and second, forming the reference links between the nodes. After initialization, we can traverse all nodes sequentially from the head node by following the next reference.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig linked_list.py
    # Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4\n# Initialize each node\nn0 = ListNode(1)\nn1 = ListNode(3)\nn2 = ListNode(2)\nn3 = ListNode(5)\nn4 = ListNode(4)\n# Build references between nodes\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.cpp
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode* n0 = new ListNode(1);\nListNode* n1 = new ListNode(3);\nListNode* n2 = new ListNode(2);\nListNode* n3 = new ListNode(5);\nListNode* n4 = new ListNode(4);\n// Build references between nodes\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.java
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode n0 = new ListNode(1);\nListNode n1 = new ListNode(3);\nListNode n2 = new ListNode(2);\nListNode n3 = new ListNode(5);\nListNode n4 = new ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.cs
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode n0 = new(1);\nListNode n1 = new(3);\nListNode n2 = new(2);\nListNode n3 = new(5);\nListNode n4 = new(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.go
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nn0 := NewListNode(1)\nn1 := NewListNode(3)\nn2 := NewListNode(2)\nn3 := NewListNode(5)\nn4 := NewListNode(4)\n// Build references between nodes\nn0.Next = n1\nn1.Next = n2\nn2.Next = n3\nn3.Next = n4\n
    linked_list.swift
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nlet n0 = ListNode(x: 1)\nlet n1 = ListNode(x: 3)\nlet n2 = ListNode(x: 2)\nlet n3 = ListNode(x: 5)\nlet n4 = ListNode(x: 4)\n// Build references between nodes\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.js
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.ts
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.dart
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode n0 = ListNode(1);\nListNode n1 = ListNode(3);\nListNode n2 = ListNode(2);\nListNode n3 = ListNode(5);\nListNode n4 = ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.rs
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nlet n0 = Rc::new(RefCell::new(ListNode { val: 1, next: None }));\nlet n1 = Rc::new(RefCell::new(ListNode { val: 3, next: None }));\nlet n2 = Rc::new(RefCell::new(ListNode { val: 2, next: None }));\nlet n3 = Rc::new(RefCell::new(ListNode { val: 5, next: None }));\nlet n4 = Rc::new(RefCell::new(ListNode { val: 4, next: None }));\n\n// Build references between nodes\nn0.borrow_mut().next = Some(n1.clone());\nn1.borrow_mut().next = Some(n2.clone());\nn2.borrow_mut().next = Some(n3.clone());\nn3.borrow_mut().next = Some(n4.clone());\n
    linked_list.c
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode* n0 = newListNode(1);\nListNode* n1 = newListNode(3);\nListNode* n2 = newListNode(2);\nListNode* n3 = newListNode(5);\nListNode* n4 = newListNode(4);\n// Build references between nodes\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.kt
    \n
    linked_list.zig
    // Initialize linked list\n// Initialize each node\nvar n0 = inc.ListNode(i32){.val = 1};\nvar n1 = inc.ListNode(i32){.val = 3};\nvar n2 = inc.ListNode(i32){.val = 2};\nvar n3 = inc.ListNode(i32){.val = 5};\nvar n4 = inc.ListNode(i32){.val = 4};\n// Build references between nodes\nn0.next = &n1;\nn1.next = &n2;\nn2.next = &n3;\nn3.next = &n4;\n

    The array as a whole is a variable, for instance, the array nums includes elements like nums[0], nums[1], and so on, whereas a linked list is made up of several distinct node objects. We typically refer to a linked list by its head node, for example, the linked list in the previous code snippet is referred to as n0.

    "},{"location":"chapter_array_and_linkedlist/linked_list/#2-inserting-nodes","title":"2. \u00a0 Inserting nodes","text":"

    Inserting a node into a linked list is very easy. As shown in the figure, let's assume we aim to insert a new node P between two adjacent nodes n0 and n1. This can be achieved by simply modifying two node references (pointers), with a time complexity of \\(O(1)\\).

    By comparison, inserting an element into an array has a time complexity of \\(O(n)\\), which becomes less efficient when dealing with large data volumes.

    Figure 4-6 \u00a0 Linked list node insertion example

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def insert(n0: ListNode, P: ListNode):\n    \"\"\"\u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\"\"\"\n    n1 = n0.next\n    P.next = n1\n    n0.next = P\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n    ListNode n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid Insert(ListNode n0, ListNode P) {\n    ListNode? n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insertNode(n0 *ListNode, P *ListNode) {\n    n1 := n0.Next\n    P.Next = n1\n    n0.Next = P\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insert(n0: ListNode, P: ListNode) {\n    let n1 = n0.next\n    P.next = n1\n    n0.next = P\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0, P) {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0: ListNode, P: ListNode): void {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n  ListNode? n1 = n0.next;\n  P.next = n1;\n  n0.next = P;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\n#[allow(non_snake_case)]\npub fn insert<T>(n0: &Rc<RefCell<ListNode<T>>>, P: Rc<RefCell<ListNode<T>>>) {\n    let n1 = n0.borrow_mut().next.take();\n    P.borrow_mut().next = n1;\n    n0.borrow_mut().next = Some(P);\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfun insert(n0: ListNode?, p: ListNode?) {\n    val n1 = n0?.next\n    p?.next = n1\n    n0?.next = p\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 _p ###\n# Ruby \u7684 `p` \u662f\u4e00\u4e2a\u5185\u7f6e\u51fd\u6570\uff0c `P` \u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u4f7f\u7528 `_p` \u4ee3\u66ff\ndef insert(n0, _p)\n  n1 = n0.next\n  _p.next = n1\n  n0.next = _p\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\nfn insert(n0: ?*inc.ListNode(i32), P: ?*inc.ListNode(i32)) void {\n    var n1 = n0.?.next;\n    P.?.next = n1;\n    n0.?.next = P;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#3-deleting-nodes","title":"3. \u00a0 Deleting nodes","text":"

    As shown in the figure, deleting a node from a linked list is also very easy, involving only the modification of a single node's reference (pointer).

    It's important to note that even though node P continues to point to n1 after being deleted, it becomes inaccessible during linked list traversal. This effectively means that P is no longer a part of the linked list.

    Figure 4-7 \u00a0 Linked list node deletion

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def remove(n0: ListNode):\n    \"\"\"\u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    if not n0.next:\n        return\n    # n0 -> P -> n1\n    P = n0.next\n    n1 = P.next\n    n0.next = n1\n
    linked_list.cpp
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode *n0) {\n    if (n0->next == nullptr)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    delete P;\n}\n
    linked_list.java
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.cs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid Remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode? n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.go
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc removeItem(n0 *ListNode) {\n    if n0.Next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    P := n0.Next\n    n1 := P.Next\n    n0.Next = n1\n}\n
    linked_list.swift
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc remove(n0: ListNode) {\n    if n0.next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    let P = n0.next\n    let n1 = P?.next\n    n0.next = n1\n}\n
    linked_list.js
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0) {\n    if (!n0.next) return;\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.ts
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0: ListNode): void {\n    if (!n0.next) {\n        return;\n    }\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.dart
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n  if (n0.next == null) return;\n  // n0 -> P -> n1\n  ListNode P = n0.next!;\n  ListNode? n1 = P.next;\n  n0.next = n1;\n}\n
    linked_list.rs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n#[allow(non_snake_case)]\npub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {\n    if n0.borrow().next.is_none() {\n        return;\n    };\n    // n0 -> P -> n1\n    let P = n0.borrow_mut().next.take();\n    if let Some(node) = P {\n        let n1 = node.borrow_mut().next.take();\n        n0.borrow_mut().next = n1;\n    }\n}\n
    linked_list.c
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(ListNode *n0) {\n    if (!n0->next)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    free(P);\n}\n
    linked_list.kt
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfun remove(n0: ListNode?) {\n    if (n0?.next == null)\n        return\n    // n0 -> P -> n1\n    val p = n0.next\n    val n1 = p?.next\n    n0.next = n1\n}\n
    linked_list.rb
    ### \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 ###\ndef remove(n0)\n  return if n0.next.nil?\n\n  # n0 -> remove_node -> n1\n  remove_node = n0.next\n  n1 = remove_node.next\n  n0.next = n1\nend\n
    linked_list.zig
    // \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\nfn remove(n0: ?*inc.ListNode(i32)) void {\n    if (n0.?.next == null) return;\n    // n0 -> P -> n1\n    var P = n0.?.next;\n    var n1 = P.?.next;\n    n0.?.next = n1;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#4-accessing-nodes","title":"4. \u00a0 Accessing nodes","text":"

    Accessing nodes in a linked list is less efficient. As previously mentioned, any element in an array can be accessed in \\(O(1)\\) time. In contrast, with a linked list, the program involves starting from the head node and sequentially traversing through the nodes until the desired node is found. In other words, to access the \\(i\\)-th node in a linked list, the program must iterate through \\(i - 1\\) nodes, resulting in a time complexity of \\(O(n)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def access(head: ListNode, index: int) -> ListNode | None:\n    \"\"\"\u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\"\"\"\n    for _ in range(index):\n        if not head:\n            return None\n        head = head.next\n    return head\n
    linked_list.cpp
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == nullptr)\n            return nullptr;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.java
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode access(ListNode head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.cs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? Access(ListNode? head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.go
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head *ListNode, index int) *ListNode {\n    for i := 0; i < index; i++ {\n        if head == nil {\n            return nil\n        }\n        head = head.Next\n    }\n    return head\n}\n
    linked_list.swift
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head: ListNode, index: Int) -> ListNode? {\n    var head: ListNode? = head\n    for _ in 0 ..< index {\n        if head == nil {\n            return nil\n        }\n        head = head?.next\n    }\n    return head\n}\n
    linked_list.js
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head, index) {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.ts
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head: ListNode | null, index: number): ListNode | null {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.dart
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? access(ListNode? head, int index) {\n  for (var i = 0; i < index; i++) {\n    if (head == null) return null;\n    head = head.next;\n  }\n  return head;\n}\n
    linked_list.rs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\npub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Rc<RefCell<ListNode<T>>> {\n    if index <= 0 {\n        return head;\n    };\n    if let Some(node) = &head.borrow().next {\n        return access(node.clone(), index - 1);\n    }\n\n    return head;\n}\n
    linked_list.c
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == NULL)\n            return NULL;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.kt
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfun access(head: ListNode?, index: Int): ListNode? {\n    var h = head\n    for (i in 0..<index) {\n        if (h == null)\n            return null\n        h = h.next\n    }\n    return h\n}\n
    linked_list.rb
    ### \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 ###\ndef access(head, index)\n  for i in 0...index\n    return nil if head.nil?\n    head = head.next\n  end\n\n  head\nend\n
    linked_list.zig
    // \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\nfn access(node: ?*inc.ListNode(i32), index: i32) ?*inc.ListNode(i32) {\n    var head = node;\n    var i: i32 = 0;\n    while (i < index) : (i += 1) {\n        head = head.?.next;\n        if (head == null) return null;\n    }\n    return head;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#5-finding-nodes","title":"5. \u00a0 Finding nodes","text":"

    Traverse the linked list to locate a node whose value matches target, and then output the index of that node within the linked list. This procedure is also an example of linear search. The corresponding code is provided below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def find(head: ListNode, target: int) -> int:\n    \"\"\"\u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    index = 0\n    while head:\n        if head.val == target:\n            return index\n        head = head.next\n        index += 1\n    return -1\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head != nullptr) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint Find(ListNode? head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc findNode(head *ListNode, target int) int {\n    index := 0\n    for head != nil {\n        if head.Val == target {\n            return index\n        }\n        head = head.Next\n        index++\n    }\n    return -1\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc find(head: ListNode, target: Int) -> Int {\n    var head: ListNode? = head\n    var index = 0\n    while head != nil {\n        if head?.val == target {\n            return index\n        }\n        head = head?.next\n        index += 1\n    }\n    return -1\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head, target) {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head: ListNode | null, target: number): number {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode? head, int target) {\n  int index = 0;\n  while (head != null) {\n    if (head.val == target) {\n      return index;\n    }\n    head = head.next;\n    index++;\n  }\n  return -1;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\npub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T, index: i32) -> i32 {\n    if head.borrow().val == target {\n        return index;\n    };\n    if let Some(node) = &head.borrow_mut().next {\n        return find(node.clone(), target, index + 1);\n    }\n    return -1;\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfun find(head: ListNode?, target: Int): Int {\n    var index = 0\n    var h = head\n    while (h != null) {\n        if (h._val == target)\n            return index\n        h = h.next\n        index++\n    }\n    return -1\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 ###\ndef find(head, target)\n  index = 0\n  while head\n    return index if head.val == target\n    head = head.next\n    index += 1\n  end\n\n  -1\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\nfn find(node: ?*inc.ListNode(i32), target: i32) i32 {\n    var head = node;\n    var index: i32 = 0;\n    while (head != null) {\n        if (head.?.val == target) return index;\n        head = head.?.next;\n        index += 1;\n    }\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#422-arrays-vs-linked-lists","title":"4.2.2 \u00a0 Arrays vs. linked lists","text":"

    The Table 4-1 summarizes the characteristics of arrays and linked lists, and it also compares their efficiencies in various operations. Because they utilize opposing storage strategies, their respective properties and operational efficiencies exhibit distinct contrasts.

    Table 4-1 \u00a0 Efficiency comparison of arrays and linked lists

    Arrays Linked Lists Storage Contiguous Memory Space Dispersed Memory Space Capacity Expansion Fixed Length Flexible Expansion Memory Efficiency Less Memory per Element, Potential Space Wastage More Memory per Element Accessing Elements \\(O(1)\\) \\(O(n)\\) Adding Elements \\(O(n)\\) \\(O(1)\\) Deleting Elements \\(O(n)\\) \\(O(1)\\)"},{"location":"chapter_array_and_linkedlist/linked_list/#423-common-types-of-linked-lists","title":"4.2.3 \u00a0 Common types of linked lists","text":"

    As shown in the figure, there are three common types of linked lists.

    • Singly linked list: This is the standard linked list described earlier. Nodes in a singly linked list include a value and a reference to the next node. The first node is known as the head node, and the last node, which points to null (None), is the tail node.
    • Circular linked list: This is formed when the tail node of a singly linked list points back to the head node, creating a loop. In a circular linked list, any node can function as the head node.
    • Doubly linked list: In contrast to a singly linked list, a doubly linked list maintains references in two directions. Each node contains references (pointer) to both its successor (the next node) and predecessor (the previous node). Although doubly linked lists offer more flexibility for traversing in either direction, they also consume more memory space.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    class ListNode:\n    \"\"\"Bidirectional linked list node class\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # Node value\n        self.next: ListNode | None = None  # Reference to the successor node\n        self.prev: ListNode | None = None  # Reference to a predecessor node\n
    /* Bidirectional linked list node structure */\nstruct ListNode {\n    int val;         // Node value\n    ListNode *next;  // Pointer to the successor node\n    ListNode *prev;  // Pointer to the predecessor node\n    ListNode(int x) : val(x), next(nullptr), prev(nullptr) {}  // Constructor\n};\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    int val;        // Node value\n    ListNode next;  // Reference to the next node\n    ListNode prev;  // Reference to the predecessor node\n    ListNode(int x) { val = x; }  // Constructor\n}\n
    /* Bidirectional linked list node class */\nclass ListNode(int x) {  // Constructor\n    int val = x;    // Node value\n    ListNode next;  // Reference to the next node\n    ListNode prev;  // Reference to the predecessor node\n}\n
    /* Bidirectional linked list node structure */\ntype DoublyListNode struct {\n    Val  int             // Node value\n    Next *DoublyListNode // Pointer to the successor node\n    Prev *DoublyListNode // Pointer to the predecessor node\n}\n\n// NewDoublyListNode initialization\nfunc NewDoublyListNode(val int) *DoublyListNode {\n    return &DoublyListNode{\n        Val:  val,\n        Next: nil,\n        Prev: nil,\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    var val: Int // Node value\n    var next: ListNode? // Reference to the next node\n    var prev: ListNode? // Reference to the predecessor node\n\n    init(x: Int) { // Constructor\n        val = x\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    constructor(val, next, prev) {\n        this.val = val  ===  undefined ? 0 : val;        // Node value\n        this.next = next  ===  undefined ? null : next;  // Reference to the successor node\n        this.prev = prev  ===  undefined ? null : prev;  // Reference to the predecessor node\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    prev: ListNode | null;\n    constructor(val?: number, next?: ListNode | null, prev?: ListNode | null) {\n        this.val = val  ===  undefined ? 0 : val;        // Node value\n        this.next = next  ===  undefined ? null : next;  // Reference to the successor node\n        this.prev = prev  ===  undefined ? null : prev;  // Reference to the predecessor node\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    int val;        // Node value\n    ListNode next;  // Reference to the next node\n    ListNode prev;  // Reference to the predecessor node\n    ListNode(this.val, [this.next, this.prev]);  // Constructor\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* Bidirectional linked list node type */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // Node value\n    next: Option<Rc<RefCell<ListNode>>>, // Pointer to successor node\n    prev: Option<Rc<RefCell<ListNode>>>, // Pointer to predecessor node\n}\n\n/* Constructors */\nimpl ListNode {\n    fn new(val: i32) -> Self {\n        ListNode {\n            val,\n            next: None,\n            prev: None,\n        }\n    }\n}\n
    /* Bidirectional linked list node structure */\ntypedef struct ListNode {\n    int val;               // Node value\n    struct ListNode *next; // Pointer to the successor node\n    struct ListNode *prev; // Pointer to the predecessor node\n} ListNode;\n\n/* Constructors */\nListNode *newListNode(int val) {\n    ListNode *node, *next;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    node->prev = NULL;\n    return node;\n}\n
    \n
    // Bidirectional linked list node class\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // Node value\n        next: ?*Self = null, // Pointer to the successor node\n        prev: ?*Self = null, // Pointer to the predecessor node\n\n        // Constructor\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n

    Figure 4-8 \u00a0 Common types of linked lists

    "},{"location":"chapter_array_and_linkedlist/linked_list/#424-typical-applications-of-linked-lists","title":"4.2.4 \u00a0 Typical applications of linked lists","text":"

    Singly linked lists are frequently utilized in implementing stacks, queues, hash tables, and graphs.

    • Stacks and queues: In singly linked lists, if insertions and deletions occur at the same end, it behaves like a stack (last-in-first-out). Conversely, if insertions are at one end and deletions at the other, it functions like a queue (first-in-first-out).
    • Hash tables: Linked lists are used in chaining, a popular method for resolving hash collisions. Here, all collided elements are grouped into a linked list.
    • Graphs: Adjacency lists, a standard method for graph representation, associate each graph vertex with a linked list. This list contains elements that represent vertices connected to the corresponding vertex.

    Doubly linked lists are ideal for scenarios requiring rapid access to preceding and succeeding elements.

    • Advanced data structures: In structures like red-black trees and B-trees, accessing a node's parent is essential. This is achieved by incorporating a reference to the parent node in each node, akin to a doubly linked list.
    • Browser history: In web browsers, doubly linked lists facilitate navigating the history of visited pages when users click forward or back.
    • LRU algorithm: Doubly linked lists are apt for Least Recently Used (LRU) cache eviction algorithms, enabling swift identification of the least recently used data and facilitating fast node addition and removal.

    Circular linked lists are ideal for applications that require periodic operations, such as resource scheduling in operating systems.

    • Round-robin scheduling algorithm: In operating systems, the round-robin scheduling algorithm is a common CPU scheduling method, requiring cycling through a group of processes. Each process is assigned a time slice, and upon expiration, the CPU rotates to the next process. This cyclical operation can be efficiently realized using a circular linked list, allowing for a fair and time-shared system among all processes.
    • Data buffers: Circular linked lists are also used in data buffers, like in audio and video players, where the data stream is divided into multiple buffer blocks arranged in a circular fashion for seamless playback.
    "},{"location":"chapter_array_and_linkedlist/list/","title":"4.3 \u00a0 List","text":"

    A \"list\" is an abstract data structure concept that represents an ordered collection of elements, supporting operations such as element access, modification, addition, deletion, and traversal, without requiring users to consider capacity limitations. Lists can be implemented based on linked lists or arrays.

    • A linked list inherently serves as a list, supporting operations for adding, deleting, searching, and modifying elements, with the flexibility to dynamically adjust its size.
    • Arrays also support these operations, but due to their immutable length, they can be considered as a list with a length limit.

    When implementing lists using arrays, the immutability of length reduces the practicality of the list. This is because predicting the amount of data to be stored in advance is often challenging, making it difficult to choose an appropriate list length. If the length is too small, it may not meet the requirements; if too large, it may waste memory space.

    To solve this problem, we can implement lists using a \"dynamic array.\" It inherits the advantages of arrays and can dynamically expand during program execution.

    In fact, many programming languages' standard libraries implement lists using dynamic arrays, such as Python's list, Java's ArrayList, C++'s vector, and C#'s List. In the following discussion, we will consider \"list\" and \"dynamic array\" as synonymous concepts.

    "},{"location":"chapter_array_and_linkedlist/list/#431-common-list-operations","title":"4.3.1 \u00a0 Common list operations","text":""},{"location":"chapter_array_and_linkedlist/list/#1-initializing-a-list","title":"1. \u00a0 Initializing a list","text":"

    We typically use two initialization methods: \"without initial values\" and \"with initial values\".

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Initialize list\n# Without initial values\nnums1: list[int] = []\n# With initial values\nnums: list[int] = [1, 3, 2, 5, 4]\n
    list.cpp
    /* Initialize list */\n// Note, in C++ the vector is the equivalent of nums described here\n// Without initial values\nvector<int> nums1;\n// With initial values\nvector<int> nums = { 1, 3, 2, 5, 4 };\n
    list.java
    /* Initialize list */\n// Without initial values\nList<Integer> nums1 = new ArrayList<>();\n// With initial values (note the element type should be the wrapper class Integer[] for int[])\nInteger[] numbers = new Integer[] { 1, 3, 2, 5, 4 };\nList<Integer> nums = new ArrayList<>(Arrays.asList(numbers));\n
    list.cs
    /* Initialize list */\n// Without initial values\nList<int> nums1 = [];\n// With initial values\nint[] numbers = [1, 3, 2, 5, 4];\nList<int> nums = [.. numbers];\n
    list_test.go
    /* Initialize list */\n// Without initial values\nnums1 := []int{}\n// With initial values\nnums := []int{1, 3, 2, 5, 4}\n
    list.swift
    /* Initialize list */\n// Without initial values\nlet nums1: [Int] = []\n// With initial values\nvar nums = [1, 3, 2, 5, 4]\n
    list.js
    /* Initialize list */\n// Without initial values\nconst nums1 = [];\n// With initial values\nconst nums = [1, 3, 2, 5, 4];\n
    list.ts
    /* Initialize list */\n// Without initial values\nconst nums1: number[] = [];\n// With initial values\nconst nums: number[] = [1, 3, 2, 5, 4];\n
    list.dart
    /* Initialize list */\n// Without initial values\nList<int> nums1 = [];\n// With initial values\nList<int> nums = [1, 3, 2, 5, 4];\n
    list.rs
    /* Initialize list */\n// Without initial values\nlet nums1: Vec<i32> = Vec::new();\n// With initial values\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Initialize list\nvar nums = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums.deinit();\ntry nums.appendSlice(&[_]i32{ 1, 3, 2, 5, 4 });\n
    "},{"location":"chapter_array_and_linkedlist/list/#2-accessing-elements","title":"2. \u00a0 Accessing elements","text":"

    Lists are essentially arrays, thus they can access and update elements in \\(O(1)\\) time, which is very efficient.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Access elements\nnum: int = nums[1]  # Access the element at index 1\n\n# Update elements\nnums[1] = 0    # Update the element at index 1 to 0\n
    list.cpp
    /* Access elements */\nint num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.java
    /* Access elements */\nint num = nums.get(1);  // Access the element at index 1\n\n/* Update elements */\nnums.set(1, 0);  // Update the element at index 1 to 0\n
    list.cs
    /* Access elements */\nint num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list_test.go
    /* Access elements */\nnum := nums[1]  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0     // Update the element at index 1 to 0\n
    list.swift
    /* Access elements */\nlet num = nums[1] // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0 // Update the element at index 1 to 0\n
    list.js
    /* Access elements */\nconst num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.ts
    /* Access elements */\nconst num: number = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.dart
    /* Access elements */\nint num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.rs
    /* Access elements */\nlet num: i32 = nums[1];  // Access the element at index 1\n/* Update elements */\nnums[1] = 0;             // Update the element at index 1 to 0\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Access elements\nvar num = nums.items[1]; // Access the element at index 1\n\n// Update elements\nnums.items[1] = 0; // Update the element at index 1 to 0  \n
    "},{"location":"chapter_array_and_linkedlist/list/#3-inserting-and-removing-elements","title":"3. \u00a0 Inserting and removing elements","text":"

    Compared to arrays, lists offer more flexibility in adding and removing elements. While adding elements to the end of a list is an \\(O(1)\\) operation, the efficiency of inserting and removing elements elsewhere in the list remains the same as in arrays, with a time complexity of \\(O(n)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Clear list\nnums.clear()\n\n# Append elements at the end\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n# Insert element in the middle\nnums.insert(3, 6)  # Insert number 6 at index 3\n\n# Remove elements\nnums.pop(3)        # Remove the element at index 3\n
    list.cpp
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.push_back(1);\nnums.push_back(3);\nnums.push_back(2);\nnums.push_back(5);\nnums.push_back(4);\n\n/* Insert element in the middle */\nnums.insert(nums.begin() + 3, 6);  // Insert number 6 at index 3\n\n/* Remove elements */\nnums.erase(nums.begin() + 3);      // Remove the element at index 3\n
    list.java
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* Insert element in the middle */\nnums.add(3, 6);  // Insert number 6 at index 3\n\n/* Remove elements */\nnums.remove(3);  // Remove the element at index 3\n
    list.cs
    /* Clear list */\nnums.Clear();\n\n/* Append elements at the end */\nnums.Add(1);\nnums.Add(3);\nnums.Add(2);\nnums.Add(5);\nnums.Add(4);\n\n/* Insert element in the middle */\nnums.Insert(3, 6);\n\n/* Remove elements */\nnums.RemoveAt(3);\n
    list_test.go
    /* Clear list */\nnums = nil\n\n/* Append elements at the end */\nnums = append(nums, 1)\nnums = append(nums, 3)\nnums = append(nums, 2)\nnums = append(nums, 5)\nnums = append(nums, 4)\n\n/* Insert element in the middle */\nnums = append(nums[:3], append([]int{6}, nums[3:]...)...) // Insert number 6 at index 3\n\n/* Remove elements */\nnums = append(nums[:3], nums[4:]...) // Remove the element at index 3\n
    list.swift
    /* Clear list */\nnums.removeAll()\n\n/* Append elements at the end */\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n/* Insert element in the middle */\nnums.insert(6, at: 3) // Insert number 6 at index 3\n\n/* Remove elements */\nnums.remove(at: 3) // Remove the element at index 3\n
    list.js
    /* Clear list */\nnums.length = 0;\n\n/* Append elements at the end */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* Insert element in the middle */\nnums.splice(3, 0, 6);\n\n/* Remove elements */\nnums.splice(3, 1);\n
    list.ts
    /* Clear list */\nnums.length = 0;\n\n/* Append elements at the end */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* Insert element in the middle */\nnums.splice(3, 0, 6);\n\n/* Remove elements */\nnums.splice(3, 1);\n
    list.dart
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* Insert element in the middle */\nnums.insert(3, 6); // Insert number 6 at index 3\n\n/* Remove elements */\nnums.removeAt(3); // Remove the element at index 3\n
    list.rs
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* Insert element in the middle */\nnums.insert(3, 6);  // Insert number 6 at index 3\n\n/* Remove elements */\nnums.remove(3);    // Remove the element at index 3\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Clear list\nnums.clearRetainingCapacity();\n\n// Append elements at the end\ntry nums.append(1);\ntry nums.append(3);\ntry nums.append(2);\ntry nums.append(5);\ntry nums.append(4);\n\n// Insert element in the middle\ntry nums.insert(3, 6); // Insert number 6 at index 3\n\n// Remove elements\n_ = nums.orderedRemove(3); // Remove the element at index 3\n
    "},{"location":"chapter_array_and_linkedlist/list/#4-iterating-the-list","title":"4. \u00a0 Iterating the list","text":"

    Similar to arrays, lists can be iterated either by using indices or by directly iterating through each element.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Iterate through the list by index\ncount = 0\nfor i in range(len(nums)):\n    count += nums[i]\n\n# Iterate directly through list elements\nfor num in nums:\n    count += num\n
    list.cpp
    /* Iterate through the list by index */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (int num : nums) {\n    count += num;\n}\n
    list.java
    /* Iterate through the list by index */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums.get(i);\n}\n\n/* Iterate directly through list elements */\nfor (int num : nums) {\n    count += num;\n}\n
    list.cs
    /* Iterate through the list by index */\nint count = 0;\nfor (int i = 0; i < nums.Count; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nforeach (int num in nums) {\n    count += num;\n}\n
    list_test.go
    /* Iterate through the list by index */\ncount := 0\nfor i := 0; i < len(nums); i++ {\n    count += nums[i]\n}\n\n/* Iterate directly through list elements */\ncount = 0\nfor _, num := range nums {\n    count += num\n}\n
    list.swift
    /* Iterate through the list by index */\nvar count = 0\nfor i in nums.indices {\n    count += nums[i]\n}\n\n/* Iterate directly through list elements */\ncount = 0\nfor num in nums {\n    count += num\n}\n
    list.js
    /* Iterate through the list by index */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.ts
    /* Iterate through the list by index */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.dart
    /* Iterate through the list by index */\nint count = 0;\nfor (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (var num in nums) {\n    count += num;\n}\n
    list.rs
    // Iterate through the list by index\nlet mut _count = 0;\nfor i in 0..nums.len() {\n    _count += nums[i];\n}\n\n// Iterate directly through list elements\n_count = 0;\nfor num in &nums {\n    _count += num;\n}\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Iterate through the list by index\nvar count: i32 = 0;\nvar i: i32 = 0;\nwhile (i < nums.items.len) : (i += 1) {\n    count += nums[i];\n}\n\n// Iterate directly through list elements\ncount = 0;\nfor (nums.items) |num| {\n    count += num;\n}\n
    "},{"location":"chapter_array_and_linkedlist/list/#5-concatenating-lists","title":"5. \u00a0 Concatenating lists","text":"

    Given a new list nums1, we can append it to the end of the original list.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Concatenate two lists\nnums1: list[int] = [6, 8, 7, 10, 9]\nnums += nums1  # Concatenate nums1 to the end of nums\n
    list.cpp
    /* Concatenate two lists */\nvector<int> nums1 = { 6, 8, 7, 10, 9 };\n// Concatenate nums1 to the end of nums\nnums.insert(nums.end(), nums1.begin(), nums1.end());\n
    list.java
    /* Concatenate two lists */\nList<Integer> nums1 = new ArrayList<>(Arrays.asList(new Integer[] { 6, 8, 7, 10, 9 }));\nnums.addAll(nums1);  // Concatenate nums1 to the end of nums\n
    list.cs
    /* Concatenate two lists */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.AddRange(nums1);  // Concatenate nums1 to the end of nums\n
    list_test.go
    /* Concatenate two lists */\nnums1 := []int{6, 8, 7, 10, 9}\nnums = append(nums, nums1...)  // Concatenate nums1 to the end of nums\n
    list.swift
    /* Concatenate two lists */\nlet nums1 = [6, 8, 7, 10, 9]\nnums.append(contentsOf: nums1) // Concatenate nums1 to the end of nums\n
    list.js
    /* Concatenate two lists */\nconst nums1 = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // Concatenate nums1 to the end of nums\n
    list.ts
    /* Concatenate two lists */\nconst nums1: number[] = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // Concatenate nums1 to the end of nums\n
    list.dart
    /* Concatenate two lists */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.addAll(nums1);  // Concatenate nums1 to the end of nums\n
    list.rs
    /* Concatenate two lists */\nlet nums1: Vec<i32> = vec![6, 8, 7, 10, 9];\nnums.extend(nums1);\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Concatenate two lists\nvar nums1 = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums1.deinit();\ntry nums1.appendSlice(&[_]i32{ 6, 8, 7, 10, 9 });\ntry nums.insertSlice(nums.items.len, nums1.items); // Concatenate nums1 to the end of nums\n
    "},{"location":"chapter_array_and_linkedlist/list/#6-sorting-the-list","title":"6. \u00a0 Sorting the list","text":"

    Once the list is sorted, we can employ algorithms commonly used in array-related algorithm problems, such as \"binary search\" and \"two-pointer\" algorithms.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Sort the list\nnums.sort()  # After sorting, the list elements are in ascending order\n
    list.cpp
    /* Sort the list */\nsort(nums.begin(), nums.end());  // After sorting, the list elements are in ascending order\n
    list.java
    /* Sort the list */\nCollections.sort(nums);  // After sorting, the list elements are in ascending order\n
    list.cs
    /* Sort the list */\nnums.Sort(); // After sorting, the list elements are in ascending order\n
    list_test.go
    /* Sort the list */\nsort.Ints(nums)  // After sorting, the list elements are in ascending order\n
    list.swift
    /* Sort the list */\nnums.sort() // After sorting, the list elements are in ascending order\n
    list.js
    /* Sort the list */  \nnums.sort((a, b) => a - b);  // After sorting, the list elements are in ascending order\n
    list.ts
    /* Sort the list */\nnums.sort((a, b) => a - b);  // After sorting, the list elements are in ascending order\n
    list.dart
    /* Sort the list */\nnums.sort(); // After sorting, the list elements are in ascending order\n
    list.rs
    /* Sort the list */\nnums.sort(); // After sorting, the list elements are in ascending order\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Sort the list\nstd.sort.sort(i32, nums.items, {}, comptime std.sort.asc(i32));\n
    "},{"location":"chapter_array_and_linkedlist/list/#432-list-implementation","title":"4.3.2 \u00a0 List implementation","text":"

    Many programming languages come with built-in lists, including Java, C++, Python, etc. Their implementations tend to be intricate, featuring carefully considered settings for various parameters, like initial capacity and expansion factors. Readers who are curious can delve into the source code for further learning.

    To enhance our understanding of how lists work, we will attempt to implement a simplified version of a list, focusing on three crucial design aspects:

    • Initial capacity: Choose a reasonable initial capacity for the array. In this example, we choose 10 as the initial capacity.
    • Size recording: Declare a variable size to record the current number of elements in the list, updating in real-time with element insertion and deletion. With this variable, we can locate the end of the list and determine whether expansion is needed.
    • Expansion mechanism: If the list reaches full capacity upon an element insertion, an expansion process is required. This involves creating a larger array based on the expansion factor, and then transferring all elements from the current array to the new one. In this example, we stipulate that the array size should double with each expansion.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_list.py
    class MyList:\n    \"\"\"\u5217\u8868\u7c7b\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._capacity: int = 10  # \u5217\u8868\u5bb9\u91cf\n        self._arr: list[int] = [0] * self._capacity  # \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        self._size: int = 0  # \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        self._extend_ratio: int = 2  # \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\"\"\"\n        return self._size\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u5bb9\u91cf\"\"\"\n        return self._capacity\n\n    def get(self, index: int) -> int:\n        \"\"\"\u8bbf\u95ee\u5143\u7d20\"\"\"\n        # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        return self._arr[index]\n\n    def set(self, num: int, index: int):\n        \"\"\"\u66f4\u65b0\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        self._arr[index] = num\n\n    def add(self, num: int):\n        \"\"\"\u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\"\"\"\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size() == self.capacity():\n            self.extend_capacity()\n        self._arr[self._size] = num\n        self._size += 1\n\n    def insert(self, num: int, index: int):\n        \"\"\"\u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self._size == self.capacity():\n            self.extend_capacity()\n        # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in range(self._size - 1, index - 1, -1):\n            self._arr[j + 1] = self._arr[j]\n        self._arr[index] = num\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size += 1\n\n    def remove(self, index: int) -> int:\n        \"\"\"\u5220\u9664\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        num = self._arr[index]\n        # \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in range(index, self._size - 1):\n            self._arr[j] = self._arr[j + 1]\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size -= 1\n        # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n\n    def extend_capacity(self):\n        \"\"\"\u5217\u8868\u6269\u5bb9\"\"\"\n        # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1)\n        # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self._capacity = len(self._arr)\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868\"\"\"\n        return self._arr[: self._size]\n
    my_list.cpp
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  private:\n    int *arr;             // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int arrCapacity = 10; // \u5217\u8868\u5bb9\u91cf\n    int arrSize = 0;      // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    int extendRatio = 2;   // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~MyList() {\n        delete[] arr;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    int size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    int capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    void set(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        arr[size()] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    void insert(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size() - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    int remove(int index) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size() - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n        int newCapacity = capacity() * extendRatio;\n        int *tmp = arr;\n        arr = new int[newCapacity];\n        // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            arr[i] = tmp[i];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete[] tmp;\n        arrCapacity = newCapacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Vector \u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> vec(size());\n        for (int i = 0; i < size(); i++) {\n            vec[i] = arr[i];\n        }\n        return vec;\n    }\n};\n
    my_list.java
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    private int size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private int extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[capacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    public int size() {\n        return size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int capacity() {\n        return capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void set(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        arr[size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void insert(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int remove(int index) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = Arrays.copyOf(arr, capacity() * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] toArray() {\n        int size = size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[size];\n        for (int i = 0; i < size; i++) {\n            arr[i] = get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.cs
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr;           // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int arrCapacity = 10;    // \u5217\u8868\u5bb9\u91cf\n    private int arrSize = 0;         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private readonly int extendRatio = 2;  // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public int Size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int Capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int Get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void Set(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void Add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        arr[arrSize] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void Insert(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = arrSize - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int Remove(int index) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < arrSize - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void ExtendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a arrCapacity * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        Array.Resize(ref arr, arrCapacity * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        arrCapacity = arr.Length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[arrSize];\n        for (int i = 0; i < arrSize; i++) {\n            arr[i] = Get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.go
    /* \u5217\u8868\u7c7b */\ntype myList struct {\n    arrCapacity int\n    arr         []int\n    arrSize     int\n    extendRatio int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newMyList() *myList {\n    return &myList{\n        arrCapacity: 10,              // \u5217\u8868\u5bb9\u91cf\n        arr:         make([]int, 10), // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrSize:     0,               // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: 2,               // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n    }\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\nfunc (l *myList) size() int {\n    return l.arrSize\n}\n\n/*  \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nfunc (l *myList) capacity() int {\n    return l.arrCapacity\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nfunc (l *myList) get(index int) int {\n    // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    return l.arr[index]\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nfunc (l *myList) set(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    l.arr[index] = num\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nfunc (l *myList) add(num int) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    l.arr[l.arrSize] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nfunc (l *myList) insert(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j := l.arrSize - 1; j >= index; j-- {\n        l.arr[j+1] = l.arr[j]\n    }\n    l.arr[index] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5220\u9664\u5143\u7d20 */\nfunc (l *myList) remove(index int) int {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    num := l.arr[index]\n    // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j := index; j < l.arrSize-1; j++ {\n        l.arr[j] = l.arr[j+1]\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize--\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return num\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nfunc (l *myList) extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    l.arr = append(l.arr, make([]int, l.arrCapacity*(l.extendRatio-1))...)\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    l.arrCapacity = len(l.arr)\n}\n\n/* \u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868 */\nfunc (l *myList) toArray() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    return l.arr[:l.arrSize]\n}\n
    my_list.swift
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: [Int] // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var _capacity: Int // \u5217\u8868\u5bb9\u91cf\n    private var _size: Int // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private let extendRatio: Int // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        _capacity = 10\n        _size = 0\n        extendRatio = 2\n        arr = Array(repeating: 0, count: _capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    func size() -> Int {\n        _size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    func capacity() -> Int {\n        _capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    func get(index: Int) -> Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\u5219\u629b\u51fa\u9519\u8bef\uff0c\u4e0b\u540c\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    func set(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    func add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        arr[size()] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    func insert(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index ..< size()).reversed() {\n            arr[j + 1] = arr[j]\n        }\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    @discardableResult\n    func remove(index: Int) -> Int {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        let num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in index ..< (size() - 1) {\n            arr[j] = arr[j + 1]\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size -= 1\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    func extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr + Array(repeating: 0, count: capacity() * (extendRatio - 1))\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        _capacity = arr.count\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        Array(arr.prefix(size()))\n    }\n}\n
    my_list.js
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    #arr = new Array(); // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    #capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    #size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    #extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#arr = new Array(this.#capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    size() {\n        return this.#size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    capacity() {\n        return this.#capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    get(index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.#arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    set(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.#arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    add(num) {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.#arr[this.#size] = num;\n        this.#size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    insert(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this.#size - 1; j >= index; j--) {\n            this.#arr[j + 1] = this.#arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#arr[index] = num;\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    remove(index) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.#arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this.#size - 1; j++) {\n            this.#arr[j] = this.#arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.#arr = this.#arr.concat(\n            new Array(this.capacity() * (this.#extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this.#capacity = this.#arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    toArray() {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.ts
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private arr: Array<number>; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private _capacity: number = 10; // \u5217\u8868\u5bb9\u91cf\n    private _size: number = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private extendRatio: number = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.arr = new Array(this._capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public size(): number {\n        return this._size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public capacity(): number {\n        return this._capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public get(index: number): number {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public set(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public add(num: number): void {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this._size === this._capacity) this.extendCapacity();\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.arr[this._size] = num;\n        this._size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public insert(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this._size === this._capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this._size - 1; j >= index; j--) {\n            this.arr[j + 1] = this.arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.arr[index] = num;\n        this._size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public remove(index: number): number {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this._size - 1; j++) {\n            this.arr[j] = this.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this._size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public extendCapacity(): void {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.arr = this.arr.concat(\n            new Array(this.capacity() * (this.extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this._capacity = this.arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public toArray(): number[] {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.dart
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  late List<int> _arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n  int _capacity = 10; // \u5217\u8868\u5bb9\u91cf\n  int _size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  int _extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  MyList() {\n    _arr = List.filled(_capacity, 0);\n  }\n\n  /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n  int size() => _size;\n\n  /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n  int capacity() => _capacity;\n\n  /* \u8bbf\u95ee\u5143\u7d20 */\n  int get(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    return _arr[index];\n  }\n\n  /* \u66f4\u65b0\u5143\u7d20 */\n  void set(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    _arr[index] = _num;\n  }\n\n  /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n  void add(int _num) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    _arr[_size] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n  void insert(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (var j = _size - 1; j >= index; j--) {\n      _arr[j + 1] = _arr[j];\n    }\n    _arr[index] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5220\u9664\u5143\u7d20 */\n  int remove(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    int _num = _arr[index];\n    // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (var j = index; j < _size - 1; j++) {\n      _arr[j] = _arr[j + 1];\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size--;\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return _num;\n  }\n\n  /* \u5217\u8868\u6269\u5bb9 */\n  void extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n    final _newNums = List.filled(_capacity * _extendRatio, 0);\n    // \u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    List.copyRange(_newNums, 0, _arr);\n    // \u66f4\u65b0 _arr \u7684\u5f15\u7528\n    _arr = _newNums;\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    _capacity = _arr.length;\n  }\n\n  /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n  List<int> toArray() {\n    List<int> arr = [];\n    for (var i = 0; i < _size; i++) {\n      arr.add(get(i));\n    }\n    return arr;\n  }\n}\n
    my_list.rs
    /* \u5217\u8868\u7c7b */\n#[allow(dead_code)]\nstruct MyList {\n    arr: Vec<i32>,       // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    capacity: usize,     // \u5217\u8868\u5bb9\u91cf\n    size: usize,         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    extend_ratio: usize, // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n}\n\n#[allow(unused, unused_comparisons)]\nimpl MyList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        let mut vec = Vec::new();\n        vec.resize(capacity, 0);\n        Self {\n            arr: vec,\n            capacity,\n            size: 0,\n            extend_ratio: 2,\n        }\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    pub fn size(&self) -> usize {\n        return self.size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        return self.capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    pub fn get(&self, index: usize) -> i32 {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        return self.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    pub fn set(&mut self, index: usize, num: i32) {\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        self.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    pub fn add(&mut self, num: i32) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        self.arr[self.size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    pub fn insert(&mut self, index: usize, num: i32) {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size).rev() {\n            self.arr[j + 1] = self.arr[j];\n        }\n        self.arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    pub fn remove(&mut self, index: usize) -> i32 {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        let num = self.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size - 1) {\n            self.arr[j] = self.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size -= 1;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    pub fn extend_capacity(&mut self) {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        let new_capacity = self.capacity * self.extend_ratio;\n        self.arr.resize(new_capacity, 0);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self.capacity = new_capacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    pub fn to_array(&mut self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut arr = Vec::new();\n        for i in 0..self.size {\n            arr.push(self.get(i));\n        }\n        arr\n    }\n}\n
    my_list.c
    /* \u5217\u8868\u7c7b */\ntypedef struct {\n    int *arr;        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int capacity;    // \u5217\u8868\u5bb9\u91cf\n    int size;        // \u5217\u8868\u5927\u5c0f\n    int extendRatio; // \u5217\u8868\u6bcf\u6b21\u6269\u5bb9\u7684\u500d\u6570\n} MyList;\n\n/* \u6784\u9020\u51fd\u6570 */\nMyList *newMyList() {\n    MyList *nums = malloc(sizeof(MyList));\n    nums->capacity = 10;\n    nums->arr = malloc(sizeof(int) * nums->capacity);\n    nums->size = 0;\n    nums->extendRatio = 2;\n    return nums;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delMyList(MyList *nums) {\n    free(nums->arr);\n    free(nums);\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6 */\nint size(MyList *nums) {\n    return nums->size;\n}\n\n/* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nint capacity(MyList *nums) {\n    return nums->capacity;\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint get(MyList *nums, int index) {\n    assert(index >= 0 && index < nums->size);\n    return nums->arr[index];\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nvoid set(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < nums->size);\n    nums->arr[index] = num;\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nvoid add(MyList *nums, int num) {\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    nums->arr[size(nums)] = num;\n    nums->size++;\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nvoid insert(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < size(nums));\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    for (int i = size(nums); i > index; --i) {\n        nums->arr[i] = nums->arr[i - 1];\n    }\n    nums->arr[index] = num;\n    nums->size++;\n}\n\n/* \u5220\u9664\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nint removeItem(MyList *nums, int index) {\n    assert(index >= 0 && index < size(nums));\n    int num = nums->arr[index];\n    for (int i = index; i < size(nums) - 1; i++) {\n        nums->arr[i] = nums->arr[i + 1];\n    }\n    nums->size--;\n    return num;\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nvoid extendCapacity(MyList *nums) {\n    // \u5148\u5206\u914d\u7a7a\u95f4\n    int newCapacity = capacity(nums) * nums->extendRatio;\n    int *extend = (int *)malloc(sizeof(int) * newCapacity);\n    int *temp = nums->arr;\n\n    // \u62f7\u8d1d\u65e7\u6570\u636e\u5230\u65b0\u6570\u636e\n    for (int i = 0; i < size(nums); i++)\n        extend[i] = nums->arr[i];\n\n    // \u91ca\u653e\u65e7\u6570\u636e\n    free(temp);\n\n    // \u66f4\u65b0\u65b0\u6570\u636e\n    nums->arr = extend;\n    nums->capacity = newCapacity;\n}\n\n/* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Array \u7528\u4e8e\u6253\u5370 */\nint *toArray(MyList *nums) {\n    return nums->arr;\n}\n
    my_list.kt
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: IntArray = intArrayOf() // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var capacity: Int = 10 // \u5217\u8868\u5bb9\u91cf\n    private var size: Int = 0 // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private var extendRatio: Int = 2 // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        arr = IntArray(capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    fun size(): Int {\n        return size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    fun capacity(): Int {\n        return capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    fun get(index: Int): Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    fun set(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    fun add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        arr[size] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    fun insert(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (j in size - 1 downTo index)\n            arr[j + 1] = arr[j]\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    fun remove(index: Int): Int {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        val num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (j in index..<size - 1)\n            arr[j] = arr[j + 1]\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    fun extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr.copyOf(capacity() * extendRatio)\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.size\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        val size = size()\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val arr = IntArray(size)\n        for (i in 0..<size) {\n            arr[i] = get(i)\n        }\n        return arr\n    }\n}\n
    my_list.rb
    ### \u5217\u8868\u7c7b ###\nclass MyList\n  attr_reader :size       # \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  attr_reader :capacity   # \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @capacity = 10\n    @size = 0\n    @extend_ratio = 2\n    @arr = Array.new(capacity)\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def get(index)\n    # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index]\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def set(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index] = num\n  end\n\n  ### \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 ###\n  def add(num)\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n    @arr[size] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 ###\n  def insert(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n\n    # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j in (size - 1).downto(index)\n      @arr[j + 1] = @arr[j]\n    end\n    @arr[index] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5220\u9664\u5143\u7d20 ###\n  def remove(index)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    num = @arr[index]\n\n    # \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j in index...size\n      @arr[j] = @arr[j + 1]\n    end\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size -= 1\n\n    # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    num\n  end\n\n  ### \u5217\u8868\u6269\u5bb9 ###\n  def extend_capacity\n    # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1))\n    # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    @capacity = arr.length\n  end\n\n  ### \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 ###\n  def to_array\n    sz = size\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    arr = Array.new(sz)\n    for i in 0...sz\n      arr[i] = get(i)\n    end\n    arr\n  end\nend\n
    my_list.zig
    // \u5217\u8868\u7c7b\nfn MyList(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        arr: []T = undefined,                        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrCapacity: usize = 10,                     // \u5217\u8868\u5bb9\u91cf\n        numSize: usize = 0,                           // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: usize = 2,                       // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined, // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u5217\u8868\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.arr = try self.mem_allocator.alloc(T, self.arrCapacity);\n            @memset(self.arr, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        pub fn size(self: *Self) usize {\n            return self.numSize;\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.arrCapacity;\n        }\n\n        // \u8bbf\u95ee\u5143\u7d20\n        pub fn get(self: *Self, index: usize) T {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            return self.arr[index];\n        }  \n\n        // \u66f4\u65b0\u5143\u7d20\n        pub fn set(self: *Self, index: usize, num: T) void {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            self.arr[index] = num;\n        }  \n\n        // \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\n        pub fn add(self: *Self, num: T) !void {\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            self.arr[self.size()] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }  \n\n        // \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\n        pub fn insert(self: *Self, index: usize, num: T) !void {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n            var j = self.size() - 1;\n            while (j >= index) : (j -= 1) {\n                self.arr[j + 1] = self.arr[j];\n            }\n            self.arr[index] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }\n\n        // \u5220\u9664\u5143\u7d20\n        pub fn remove(self: *Self, index: usize) T {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            var num = self.arr[index];\n            // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n            var j = index;\n            while (j < self.size() - 1) : (j += 1) {\n                self.arr[j] = self.arr[j + 1];\n            }\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize -= 1;\n            // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n            return num;\n        }\n\n        // \u5217\u8868\u6269\u5bb9\n        pub fn extendCapacity(self: *Self) !void {\n            // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            var newCapacity = self.capacity() * self.extendRatio;\n            var extend = try self.mem_allocator.alloc(T, newCapacity);\n            @memset(extend, @as(T, 0));\n            // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            std.mem.copy(T, extend, self.arr);\n            self.arr = extend;\n            // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n            self.arrCapacity = newCapacity;\n        }\n\n        // \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var arr = try self.mem_allocator.alloc(T, self.size());\n           @memset(arr, @as(T, 0));\n            for (arr, 0..) |*num, i| {\n                num.* = self.get(i);\n            }\n            return arr;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/","title":"4.4 \u00a0 Memory and cache *","text":"

    In the first two sections of this chapter, we explored arrays and linked lists, two fundamental and important data structures, representing \"continuous storage\" and \"dispersed storage\" respectively.

    In fact, the physical structure largely determines the efficiency of a program's use of memory and cache, which in turn affects the overall performance of the algorithm.

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#441-computer-storage-devices","title":"4.4.1 \u00a0 Computer storage devices","text":"

    There are three types of storage devices in computers: \"hard disk,\" \"random-access memory (RAM),\" and \"cache memory.\" The following table shows their different roles and performance characteristics in computer systems.

    Table 4-2 \u00a0 Computer storage devices

    Hard Disk Memory Cache Usage Long-term storage of data, including OS, programs, files, etc. Temporary storage of currently running programs and data being processed Stores frequently accessed data and instructions, reducing the number of CPU accesses to memory Volatility Data is not lost after power off Data is lost after power off Data is lost after power off Capacity Larger, TB level Smaller, GB level Very small, MB level Speed Slower, several hundred to thousands MB/s Faster, several tens of GB/s Very fast, several tens to hundreds of GB/s Price Cheaper, several cents to yuan / GB More expensive, tens to hundreds of yuan / GB Very expensive, priced with CPU

    We can imagine the computer storage system as a pyramid structure shown in the Figure 4-9 . The storage devices closer to the top of the pyramid are faster, have smaller capacity, and are more costly. This multi-level design is not accidental, but the result of careful consideration by computer scientists and engineers.

    • Hard disks are difficult to replace with memory. Firstly, data in memory is lost after power off, making it unsuitable for long-term data storage; secondly, the cost of memory is dozens of times that of hard disks, making it difficult to popularize in the consumer market.
    • It is difficult for caches to have both large capacity and high speed. As the capacity of L1, L2, L3 caches gradually increases, their physical size becomes larger, increasing the physical distance from the CPU core, leading to increased data transfer time and higher element access latency. Under current technology, a multi-level cache structure is the best balance between capacity, speed, and cost.

    Figure 4-9 \u00a0 Computer storage system

    Tip

    The storage hierarchy of computers reflects a delicate balance between speed, capacity, and cost. In fact, this kind of trade-off is common in all industrial fields, requiring us to find the best balance between different advantages and limitations.

    Overall, hard disks are used for long-term storage of large amounts of data, memory is used for temporary storage of data being processed during program execution, and cache is used to store frequently accessed data and instructions to improve program execution efficiency. Together, they ensure the efficient operation of computer systems.

    As shown in the Figure 4-10 , during program execution, data is read from the hard disk into memory for CPU computation. The cache can be considered a part of the CPU, smartly loading data from memory to provide fast data access to the CPU, significantly enhancing program execution efficiency and reducing reliance on slower memory.

    Figure 4-10 \u00a0 Data flow between hard disk, memory, and cache

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#442-memory-efficiency-of-data-structures","title":"4.4.2 \u00a0 Memory efficiency of data structures","text":"

    In terms of memory space utilization, arrays and linked lists have their advantages and limitations.

    On one hand, memory is limited and cannot be shared by multiple programs, so we hope that data structures can use space as efficiently as possible. The elements of an array are tightly packed without extra space for storing references (pointers) between linked list nodes, making them more space-efficient. However, arrays require allocating sufficient continuous memory space at once, which may lead to memory waste, and array expansion also requires additional time and space costs. In contrast, linked lists allocate and reclaim memory dynamically on a per-node basis, providing greater flexibility.

    On the other hand, during program execution, as memory is repeatedly allocated and released, the degree of fragmentation of free memory becomes higher, leading to reduced memory utilization efficiency. Arrays, due to their continuous storage method, are relatively less likely to cause memory fragmentation. In contrast, the elements of a linked list are dispersedly stored, and frequent insertion and deletion operations make memory fragmentation more likely.

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#443-cache-efficiency-of-data-structures","title":"4.4.3 \u00a0 Cache efficiency of data structures","text":"

    Although caches are much smaller in space capacity than memory, they are much faster and play a crucial role in program execution speed. Since the cache's capacity is limited and can only store a small part of frequently accessed data, when the CPU tries to access data not in the cache, a \"cache miss\" occurs, forcing the CPU to load the needed data from slower memory.

    Clearly, the fewer the cache misses, the higher the CPU's data read-write efficiency, and the better the program performance. The proportion of successful data retrieval from the cache by the CPU is called the \"cache hit rate,\" a metric often used to measure cache efficiency.

    To achieve higher efficiency, caches adopt the following data loading mechanisms.

    • Cache lines: Caches don't store and load data byte by byte but in units of cache lines. Compared to byte-by-byte transfer, the transmission of cache lines is more efficient.
    • Prefetch mechanism: Processors try to predict data access patterns (such as sequential access, fixed stride jumping access, etc.) and load data into the cache according to specific patterns to improve the hit rate.
    • Spatial locality: If data is accessed, data nearby is likely to be accessed in the near future. Therefore, when loading certain data, the cache also loads nearby data to improve the hit rate.
    • Temporal locality: If data is accessed, it's likely to be accessed again in the near future. Caches use this principle to retain recently accessed data to improve the hit rate.

    In fact, arrays and linked lists have different cache utilization efficiencies, mainly reflected in the following aspects.

    • Occupied space: Linked list elements occupy more space than array elements, resulting in less effective data volume in the cache.
    • Cache lines: Linked list data is scattered throughout memory, and since caches load \"by line,\" the proportion of loading invalid data is higher.
    • Prefetch mechanism: The data access pattern of arrays is more \"predictable\" than that of linked lists, meaning the system is more likely to guess which data will be loaded next.
    • Spatial locality: Arrays are stored in concentrated memory spaces, so the data near the loaded data is more likely to be accessed next.

    Overall, arrays have a higher cache hit rate and are generally more efficient in operation than linked lists. This makes data structures based on arrays more popular in solving algorithmic problems.

    It should be noted that high cache efficiency does not mean that arrays are always better than linked lists. Which data structure to choose in actual applications should be based on specific requirements. For example, both arrays and linked lists can implement the \"stack\" data structure (which will be detailed in the next chapter), but they are suitable for different scenarios.

    • In algorithm problems, we tend to choose stacks based on arrays because they provide higher operational efficiency and random access capabilities, with the only cost being the need to pre-allocate a certain amount of memory space for the array.
    • If the data volume is very large, highly dynamic, and the expected size of the stack is difficult to estimate, then a stack based on a linked list is more appropriate. Linked lists can disperse a large amount of data in different parts of the memory and avoid the additional overhead of array expansion.
    "},{"location":"chapter_array_and_linkedlist/summary/","title":"4.5 \u00a0 Summary","text":""},{"location":"chapter_array_and_linkedlist/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Arrays and linked lists are two basic data structures, representing two storage methods in computer memory: contiguous space storage and non-contiguous space storage. Their characteristics complement each other.
    • Arrays support random access and use less memory; however, they are inefficient in inserting and deleting elements and have a fixed length after initialization.
    • Linked lists implement efficient node insertion and deletion through changing references (pointers) and can flexibly adjust their length; however, they have lower node access efficiency and consume more memory.
    • Common types of linked lists include singly linked lists, circular linked lists, and doubly linked lists, each with its own application scenarios.
    • Lists are ordered collections of elements that support addition, deletion, and modification, typically implemented based on dynamic arrays, retaining the advantages of arrays while allowing flexible length adjustment.
    • The advent of lists significantly enhanced the practicality of arrays but may lead to some memory space wastage.
    • During program execution, data is mainly stored in memory. Arrays provide higher memory space efficiency, while linked lists are more flexible in memory usage.
    • Caches provide fast data access to CPUs through mechanisms like cache lines, prefetching, spatial locality, and temporal locality, significantly enhancing program execution efficiency.
    • Due to higher cache hit rates, arrays are generally more efficient than linked lists. When choosing a data structure, the appropriate choice should be made based on specific needs and scenarios.
    "},{"location":"chapter_array_and_linkedlist/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Does storing arrays on the stack versus the heap affect time and space efficiency?

    Arrays stored on both the stack and heap are stored in contiguous memory spaces, and data operation efficiency is essentially the same. However, stacks and heaps have their own characteristics, leading to the following differences.

    1. Allocation and release efficiency: The stack is a smaller memory block, allocated automatically by the compiler; the heap memory is relatively larger and can be dynamically allocated in the code, more prone to fragmentation. Therefore, allocation and release operations on the heap are generally slower than on the stack.
    2. Size limitation: Stack memory is relatively small, while the heap size is generally limited by available memory. Therefore, the heap is more suitable for storing large arrays.
    3. Flexibility: The size of arrays on the stack needs to be determined at compile-time, while the size of arrays on the heap can be dynamically determined at runtime.

    Q: Why do arrays require elements of the same type, while linked lists do not emphasize same-type elements?

    Linked lists consist of nodes connected by references (pointers), and each node can store data of different types, such as int, double, string, object, etc.

    In contrast, array elements must be of the same type, allowing the calculation of offsets to access the corresponding element positions. For example, an array containing both int and long types, with single elements occupying 4 bytes and 8 bytes respectively, cannot use the following formula to calculate offsets, as the array contains elements of two different lengths.

    # Element memory address = array memory address + element length * element index\n

    Q: After deleting a node, is it necessary to set P.next to None?

    Not modifying P.next is also acceptable. From the perspective of the linked list, traversing from the head node to the tail node will no longer encounter P. This means that node P has been effectively removed from the list, and where P points no longer affects the list.

    From a garbage collection perspective, for languages with automatic garbage collection mechanisms like Java, Python, and Go, whether node P is collected depends on whether there are still references pointing to it, not on the value of P.next. In languages like C and C++, we need to manually free the node's memory.

    Q: In linked lists, the time complexity for insertion and deletion operations is O(1). But searching for the element before insertion or deletion takes O(n) time, so why isn't the time complexity O(n)?

    If an element is searched first and then deleted, the time complexity is indeed O(n). However, the O(1) advantage of linked lists in insertion and deletion can be realized in other applications. For example, in the implementation of double-ended queues using linked lists, we maintain pointers always pointing to the head and tail nodes, making each insertion and deletion operation O(1).

    Q: In the image \"Linked List Definition and Storage Method\", do the light blue storage nodes occupy a single memory address, or do they share half with the node value?

    The diagram is just a qualitative representation; quantitative analysis depends on specific situations.

    • Different types of node values occupy different amounts of space, such as int, long, double, and object instances.
    • The memory space occupied by pointer variables depends on the operating system and compilation environment used, usually 8 bytes or 4 bytes.

    Q: Is adding elements to the end of a list always O(1)?

    If adding an element exceeds the list length, the list needs to be expanded first. The system will request a new memory block and move all elements of the original list over, in which case the time complexity becomes O(n).

    Q: The statement \"The emergence of lists greatly improves the practicality of arrays, but may lead to some memory space wastage\" - does this refer to the memory occupied by additional variables like capacity, length, and expansion multiplier?

    The space wastage here mainly refers to two aspects: on the one hand, lists are set with an initial length, which we may not always need; on the other hand, to prevent frequent expansion, expansion usually multiplies by a coefficient, such as \\(\\times 1.5\\). This results in many empty slots, which we typically cannot fully fill.

    Q: In Python, after initializing n = [1, 2, 3], the addresses of these 3 elements are contiguous, but initializing m = [2, 1, 3] shows that each element's id is not consecutive but identical to those in n. If the addresses of these elements are not contiguous, is m still an array?

    If we replace list elements with linked list nodes n = [n1, n2, n3, n4, n5], these 5 node objects are also typically dispersed throughout memory. However, given a list index, we can still access the node's memory address in O(1) time, thereby accessing the corresponding node. This is because the array stores references to the nodes, not the nodes themselves.

    Unlike many languages, in Python, numbers are also wrapped as objects, and lists store references to these numbers, not the numbers themselves. Therefore, we find that the same number in two arrays has the same id, and these numbers' memory addresses need not be contiguous.

    Q: The std::list in C++ STL has already implemented a doubly linked list, but it seems that some algorithm books don't directly use it. Is there any limitation?

    On the one hand, we often prefer to use arrays to implement algorithms, only using linked lists when necessary, mainly for two reasons.

    • Space overhead: Since each element requires two additional pointers (one for the previous element and one for the next), std::list usually occupies more space than std::vector.
    • Cache unfriendly: As the data is not stored continuously, std::list has a lower cache utilization rate. Generally, std::vector performs better.

    On the other hand, linked lists are primarily necessary for binary trees and graphs. Stacks and queues are often implemented using the programming language's stack and queue classes, rather than linked lists.

    Q: Does initializing a list res = [0] * self.size() result in each element of res referencing the same address?

    No. However, this issue arises with two-dimensional arrays, for example, initializing a two-dimensional list res = [[0] * self.size()] would reference the same list [0] multiple times.

    Q: In deleting a node, is it necessary to break the reference to its successor node?

    From the perspective of data structures and algorithms (problem-solving), it's okay not to break the link, as long as the program's logic is correct. From the perspective of standard libraries, breaking the link is safer and more logically clear. If the link is not broken, and the deleted node is not properly recycled, it could affect the recycling of the successor node's memory.

    "},{"location":"chapter_computational_complexity/","title":"Chapter 2. \u00a0 Complexity analysis","text":"

    Abstract

    Complexity analysis is like a space-time navigator in the vast universe of algorithms.

    It guides us in exploring deeper within the the dimensions of time and space, seeking more elegant solutions.

    "},{"location":"chapter_computational_complexity/#chapter-contents","title":"Chapter contents","text":"
    • 2.1 \u00a0 Algorithm efficiency assessment
    • 2.2 \u00a0 Iteration and recursion
    • 2.3 \u00a0 Time complexity
    • 2.4 \u00a0 Space complexity
    • 2.5 \u00a0 Summary
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/","title":"2.2 \u00a0 Iteration and recursion","text":"

    In algorithms, the repeated execution of a task is quite common and is closely related to the analysis of complexity. Therefore, before delving into the concepts of time complexity and space complexity, let's first explore how to implement repetitive tasks in programming. This involves understanding two fundamental programming control structures: iteration and recursion.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#221-iteration","title":"2.2.1 \u00a0 Iteration","text":"

    \"Iteration\" is a control structure for repeatedly performing a task. In iteration, a program repeats a block of code as long as a certain condition is met until this condition is no longer satisfied.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1-for-loops","title":"1. \u00a0 For loops","text":"

    The for loop is one of the most common forms of iteration, and it's particularly suitable when the number of iterations is known in advance.

    The following function uses a for loop to perform a summation of \\(1 + 2 + \\dots + n\\), with the sum being stored in the variable res. It's important to note that in Python, range(a, b) creates an interval that is inclusive of a but exclusive of b, meaning it iterates over the range from \\(a\\) up to \\(b\u22121\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def for_loop(n: int) -> int:\n    \"\"\"for \u5faa\u73af\"\"\"\n    res = 0\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        res += i\n    return res\n
    iteration.cpp
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.java
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.cs
    /* for \u5faa\u73af */\nint ForLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.go
    /* for \u5faa\u73af */\nfunc forLoop(n int) int {\n    res := 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        res += i\n    }\n    return res\n}\n
    iteration.swift
    /* for \u5faa\u73af */\nfunc forLoop(n: Int) -> Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        res += i\n    }\n    return res\n}\n
    iteration.js
    /* for \u5faa\u73af */\nfunction forLoop(n) {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.ts
    /* for \u5faa\u73af */\nfunction forLoop(n: number): number {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.dart
    /* for \u5faa\u73af */\nint forLoop(int n) {\n  int res = 0;\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    res += i;\n  }\n  return res;\n}\n
    iteration.rs
    /* for \u5faa\u73af */\nfn for_loop(n: i32) -> i32 {\n    let mut res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1..=n {\n        res += i;\n    }\n    res\n}\n
    iteration.c
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.kt
    /* for \u5faa\u73af */\nfun forLoop(n: Int): Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        res += i\n    }\n    return res\n}\n
    iteration.rb
    ### for \u5faa\u73af ###\ndef for_loop(n)\n  res = 0\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for i in 1..n\n    res += i\n  end\n\n  res\nend\n
    iteration.zig
    // for \u5faa\u73af\nfn forLoop(n: usize) i32 {\n    var res: i32 = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        res = res + @as(i32, @intCast(i));\n    }\n    return res;\n} \n
    Code Visualization

    Full Screen >

    The flowchart below represents this sum function.

    Figure 2-1 \u00a0 Flowchart of the sum function

    The number of operations in this summation function is proportional to the size of the input data \\(n\\), or in other words, it has a \"linear relationship.\" This \"linear relationship\" is what time complexity describes. This topic will be discussed in more detail in the next section.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2-while-loops","title":"2. \u00a0 While loops","text":"

    Similar to for loops, while loops are another approach for implementing iteration. In a while loop, the program checks a condition at the beginning of each iteration; if the condition is true, the execution continues, otherwise, the loop ends.

    Below we use a while loop to implement the sum \\(1 + 2 + \\dots + n\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop(n: int) -> int:\n    \"\"\"while \u5faa\u73af\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n:\n        res += i\n        i += 1  # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af */\nint WhileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af */\nfunc whileLoop(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af */\nfunc whileLoop(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i\n        i += 1 // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af */\nfunction whileLoop(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af */\nfunction whileLoop(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while (i <= n) {\n    res += i;\n    i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af */\nfn while_loop(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af */\nfun whileLoop(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i\n        i++ // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af ###\ndef while_loop(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while i <= n\n    res += i\n    i += 1 # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  end\n\n  res\nend\n
    iteration.zig
    // while \u5faa\u73af\nfn whileLoop(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += @intCast(i);\n        i += 1;\n    }\n    return res;\n}\n
    Code Visualization

    Full Screen >

    While loops provide more flexibility than for loops, especially since they allow for custom initialization and modification of the condition variable at each step.

    For example, in the following code, the condition variable \\(i\\) is updated twice each round, which would be inconvenient to implement with a for loop.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop_ii(n: int) -> int:\n    \"\"\"while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n:\n        res += i\n        # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint WhileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1; \n        i *= 2;\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while (i <= n) {\n    res += i;\n    // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i++;\n    i *= 2;\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfn while_loop_ii(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfun whileLoopII(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09###\ndef while_loop_ii(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while i <= n\n    res += i\n    # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i += 1\n    i *= 2\n  end\n\n  res\nend\n
    iteration.zig
    //  while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\nfn whileLoopII(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += @intCast(i);\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    return res;\n}\n
    Code Visualization

    Full Screen >

    Overall, for loops are more concise, while while loops are more flexible. Both can implement iterative structures. Which one to use should be determined based on the specific requirements of the problem.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3-nested-loops","title":"3. \u00a0 Nested loops","text":"

    We can nest one loop structure within another. Below is an example using for loops:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def nested_for_loop(n: int) -> str:\n    \"\"\"\u53cc\u5c42 for \u5faa\u73af\"\"\"\n    res = \"\"\n    # \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        # \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in range(1, n + 1):\n            res += f\"({i}, {j}), \"\n    return res\n
    iteration.cpp
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring nestedForLoop(int n) {\n    ostringstream res;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; ++j) {\n            res << \"(\" << i << \", \" << j << \"), \";\n        }\n    }\n    return res.str();\n}\n
    iteration.java
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n    StringBuilder res = new StringBuilder();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.append(\"(\" + i + \", \" + j + \"), \");\n        }\n    }\n    return res.toString();\n}\n
    iteration.cs
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring NestedForLoop(int n) {\n    StringBuilder res = new();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.Append($\"({i}, {j}), \");\n        }\n    }\n    return res.ToString();\n}\n
    iteration.go
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n int) string {\n    res := \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= n; j++ {\n            // \u5faa\u73af j = 1, 2, ..., n-1, n\n            res += fmt.Sprintf(\"(%d, %d), \", i, j)\n        }\n    }\n    return res\n}\n
    iteration.swift
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n: Int) -> String {\n    var res = \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1 ... n {\n            res.append(\"(\\(i), \\(j)), \")\n        }\n    }\n    return res\n}\n
    iteration.js
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n) {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.ts
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n: number): string {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.dart
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n  String res = \"\";\n  // \u5faa\u73af i = 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    // \u5faa\u73af j = 1, 2, ..., n-1, n\n    for (int j = 1; j <= n; j++) {\n      res += \"($i, $j), \";\n    }\n  }\n  return res;\n}\n
    iteration.rs
    /* \u53cc\u5c42 for \u5faa\u73af */\nfn nested_for_loop(n: i32) -> String {\n    let mut res = vec![];\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1..=n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1..=n {\n            res.push(format!(\"({}, {}), \", i, j));\n        }\n    }\n    res.join(\"\")\n}\n
    iteration.c
    /* \u53cc\u5c42 for \u5faa\u73af */\nchar *nestedForLoop(int n) {\n    // n * n \u4e3a\u5bf9\u5e94\u70b9\u6570\u91cf\uff0c\"(i, j), \" \u5bf9\u5e94\u5b57\u7b26\u4e32\u957f\u6700\u5927\u4e3a 6+10*2\uff0c\u52a0\u4e0a\u6700\u540e\u4e00\u4e2a\u7a7a\u5b57\u7b26 \\0 \u7684\u989d\u5916\u7a7a\u95f4\n    int size = n * n * 26 + 1;\n    char *res = malloc(size * sizeof(char));\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            char tmp[26];\n            snprintf(tmp, sizeof(tmp), \"(%d, %d), \", i, j);\n            strncat(res, tmp, size - strlen(res) - 1);\n        }\n    }\n    return res;\n}\n
    iteration.kt
    /* \u53cc\u5c42 for \u5faa\u73af */\nfun nestedForLoop(n: Int): String {\n    val res = StringBuilder()\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (j in 1..n) {\n            res.append(\" ($i, $j), \")\n        }\n    }\n    return res.toString()\n}\n
    iteration.rb
    ### \u53cc\u5c42 for \u5faa\u73af ###\ndef nested_for_loop(n)\n  res = \"\"\n\n  # \u5faa\u73af i = 1, 2, ..., n-1, n\n  for i in 1..n\n    # \u5faa\u73af j = 1, 2, ..., n-1, n\n    for j in 1..n\n      res += \"(#{i}, #{j}), \"\n    end\n  end\n\n  res\nend\n
    iteration.zig
    // \u53cc\u5c42 for \u5faa\u73af\nfn nestedForLoop(allocator: Allocator, n: usize) ![]const u8 {\n    var res = std.ArrayList(u8).init(allocator);\n    defer res.deinit();\n    var buffer: [20]u8 = undefined;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (1..n+1) |j| {\n            var _str = try std.fmt.bufPrint(&buffer, \"({d}, {d}), \", .{i, j});\n            try res.appendSlice(_str);\n        }\n    }\n    return res.toOwnedSlice();\n}\n
    Code Visualization

    Full Screen >

    The flowchart below represents this nested loop.

    Figure 2-2 \u00a0 Flowchart of the nested loop

    In such cases, the number of operations of the function is proportional to \\(n^2\\), meaning the algorithm's runtime and the size of the input data \\(n\\) has a 'quadratic relationship.'

    We can further increase the complexity by adding more nested loops, each level of nesting effectively \"increasing the dimension,\" which raises the time complexity to \"cubic,\" \"quartic,\" and so on.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#222-recursion","title":"2.2.2 \u00a0 Recursion","text":"

    \"Recursion\" is an algorithmic strategy where a function solves a problem by calling itself. It primarily involves two phases:

    1. Calling: This is where the program repeatedly calls itself, often with progressively smaller or simpler arguments, moving towards the \"termination condition.\"
    2. Returning: Upon triggering the \"termination condition,\" the program begins to return from the deepest recursive function, aggregating the results of each layer.

    From an implementation perspective, recursive code mainly includes three elements.

    1. Termination Condition: Determines when to switch from \"calling\" to \"returning.\"
    2. Recursive Call: Corresponds to \"calling,\" where the function calls itself, usually with smaller or more simplified parameters.
    3. Return Result: Corresponds to \"returning,\" where the result of the current recursion level is returned to the previous layer.

    Observe the following code, where simply calling the function recur(n) can compute the sum of \\(1 + 2 + \\dots + n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def recur(n: int) -> int:\n    \"\"\"\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 1:\n        return 1\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res = recur(n - 1)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n
    recursion.cpp
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.java
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.cs
    /* \u9012\u5f52 */\nint Recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = Recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.go
    /* \u9012\u5f52 */\nfunc recur(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res := recur(n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.swift
    /* \u9012\u5f52 */\nfunc recur(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n: n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.js
    /* \u9012\u5f52 */\nfunction recur(n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.ts
    /* \u9012\u5f52 */\nfunction recur(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.dart
    /* \u9012\u5f52 */\nint recur(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 1) return 1;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  int res = recur(n - 1);\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  return n + res;\n}\n
    recursion.rs
    /* \u9012\u5f52 */\nfn recur(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    n + res\n}\n
    recursion.c
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.kt
    /* \u9012\u5f52 */\nfun recur(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    val res = recur(n - 1)\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.rb
    ### \u9012\u5f52 ###\ndef recur(n)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return 1 if n == 1\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  res = recur(n - 1)\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  n + res\nend\n
    recursion.zig
    // \u9012\u5f52\u51fd\u6570\nfn recur(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1) {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var res: i32 = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    Code Visualization

    Full Screen >

    The Figure 2-3 shows the recursive process of this function.

    Figure 2-3 \u00a0 Recursive process of the sum function

    Although iteration and recursion can achieve the same results from a computational standpoint, they represent two entirely different paradigms of thinking and problem-solving.

    • Iteration: Solves problems \"from the bottom up.\" It starts with the most basic steps, and then repeatedly adds or accumulates these steps until the task is complete.
    • Recursion: Solves problems \"from the top down.\" It breaks down the original problem into smaller sub-problems, each of which has the same form as the original problem. These sub-problems are then further decomposed into even smaller sub-problems, stopping at the base case whose solution is known.

    Let's take the earlier example of the summation function, defined as \\(f(n) = 1 + 2 + \\dots + n\\).

    • Iteration: In this approach, we simulate the summation process within a loop. Starting from \\(1\\) and traversing to \\(n\\), we perform the summation operation in each iteration to eventually compute \\(f(n)\\).
    • Recursion: Here, the problem is broken down into a sub-problem: \\(f(n) = n + f(n-1)\\). This decomposition continues recursively until reaching the base case, \\(f(1) = 1\\), at which point the recursion terminates.
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1-call-stack","title":"1. \u00a0 Call stack","text":"

    Every time a recursive function calls itself, the system allocates memory for the newly initiated function to store local variables, the return address, and other relevant information. This leads to two primary outcomes.

    • The function's context data is stored in a memory area called \"stack frame space\" and is only released after the function returns. Therefore, recursion generally consumes more memory space than iteration.
    • Recursive calls introduce additional overhead. Hence, recursion is usually less time-efficient than loops.

    As shown in the Figure 2-4 , there are \\(n\\) unreturned recursive functions before triggering the termination condition, indicating a recursion depth of \\(n\\).

    Figure 2-4 \u00a0 Recursion call depth

    In practice, the depth of recursion allowed by programming languages is usually limited, and excessively deep recursion can lead to stack overflow errors.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2-tail-recursion","title":"2. \u00a0 Tail recursion","text":"

    Interestingly, if a function performs its recursive call as the very last step before returning, it can be optimized by the compiler or interpreter to be as space-efficient as iteration. This scenario is known as \"tail recursion.\"

    • Regular recursion: In standard recursion, when the function returns to the previous level, it continues to execute more code, requiring the system to save the context of the previous call.
    • Tail recursion: Here, the recursive call is the final operation before the function returns. This means that upon returning to the previous level, no further actions are needed, so the system does not need to save the context of the previous level.

    For example, in calculating \\(1 + 2 + \\dots + n\\), we can make the result variable res a parameter of the function, thereby achieving tail recursion:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def tail_recur(n, res):\n    \"\"\"\u5c3e\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 0:\n        return res\n    # \u5c3e\u9012\u5f52\u8c03\u7528\n    return tail_recur(n - 1, res + n)\n
    recursion.cpp
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.java
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.cs
    /* \u5c3e\u9012\u5f52 */\nint TailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return TailRecur(n - 1, res + n);\n}\n
    recursion.go
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n int, res int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n-1, res+n)\n}\n
    recursion.swift
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n: Int, res: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n: n - 1, res: res + n)\n}\n
    recursion.js
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n, res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.ts
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n: number, res: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.dart
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 0) return res;\n  // \u5c3e\u9012\u5f52\u8c03\u7528\n  return tailRecur(n - 1, res + n);\n}\n
    recursion.rs
    /* \u5c3e\u9012\u5f52 */\nfn tail_recur(n: i32, res: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    tail_recur(n - 1, res + n)\n}\n
    recursion.c
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.kt
    /* \u5c3e\u9012\u5f52 */\ntailrec fun tailRecur(n: Int, res: Int): Int {\n    // \u6dfb\u52a0 tailrec \u5173\u952e\u8bcd\uff0c\u4ee5\u5f00\u542f\u5c3e\u9012\u5f52\u4f18\u5316\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n)\n}\n
    recursion.rb
    ### \u5c3e\u9012\u5f52 ###\ndef tail_recur(n, res)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return res if n == 0\n  # \u5c3e\u9012\u5f52\u8c03\u7528\n  tail_recur(n - 1, res + n)\nend\n
    recursion.zig
    // \u5c3e\u9012\u5f52\u51fd\u6570\nfn tailRecur(n: i32, res: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0) {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    Code Visualization

    Full Screen >

    The execution process of tail recursion is shown in the following figure. Comparing regular recursion and tail recursion, the point of the summation operation is different.

    • Regular recursion: The summation operation occurs during the \"returning\" phase, requiring another summation after each layer returns.
    • Tail recursion: The summation operation occurs during the \"calling\" phase, and the \"returning\" phase only involves returning through each layer.

    Figure 2-5 \u00a0 Tail recursion process

    Tip

    Note that many compilers or interpreters do not support tail recursion optimization. For example, Python does not support tail recursion optimization by default, so even if the function is in the form of tail recursion, it may still encounter stack overflow issues.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3-recursion-tree","title":"3. \u00a0 Recursion tree","text":"

    When dealing with algorithms related to \"divide and conquer\", recursion often offers a more intuitive approach and more readable code than iteration. Take the \"Fibonacci sequence\" as an example.

    Question

    Given a Fibonacci sequence \\(0, 1, 1, 2, 3, 5, 8, 13, \\dots\\), find the \\(n\\)th number in the sequence.

    Let the \\(n\\)th number of the Fibonacci sequence be \\(f(n)\\), it's easy to deduce two conclusions:

    • The first two numbers of the sequence are \\(f(1) = 0\\) and \\(f(2) = 1\\).
    • Each number in the sequence is the sum of the two preceding ones, that is, \\(f(n) = f(n - 1) + f(n - 2)\\).

    Using the recursive relation, and considering the first two numbers as termination conditions, we can write the recursive code. Calling fib(n) will yield the \\(n\\)th number of the Fibonacci sequence:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def fib(n: int) -> int:\n    \"\"\"\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 or n == 2:\n        return n - 1\n    # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res = fib(n - 1) + fib(n - 2)\n    # \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n
    recursion.cpp
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.java
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.cs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint Fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = Fib(n - 1) + Fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.go
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res := fib(n-1) + fib(n-2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.swift
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n: n - 1) + fib(n: n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.js
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.ts
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.dart
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  if (n == 1 || n == 2) return n - 1;\n  // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  int res = fib(n - 1) + fib(n - 2);\n  // \u8fd4\u56de\u7ed3\u679c f(n)\n  return res;\n}\n
    recursion.rs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfn fib(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c\n    res\n}\n
    recursion.c
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.kt
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfun fib(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    val res = fib(n - 1) + fib(n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.rb
    ### \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 ###\ndef fib(n)\n  # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  return n - 1 if n == 1 || n == 2\n  # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  res = fib(n - 1) + fib(n - 2)\n  # \u8fd4\u56de\u7ed3\u679c f(n)\n  res\nend\n
    recursion.zig
    // \u6590\u6ce2\u90a3\u5951\u6570\u5217\nfn fib(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 or n == 2) {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    var res: i32 = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    Code Visualization

    Full Screen >

    Observing the above code, we see that it recursively calls two functions within itself, meaning that one call generates two branching calls. As illustrated below, this continuous recursive calling eventually creates a \"recursion tree\" with a depth of \\(n\\).

    Figure 2-6 \u00a0 Fibonacci sequence recursion tree

    Fundamentally, recursion embodies the paradigm of \"breaking down a problem into smaller sub-problems.\" This divide-and-conquer strategy is crucial.

    • From an algorithmic perspective, many important strategies like searching, sorting, backtracking, divide-and-conquer, and dynamic programming directly or indirectly use this way of thinking.
    • From a data structure perspective, recursion is naturally suited for dealing with linked lists, trees, and graphs, as they are well suited for analysis using the divide-and-conquer approach.
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#223-comparison","title":"2.2.3 \u00a0 Comparison","text":"

    Summarizing the above content, the following table shows the differences between iteration and recursion in terms of implementation, performance, and applicability.

    Table: Comparison of iteration and recursion characteristics

    Iteration Recursion Approach Loop structure Function calls itself Time Efficiency Generally higher efficiency, no function call overhead Each function call generates overhead Memory Usage Typically uses a fixed size of memory space Accumulative function calls can use a substantial amount of stack frame space Suitable Problems Suitable for simple loop tasks, intuitive and readable code Suitable for problem decomposition, like trees, graphs, divide-and-conquer, backtracking, etc., concise and clear code structure

    Tip

    If you find the following content difficult to understand, consider revisiting it after reading the \"Stack\" chapter.

    So, what is the intrinsic connection between iteration and recursion? Taking the above recursive function as an example, the summation operation occurs during the recursion's \"return\" phase. This means that the initially called function is the last to complete its summation operation, mirroring the \"last in, first out\" principle of a stack.

    Recursive terms like \"call stack\" and \"stack frame space\" hint at the close relationship between recursion and stacks.

    1. Calling: When a function is called, the system allocates a new stack frame on the \"call stack\" for that function, storing local variables, parameters, return addresses, and other data.
    2. Returning: When a function completes execution and returns, the corresponding stack frame is removed from the \"call stack,\" restoring the execution environment of the previous function.

    Therefore, we can use an explicit stack to simulate the behavior of the call stack, thus transforming recursion into an iterative form:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def for_loop_recur(n: int) -> int:\n    \"\"\"\u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\"\"\"\n    # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack = []\n    res = 0\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in range(n, 0, -1):\n        # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while stack:\n        # \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    # res = 1+2+3+...+n\n    return res\n
    recursion.cpp
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack<int> stack;\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.empty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.top();\n        stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.java
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<Integer> stack = new Stack<>();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.isEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.cs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint ForLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<int> stack = new();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.Push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.Count > 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.go
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n int) int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack := list.New()\n    res := 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i := n; i > 0; i-- {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.PushBack(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    for stack.Len() != 0 {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Back().Value.(int)\n        stack.Remove(stack.Back())\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.swift
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n: Int) -> Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [Int] = []\n    var res = 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1 ... n).reversed() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.isEmpty {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.removeLast()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.js
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    const stack = [];\n    let res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.ts
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n: number): number {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808 \n    const stack: number[] = [];\n    let res: number = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.dart
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n  // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  List<int> stack = [];\n  int res = 0;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for (int i = n; i > 0; i--) {\n    // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack.add(i);\n  }\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while (!stack.isEmpty) {\n    // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n    res += stack.removeLast();\n  }\n  // res = 1+2+3+...+n\n  return res;\n}\n
    recursion.rs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfn for_loop_recur(n: i32) -> i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    let mut stack = Vec::new();\n    let mut res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1..=n).rev() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.is_empty() {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop().unwrap();\n    }\n    // res = 1+2+3+...+n\n    res\n}\n
    recursion.c
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    int stack[1000]; // \u501f\u52a9\u4e00\u4e2a\u5927\u6570\u7ec4\u6765\u6a21\u62df\u6808\n    int top = -1;    // \u6808\u9876\u7d22\u5f15\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack[1 + top++] = i;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (top >= 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack[top--];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.kt
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfun forLoopRecur(n: Int): Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    val stack = Stack<Int>()\n    var res = 0\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    for (i in n downTo 0) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i)\n    }\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    while (stack.isNotEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.rb
    ### \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 ###\ndef for_loop_recur(n)\n  # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  stack = []\n  res = 0\n\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for i in n.downto(0)\n    # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack << i\n  end\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while !stack.empty?\n    res += stack.pop\n  end\n\n  # res = 1+2+3+...+n\n  res\nend\n
    recursion.zig
    // \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\nfn forLoopRecur(comptime n: i32) i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [n]i32 = undefined;\n    var res: i32 = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var i: usize = n;\n    while (i > 0) {\n        stack[i - 1] = @intCast(i);\n        i -= 1;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    var index: usize = n;\n    while (index > 0) {\n        index -= 1;\n        res += stack[index];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    Code Visualization

    Full Screen >

    Observing the above code, when recursion is transformed into iteration, the code becomes more complex. Although iteration and recursion can often be transformed into each other, it's not always advisable to do so for two reasons:

    • The transformed code may become more challenging to understand and less readable.
    • For some complex problems, simulating the behavior of the system's call stack can be quite challenging.

    In conclusion, whether to choose iteration or recursion depends on the specific nature of the problem. In programming practice, it's crucial to weigh the pros and cons of both and choose the most suitable approach for the situation at hand.

    "},{"location":"chapter_computational_complexity/performance_evaluation/","title":"2.1 \u00a0 Algorithm efficiency assessment","text":"

    In algorithm design, we pursue the following two objectives in sequence.

    1. Finding a Solution to the Problem: The algorithm should reliably find the correct solution within the stipulated range of inputs.
    2. Seeking the Optimal Solution: For the same problem, multiple solutions might exist, and we aim to find the most efficient algorithm possible.

    In other words, under the premise of being able to solve the problem, algorithm efficiency has become the main criterion for evaluating the merits of an algorithm, which includes the following two dimensions.

    • Time efficiency: The speed at which an algorithm runs.
    • Space efficiency: The size of the memory space occupied by an algorithm.

    In short, our goal is to design data structures and algorithms that are both fast and memory-efficient. Effectively assessing algorithm efficiency is crucial because only then can we compare various algorithms and guide the process of algorithm design and optimization.

    There are mainly two methods of efficiency assessment: actual testing and theoretical estimation.

    "},{"location":"chapter_computational_complexity/performance_evaluation/#211-actual-testing","title":"2.1.1 \u00a0 Actual testing","text":"

    Suppose we have algorithms A and B, both capable of solving the same problem, and we need to compare their efficiencies. The most direct method is to use a computer to run these two algorithms and monitor and record their runtime and memory usage. This assessment method reflects the actual situation but has significant limitations.

    On one hand, it's difficult to eliminate interference from the testing environment. Hardware configurations can affect algorithm performance. For example, algorithm A might run faster than B on one computer, but the opposite result may occur on another computer with different configurations. This means we would need to test on a variety of machines to calculate average efficiency, which is impractical.

    On the other hand, conducting a full test is very resource-intensive. As the volume of input data changes, the efficiency of the algorithms may vary. For example, with smaller data volumes, algorithm A might run faster than B, but the opposite might be true with larger data volumes. Therefore, to draw convincing conclusions, we need to test a wide range of input data sizes, which requires significant computational resources.

    "},{"location":"chapter_computational_complexity/performance_evaluation/#212-theoretical-estimation","title":"2.1.2 \u00a0 Theoretical estimation","text":"

    Due to the significant limitations of actual testing, we can consider evaluating algorithm efficiency solely through calculations. This estimation method is known as \"asymptotic complexity analysis,\" or simply \"complexity analysis.\"

    Complexity analysis reflects the relationship between the time and space resources required for algorithm execution and the size of the input data. It describes the trend of growth in the time and space required by the algorithm as the size of the input data increases. This definition might sound complex, but we can break it down into three key points to understand it better.

    • \"Time and space resources\" correspond to \"time complexity\" and \"space complexity,\" respectively.
    • \"As the size of input data increases\" means that complexity reflects the relationship between algorithm efficiency and the volume of input data.
    • \"The trend of growth in time and space\" indicates that complexity analysis focuses not on the specific values of runtime or space occupied but on the \"rate\" at which time or space grows.

    Complexity analysis overcomes the disadvantages of actual testing methods, reflected in the following aspects:

    • It is independent of the testing environment and applicable to all operating platforms.
    • It can reflect algorithm efficiency under different data volumes, especially in the performance of algorithms with large data volumes.

    Tip

    If you're still confused about the concept of complexity, don't worry. We will introduce it in detail in subsequent chapters.

    Complexity analysis provides us with a \"ruler\" to measure the time and space resources needed to execute an algorithm and compare the efficiency between different algorithms.

    Complexity is a mathematical concept and may be abstract and challenging for beginners. From this perspective, complexity analysis might not be the best content to introduce first. However, when discussing the characteristics of a particular data structure or algorithm, it's hard to avoid analyzing its speed and space usage.

    In summary, it's recommended that you establish a preliminary understanding of complexity analysis before diving deep into data structures and algorithms, so that you can carry out simple complexity analyses of algorithms.

    "},{"location":"chapter_computational_complexity/space_complexity/","title":"2.4 \u00a0 Space complexity","text":"

    \"Space complexity\" is used to measure the growth trend of the memory space occupied by an algorithm as the amount of data increases. This concept is very similar to time complexity, except that \"running time\" is replaced with \"occupied memory space\".

    "},{"location":"chapter_computational_complexity/space_complexity/#241-space-related-to-algorithms","title":"2.4.1 \u00a0 Space related to algorithms","text":"

    The memory space used by an algorithm during its execution mainly includes the following types.

    • Input space: Used to store the input data of the algorithm.
    • Temporary space: Used to store variables, objects, function contexts, and other data during the algorithm's execution.
    • Output space: Used to store the output data of the algorithm.

    Generally, the scope of space complexity statistics includes both \"Temporary Space\" and \"Output Space\".

    Temporary space can be further divided into three parts.

    • Temporary data: Used to save various constants, variables, objects, etc., during the algorithm's execution.
    • Stack frame space: Used to save the context data of the called function. The system creates a stack frame at the top of the stack each time a function is called, and the stack frame space is released after the function returns.
    • Instruction space: Used to store compiled program instructions, which are usually negligible in actual statistics.

    When analyzing the space complexity of a program, we typically count the Temporary Data, Stack Frame Space, and Output Data, as shown in the Figure 2-15 .

    Figure 2-15 \u00a0 Space types used in algorithms

    The relevant code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    class Node:\n    \"\"\"Classes\"\"\"\n    def __init__(self, x: int):\n        self.val: int = x               # node value\n        self.next: Node | None = None   # reference to the next node\n\ndef function() -> int:\n    \"\"\"Functions\"\"\"\n    # Perform certain operations...\n    return 0\n\ndef algorithm(n) -> int:    # input data\n    A = 0                   # temporary data (constant, usually in uppercase)\n    b = 0                   # temporary data (variable)\n    node = Node(0)          # temporary data (object)\n    c = function()          # Stack frame space (call function)\n    return A + b + c        # output data\n
    /* Structures */\nstruct Node {\n    int val;\n    Node *next;\n    Node(int x) : val(x), next(nullptr) {}\n};\n\n/* Functions */\nint func() {\n    // Perform certain operations...\n    return 0;\n}\n\nint algorithm(int n) {          // input data\n    const int a = 0;            // temporary data (constant)\n    int b = 0;                  // temporary data (variable)\n    Node* node = new Node(0);   // temporary data (object)\n    int c = func();             // stack frame space (call function)\n    return a + b + c;           // output data\n}\n
    /* Classes */\nclass Node {\n    int val;\n    Node next;\n    Node(int x) { val = x; }\n}\n\n/* Functions */\nint function() {\n    // Perform certain operations...\n    return 0;\n}\n\nint algorithm(int n) {          // input data\n    final int a = 0;            // temporary data (constant)\n    int b = 0;                  // temporary data (variable)\n    Node node = new Node(0);    // temporary data (object)\n    int c = function();         // stack frame space (call function)\n    return a + b + c;           // output data\n}\n
    /* Classes */\nclass Node {\n    int val;\n    Node next;\n    Node(int x) { val = x; }\n}\n\n/* Functions */\nint Function() {\n    // Perform certain operations...\n    return 0;\n}\n\nint Algorithm(int n) {  // input data\n    const int a = 0;    // temporary data (constant)\n    int b = 0;          // temporary data (variable)\n    Node node = new(0); // temporary data (object)\n    int c = Function(); // stack frame space (call function)\n    return a + b + c;   // output data\n}\n
    /* Structures */\ntype node struct {\n    val  int\n    next *node\n}\n\n/* Create node structure */\nfunc newNode(val int) *node {\n    return &node{val: val}\n}\n\n/* Functions */\nfunc function() int {\n    // Perform certain operations...\n    return 0\n}\n\nfunc algorithm(n int) int { // input data\n    const a = 0             // temporary data (constant)\n    b := 0                  // temporary storage of data (variable)\n    newNode(0)              // temporary data (object)\n    c := function()         // stack frame space (call function)\n    return a + b + c        // output data\n}\n
    /* Classes */\nclass Node {\n    var val: Int\n    var next: Node?\n\n    init(x: Int) {\n        val = x\n    }\n}\n\n/* Functions */\nfunc function() -> Int {\n    // Perform certain operations...\n    return 0\n}\n\nfunc algorithm(n: Int) -> Int { // input data\n    let a = 0                   // temporary data (constant)\n    var b = 0                   // temporary data (variable)\n    let node = Node(x: 0)       // temporary data (object)\n    let c = function()          // stack frame space (call function)\n    return a + b + c            // output data\n}\n
    /* Classes */\nclass Node {\n    val;\n    next;\n    constructor(val) {\n        this.val = val === undefined ? 0 : val; // node value\n        this.next = null;                       // reference to the next node\n    }\n}\n\n/* Functions */\nfunction constFunc() {\n    // Perform certain operations\n    return 0;\n}\n\nfunction algorithm(n) {         // input data\n    const a = 0;                // temporary data (constant)\n    let b = 0;                  // temporary data (variable)\n    const node = new Node(0);   // temporary data (object)\n    const c = constFunc();      // Stack frame space (calling function)\n    return a + b + c;           // output data\n}\n
    /* Classes */\nclass Node {\n    val: number;\n    next: Node | null;\n    constructor(val?: number) {\n        this.val = val === undefined ? 0 : val; // node value\n        this.next = null;                       // reference to the next node\n    }\n}\n\n/* Functions */\nfunction constFunc(): number {\n    // Perform certain operations\n    return 0;\n}\n\nfunction algorithm(n: number): number { // input data\n    const a = 0;                        // temporary data (constant)\n    let b = 0;                          // temporary data (variable)\n    const node = new Node(0);           // temporary data (object)\n    const c = constFunc();              // Stack frame space (calling function)\n    return a + b + c;                   // output data\n}\n
    /* Classes */\nclass Node {\n  int val;\n  Node next;\n  Node(this.val, [this.next]);\n}\n\n/* Functions */\nint function() {\n  // Perform certain operations...\n  return 0;\n}\n\nint algorithm(int n) {  // input data\n  const int a = 0;      // temporary data (constant)\n  int b = 0;            // temporary data (variable)\n  Node node = Node(0);  // temporary data (object)\n  int c = function();   // stack frame space (call function)\n  return a + b + c;     // output data\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* Structures */\nstruct Node {\n    val: i32,\n    next: Option<Rc<RefCell<Node>>>,\n}\n\n/* Constructor */\nimpl Node {\n    fn new(val: i32) -> Self {\n        Self { val: val, next: None }\n    }\n}\n\n/* Functions */\nfn function() -> i32 {     \n    // Perform certain operations...\n    return 0;\n}\n\nfn algorithm(n: i32) -> i32 {   // input data\n    const a: i32 = 0;           // temporary data (constant)\n    let mut b = 0;              // temporary data (variable)\n    let node = Node::new(0);    // temporary data (object)\n    let c = function();         // stack frame space (call function)\n    return a + b + c;           // output data\n}\n
    /* Functions */\nint func() {\n    // Perform certain operations...\n    return 0;\n}\n\nint algorithm(int n) {  // input data\n    const int a = 0;    // temporary data (constant)\n    int b = 0;          // temporary data (variable)\n    int c = func();     // stack frame space (call function)\n    return a + b + c;   // output data\n}\n
    \n
    \n
    "},{"location":"chapter_computational_complexity/space_complexity/#242-calculation-method","title":"2.4.2 \u00a0 Calculation method","text":"

    The method for calculating space complexity is roughly similar to that of time complexity, with the only change being the shift of the statistical object from \"number of operations\" to \"size of used space\".

    However, unlike time complexity, we usually only focus on the worst-case space complexity. This is because memory space is a hard requirement, and we must ensure that there is enough memory space reserved under all input data.

    Consider the following code, the term \"worst-case\" in worst-case space complexity has two meanings.

    1. Based on the worst input data: When \\(n < 10\\), the space complexity is \\(O(1)\\); but when \\(n > 10\\), the initialized array nums occupies \\(O(n)\\) space, thus the worst-case space complexity is \\(O(n)\\).
    2. Based on the peak memory used during the algorithm's execution: For example, before executing the last line, the program occupies \\(O(1)\\) space; when initializing the array nums, the program occupies \\(O(n)\\) space, hence the worst-case space complexity is \\(O(n)\\).
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def algorithm(n: int):\n    a = 0               # O(1)\n    b = [0] * 10000     # O(1)\n    if n > 10:\n        nums = [0] * n  # O(n)\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    vector<int> b(10000);    // O(1)\n    if (n > 10)\n        vector<int> nums(n); // O(n)\n}\n
    void algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10)\n        int[] nums = new int[n]; // O(n)\n}\n
    void Algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10) {\n        int[] nums = new int[n]; // O(n)\n    }\n}\n
    func algorithm(n int) {\n    a := 0                      // O(1)\n    b := make([]int, 10000)     // O(1)\n    var nums []int\n    if n > 10 {\n        nums := make([]int, n)  // O(n)\n    }\n    fmt.Println(a, b, nums)\n}\n
    func algorithm(n: Int) {\n    let a = 0 // O(1)\n    let b = Array(repeating: 0, count: 10000) // O(1)\n    if n > 10 {\n        let nums = Array(repeating: 0, count: n) // O(n)\n    }\n}\n
    function algorithm(n) {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    function algorithm(n: number): void {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    void algorithm(int n) {\n  int a = 0;                            // O(1)\n  List<int> b = List.filled(10000, 0);  // O(1)\n  if (n > 10) {\n    List<int> nums = List.filled(n, 0); // O(n)\n  }\n}\n
    fn algorithm(n: i32) {\n    let a = 0;                           // O(1)\n    let b = [0; 10000];                  // O(1)\n    if n > 10 {\n        let nums = vec![0; n as usize];  // O(n)\n    }\n}\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    int b[10000];            // O(1)\n    if (n > 10)\n        int nums[n] = {0};   // O(n)\n}\n
    \n
    \n

    In recursive functions, stack frame space must be taken into count. Consider the following code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def function() -> int:\n    # Perform certain operations\n    return 0\n\ndef loop(n: int):\n    \"\"\"Loop O(1)\"\"\"\n    for _ in range(n):\n        function()\n\ndef recur(n: int):\n    \"\"\"Recursion O(n)\"\"\"\n    if n == 1:\n        return\n    return recur(n - 1)\n
    int func() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int Function() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid Loop(int n) {\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n/* Recursion O(n) */\nint Recur(int n) {\n    if (n == 1) return 1;\n    return Recur(n - 1);\n}\n
    func function() int {\n    // Perform certain operations\n    return 0\n}\n\n/* Cycle O(1) */\nfunc loop(n int) {\n    for i := 0; i < n; i++ {\n        function()\n    }\n}\n\n/* Recursion O(n) */\nfunc recur(n int) {\n    if n == 1 {\n        return\n    }\n    recur(n - 1)\n}\n
    @discardableResult\nfunc function() -> Int {\n    // Perform certain operations\n    return 0\n}\n\n/* Cycle O(1) */\nfunc loop(n: Int) {\n    for _ in 0 ..< n {\n        function()\n    }\n}\n\n/* Recursion O(n) */\nfunc recur(n: Int) {\n    if n == 1 {\n        return\n    }\n    recur(n: n - 1)\n}\n
    function constFunc() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nfunction loop(n) {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* Recursion O(n) */\nfunction recur(n) {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    function constFunc(): number {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nfunction loop(n: number): void {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* Recursion O(n) */\nfunction recur(n: number): void {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n  // Perform certain operations\n  return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n  for (int i = 0; i < n; i++) {\n    function();\n  }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n  if (n == 1) return;\n  return recur(n - 1);\n}\n
    fn function() -> i32 {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nfn loop(n: i32) {\n    for i in 0..n {\n        function();\n    }\n}\n/* Recursion O(n) */\nvoid recur(n: i32) {\n    if n == 1 {\n        return;\n    }\n    recur(n - 1);\n}\n
    int func() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    \n
    \n

    The time complexity of both loop() and recur() functions is \\(O(n)\\), but their space complexities differ.

    • The loop() function calls function() \\(n\\) times in a loop, where each iteration's function() returns and releases its stack frame space, so the space complexity remains \\(O(1)\\).
    • The recursive function recur() will have \\(n\\) instances of unreturned recur() existing simultaneously during its execution, thus occupying \\(O(n)\\) stack frame space.
    "},{"location":"chapter_computational_complexity/space_complexity/#243-common-types","title":"2.4.3 \u00a0 Common types","text":"

    Let the size of the input data be \\(n\\), the following chart displays common types of space complexities (arranged from low to high).

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n^2) < O(2^n) \\newline \\text{Constant Order} < \\text{Logarithmic Order} < \\text{Linear Order} < \\text{Quadratic Order} < \\text{Exponential Order} \\end{aligned} \\]

    Figure 2-16 \u00a0 Common types of space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#1-constant-order-o1","title":"1. \u00a0 Constant order \\(O(1)\\)","text":"

    Constant order is common in constants, variables, objects that are independent of the size of input data \\(n\\).

    Note that memory occupied by initializing variables or calling functions in a loop, which is released upon entering the next cycle, does not accumulate over space, thus the space complexity remains \\(O(1)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def function() -> int:\n    \"\"\"\u51fd\u6570\"\"\"\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n\ndef constant(n: int):\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    a = 0\n    nums = [0] * 10000\n    node = ListNode(0)\n    # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        c = 0\n    # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        function()\n
    space_complexity.cpp
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    vector<int> nums(10000);\n    ListNode node(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.java
    /* \u51fd\u6570 */\nint function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    final int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n
    space_complexity.cs
    /* \u51fd\u6570 */\nint Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid Constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n
    space_complexity.go
    /* \u51fd\u6570 */\nfunc function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc spaceConstant(n int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0\n    b := 0\n    nums := make([]int, 10000)\n    node := newNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    var c int\n    for i := 0; i < n; i++ {\n        c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i := 0; i < n; i++ {\n        function()\n    }\n    b += 0\n    c += 0\n    nums[0] = 0\n    node.val = 0\n}\n
    space_complexity.swift
    /* \u51fd\u6570 */\n@discardableResult\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    let a = 0\n    var b = 0\n    let nums = Array(repeating: 0, count: 10000)\n    let node = ListNode(x: 0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        let c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        function()\n    }\n}\n
    space_complexity.js
    /* \u51fd\u6570 */\nfunction constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.ts
    /* \u51fd\u6570 */\nfunction constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n: number): void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.dart
    /* \u51fd\u6570 */\nint function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n  // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  final int a = 0;\n  int b = 0;\n  List<int> nums = List.filled(10000, 0);\n  ListNode node = ListNode(0);\n  // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    int c = 0;\n  }\n  // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    function();\n  }\n}\n
    space_complexity.rs
    /* \u51fd\u6570 */\nfn function() -> i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\n#[allow(unused)]\nfn constant(n: i32) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const A: i32 = 0;\n    let b = 0;\n    let nums = vec![0; 10000];\n    let node = ListNode::new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        let c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        function();\n    }\n}\n
    space_complexity.c
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    int nums[1000];\n    ListNode *node = newListNode(0);\n    free(node);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.kt
    /* \u51fd\u6570 */\nfun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfun constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    val a = 0\n    var b = 0\n    val nums = Array(10000) { 0 }\n    val node = ListNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        val c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        function()\n    }\n}\n
    space_complexity.rb
    ### \u51fd\u6570 ###\ndef function\n  # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  0\nend\n\n### \u5e38\u6570\u9636 ###\ndef constant(n)\n  # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  a = 0\n  nums = [0] * 10000\n  node = ListNode.new\n\n  # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { c = 0 }\n  # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { function }\nend\n
    space_complexity.zig
    // \u51fd\u6570\nfn function() i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n// \u5e38\u6570\u9636\nfn constant(n: i32) void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a: i32 = 0;\n    var b: i32 = 0;\n    var nums = [_]i32{0}**10000;\n    var node = inc.ListNode(i32){.val = 0};\n    var i: i32 = 0;\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    while (i < n) : (i += 1) {\n        var c: i32 = 0;\n        _ = c;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    i = 0;\n    while (i < n) : (i += 1) {\n        _ = function();\n    }\n    _ = a;\n    _ = b;\n    _ = nums;\n    _ = node;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_computational_complexity/space_complexity/#2-linear-order-on","title":"2. \u00a0 Linear order \\(O(n)\\)","text":"

    Linear order is common in arrays, linked lists, stacks, queues, etc., where the number of elements is proportional to \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear(n: int):\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    nums = [0] * n\n    # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    hmap = dict[int, str]()\n    for i in range(n):\n        hmap[i] = str(i)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<int> nums(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<ListNode> nodes;\n    for (int i = 0; i < n; i++) {\n        nodes.push_back(ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    unordered_map<int, string> map;\n    for (int i = 0; i < n; i++) {\n        map[i] = to_string(i);\n    }\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        nodes.add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Map<Integer, String> map = new HashMap<>();\n    for (int i = 0; i < n; i++) {\n        map.put(i, String.valueOf(i));\n    }\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636 */\nvoid Linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = [];\n    for (int i = 0; i < n; i++) {\n        nodes.Add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Dictionary<int, string> map = [];\n    for (int i = 0; i < n; i++) {\n        map.Add(i, i.ToString());\n    }\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc spaceLinear(n int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    _ = make([]int, n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes []*node\n    for i := 0; i < n; i++ {\n        nodes = append(nodes, newNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    m := make(map[int]string, n)\n    for i := 0; i < n; i++ {\n        m[i] = strconv.Itoa(i)\n    }\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let nums = Array(repeating: 0, count: n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let nodes = (0 ..< n).map { ListNode(x: $0) }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let map = Dictionary(uniqueKeysWithValues: (0 ..< n).map { ($0, \"\\($0)\") })\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes: ListNode[] = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n  // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n  List<int> nums = List.filled(n, 0);\n  // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  List<ListNode> nodes = [];\n  for (var i = 0; i < n; i++) {\n    nodes.add(ListNode(i));\n  }\n  // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  Map<int, String> map = HashMap();\n  for (var i = 0; i < n; i++) {\n    map.putIfAbsent(i, () => i.toString());\n  }\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636 */\n#[allow(unused)]\nfn linear(n: i32) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nums = vec![0; n as usize];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nodes = Vec::new();\n    for i in 0..n {\n        nodes.push(ListNode::new(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut map = HashMap::new();\n    for i in 0..n {\n        map.insert(i, i.to_string());\n    }\n}\n
    space_complexity.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int *nums = malloc(sizeof(int) * n);\n    free(nums);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    ListNode **nodes = malloc(sizeof(ListNode *) * n);\n    for (int i = 0; i < n; i++) {\n        nodes[i] = newListNode(i);\n    }\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(nodes[i]);\n    }\n    free(nodes);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    HashTable *h = NULL;\n    for (int i = 0; i < n; i++) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = i;\n        tmp->val = i;\n        HASH_ADD_INT(h, key, tmp);\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    HashTable *curr, *tmp;\n    HASH_ITER(hh, h, curr, tmp) {\n        HASH_DEL(h, curr);\n        free(curr);\n    }\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    val nums = Array(n) { 0 }\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val nodes = mutableListOf<ListNode>()\n    for (i in 0..<n) {\n        nodes.add(ListNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val map = mutableMapOf<Int, String>()\n    for (i in 0..<n) {\n        map[i] = i.toString()\n    }\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  nums = Array.new(n, 0)\n\n  # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  hmap = {}\n  for i in 0...n\n    hmap[i] = i.to_s\n  end\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(comptime n: i32) !void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    var nums = [_]i32{0}**n;\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        try nodes.append(i);\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var map = std.AutoArrayHashMap(i32, []const u8).init(std.heap.page_allocator);\n    defer map.deinit();\n    var j: i32 = 0;\n    while (j < n) : (j += 1) {\n        const string = try std.fmt.allocPrint(std.heap.page_allocator, \"{d}\", .{j});\n        defer std.heap.page_allocator.free(string);\n        try map.put(i, string);\n    }\n    _ = nums;\n}\n
    Code Visualization

    Full Screen >

    As shown below, this function's recursive depth is \\(n\\), meaning there are \\(n\\) instances of unreturned linear_recur() function, using \\(O(n)\\) size of stack frame space:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear_recur(n: int):\n    \"\"\"\u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    print(\"\u9012\u5f52 n =\", n)\n    if n == 1:\n        return\n    linear_recur(n - 1)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    cout << \"\u9012\u5f52 n = \" << n << endl;\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    System.out.println(\"\u9012\u5f52 n = \" + n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid LinearRecur(int n) {\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n);\n    if (n == 1) return;\n    LinearRecur(n - 1);\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceLinearRecur(n int) {\n    fmt.Println(\"\u9012\u5f52 n =\", n)\n    if n == 1 {\n        return\n    }\n    spaceLinearRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc linearRecur(n: Int) {\n    print(\"\u9012\u5f52 n = \\(n)\")\n    if n == 1 {\n        return\n    }\n    linearRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n) {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n: number): void {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n  print('\u9012\u5f52 n = $n');\n  if (n == 1) return;\n  linearRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn linear_recur(n: i32) {\n    println!(\"\u9012\u5f52 n = {}\", n);\n    if n == 1 {\n        return;\n    };\n    linear_recur(n - 1);\n}\n
    space_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    printf(\"\u9012\u5f52 n = %d\\r\\n\", n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun linearRecur(n: Int) {\n    println(\"\u9012\u5f52 n = $n\")\n    if (n == 1)\n        return\n    linearRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef linear_recur(n)\n  puts \"\u9012\u5f52 n = #{n}\"\n  return if n == 1\n  linear_recur(n - 1)\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn linearRecur(comptime n: i32) void {\n    std.debug.print(\"\u9012\u5f52 n = {}\\n\", .{n});\n    if (n == 1) return;\n    linearRecur(n - 1);\n}\n
    Code Visualization

    Full Screen >

    Figure 2-17 \u00a0 Recursive function generating linear order space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#3-quadratic-order-on2","title":"3. \u00a0 Quadratic order \\(O(n^2)\\)","text":"

    Quadratic order is common in matrices and graphs, where the number of elements is quadratic to \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic(n: int):\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    num_matrix = [[0] * n for _ in range(n)]\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    vector<vector<int>> numMatrix;\n    for (int i = 0; i < n; i++) {\n        vector<int> tmp;\n        for (int j = 0; j < n; j++) {\n            tmp.push_back(0);\n        }\n        numMatrix.push_back(tmp);\n    }\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[][] numMatrix = new int[n][n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<Integer>> numList = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<Integer> tmp = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            tmp.add(0);\n        }\n        numList.add(tmp);\n    }\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636 */\nvoid Quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[,] numMatrix = new int[n, n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<int>> numList = [];\n    for (int i = 0; i < n; i++) {\n        List<int> tmp = [];\n        for (int j = 0; j < n; j++) {\n            tmp.Add(0);\n        }\n        numList.Add(tmp);\n    }\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc spaceQuadratic(n int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    numMatrix := make([][]int, n)\n    for i := 0; i < n; i++ {\n        numMatrix[i] = make([]int, n)\n    }\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let numList = Array(repeating: Array(repeating: 0, count: n), count: n)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): void {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n  // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numMatrix = List.generate(n, (_) => List.filled(n, 0));\n  // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numList = [];\n  for (var i = 0; i < n; i++) {\n    List<int> tmp = [];\n    for (int j = 0; j < n; j++) {\n      tmp.add(0);\n    }\n    numList.add(tmp);\n  }\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636 */\n#[allow(unused)]\nfn quadratic(n: i32) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let num_matrix = vec![vec![0; n as usize]; n as usize];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let mut num_list = Vec::new();\n    for i in 0..n {\n        let mut tmp = Vec::new();\n        for j in 0..n {\n            tmp.push(0);\n        }\n        num_list.push(tmp);\n    }\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int **numMatrix = malloc(sizeof(int *) * n);\n    for (int i = 0; i < n; i++) {\n        int *tmp = malloc(sizeof(int) * n);\n        for (int j = 0; j < n; j++) {\n            tmp[j] = 0;\n        }\n        numMatrix[i] = tmp;\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(numMatrix[i]);\n    }\n    free(numMatrix);\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numMatrix = arrayOfNulls<Array<Int>?>(n)\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numList = mutableListOf<MutableList<Int>>()\n    for (i in 0..<n) {\n        val tmp = mutableListOf<Int>()\n        for (j in 0..<n) {\n            tmp.add(0)\n        }\n        numList.add(tmp)\n    }\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  Array.new(n) { Array.new(n, 0) }\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) !void {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    var nodes = std.ArrayList(std.ArrayList(i32)).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        var tmp = std.ArrayList(i32).init(std.heap.page_allocator);\n        defer tmp.deinit();\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            try tmp.append(0);\n        }\n        try nodes.append(tmp);\n    }\n}\n
    Code Visualization

    Full Screen >

    As shown below, the recursive depth of this function is \\(n\\), and in each recursive call, an array is initialized with lengths \\(n\\), \\(n-1\\), \\(\\dots\\), \\(2\\), \\(1\\), averaging \\(n/2\\), thus overall occupying \\(O(n^2)\\) space:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic_recur(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 0:\n        return 0\n    # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    nums = [0] * n\n    return quadratic_recur(n - 1)\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    vector<int> nums(n);\n    cout << \"\u9012\u5f52 n = \" << n << \" \u4e2d\u7684 nums \u957f\u5ea6 = \" << nums.size() << endl;\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    int[] nums = new int[n];\n    System.out.println(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.length);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint QuadraticRecur(int n) {\n    if (n <= 0) return 0;\n    int[] nums = new int[n];\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.Length);\n    return QuadraticRecur(n - 1);\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceQuadraticRecur(n int) int {\n    if n <= 0 {\n        return 0\n    }\n    nums := make([]int, n)\n    fmt.Printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d \\n\", n, len(nums))\n    return spaceQuadraticRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\n@discardableResult\nfunc quadraticRecur(n: Int) -> Int {\n    if n <= 0 {\n        return 0\n    }\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = Array(repeating: 0, count: n)\n    print(\"\u9012\u5f52 n = \\(n) \u4e2d\u7684 nums \u957f\u5ea6 = \\(nums.count)\")\n    return quadraticRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n) {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n: number): number {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n  if (n <= 0) return 0;\n  List<int> nums = List.filled(n, 0);\n  print('\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}');\n  return quadraticRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn quadratic_recur(n: i32) -> i32 {\n    if n <= 0 {\n        return 0;\n    };\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = vec![0; n as usize];\n    println!(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\", n, nums.len());\n    return quadratic_recur(n - 1);\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    int *nums = malloc(sizeof(int) * n);\n    printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d\\r\\n\", n, n);\n    int res = quadraticRecur(n - 1);\n    free(nums);\n    return res;\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\ntailrec fun quadraticRecur(n: Int): Int {\n    if (n <= 0)\n        return 0\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    val nums = Array(n) { 0 }\n    println(\"\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.size}\")\n    return quadraticRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef quadratic_recur(n)\n  return 0 unless n > 0\n\n  # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n  nums = Array.new(n, 0)\n  quadratic_recur(n - 1)\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn quadraticRecur(comptime n: i32) i32 {\n    if (n <= 0) return 0;\n    var nums = [_]i32{0}**n;\n    std.debug.print(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\\n\", .{n, nums.len});\n    return quadraticRecur(n - 1);\n}\n
    Code Visualization

    Full Screen >

    Figure 2-18 \u00a0 Recursive function generating quadratic order space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#4-exponential-order-o2n","title":"4. \u00a0 Exponential order \\(O(2^n)\\)","text":"

    Exponential order is common in binary trees. Observe the below image, a \"full binary tree\" with \\(n\\) levels has \\(2^n - 1\\) nodes, occupying \\(O(2^n)\\) space:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def build_tree(n: int) -> TreeNode | None:\n    \"\"\"\u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\"\"\"\n    if n == 0:\n        return None\n    root = TreeNode(0)\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n    return root\n
    space_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return nullptr;\n    TreeNode *root = new TreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.java
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode buildTree(int n) {\n    if (n == 0)\n        return null;\n    TreeNode root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? BuildTree(int n) {\n    if (n == 0) return null;\n    TreeNode root = new(0) {\n        left = BuildTree(n - 1),\n        right = BuildTree(n - 1)\n    };\n    return root;\n}\n
    space_complexity.go
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n int) *TreeNode {\n    if n == 0 {\n        return nil\n    }\n    root := NewTreeNode(0)\n    root.Left = buildTree(n - 1)\n    root.Right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n: Int) -> TreeNode? {\n    if n == 0 {\n        return nil\n    }\n    let root = TreeNode(x: 0)\n    root.left = buildTree(n: n - 1)\n    root.right = buildTree(n: n - 1)\n    return root\n}\n
    space_complexity.js
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n) {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n: number): TreeNode | null {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? buildTree(int n) {\n  if (n == 0) return null;\n  TreeNode root = TreeNode(0);\n  root.left = buildTree(n - 1);\n  root.right = buildTree(n - 1);\n  return root;\n}\n
    space_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfn build_tree(n: i32) -> Option<Rc<RefCell<TreeNode>>> {\n    if n == 0 {\n        return None;\n    };\n    let root = TreeNode::new(0);\n    root.borrow_mut().left = build_tree(n - 1);\n    root.borrow_mut().right = build_tree(n - 1);\n    return Some(root);\n}\n
    space_complexity.c
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return NULL;\n    TreeNode *root = newTreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfun buildTree(n: Int): TreeNode? {\n    if (n == 0)\n        return null\n    val root = TreeNode(0)\n    root.left = buildTree(n - 1)\n    root.right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09###\ndef build_tree(n)\n  return if n == 0\n\n  TreeNode.new.tap do |root|\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n  end\nend\n
    space_complexity.zig
    // \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\nfn buildTree(mem_allocator: std.mem.Allocator, n: i32) !?*inc.TreeNode(i32) {\n    if (n == 0) return null;\n    const root = try mem_allocator.create(inc.TreeNode(i32));\n    root.init(0);\n    root.left = try buildTree(mem_allocator, n - 1);\n    root.right = try buildTree(mem_allocator, n - 1);\n    return root;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-19 \u00a0 Full binary tree generating exponential order space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#5-logarithmic-order-olog-n","title":"5. \u00a0 Logarithmic order \\(O(\\log n)\\)","text":"

    Logarithmic order is common in divide-and-conquer algorithms. For example, in merge sort, an array of length \\(n\\) is recursively divided in half each round, forming a recursion tree of height \\(\\log n\\), using \\(O(\\log n)\\) stack frame space.

    Another example is converting a number to a string. Given a positive integer \\(n\\), its number of digits is \\(\\log_{10} n + 1\\), corresponding to the length of the string, thus the space complexity is \\(O(\\log_{10} n + 1) = O(\\log n)\\).

    "},{"location":"chapter_computational_complexity/space_complexity/#244-balancing-time-and-space","title":"2.4.4 \u00a0 Balancing time and space","text":"

    Ideally, we aim for both time complexity and space complexity to be optimal. However, in practice, optimizing both simultaneously is often difficult.

    Lowering time complexity usually comes at the cost of increased space complexity, and vice versa. The approach of sacrificing memory space to improve algorithm speed is known as \"space-time tradeoff\"; the reverse is known as \"time-space tradeoff\".

    The choice depends on which aspect we value more. In most cases, time is more precious than space, so \"space-time tradeoff\" is often the more common strategy. Of course, controlling space complexity is also very important when dealing with large volumes of data.

    "},{"location":"chapter_computational_complexity/summary/","title":"2.5 \u00a0 Summary","text":""},{"location":"chapter_computational_complexity/summary/#1-key-review","title":"1. \u00a0 Key review","text":"

    Algorithm Efficiency Assessment

    • Time efficiency and space efficiency are the two main criteria for assessing the merits of an algorithm.
    • We can assess algorithm efficiency through actual testing, but it's challenging to eliminate the influence of the test environment, and it consumes substantial computational resources.
    • Complexity analysis can overcome the disadvantages of actual testing. Its results are applicable across all operating platforms and can reveal the efficiency of algorithms at different data scales.

    Time Complexity

    • Time complexity measures the trend of an algorithm's running time with the increase in data volume, effectively assessing algorithm efficiency. However, it can fail in certain cases, such as with small input data volumes or when time complexities are the same, making it challenging to precisely compare the efficiency of algorithms.
    • Worst-case time complexity is denoted using big O notation, representing the asymptotic upper bound, reflecting the growth level of the number of operations \\(T(n)\\) as \\(n\\) approaches infinity.
    • Calculating time complexity involves two steps: first counting the number of operations, then determining the asymptotic upper bound.
    • Common time complexities, arranged from low to high, include \\(O(1)\\), \\(O(\\log n)\\), \\(O(n)\\), \\(O(n \\log n)\\), \\(O(n^2)\\), \\(O(2^n)\\), and \\(O(n!)\\), among others.
    • The time complexity of some algorithms is not fixed and depends on the distribution of input data. Time complexities are divided into worst, best, and average cases. The best case is rarely used because input data generally needs to meet strict conditions to achieve the best case.
    • Average time complexity reflects the efficiency of an algorithm under random data inputs, closely resembling the algorithm's performance in actual applications. Calculating average time complexity requires accounting for the distribution of input data and the subsequent mathematical expectation.

    Space Complexity

    • Space complexity, similar to time complexity, measures the trend of memory space occupied by an algorithm with the increase in data volume.
    • The relevant memory space used during the algorithm's execution can be divided into input space, temporary space, and output space. Generally, input space is not included in space complexity calculations. Temporary space can be divided into temporary data, stack frame space, and instruction space, where stack frame space usually affects space complexity only in recursive functions.
    • We usually focus only on the worst-case space complexity, which means calculating the space complexity of the algorithm under the worst input data and at the worst moment of operation.
    • Common space complexities, arranged from low to high, include \\(O(1)\\), \\(O(\\log n)\\), \\(O(n)\\), \\(O(n^2)\\), and \\(O(2^n)\\), among others.
    "},{"location":"chapter_computational_complexity/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is the space complexity of tail recursion \\(O(1)\\)?

    Theoretically, the space complexity of a tail-recursive function can be optimized to \\(O(1)\\). However, most programming languages (such as Java, Python, C++, Go, C#) do not support automatic optimization of tail recursion, so it's generally considered to have a space complexity of \\(O(n)\\).

    Q: What is the difference between the terms \"function\" and \"method\"?

    A \"function\" can be executed independently, with all parameters passed explicitly. A \"method\" is associated with an object and is implicitly passed to the object calling it, able to operate on the data contained within an instance of a class.

    Here are some examples from common programming languages:

    • C is a procedural programming language without object-oriented concepts, so it only has functions. However, we can simulate object-oriented programming by creating structures (struct), and functions associated with these structures are equivalent to methods in other programming languages.
    • Java and C# are object-oriented programming languages where code blocks (methods) are typically part of a class. Static methods behave like functions because they are bound to the class and cannot access specific instance variables.
    • C++ and Python support both procedural programming (functions) and object-oriented programming (methods).

    Q: Does the \"Common Types of Space Complexity\" figure reflect the absolute size of occupied space?

    No, the figure shows space complexities, which reflect growth trends, not the absolute size of the occupied space.

    If you take \\(n = 8\\), you might find that the values of each curve don't correspond to their functions. This is because each curve includes a constant term, intended to compress the value range into a visually comfortable range.

    In practice, since we usually don't know the \"constant term\" complexity of each method, it's generally not possible to choose the best solution for \\(n = 8\\) based solely on complexity. However, for \\(n = 8^5\\), it's much easier to choose, as the growth trend becomes dominant.

    "},{"location":"chapter_computational_complexity/time_complexity/","title":"2.3 \u00a0 Time complexity","text":"

    Time complexity is a concept used to measure how the run time of an algorithm increases with the size of the input data. Understanding time complexity is crucial for accurately assessing the efficiency of an algorithm.

    1. Determining the Running Platform: This includes hardware configuration, programming language, system environment, etc., all of which can affect the efficiency of code execution.
    2. Evaluating the Run Time for Various Computational Operations: For instance, an addition operation + might take 1 ns, a multiplication operation * might take 10 ns, a print operation print() might take 5 ns, etc.
    3. Counting All the Computational Operations in the Code: Summing the execution times of all these operations gives the total run time.

    For example, consider the following code with an input size of \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    # Under an operating platform\ndef algorithm(n: int):\n    a = 2      # 1 ns\n    a = a + 1  # 1 ns\n    a = a * 2  # 10 ns\n    # Cycle n times\n    for _ in range(n):  # 1 ns\n        print(0)        # 5 ns\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {  // 1 ns , every round i++ is executed\n        cout << 0 << endl;         // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {  // 1 ns , every round i++ is executed\n        System.out.println(0);     // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid Algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {  // 1 ns , every round i++ is executed\n        Console.WriteLine(0);      // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunc algorithm(n int) {\n    a := 2     // 1 ns\n    a = a + 1  // 1 ns\n    a = a * 2  // 10 ns\n    // Loop n times\n    for i := 0; i < n; i++ {  // 1 ns\n        fmt.Println(a)        // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunc algorithm(n: Int) {\n    var a = 2 // 1 ns\n    a = a + 1 // 1 ns\n    a = a * 2 // 10 ns\n    // Loop n times\n    for _ in 0 ..< n { // 1 ns\n        print(0) // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunction algorithm(n) {\n    var a = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // Loop n times\n    for(let i = 0; i < n; i++) { // 1 ns , every round i++ is executed\n        console.log(0); // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunction algorithm(n: number): void {\n    var a: number = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // Loop n times\n    for(let i = 0; i < n; i++) { // 1 ns , every round i++ is executed\n        console.log(0); // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n  int a = 2; // 1 ns\n  a = a + 1; // 1 ns\n  a = a * 2; // 10 ns\n  // Loop n times\n  for (int i = 0; i < n; i++) { // 1 ns , every round i++ is executed\n    print(0); // 5 ns\n  }\n}\n
    // Under a particular operating platform\nfn algorithm(n: i32) {\n    let mut a = 2;      // 1 ns\n    a = a + 1;          // 1 ns\n    a = a * 2;          // 10 ns\n    // Loop n times\n    for _ in 0..n {     // 1 ns for each round i++\n        println!(\"{}\", 0);  // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {   // 1 ns , every round i++ is executed\n        printf(\"%d\", 0);            // 5 ns\n    }\n}\n
    \n
    // Under a particular operating platform\nfn algorithm(n: usize) void {\n    var a: i32 = 2; // 1 ns\n    a += 1; // 1 ns\n    a *= 2; // 10 ns\n    // Loop n times\n    for (0..n) |_| { // 1 ns\n        std.debug.print(\"{}\\n\", .{0}); // 5 ns\n    }\n}\n

    Using the above method, the run time of the algorithm can be calculated as \\((6n + 12)\\) ns:

    \\[ 1 + 1 + 10 + (1 + 5) \\times n = 6n + 12 \\]

    However, in practice, counting the run time of an algorithm is neither practical nor reasonable. First, we don't want to tie the estimated time to the running platform, as algorithms need to run on various platforms. Second, it's challenging to know the run time for each type of operation, making the estimation process difficult.

    "},{"location":"chapter_computational_complexity/time_complexity/#231-assessing-time-growth-trend","title":"2.3.1 \u00a0 Assessing time growth trend","text":"

    Time complexity analysis does not count the algorithm's run time, but rather the growth trend of the run time as the data volume increases.

    Let's understand this concept of \"time growth trend\" with an example. Assume the input data size is \\(n\\), and consider three algorithms A, B, and C:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    # Time complexity of algorithm A: constant order\ndef algorithm_A(n: int):\n    print(0)\n# Time complexity of algorithm B: linear order\ndef algorithm_B(n: int):\n    for _ in range(n):\n        print(0)\n# Time complexity of algorithm C: constant order\ndef algorithm_C(n: int):\n    for _ in range(1000000):\n        print(0)\n
    // Time complexity of algorithm A: constant order\nvoid algorithm_A(int n) {\n    cout << 0 << endl;\n}\n// Time complexity of algorithm B: linear order\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        cout << 0 << endl;\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        cout << 0 << endl;\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid algorithm_A(int n) {\n    System.out.println(0);\n}\n// Time complexity of algorithm B: linear order\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        System.out.println(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        System.out.println(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid AlgorithmA(int n) {\n    Console.WriteLine(0);\n}\n// Time complexity of algorithm B: linear order\nvoid AlgorithmB(int n) {\n    for (int i = 0; i < n; i++) {\n        Console.WriteLine(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid AlgorithmC(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        Console.WriteLine(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunc algorithm_A(n int) {\n    fmt.Println(0)\n}\n// Time complexity of algorithm B: linear order\nfunc algorithm_B(n int) {\n    for i := 0; i < n; i++ {\n        fmt.Println(0)\n    }\n}\n// Time complexity of algorithm C: constant order\nfunc algorithm_C(n int) {\n    for i := 0; i < 1000000; i++ {\n        fmt.Println(0)\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunc algorithmA(n: Int) {\n    print(0)\n}\n\n// Time complexity of algorithm B: linear order\nfunc algorithmB(n: Int) {\n    for _ in 0 ..< n {\n        print(0)\n    }\n}\n\n// Time complexity of algorithm C: constant order\nfunc algorithmC(n: Int) {\n    for _ in 0 ..< 1_000_000 {\n        print(0)\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunction algorithm_A(n) {\n    console.log(0);\n}\n// Time complexity of algorithm B: linear order\nfunction algorithm_B(n) {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nfunction algorithm_C(n) {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunction algorithm_A(n: number): void {\n    console.log(0);\n}\n// Time complexity of algorithm B: linear order\nfunction algorithm_B(n: number): void {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nfunction algorithm_C(n: number): void {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid algorithmA(int n) {\n  print(0);\n}\n// Time complexity of algorithm B: linear order\nvoid algorithmB(int n) {\n  for (int i = 0; i < n; i++) {\n    print(0);\n  }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithmC(int n) {\n  for (int i = 0; i < 1000000; i++) {\n    print(0);\n  }\n}\n
    // Time complexity of algorithm A: constant order\nfn algorithm_A(n: i32) {\n    println!(\"{}\", 0);\n}\n// Time complexity of algorithm B: linear order\nfn algorithm_B(n: i32) {\n    for _ in 0..n {\n        println!(\"{}\", 0);\n    }\n}\n// Time complexity of algorithm C: constant order\nfn algorithm_C(n: i32) {\n    for _ in 0..1000000 {\n        println!(\"{}\", 0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid algorithm_A(int n) {\n    printf(\"%d\", 0);\n}\n// Time complexity of algorithm B: linear order\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        printf(\"%d\", 0);\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        printf(\"%d\", 0);\n    }\n}\n
    \n
    // Time complexity of algorithm A: constant order\nfn algorithm_A(n: usize) void {\n    _ = n;\n    std.debug.print(\"{}\\n\", .{0});\n}\n// Time complexity of algorithm B: linear order\nfn algorithm_B(n: i32) void {\n    for (0..n) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n// Time complexity of algorithm C: constant order\nfn algorithm_C(n: i32) void {\n    _ = n;\n    for (0..1000000) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n

    The following figure shows the time complexities of these three algorithms.

    • Algorithm A has just one print operation, and its run time does not grow with \\(n\\). Its time complexity is considered \"constant order.\"
    • Algorithm B involves a print operation looping \\(n\\) times, and its run time grows linearly with \\(n\\). Its time complexity is \"linear order.\"
    • Algorithm C has a print operation looping 1,000,000 times. Although it takes a long time, it is independent of the input data size \\(n\\). Therefore, the time complexity of C is the same as A, which is \"constant order.\"

    Figure 2-7 \u00a0 Time growth trend of algorithms a, b, and c

    Compared to directly counting the run time of an algorithm, what are the characteristics of time complexity analysis?

    • Time complexity effectively assesses algorithm efficiency. For instance, algorithm B has linearly growing run time, which is slower than algorithm A when \\(n > 1\\) and slower than C when \\(n > 1,000,000\\). In fact, as long as the input data size \\(n\\) is sufficiently large, a \"constant order\" complexity algorithm will always be better than a \"linear order\" one, demonstrating the essence of time growth trend.
    • Time complexity analysis is more straightforward. Obviously, the running platform and the types of computational operations are irrelevant to the trend of run time growth. Therefore, in time complexity analysis, we can simply treat the execution time of all computational operations as the same \"unit time,\" simplifying the \"computational operation run time count\" to a \"computational operation count.\" This significantly reduces the complexity of estimation.
    • Time complexity has its limitations. For example, although algorithms A and C have the same time complexity, their actual run times can be quite different. Similarly, even though algorithm B has a higher time complexity than C, it is clearly superior when the input data size \\(n\\) is small. In these cases, it's difficult to judge the efficiency of algorithms based solely on time complexity. Nonetheless, despite these issues, complexity analysis remains the most effective and commonly used method for evaluating algorithm efficiency.
    "},{"location":"chapter_computational_complexity/time_complexity/#232-asymptotic-upper-bound","title":"2.3.2 \u00a0 Asymptotic upper bound","text":"

    Consider a function with an input size of \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def algorithm(n: int):\n    a = 1      # +1\n    a = a + 1  # +1\n    a = a * 2  # +1\n    # Cycle n times\n    for i in range(n):  # +1\n        print(0)        # +1\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) { // +1 (execute i ++ every round)\n        cout << 0 << endl;    // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) { // +1 (execute i ++ every round)\n        System.out.println(0);    // +1\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) {   // +1 (execute i ++ every round)\n        Console.WriteLine(0);   // +1\n    }\n}\n
    func algorithm(n int) {\n    a := 1      // +1\n    a = a + 1   // +1\n    a = a * 2   // +1\n    // Loop n times\n    for i := 0; i < n; i++ {   // +1\n        fmt.Println(a)         // +1\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +1\n    a = a + 1 // +1\n    a = a * 2 // +1\n    // Loop n times\n    for _ in 0 ..< n { // +1\n        print(0) // +1\n    }\n}\n
    function algorithm(n) {\n    var a = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // Loop n times\n    for(let i = 0; i < n; i++){ // +1 (execute i ++ every round)\n        console.log(0); // +1\n    }\n}\n
    function algorithm(n: number): void{\n    var a: number = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // Loop n times\n    for(let i = 0; i < n; i++){ // +1 (execute i ++ every round)\n        console.log(0); // +1\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +1\n  a = a + 1; // +1\n  a = a * 2; // +1\n  // Loop n times\n  for (int i = 0; i < n; i++) { // +1 (execute i ++ every round)\n    print(0); // +1\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;   // +1\n    a = a + 1;      // +1\n    a = a * 2;      // +1\n\n    // Loop n times\n    for _ in 0..n { // +1 (execute i ++ every round)\n        println!(\"{}\", 0); // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) {   // +1 (execute i ++ every round)\n        printf(\"%d\", 0);            // +1\n    }\n} \n
    \n
    fn algorithm(n: usize) void {\n    var a: i32 = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // Loop n times\n    for (0..n) |_| { // +1 (execute i ++ every round)\n        std.debug.print(\"{}\\n\", .{0}); // +1\n    }\n}\n

    Given a function that represents the number of operations of an algorithm as a function of the input size \\(n\\), denoted as \\(T(n)\\), consider the following example:

    \\[ T(n) = 3 + 2n \\]

    Since \\(T(n)\\) is a linear function, its growth trend is linear, and therefore, its time complexity is of linear order, denoted as \\(O(n)\\). This mathematical notation, known as \"big-O notation,\" represents the \"asymptotic upper bound\" of the function \\(T(n)\\).

    In essence, time complexity analysis is about finding the asymptotic upper bound of the \"number of operations \\(T(n)\\)\". It has a precise mathematical definition.

    Asymptotic Upper Bound

    If there exist positive real numbers \\(c\\) and \\(n_0\\) such that for all \\(n > n_0\\), \\(T(n) \\leq c \\cdot f(n)\\), then \\(f(n)\\) is considered an asymptotic upper bound of \\(T(n)\\), denoted as \\(T(n) = O(f(n))\\).

    As illustrated below, calculating the asymptotic upper bound involves finding a function \\(f(n)\\) such that, as \\(n\\) approaches infinity, \\(T(n)\\) and \\(f(n)\\) have the same growth order, differing only by a constant factor \\(c\\).

    Figure 2-8 \u00a0 Asymptotic upper bound of a function

    "},{"location":"chapter_computational_complexity/time_complexity/#233-calculation-method","title":"2.3.3 \u00a0 Calculation method","text":"

    While the concept of asymptotic upper bound might seem mathematically dense, you don't need to fully grasp it right away. Let's first understand the method of calculation, which can be practiced and comprehended over time.

    Once \\(f(n)\\) is determined, we obtain the time complexity \\(O(f(n))\\). But how do we determine the asymptotic upper bound \\(f(n)\\)? This process generally involves two steps: counting the number of operations and determining the asymptotic upper bound.

    "},{"location":"chapter_computational_complexity/time_complexity/#1-step-1-counting-the-number-of-operations","title":"1. \u00a0 Step 1: counting the number of operations","text":"

    This step involves going through the code line by line. However, due to the presence of the constant \\(c\\) in \\(c \\cdot f(n)\\), all coefficients and constant terms in \\(T(n)\\) can be ignored. This principle allows for simplification techniques in counting operations.

    1. Ignore constant terms in \\(T(n)\\), as they do not affect the time complexity being independent of \\(n\\).
    2. Omit all coefficients. For example, looping \\(2n\\), \\(5n + 1\\) times, etc., can be simplified to \\(n\\) times since the coefficient before \\(n\\) does not impact the time complexity.
    3. Use multiplication for nested loops. The total number of operations equals the product of the number of operations in each loop, applying the simplification techniques from points 1 and 2 for each loop level.

    Given a function, we can use these techniques to count operations:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def algorithm(n: int):\n    a = 1      # +0 (trick 1)\n    a = a + n  # +0 (trick 1)\n    # +n (technique 2)\n    for i in range(5 * n + 1):\n        print(0)\n    # +n*n (technique 3)\n    for i in range(2 * n):\n        for j in range(n + 1):\n            print(0)\n
    void algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        cout << 0 << endl;\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            cout << 0 << endl;\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        System.out.println(0);\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            System.out.println(0);\n        }\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        Console.WriteLine(0);\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            Console.WriteLine(0);\n        }\n    }\n}\n
    func algorithm(n int) {\n    a := 1     // +0 (trick 1)\n    a = a + n  // +0 (trick 1)\n    // +n (technique 2)\n    for i := 0; i < 5 * n + 1; i++ {\n        fmt.Println(0)\n    }\n    // +n*n (technique 3)\n    for i := 0; i < 2 * n; i++ {\n        for j := 0; j < n + 1; j++ {\n            fmt.Println(0)\n        }\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +0 (trick 1)\n    a = a + n // +0 (trick 1)\n    // +n (technique 2)\n    for _ in 0 ..< (5 * n + 1) {\n        print(0)\n    }\n    // +n*n (technique 3)\n    for _ in 0 ..< (2 * n) {\n        for _ in 0 ..< (n + 1) {\n            print(0)\n        }\n    }\n}\n
    function algorithm(n) {\n    let a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n (technique 3)\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    function algorithm(n: number): void {\n    let a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n (technique 3)\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +0 (trick 1)\n  a = a + n; // +0 (trick 1)\n  // +n (technique 2)\n  for (int i = 0; i < 5 * n + 1; i++) {\n    print(0);\n  }\n  // +n*n (technique 3)\n  for (int i = 0; i < 2 * n; i++) {\n    for (int j = 0; j < n + 1; j++) {\n      print(0);\n    }\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;     // +0 (trick 1)\n    a = a + n;        // +0 (trick 1)\n\n    // +n (technique 2)\n    for i in 0..(5 * n + 1) {\n        println!(\"{}\", 0);\n    }\n\n    // +n*n (technique 3)\n    for i in 0..(2 * n) {\n        for j in 0..(n + 1) {\n            println!(\"{}\", 0);\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        printf(\"%d\", 0);\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            printf(\"%d\", 0);\n        }\n    }\n}\n
    \n
    fn algorithm(n: usize) void {\n    var a: i32 = 1;     // +0 (trick 1)\n    a = a + @as(i32, @intCast(n));        // +0 (trick 1)\n\n    // +n (technique 2)\n    for(0..(5 * n + 1)) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n\n    // +n*n (technique 3)\n    for(0..(2 * n)) |_| {\n        for(0..(n + 1)) |_| {\n            std.debug.print(\"{}\\n\", .{0});\n        }\n    }\n}\n

    The formula below shows the counting results before and after simplification, both leading to a time complexity of \\(O(n^2)\\):

    \\[ \\begin{aligned} T(n) & = 2n(n + 1) + (5n + 1) + 2 & \\text{Complete Count (-.-|||)} \\newline & = 2n^2 + 7n + 3 \\newline T(n) & = n^2 + n & \\text{Simplified Count (o.O)} \\end{aligned} \\]"},{"location":"chapter_computational_complexity/time_complexity/#2-step-2-determining-the-asymptotic-upper-bound","title":"2. \u00a0 Step 2: determining the asymptotic upper bound","text":"

    The time complexity is determined by the highest order term in \\(T(n)\\). This is because, as \\(n\\) approaches infinity, the highest order term dominates, rendering the influence of other terms negligible.

    The following table illustrates examples of different operation counts and their corresponding time complexities. Some exaggerated values are used to emphasize that coefficients cannot alter the order of growth. When \\(n\\) becomes very large, these constants become insignificant.

    Table: Time complexity for different operation counts

    Operation Count \\(T(n)\\) Time Complexity \\(O(f(n))\\) \\(100000\\) \\(O(1)\\) \\(3n + 2\\) \\(O(n)\\) \\(2n^2 + 3n + 2\\) \\(O(n^2)\\) \\(n^3 + 10000n^2\\) \\(O(n^3)\\) \\(2^n + 10000n^{10000}\\) \\(O(2^n)\\)"},{"location":"chapter_computational_complexity/time_complexity/#234-common-types-of-time-complexity","title":"2.3.4 \u00a0 Common types of time complexity","text":"

    Let's consider the input data size as \\(n\\). The common types of time complexities are illustrated below, arranged from lowest to highest:

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n \\log n) < O(n^2) < O(2^n) < O(n!) \\newline \\text{Constant Order} < \\text{Logarithmic Order} < \\text{Linear Order} < \\text{Linear-Logarithmic Order} < \\text{Quadratic Order} < \\text{Exponential Order} < \\text{Factorial Order} \\end{aligned} \\]

    Figure 2-9 \u00a0 Common types of time complexity

    "},{"location":"chapter_computational_complexity/time_complexity/#1-constant-order-o1","title":"1. \u00a0 Constant order \\(O(1)\\)","text":"

    Constant order means the number of operations is independent of the input data size \\(n\\). In the following function, although the number of operations size might be large, the time complexity remains \\(O(1)\\) as it's unrelated to \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def constant(n: int) -> int:\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    count = 0\n    size = 100000\n    for _ in range(size):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u5e38\u6570\u9636 */\nint Constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u5e38\u6570\u9636 */\nfunc constant(n int) int {\n    count := 0\n    size := 100000\n    for i := 0; i < size; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e38\u6570\u9636 */\nfunc constant(n: Int) -> Int {\n    var count = 0\n    let size = 100_000\n    for _ in 0 ..< size {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u5e38\u6570\u9636 */\nfunction constant(n: number): number {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n  int count = 0;\n  int size = 100000;\n  for (var i = 0; i < size; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e38\u6570\u9636 */\nfn constant(n: i32) -> i32 {\n    _ = n;\n    let mut count = 0;\n    let size = 100_000;\n    for _ in 0..size {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    int i = 0;\n    for (int i = 0; i < size; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e38\u6570\u9636 */\nfun constant(n: Int): Int {\n    var count = 0\n    val size = 100000\n    for (i in 0..<size)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u5e38\u6570\u9636 ###\ndef constant(n)\n  count = 0\n  size = 100000\n\n  (0...size).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u5e38\u6570\u9636\nfn constant(n: i32) i32 {\n    _ = n;\n    var count: i32 = 0;\n    const size: i32 = 100_000;\n    var i: i32 = 0;\n    while(i<size) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_computational_complexity/time_complexity/#2-linear-order-on","title":"2. \u00a0 Linear order \\(O(n)\\)","text":"

    Linear order indicates the number of operations grows linearly with the input data size \\(n\\). Linear order commonly appears in single-loop structures:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    count = 0\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636 */\nint Linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc linear(n int) int {\n    count := 0\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) -> Int {\n    var count = 0\n    for _ in 0 ..< n {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): number {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n  int count = 0;\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636 */\nfn linear(n: i32) -> i32 {\n    let mut count = 0;\n    for _ in 0..n {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int): Int {\n    var count = 0\n    for (i in 0..<n)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  count = 0\n  (0...n).each { count += 1 }\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Operations like array traversal and linked list traversal have a time complexity of \\(O(n)\\), where \\(n\\) is the length of the array or list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def array_traversal(nums: list[int]) -> int:\n    \"\"\"\u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for num in nums:\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(vector<int> &nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint ArrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    foreach (int num in nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums []int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for range nums {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums: [Int]) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums: number[]): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(List<int> nums) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for (var _num in nums) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfn array_traversal(nums: &[i32]) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int *nums, int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfun arrayTraversal(nums: IntArray): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (num in nums) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09###\ndef array_traversal(nums)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for num in nums\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\nfn arrayTraversal(nums: []i32) i32 {\n    var count: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (nums) |_| {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    It's important to note that the input data size \\(n\\) should be determined based on the type of input data. For example, in the first example, \\(n\\) represents the input data size, while in the second example, the length of the array \\(n\\) is the data size.

    "},{"location":"chapter_computational_complexity/time_complexity/#3-quadratic-order-on2","title":"3. \u00a0 Quadratic order \\(O(n^2)\\)","text":"

    Quadratic order means the number of operations grows quadratically with the input data size \\(n\\). Quadratic order typically appears in nested loops, where both the outer and inner loops have a time complexity of \\(O(n)\\), resulting in an overall complexity of \\(O(n^2)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def quadratic(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i in range(n):\n        for j in range(n):\n            count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636 */\nint Quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i := 0; i < n; i++ {\n        for j := 0; j < n; j++ {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0 ..< n {\n        for _ in 0 ..< n {\n            count += 1\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for (int i = 0; i < n; i++) {\n    for (int j = 0; j < n; j++) {\n      count++;\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636 */\nfn quadratic(n: i32) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0..n {\n        for _ in 0..n {\n            count += 1;\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (i in 0..<n) {\n        for (j in 0..<n) {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for i in 0...n\n    for j in 0...n\n      count += 1\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            count += 1;\n        }\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    The following image compares constant order, linear order, and quadratic order time complexities.

    Figure 2-10 \u00a0 Constant, linear, and quadratic order time complexities

    For instance, in bubble sort, the outer loop runs \\(n - 1\\) times, and the inner loop runs \\(n-1\\), \\(n-2\\), ..., \\(2\\), \\(1\\) times, averaging \\(n / 2\\) times, resulting in a time complexity of \\(O((n - 1) n / 2) = O(n^2)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def bubble_sort(nums: list[int]) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\"\"\"\n    count = 0  # \u8ba1\u6570\u5668\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(len(nums) - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp: int = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3  # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(vector<int> &nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int[] nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint BubbleSort(int[] nums) {\n    int count = 0;  // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums []int) int {\n    count := 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp := nums[j]\n                nums[j] = nums[j+1]\n                nums[j+1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums: inout [Int]) -> Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums) {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums: number[]): number {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(List<int> nums) {\n  int count = 0; // \u8ba1\u6570\u5668\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (var i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (var j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      }\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfn bubble_sort(nums: &mut [i32]) -> i32 {\n    let mut count = 0; // \u8ba1\u6570\u5668\n\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int *nums, int n) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = n - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfun bubbleSort(nums: IntArray): Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09###\ndef bubble_sort(nums)\n  count = 0  # \u8ba1\u6570\u5668\n\n  # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for i in (nums.length - 1).downto(0)\n    # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for j in 0...i\n      if nums[j] > nums[j + 1]\n        # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        tmp = nums[j]\n        nums[j] = nums[j + 1]\n        nums[j + 1] = tmp\n        count += 3 # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      end\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\nfn bubbleSort(nums: []i32) i32 {\n    var count: i32 = 0;  // \u8ba1\u6570\u5668 \n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: i32 = @as(i32, @intCast(nums.len)) - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_computational_complexity/time_complexity/#4-exponential-order-o2n","title":"4. \u00a0 Exponential order \\(O(2^n)\\)","text":"

    Biological \"cell division\" is a classic example of exponential order growth: starting with one cell, it becomes two after one division, four after two divisions, and so on, resulting in \\(2^n\\) cells after \\(n\\) divisions.

    The following image and code simulate the cell division process, with a time complexity of \\(O(2^n)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exponential(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    base = 1\n    # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in range(n):\n        for _ in range(base):\n            count += 1\n        base *= 2\n    # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Exponential(int n) {\n    int count = 0, bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc exponential(n int) int {\n    count, base := 0, 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for i := 0; i < n; i++ {\n        for j := 0; j < base; j++ {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc exponential(n: Int) -> Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0 ..< n {\n        for _ in 0 ..< base {\n            count += 1\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n) {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n: number): number {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n  int count = 0, base = 1;\n  // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  for (var i = 0; i < n; i++) {\n    for (var j = 0; j < base; j++) {\n      count++;\n    }\n    base *= 2;\n  }\n  // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  return count;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn exponential(n: i32) -> i32 {\n    let mut count = 0;\n    let mut base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0..n {\n        for _ in 0..base {\n            count += 1\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    count\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0;\n    int bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun exponential(n: Int): Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (i in 0..<n) {\n        for (j in 0..<base) {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef exponential(n)\n  count, base = 0, 1\n\n  # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  (0...n).each do\n    (0...base).each { count += 1 }\n    base *= 2\n  end\n\n  # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  count\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn exponential(n: i32) i32 {\n    var count: i32 = 0;\n    var bas: i32 = 1;\n    var i: i32 = 0;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < bas) : (j += 1) {\n            count += 1;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-11 \u00a0 Exponential order time complexity

    In practice, exponential order often appears in recursive functions. For example, in the code below, it recursively splits into two halves, stopping after \\(n\\) divisions:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exp_recur(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 1:\n        return 1\n    return exp_recur(n - 1) + exp_recur(n - 1) + 1\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint ExpRecur(int n) {\n    if (n == 1) return 1;\n    return ExpRecur(n - 1) + ExpRecur(n - 1) + 1;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc expRecur(n int) int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n-1) + expRecur(n-1) + 1\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc expRecur(n: Int) -> Int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n: n - 1) + expRecur(n: n - 1) + 1\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n) {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n: number): number {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n  if (n == 1) return 1;\n  return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn exp_recur(n: i32) -> i32 {\n    if n == 1 {\n        return 1;\n    }\n    exp_recur(n - 1) + exp_recur(n - 1) + 1\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun expRecur(n: Int): Int {\n    if (n == 1) {\n        return 1\n    }\n    return expRecur(n - 1) + expRecur(n - 1) + 1\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef exp_recur(n)\n  return 1 if n == 1\n  exp_recur(n - 1) + exp_recur(n - 1) + 1\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn expRecur(n: i32) i32 {\n    if (n == 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    Code Visualization

    Full Screen >

    Exponential order growth is extremely rapid and is commonly seen in exhaustive search methods (brute force, backtracking, etc.). For large-scale problems, exponential order is unacceptable, often requiring dynamic programming or greedy algorithms as solutions.

    "},{"location":"chapter_computational_complexity/time_complexity/#5-logarithmic-order-olog-n","title":"5. \u00a0 Logarithmic order \\(O(\\log n)\\)","text":"

    In contrast to exponential order, logarithmic order reflects situations where \"the size is halved each round.\" Given an input data size \\(n\\), since the size is halved each round, the number of iterations is \\(\\log_2 n\\), the inverse function of \\(2^n\\).

    The following image and code simulate the \"halving each round\" process, with a time complexity of \\(O(\\log_2 n)\\), commonly abbreviated as \\(O(\\log n)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def logarithmic(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    while n > 1:\n        n = n / 2\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n /= 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc logarithmic(n int) int {\n    count := 0\n    for n > 1 {\n        n = n / 2\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc logarithmic(n: Int) -> Int {\n    var count = 0\n    var n = n\n    while n > 1 {\n        n = n / 2\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n) {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n: number): number {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n  int count = 0;\n  while (n > 1) {\n    n = n ~/ 2;\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn logarithmic(mut n: i32) -> i32 {\n    let mut count = 0;\n    while n > 1 {\n        n = n / 2;\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun logarithmic(n: Int): Int {\n    var n1 = n\n    var count = 0\n    while (n1 > 1) {\n        n1 /= 2\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef logarithmic(n)\n  count = 0\n\n  while n > 1\n    n /= 2\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn logarithmic(n: i32) i32 {\n    var count: i32 = 0;\n    var n_var = n;\n    while (n_var > 1)\n    {\n        n_var = n_var / 2;\n        count +=1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-12 \u00a0 Logarithmic order time complexity

    Like exponential order, logarithmic order also frequently appears in recursive functions. The code below forms a recursive tree of height \\(\\log_2 n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def log_recur(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 1:\n        return 0\n    return log_recur(n / 2) + 1\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint LogRecur(int n) {\n    if (n <= 1) return 0;\n    return LogRecur(n / 2) + 1;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc logRecur(n int) int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n/2) + 1\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc logRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n: n / 2) + 1\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n) {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n: number): number {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n  if (n <= 1) return 0;\n  return logRecur(n ~/ 2) + 1;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 0;\n    }\n    log_recur(n / 2) + 1\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun logRecur(n: Int): Int {\n    if (n <= 1)\n        return 0\n    return logRecur(n / 2) + 1\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef log_recur(n)\n  return 0 unless n > 1\n  log_recur(n / 2) + 1\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn logRecur(n: i32) i32 {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    Code Visualization

    Full Screen >

    Logarithmic order is typical in algorithms based on the divide-and-conquer strategy, embodying the \"split into many\" and \"simplify complex problems\" approach. It's slow-growing and is the most ideal time complexity after constant order.

    What is the base of \\(O(\\log n)\\)?

    Technically, \"splitting into \\(m\\)\" corresponds to a time complexity of \\(O(\\log_m n)\\). Using the logarithm base change formula, we can equate different logarithmic complexities:

    \\[ O(\\log_m n) = O(\\log_k n / \\log_k m) = O(\\log_k n) \\]

    This means the base \\(m\\) can be changed without affecting the complexity. Therefore, we often omit the base \\(m\\) and simply denote logarithmic order as \\(O(\\log n)\\).

    "},{"location":"chapter_computational_complexity/time_complexity/#6-linear-logarithmic-order-on-log-n","title":"6. \u00a0 Linear-logarithmic order \\(O(n \\log n)\\)","text":"

    Linear-logarithmic order often appears in nested loops, with the complexities of the two loops being \\(O(\\log n)\\) and \\(O(n)\\) respectively. The related code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear_log_recur(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u5bf9\u6570\u9636\"\"\"\n    if n <= 1:\n        return 1\n    count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2)\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint LinearLogRecur(int n) {\n    if (n <= 1) return 1;\n    int count = LinearLogRecur(n / 2) + LinearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n int) int {\n    if n <= 1 {\n        return 1\n    }\n    count := linearLogRecur(n/2) + linearLogRecur(n/2)\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 1\n    }\n    var count = linearLogRecur(n: n / 2) + linearLogRecur(n: n / 2)\n    for _ in stride(from: 0, to: n, by: 1) {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n) {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n: number): number {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n  if (n <= 1) return 1;\n  int count = linearLogRecur(n ~/ 2) + linearLogRecur(n ~/ 2);\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfn linear_log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 1;\n    }\n    let mut count = linear_log_recur(n / 2) + linear_log_recur(n / 2);\n    for _ in 0..n as i32 {\n        count += 1;\n    }\n    return count;\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfun linearLogRecur(n: Int): Int {\n    if (n <= 1)\n        return 1\n    var count = linearLogRecur(n / 2) + linearLogRecur(n / 2)\n    for (i in 0..<n) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u5bf9\u6570\u9636 ###\ndef linear_log_recur(n)\n  return 1 unless n > 1\n\n  count = linear_log_recur(n / 2) + linear_log_recur(n / 2)\n  (0...n).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u5bf9\u6570\u9636\nfn linearLogRecur(n: i32) i32 {\n    if (n <= 1) return 1;\n    var count: i32 = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    The image below demonstrates how linear-logarithmic order is generated. Each level of a binary tree has \\(n\\) operations, and the tree has \\(\\log_2 n + 1\\) levels, resulting in a time complexity of \\(O(n \\log n)\\).

    Figure 2-13 \u00a0 Linear-logarithmic order time complexity

    Mainstream sorting algorithms typically have a time complexity of \\(O(n \\log n)\\), such as quicksort, mergesort, and heapsort.

    "},{"location":"chapter_computational_complexity/time_complexity/#7-factorial-order-on","title":"7. \u00a0 Factorial order \\(O(n!)\\)","text":"

    Factorial order corresponds to the mathematical problem of \"full permutation.\" Given \\(n\\) distinct elements, the total number of possible permutations is:

    \\[ n! = n \\times (n - 1) \\times (n - 2) \\times \\dots \\times 2 \\times 1 \\]

    Factorials are typically implemented using recursion. As shown in the image and code below, the first level splits into \\(n\\) branches, the second level into \\(n - 1\\) branches, and so on, stopping after the \\(n\\)th level:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def factorial_recur(n: int) -> int:\n    \"\"\"\u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 0:\n        return 1\n    count = 0\n    # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in range(n):\n        count += factorial_recur(n - 1)\n    return count\n
    time_complexity.cpp
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint FactorialRecur(int n) {\n    if (n == 0) return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += FactorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n int) int {\n    if n == 0 {\n        return 1\n    }\n    count := 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for i := 0; i < n; i++ {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n: Int) -> Int {\n    if n == 0 {\n        return 1\n    }\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0 ..< n {\n        count += factorialRecur(n: n - 1)\n    }\n    return count\n}\n
    time_complexity.js
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n) {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n: number): number {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n  if (n == 0) return 1;\n  int count = 0;\n  // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  for (var i = 0; i < n; i++) {\n    count += factorialRecur(n - 1);\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn factorial_recur(n: i32) -> i32 {\n    if n == 0 {\n        return 1;\n    }\n    let mut count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0..n {\n        count += factorial_recur(n - 1);\n    }\n    count\n}\n
    time_complexity.c
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun factorialRecur(n: Int): Int {\n    if (n == 0)\n        return 1\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (i in 0..<n) {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef factorial_recur(n)\n  return 1 if n == 0\n\n  count = 0\n  # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  (0...n).each { count += factorial_recur(n - 1) }\n\n  count\nend\n
    time_complexity.zig
    // \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn factorialRecur(n: i32) i32 {\n    if (n == 0) return 1;\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    while (i < n) : (i += 1) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-14 \u00a0 Factorial order time complexity

    Note that factorial order grows even faster than exponential order; it's unacceptable for larger \\(n\\) values.

    "},{"location":"chapter_computational_complexity/time_complexity/#235-worst-best-and-average-time-complexities","title":"2.3.5 \u00a0 Worst, best, and average time complexities","text":"

    The time efficiency of an algorithm is often not fixed but depends on the distribution of the input data. Assume we have an array nums of length \\(n\\), consisting of numbers from \\(1\\) to \\(n\\), each appearing only once, but in a randomly shuffled order. The task is to return the index of the element \\(1\\). We can draw the following conclusions:

    • When nums = [?, ?, ..., 1], that is, when the last element is \\(1\\), it requires a complete traversal of the array, achieving the worst-case time complexity of \\(O(n)\\).
    • When nums = [1, ?, ?, ...], that is, when the first element is \\(1\\), no matter the length of the array, no further traversal is needed, achieving the best-case time complexity of \\(\\Omega(1)\\).

    The \"worst-case time complexity\" corresponds to the asymptotic upper bound, denoted by the big \\(O\\) notation. Correspondingly, the \"best-case time complexity\" corresponds to the asymptotic lower bound, denoted by \\(\\Omega\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig worst_best_time_complexity.py
    def random_numbers(n: int) -> list[int]:\n    \"\"\"\u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71\"\"\"\n    # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n    nums = [i for i in range(1, n + 1)]\n    # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    random.shuffle(nums)\n    return nums\n\ndef find_one(nums: list[int]) -> int:\n    \"\"\"\u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\"\"\"\n    for i in range(len(nums)):\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1:\n            return i\n    return -1\n
    worst_best_time_complexity.cpp
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nvector<int> randomNumbers(int n) {\n    vector<int> nums(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u4f7f\u7528\u7cfb\u7edf\u65f6\u95f4\u751f\u6210\u968f\u673a\u79cd\u5b50\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    shuffle(nums.begin(), nums.end(), default_random_engine(seed));\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(vector<int> &nums) {\n    for (int i = 0; i < nums.size(); i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.java
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] randomNumbers(int n) {\n    Integer[] nums = new Integer[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    Collections.shuffle(Arrays.asList(nums));\n    // Integer[] -> int[]\n    int[] res = new int[n];\n    for (int i = 0; i < n; i++) {\n        res[i] = nums[i];\n    }\n    return res;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int[] nums) {\n    for (int i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.cs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] RandomNumbers(int n) {\n    int[] nums = new int[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = 0; i < nums.Length; i++) {\n        int index = new Random().Next(i, nums.Length);\n        (nums[i], nums[index]) = (nums[index], nums[i]);\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint FindOne(int[] nums) {\n    for (int i = 0; i < nums.Length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.go
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n int) []int {\n    nums := make([]int, n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for i := 0; i < n; i++ {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    rand.Shuffle(len(nums), func(i, j int) {\n        nums[i], nums[j] = nums[j], nums[i]\n    })\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums []int) int {\n    for i := 0; i < len(nums); i++ {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.swift
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n: Int) -> [Int] {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    var nums = Array(1 ... n)\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums: [Int]) -> Int {\n    for i in nums.indices {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.js
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n) {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums) {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.ts
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n: number): number[] {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums: number[]): number {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.dart
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nList<int> randomNumbers(int n) {\n  final nums = List.filled(n, 0);\n  // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n  for (var i = 0; i < n; i++) {\n    nums[i] = i + 1;\n  }\n  // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle();\n\n  return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(List<int> nums) {\n  for (var i = 0; i < nums.length; i++) {\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    if (nums[i] == 1) return i;\n  }\n\n  return -1;\n}\n
    worst_best_time_complexity.rs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfn random_numbers(n: i32) -> Vec<i32> {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    let mut nums = (1..=n).collect::<Vec<i32>>();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle(&mut thread_rng());\n    nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfn find_one(nums: &[i32]) -> Option<usize> {\n    for i in 0..nums.len() {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return Some(i);\n        }\n    }\n    None\n}\n
    worst_best_time_complexity.c
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint *randomNumbers(int n) {\n    // \u5206\u914d\u5806\u533a\u5185\u5b58\uff08\u521b\u5efa\u4e00\u7ef4\u53ef\u53d8\u957f\u6570\u7ec4\uff1a\u6570\u7ec4\u4e2d\u5143\u7d20\u6570\u91cf\u4e3a n \uff0c\u5143\u7d20\u7c7b\u578b\u4e3a int \uff09\n    int *nums = (int *)malloc(n * sizeof(int));\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = n - 1; i > 0; i--) {\n        int j = rand() % (i + 1);\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int *nums, int n) {\n    for (int i = 0; i < n; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.kt
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfun randomNumbers(n: Int): Array<Int?> {\n    val nums = IntArray(n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (i in 0..<n) {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    val res = arrayOfNulls<Int>(n)\n    for (i in 0..<n) {\n        res[i] = nums[i]\n    }\n    return res\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfun findOne(nums: Array<Int?>): Int {\n    for (i in nums.indices) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i\n    }\n    return -1\n}\n
    worst_best_time_complexity.rb
    ### \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71 ###\ndef random_numbers(n)\n  # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n  nums = Array.new(n) { |i| i + 1 }\n  # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle!\nend\n\n### \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 ###\ndef find_one(nums)\n  for i in 0...nums.length\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    return i if nums[i] == 1\n  end\n\n  -1\nend\n
    worst_best_time_complexity.zig
    // \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71\nfn randomNumbers(comptime n: usize) [n]i32 {\n    var nums: [n]i32 = undefined;\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (&nums, 0..) |*num, i| {\n        num.* = @as(i32, @intCast(i)) + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    const rand = std.crypto.random;\n    rand.shuffle(i32, &nums);\n    return nums;\n}\n\n// \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\nfn findOne(nums: []i32) i32 {\n    for (nums, 0..) |num, i| {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (num == 1) return @intCast(i);\n    }\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    It's important to note that the best-case time complexity is rarely used in practice, as it is usually only achievable under very low probabilities and might be misleading. The worst-case time complexity is more practical as it provides a safety value for efficiency, allowing us to confidently use the algorithm.

    From the above example, it's clear that both the worst-case and best-case time complexities only occur under \"special data distributions,\" which may have a small probability of occurrence and may not accurately reflect the algorithm's run efficiency. In contrast, the average time complexity can reflect the algorithm's efficiency under random input data, denoted by the \\(\\Theta\\) notation.

    For some algorithms, we can simply estimate the average case under a random data distribution. For example, in the aforementioned example, since the input array is shuffled, the probability of element \\(1\\) appearing at any index is equal. Therefore, the average number of loops for the algorithm is half the length of the array \\(n / 2\\), giving an average time complexity of \\(\\Theta(n / 2) = \\Theta(n)\\).

    However, calculating the average time complexity for more complex algorithms can be quite difficult, as it's challenging to analyze the overall mathematical expectation under the data distribution. In such cases, we usually use the worst-case time complexity as the standard for judging the efficiency of the algorithm.

    Why is the \\(\\Theta\\) symbol rarely seen?

    Possibly because the \\(O\\) notation is more commonly spoken, it is often used to represent the average time complexity. However, strictly speaking, this practice is not accurate. In this book and other materials, if you encounter statements like \"average time complexity \\(O(n)\\)\", please understand it directly as \\(\\Theta(n)\\).

    "},{"location":"chapter_data_structure/","title":"Chapter 3. \u00a0 Data structures","text":"

    Abstract

    Data structures serve as a robust and diverse framework.

    They offer a blueprint for the orderly organization of data, upon which algorithms come to life.

    "},{"location":"chapter_data_structure/#chapter-contents","title":"Chapter contents","text":"
    • 3.1 \u00a0 Classification of data structures
    • 3.2 \u00a0 Basic data types
    • 3.3 \u00a0 Number encoding *
    • 3.4 \u00a0 Character encoding *
    • 3.5 \u00a0 Summary
    "},{"location":"chapter_data_structure/basic_data_types/","title":"3.2 \u00a0 Basic data types","text":"

    When discussing data in computers, various forms like text, images, videos, voice and 3D models comes to mind. Despite their different organizational forms, they are all composed of various basic data types.

    Basic data types are those that the CPU can directly operate on and are directly used in algorithms, mainly including the following.

    • Integer types: byte, short, int, long.
    • Floating-point types: float, double, used to represent decimals.
    • Character type: char, used to represent letters, punctuation, and even emojis in various languages.
    • Boolean type: bool, used to represent \"yes\" or \"no\" decisions.

    Basic data types are stored in computers in binary form. One binary digit is 1 bit. In most modern operating systems, 1 byte consists of 8 bits.

    The range of values for basic data types depends on the size of the space they occupy. Below, we take Java as an example.

    • The integer type byte occupies 1 byte = 8 bits and can represent \\(2^8\\) numbers.
    • The integer type int occupies 4 bytes = 32 bits and can represent \\(2^{32}\\) numbers.

    The following table lists the space occupied, value range, and default values of various basic data types in Java. While memorizing this table isn't necessary, having a general understanding of it and referencing it when required is recommended.

    Table 3-1 \u00a0 Space occupied and value range of basic data types

    Type Symbol Space Occupied Minimum Value Maximum Value Default Value Integer byte 1 byte \\(-2^7\\) (\\(-128\\)) \\(2^7 - 1\\) (\\(127\\)) 0 short 2 bytes \\(-2^{15}\\) \\(2^{15} - 1\\) 0 int 4 bytes \\(-2^{31}\\) \\(2^{31} - 1\\) 0 long 8 bytes \\(-2^{63}\\) \\(2^{63} - 1\\) 0 Float float 4 bytes \\(1.175 \\times 10^{-38}\\) \\(3.403 \\times 10^{38}\\) \\(0.0\\text{f}\\) double 8 bytes \\(2.225 \\times 10^{-308}\\) \\(1.798 \\times 10^{308}\\) 0.0 Char char 2 bytes 0 \\(2^{16} - 1\\) 0 Boolean bool 1 byte \\(\\text{false}\\) \\(\\text{true}\\) \\(\\text{false}\\)

    Please note that the above table is specific to Java's basic data types. Every programming language has its own data type definitions, which might differ in space occupied, value ranges, and default values.

    • In Python, the integer type int can be of any size, limited only by available memory; the floating-point float is double precision 64-bit; there is no char type, as a single character is actually a string str of length 1.
    • C and C++ do not specify the size of basic data types, it varies with implementation and platform. The above table follows the LP64 data model, used for Unix 64-bit operating systems including Linux and macOS.
    • The size of char in C and C++ is 1 byte, while in most programming languages, it depends on the specific character encoding method, as detailed in the \"Character Encoding\" chapter.
    • Even though representing a boolean only requires 1 bit (0 or 1), it is usually stored in memory as 1 byte. This is because modern computer CPUs typically use 1 byte as the smallest addressable memory unit.

    So, what is the connection between basic data types and data structures? We know that data structures are ways to organize and store data in computers. The focus here is on \"structure\" rather than \"data\".

    If we want to represent \"a row of numbers\", we naturally think of using an array. This is because the linear structure of an array can represent the adjacency and the ordering of the numbers, but whether the stored content is an integer int, a decimal float, or a character char, is irrelevant to the \"data structure\".

    In other words, basic data types provide the \"content type\" of data, while data structures provide the \"way of organizing\" data. For example, in the following code, we use the same data structure (array) to store and represent different basic data types, including int, float, char, bool, etc.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    # Using various basic data types to initialize arrays\nnumbers: list[int] = [0] * 5\ndecimals: list[float] = [0.0] * 5\n# Python's characters are actually strings of length 1\ncharacters: list[str] = ['0'] * 5\nbools: list[bool] = [False] * 5\n# Python's lists can freely store various basic data types and object references\ndata = [0, 0.0, 'a', False, ListNode(0)]\n
    // Using various basic data types to initialize arrays\nint numbers[5];\nfloat decimals[5];\nchar characters[5];\nbool bools[5];\n
    // Using various basic data types to initialize arrays\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nboolean[] bools = new boolean[5];\n
    // Using various basic data types to initialize arrays\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nbool[] bools = new bool[5];\n
    // Using various basic data types to initialize arrays\nvar numbers = [5]int{}\nvar decimals = [5]float64{}\nvar characters = [5]byte{}\nvar bools = [5]bool{}\n
    // Using various basic data types to initialize arrays\nlet numbers = Array(repeating: 0, count: 5)\nlet decimals = Array(repeating: 0.0, count: 5)\nlet characters: [Character] = Array(repeating: \"a\", count: 5)\nlet bools = Array(repeating: false, count: 5)\n
    // JavaScript's arrays can freely store various basic data types and objects\nconst array = [0, 0.0, 'a', false];\n
    // Using various basic data types to initialize arrays\nconst numbers: number[] = [];\nconst characters: string[] = [];\nconst bools: boolean[] = [];\n
    // Using various basic data types to initialize arrays\nList<int> numbers = List.filled(5, 0);\nList<double> decimals = List.filled(5, 0.0);\nList<String> characters = List.filled(5, 'a');\nList<bool> bools = List.filled(5, false);\n
    // Using various basic data types to initialize arrays\nlet numbers: Vec<i32> = vec![0; 5];\nlet decimals: Vec<f32> = vec![0.0, 5];\nlet characters: Vec<char> = vec!['0'; 5];\nlet bools: Vec<bool> = vec![false; 5];\n
    // Using various basic data types to initialize arrays\nint numbers[10];\nfloat decimals[10];\nchar characters[10];\nbool bools[10];\n
    \n
    // Using various basic data types to initialize arrays\nvar numbers: [5]i32 = undefined;\nvar decimals: [5]f32 = undefined;\nvar characters: [5]u8 = undefined;\nvar bools: [5]bool = undefined;\n
    "},{"location":"chapter_data_structure/character_encoding/","title":"3.4 \u00a0 Character encoding *","text":"

    In the computer system, all data is stored in binary form, and characters (represented by char) are no exception. To represent characters, we need to develop a \"character set\" that defines a one-to-one mapping between each character and binary numbers. With the character set, computers can convert binary numbers to characters by looking up the table.

    "},{"location":"chapter_data_structure/character_encoding/#341-ascii-character-set","title":"3.4.1 \u00a0 ASCII character set","text":"

    The \"ASCII code\" is one of the earliest character sets, officially known as the American Standard Code for Information Interchange. It uses 7 binary digits (the lower 7 bits of a byte) to represent a character, allowing for a maximum of 128 different characters. As shown in the Figure 3-6 , ASCII includes uppercase and lowercase English letters, numbers 0 ~ 9, various punctuation marks, and certain control characters (such as newline and tab).

    Figure 3-6 \u00a0 ASCII code

    However, ASCII can only represent English characters. With the globalization of computers, a character set called \"EASCII\" was developed to represent more languages. It expands from the 7-bit structure of ASCII to 8 bits, enabling the representation of 256 characters.

    Globally, various region-specific EASCII character sets have been introduced. The first 128 characters of these sets are consistent with the ASCII, while the remaining 128 characters are defined differently to accommodate the requirements of different languages.

    "},{"location":"chapter_data_structure/character_encoding/#342-gbk-character-set","title":"3.4.2 \u00a0 GBK character set","text":"

    Later, it was found that EASCII still could not meet the character requirements of many languages. For instance, there are nearly a hundred thousand Chinese characters, with several thousand used regularly. In 1980, the Standardization Administration of China released the \"GB2312\" character set, which included 6763 Chinese characters, essentially fulfilling the computer processing needs for the Chinese language.

    However, GB2312 could not handle some rare and traditional characters. The \"GBK\" character set expands GB2312 and includes 21886 Chinese characters. In the GBK encoding scheme, ASCII characters are represented with one byte, while Chinese characters use two bytes.

    "},{"location":"chapter_data_structure/character_encoding/#343-unicode-character-set","title":"3.4.3 \u00a0 Unicode character set","text":"

    With the rapid evolution of computer technology and a plethora of character sets and encoding standards, numerous problems arose. On the one hand, these character sets generally only defined characters for specific languages and could not function properly in multilingual environments. On the other hand, the existence of multiple character set standards for the same language caused garbled text when information was exchanged between computers using different encoding standards.

    Researchers of that era thought: What if a comprehensive character set encompassing all global languages and symbols was developed? Wouldn't this resolve the issues associated with cross-linguistic environments and garbled text? Inspired by this idea, the extensive character set, Unicode, was born.

    \"Unicode\" is referred to as \"\u7edf\u4e00\u7801\" (Unified Code) in Chinese, theoretically capable of accommodating over a million characters. It aims to incorporate characters from all over the world into a single set, providing a universal character set for processing and displaying various languages and reducing the issues of garbled text due to different encoding standards.

    Since its release in 1991, Unicode has continually expanded to include new languages and characters. As of September 2022, Unicode contains 149,186 characters, including characters, symbols, and even emojis from various languages. In the vast Unicode character set, commonly used characters occupy 2 bytes, while some rare characters may occupy 3 or even 4 bytes.

    Unicode is a universal character set that assigns a number (called a \"code point\") to each character, but it does not specify how these character code points should be stored in a computer system. One might ask: How does a system interpret Unicode code points of varying lengths within a text? For example, given a 2-byte code, how does the system determine if it represents a single 2-byte character or two 1-byte characters?

    A straightforward solution to this problem is to store all characters as equal-length encodings. As shown in the Figure 3-7 , each character in \"Hello\" occupies 1 byte, while each character in \"\u7b97\u6cd5\" (algorithm) occupies 2 bytes. We could encode all characters in \"Hello \u7b97\u6cd5\" as 2 bytes by padding the higher bits with zeros. This method would enable the system to interpret a character every 2 bytes, recovering the content of the phrase.

    Figure 3-7 \u00a0 Unicode encoding example

    However, as ASCII has shown us, encoding English only requires 1 byte. Using the above approach would double the space occupied by English text compared to ASCII encoding, which is a waste of memory space. Therefore, a more efficient Unicode encoding method is needed.

    "},{"location":"chapter_data_structure/character_encoding/#344-utf-8-encoding","title":"3.4.4 \u00a0 UTF-8 encoding","text":"

    Currently, UTF-8 has become the most widely used Unicode encoding method internationally. It is a variable-length encoding, using 1 to 4 bytes to represent a character, depending on the complexity of the character. ASCII characters need only 1 byte, Latin and Greek letters require 2 bytes, commonly used Chinese characters need 3 bytes, and some other rare characters need 4 bytes.

    The encoding rules for UTF-8 are not complex and can be divided into two cases:

    • For 1-byte characters, set the highest bit to \\(0\\), and the remaining 7 bits to the Unicode code point. Notably, ASCII characters occupy the first 128 code points in the Unicode set. This means that UTF-8 encoding is backward compatible with ASCII. This implies that UTF-8 can be used to parse ancient ASCII text.
    • For characters of length \\(n\\) bytes (where \\(n > 1\\)), set the highest \\(n\\) bits of the first byte to \\(1\\), and the \\((n + 1)^{\\text{th}}\\) bit to \\(0\\); starting from the second byte, set the highest 2 bits of each byte to \\(10\\); the rest of the bits are used to fill the Unicode code point.

    The Figure 3-8 shows the UTF-8 encoding for \"Hello\u7b97\u6cd5\". It can be observed that since the highest \\(n\\) bits are set to \\(1\\), the system can determine the length of the character as \\(n\\) by counting the number of highest bits set to \\(1\\).

    But why set the highest 2 bits of the remaining bytes to \\(10\\)? Actually, this \\(10\\) serves as a kind of checksum. If the system starts parsing text from an incorrect byte, the \\(10\\) at the beginning of the byte can help the system quickly detect anomalies.

    The reason for using \\(10\\) as a checksum is that, under UTF-8 encoding rules, it's impossible for the highest two bits of a character to be \\(10\\). This can be proven by contradiction: If the highest two bits of a character are \\(10\\), it indicates that the character's length is \\(1\\), corresponding to ASCII. However, the highest bit of an ASCII character should be \\(0\\), which contradicts the assumption.

    Figure 3-8 \u00a0 UTF-8 encoding example

    Apart from UTF-8, other common encoding methods include:

    • UTF-16 encoding: Uses 2 or 4 bytes to represent a character. All ASCII characters and commonly used non-English characters are represented with 2 bytes; a few characters require 4 bytes. For 2-byte characters, the UTF-16 encoding equals the Unicode code point.
    • UTF-32 encoding: Every character uses 4 bytes. This means UTF-32 occupies more space than UTF-8 and UTF-16, especially for texts with a high proportion of ASCII characters.

    From the perspective of storage space, using UTF-8 to represent English characters is very efficient because it only requires 1 byte; using UTF-16 to encode some non-English characters (such as Chinese) can be more efficient because it only requires 2 bytes, while UTF-8 might need 3 bytes.

    From a compatibility perspective, UTF-8 is the most versatile, with many tools and libraries supporting UTF-8 as a priority.

    "},{"location":"chapter_data_structure/character_encoding/#345-character-encoding-in-programming-languages","title":"3.4.5 \u00a0 Character encoding in programming languages","text":"

    Historically, many programming languages utilized fixed-length encodings such as UTF-16 or UTF-32 for processing strings during program execution. This allows strings to be handled as arrays, offering several advantages:

    • Random access: Strings encoded in UTF-16 can be accessed randomly with ease. For UTF-8, which is a variable-length encoding, locating the \\(i^{th}\\) character requires traversing the string from the start to the \\(i^{th}\\) position, taking \\(O(n)\\) time.
    • Character counting: Similar to random access, counting the number of characters in a UTF-16 encoded string is an \\(O(1)\\) operation. However, counting characters in a UTF-8 encoded string requires traversing the entire string.
    • String operations: Many string operations like splitting, concatenating, inserting, and deleting are easier on UTF-16 encoded strings. These operations generally require additional computation on UTF-8 encoded strings to ensure the validity of the UTF-8 encoding.

    The design of character encoding schemes in programming languages is an interesting topic involving various factors:

    • Java\u2019s String type uses UTF-16 encoding, with each character occupying 2 bytes. This was based on the initial belief that 16 bits were sufficient to represent all possible characters and proven incorrect later. As the Unicode standard expanded beyond 16 bits, characters in Java may now be represented by a pair of 16-bit values, known as \u201csurrogate pairs.\u201d
    • JavaScript and TypeScript use UTF-16 encoding for similar reasons as Java. When JavaScript was first introduced by Netscape in 1995, Unicode was still in its early stages, and 16-bit encoding was sufficient to represent all Unicode characters.
    • C# uses UTF-16 encoding, largely because the .NET platform, designed by Microsoft, and many Microsoft technologies, including the Windows operating system, extensively use UTF-16 encoding.

    Due to the underestimation of character counts, these languages had to use \"surrogate pairs\" to represent Unicode characters exceeding 16 bits. This approach has its drawbacks: strings containing surrogate pairs may have characters occupying 2 or 4 bytes, losing the advantage of fixed-length encoding. Additionally, handling surrogate pairs adds complexity and debugging difficulty to programming.

    Addressing these challenges, some languages have adopted alternative encoding strategies:

    • Python\u2019s str type uses Unicode encoding with a flexible representation where the storage length of characters depends on the largest Unicode code point in the string. If all characters are ASCII, each character occupies 1 byte, 2 bytes for characters within the Basic Multilingual Plane (BMP), and 4 bytes for characters beyond the BMP.
    • Go\u2019s string type internally uses UTF-8 encoding. Go also provides the rune type for representing individual Unicode code points.
    • Rust\u2019s str and String types use UTF-8 encoding internally. Rust also offers the char type for individual Unicode code points.

    It\u2019s important to note that the above discussion pertains to how strings are stored in programming languages, which is different from how strings are stored in files or transmitted over networks. For file storage or network transmission, strings are usually encoded in UTF-8 format for optimal compatibility and space efficiency.

    "},{"location":"chapter_data_structure/classification_of_data_structure/","title":"3.1 \u00a0 Classification of data structures","text":"

    Common data structures include arrays, linked lists, stacks, queues, hash tables, trees, heaps, and graphs. They can be classified into \"logical structure\" and \"physical structure\".

    "},{"location":"chapter_data_structure/classification_of_data_structure/#311-logical-structure-linear-and-non-linear","title":"3.1.1 \u00a0 Logical structure: linear and non-linear","text":"

    The logical structures reveal the logical relationships between data elements. In arrays and linked lists, data are arranged in a specific sequence, demonstrating the linear relationship between data; while in trees, data are arranged hierarchically from the top down, showing the derived relationship between \"ancestors\" and \"descendants\"; and graphs are composed of nodes and edges, reflecting the intricate network relationship.

    As shown in the Figure 3-1 , logical structures can be divided into two major categories: \"linear\" and \"non-linear\". Linear structures are more intuitive, indicating data is arranged linearly in logical relationships; non-linear structures, conversely, are arranged non-linearly.

    • Linear data structures: Arrays, Linked Lists, Stacks, Queues, Hash Tables.
    • Non-linear data structures: Trees, Heaps, Graphs, Hash Tables.

    Figure 3-1 \u00a0 Linear and non-linear data structures

    Non-linear data structures can be further divided into tree structures and network structures.

    • Linear structures: Arrays, linked lists, queues, stacks, and hash tables, where elements have a one-to-one sequential relationship.
    • Tree structures: Trees, Heaps, Hash Tables, where elements have a one-to-many relationship.
    • Network structures: Graphs, where elements have a many-to-many relationships.
    "},{"location":"chapter_data_structure/classification_of_data_structure/#312-physical-structure-contiguous-and-dispersed","title":"3.1.2 \u00a0 Physical structure: contiguous and dispersed","text":"

    During the execution of an algorithm, the data being processed is stored in memory. The Figure 3-2 shows a computer memory stick where each black square is a physical memory space. We can think of memory as a vast Excel spreadsheet, with each cell capable of storing a certain amount of data.

    The system accesses the data at the target location by means of a memory address. As shown in the Figure 3-2 , the computer assigns a unique identifier to each cell in the table according to specific rules, ensuring that each memory space has a unique memory address. With these addresses, the program can access the data stored in memory.

    Figure 3-2 \u00a0 Memory stick, memory spaces, memory addresses

    Tip

    It's worth noting that comparing memory to an Excel spreadsheet is a simplified analogy. The actual working mechanism of memory is more complex, involving concepts like address space, memory management, cache mechanisms, virtual memory, and physical memory.

    Memory is a shared resource for all programs. When a block of memory is occupied by one program, it cannot be simultaneously used by other programs. Therefore, considering memory resources is crucial in designing data structures and algorithms. For instance, the algorithm's peak memory usage should not exceed the remaining free memory of the system; if there is a lack of contiguous memory blocks, then the data structure chosen must be able to be stored in non-contiguous memory blocks.

    As illustrated in the Figure 3-3 , the physical structure reflects the way data is stored in computer memory and it can be divided into contiguous space storage (arrays) and non-contiguous space storage (linked lists). The two types of physical structures exhibit complementary characteristics in terms of time efficiency and space efficiency.

    Figure 3-3 \u00a0 Contiguous space storage and dispersed space storage

    It is worth noting that all data structures are implemented based on arrays, linked lists, or a combination of both. For example, stacks and queues can be implemented using either arrays or linked lists; while implementations of hash tables may involve both arrays and linked lists. - Array-based implementations: Stacks, Queues, Hash Tables, Trees, Heaps, Graphs, Matrices, Tensors (arrays with dimensions \\(\\geq 3\\)). - Linked-list-based implementations: Stacks, Queues, Hash Tables, Trees, Heaps, Graphs, etc.

    Data structures implemented based on arrays are also called \u201cStatic Data Structures,\u201d meaning their length cannot be changed after initialization. Conversely, those based on linked lists are called \u201cDynamic Data Structures,\u201d which can still adjust their size during program execution.

    Tip

    If you find it challenging to comprehend the physical structure, it is recommended that you read the next chapter, \"Arrays and Linked Lists,\" and revisit this section later.

    "},{"location":"chapter_data_structure/number_encoding/","title":"3.3 \u00a0 Number encoding *","text":"

    Tip

    In this book, chapters marked with an asterisk '*' are optional readings. If you are short on time or find them challenging, you may skip these initially and return to them after completing the essential chapters.

    "},{"location":"chapter_data_structure/number_encoding/#331-integer-encoding","title":"3.3.1 \u00a0 Integer encoding","text":"

    In the table from the previous section, we observed that all integer types can represent one more negative number than positive numbers, such as the byte range of \\([-128, 127]\\). This phenomenon seems counterintuitive, and its underlying reason involves knowledge of sign-magnitude, one's complement, and two's complement encoding.

    Firstly, it's important to note that numbers are stored in computers using the two's complement form. Before analyzing why this is the case, let's define these three encoding methods:

    • Sign-magnitude: The highest bit of a binary representation of a number is considered the sign bit, where \\(0\\) represents a positive number and \\(1\\) represents a negative number. The remaining bits represent the value of the number.
    • One's complement: The one's complement of a positive number is the same as its sign-magnitude. For negative numbers, it's obtained by inverting all bits except the sign bit.
    • Two's complement: The two's complement of a positive number is the same as its sign-magnitude. For negative numbers, it's obtained by adding \\(1\\) to their one's complement.

    The following diagram illustrates the conversions among sign-magnitude, one's complement, and two's complement:

    Figure 3-4 \u00a0 Conversions between sign-magnitude, one's complement, and two's complement

    Although sign-magnitude is the most intuitive, it has limitations. For one, negative numbers in sign-magnitude cannot be directly used in calculations. For example, in sign-magnitude, calculating \\(1 + (-2)\\) results in \\(-3\\), which is incorrect.

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 + 1000 \\; 0010 \\newline & = 1000 \\; 0011 \\newline & \\rightarrow -3 \\end{aligned} \\]

    To address this, computers introduced the one's complement. If we convert to one's complement and calculate \\(1 + (-2)\\), then convert the result back to sign-magnitude, we get the correct result of \\(-1\\).

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 \\; \\text{(Sign-magnitude)} + 1000 \\; 0010 \\; \\text{(Sign-magnitude)} \\newline & = 0000 \\; 0001 \\; \\text{(One's complement)} + 1111 \\; 1101 \\; \\text{(One's complement)} \\newline & = 1111 \\; 1110 \\; \\text{(One's complement)} \\newline & = 1000 \\; 0001 \\; \\text{(Sign-magnitude)} \\newline & \\rightarrow -1 \\end{aligned} \\]

    Additionally, there are two representations of zero in sign-magnitude: \\(+0\\) and \\(-0\\). This means two different binary encodings for zero, which could lead to ambiguity. For example, in conditional checks, not differentiating between positive and negative zero might result in incorrect outcomes. Addressing this ambiguity would require additional checks, potentially reducing computational efficiency.

    \\[ \\begin{aligned} +0 & \\rightarrow 0000 \\; 0000 \\newline -0 & \\rightarrow 1000 \\; 0000 \\end{aligned} \\]

    Like sign-magnitude, one's complement also suffers from the positive and negative zero ambiguity. Therefore, computers further introduced the two's complement. Let's observe the conversion process for negative zero in sign-magnitude, one's complement, and two's complement:

    \\[ \\begin{aligned} -0 \\rightarrow \\; & 1000 \\; 0000 \\; \\text{(Sign-magnitude)} \\newline = \\; & 1111 \\; 1111 \\; \\text{(One's complement)} \\newline = 1 \\; & 0000 \\; 0000 \\; \\text{(Two's complement)} \\newline \\end{aligned} \\]

    Adding \\(1\\) to the one's complement of negative zero produces a carry, but with byte length being only 8 bits, the carried-over \\(1\\) to the 9th bit is discarded. Therefore, the two's complement of negative zero is \\(0000 \\; 0000\\), the same as positive zero, thus resolving the ambiguity.

    One last puzzle is the \\([-128, 127]\\) range for byte, with an additional negative number, \\(-128\\). We observe that for the interval \\([-127, +127]\\), all integers have corresponding sign-magnitude, one's complement, and two's complement, allowing for mutual conversion between them.

    However, the two's complement \\(1000 \\; 0000\\) is an exception without a corresponding sign-magnitude. According to the conversion method, its sign-magnitude would be \\(0000 \\; 0000\\), indicating zero. This presents a contradiction because its two's complement should represent itself. Computers designate this special two's complement \\(1000 \\; 0000\\) as representing \\(-128\\). In fact, the calculation of \\((-1) + (-127)\\) in two's complement results in \\(-128\\).

    \\[ \\begin{aligned} & (-127) + (-1) \\newline & \\rightarrow 1111 \\; 1111 \\; \\text{(Sign-magnitude)} + 1000 \\; 0001 \\; \\text{(Sign-magnitude)} \\newline & = 1000 \\; 0000 \\; \\text{(One's complement)} + 1111 \\; 1110 \\; \\text{(One's complement)} \\newline & = 1000 \\; 0001 \\; \\text{(Two's complement)} + 1111 \\; 1111 \\; \\text{(Two's complement)} \\newline & = 1000 \\; 0000 \\; \\text{(Two's complement)} \\newline & \\rightarrow -128 \\end{aligned} \\]

    As you might have noticed, all these calculations are additions, hinting at an important fact: computers' internal hardware circuits are primarily designed around addition operations. This is because addition is simpler to implement in hardware compared to other operations like multiplication, division, and subtraction, allowing for easier parallelization and faster computation.

    It's important to note that this doesn't mean computers can only perform addition. By combining addition with basic logical operations, computers can execute a variety of other mathematical operations. For example, the subtraction \\(a - b\\) can be translated into \\(a + (-b)\\); multiplication and division can be translated into multiple additions or subtractions.

    We can now summarize the reason for using two's complement in computers: with two's complement representation, computers can use the same circuits and operations to handle both positive and negative number addition, eliminating the need for special hardware circuits for subtraction and avoiding the ambiguity of positive and negative zero. This greatly simplifies hardware design and enhances computational efficiency.

    The design of two's complement is quite ingenious, and due to space constraints, we'll stop here. Interested readers are encouraged to explore further.

    "},{"location":"chapter_data_structure/number_encoding/#332-floating-point-number-encoding","title":"3.3.2 \u00a0 Floating-point number encoding","text":"

    You might have noticed something intriguing: despite having the same length of 4 bytes, why does a float have a much larger range of values compared to an int? This seems counterintuitive, as one would expect the range to shrink for float since it needs to represent fractions.

    In fact, this is due to the different representation method used by floating-point numbers (float). Let's consider a 32-bit binary number as:

    \\[ b_{31} b_{30} b_{29} \\ldots b_2 b_1 b_0 \\]

    According to the IEEE 754 standard, a 32-bit float consists of the following three parts:

    • Sign bit \\(\\mathrm{S}\\): Occupies 1 bit, corresponding to \\(b_{31}\\).
    • Exponent bit \\(\\mathrm{E}\\): Occupies 8 bits, corresponding to \\(b_{30} b_{29} \\ldots b_{23}\\).
    • Fraction bit \\(\\mathrm{N}\\): Occupies 23 bits, corresponding to \\(b_{22} b_{21} \\ldots b_0\\).

    The value of a binary float number is calculated as:

    \\[ \\text{val} = (-1)^{b_{31}} \\times 2^{\\left(b_{30} b_{29} \\ldots b_{23}\\right)_2 - 127} \\times \\left(1 . b_{22} b_{21} \\ldots b_0\\right)_2 \\]

    Converted to a decimal formula, this becomes:

    \\[ \\text{val} = (-1)^{\\mathrm{S}} \\times 2^{\\mathrm{E} - 127} \\times (1 + \\mathrm{N}) \\]

    The range of each component is:

    \\[ \\begin{aligned} \\mathrm{S} \\in & \\{ 0, 1\\}, \\quad \\mathrm{E} \\in \\{ 1, 2, \\dots, 254 \\} \\newline (1 + \\mathrm{N}) = & (1 + \\sum_{i=1}^{23} b_{23-i} \\times 2^{-i}) \\subset [1, 2 - 2^{-23}] \\end{aligned} \\]

    Figure 3-5 \u00a0 Example calculation of a float in IEEE 754 standard

    Observing the diagram, given an example data \\(\\mathrm{S} = 0\\), \\(\\mathrm{E} = 124\\), \\(\\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\\), we have:

    \\[ \\text{val} = (-1)^0 \\times 2^{124 - 127} \\times (1 + 0.375) = 0.171875 \\]

    Now we can answer the initial question: The representation of float includes an exponent bit, leading to a much larger range than int. Based on the above calculation, the maximum positive number representable by float is approximately \\(2^{254 - 127} \\times (2 - 2^{-23}) \\approx 3.4 \\times 10^{38}\\), and the minimum negative number is obtained by switching the sign bit.

    However, the trade-off for float's expanded range is a sacrifice in precision. The integer type int uses all 32 bits to represent the number, with values evenly distributed; but due to the exponent bit, the larger the value of a float, the greater the difference between adjacent numbers.

    As shown in the Table 3-2 , exponent bits \\(\\mathrm{E} = 0\\) and \\(\\mathrm{E} = 255\\) have special meanings, used to represent zero, infinity, \\(\\mathrm{NaN}\\), etc.

    Table 3-2 \u00a0 Meaning of exponent bits

    Exponent Bit E Fraction Bit \\(\\mathrm{N} = 0\\) Fraction Bit \\(\\mathrm{N} \\ne 0\\) Calculation Formula \\(0\\) \\(\\pm 0\\) Subnormal Numbers \\((-1)^{\\mathrm{S}} \\times 2^{-126} \\times (0.\\mathrm{N})\\) \\(1, 2, \\dots, 254\\) Normal Numbers Normal Numbers \\((-1)^{\\mathrm{S}} \\times 2^{(\\mathrm{E} -127)} \\times (1.\\mathrm{N})\\) \\(255\\) \\(\\pm \\infty\\) \\(\\mathrm{NaN}\\)

    It's worth noting that subnormal numbers significantly improve the precision of floating-point numbers. The smallest positive normal number is \\(2^{-126}\\), and the smallest positive subnormal number is \\(2^{-126} \\times 2^{-23}\\).

    Double-precision double also uses a similar representation method to float, which is not elaborated here for brevity.

    "},{"location":"chapter_data_structure/summary/","title":"3.5 \u00a0 Summary","text":""},{"location":"chapter_data_structure/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Data structures can be categorized from two perspectives: logical structure and physical structure. Logical structure describes the logical relationships between data elements, while physical structure describes how data is stored in computer memory.
    • Common logical structures include linear, tree-like, and network structures. We generally classify data structures into linear (arrays, linked lists, stacks, queues) and non-linear (trees, graphs, heaps) based on their logical structure. The implementation of hash tables may involve both linear and non-linear data structures.
    • When a program runs, data is stored in computer memory. Each memory space has a corresponding memory address, and the program accesses data through these addresses.
    • Physical structures are primarily divided into contiguous space storage (arrays) and dispersed space storage (linked lists). All data structures are implemented using arrays, linked lists, or a combination of both.
    • Basic data types in computers include integers (byte, short, int, long), floating-point numbers (float, double), characters (char), and booleans (boolean). Their range depends on the size of the space occupied and the representation method.
    • Original code, complement code, and two's complement code are three methods of encoding numbers in computers, and they can be converted into each other. The highest bit of the original code of an integer is the sign bit, and the remaining bits represent the value of the number.
    • Integers are stored in computers in the form of two's complement. In this representation, the computer can treat the addition of positive and negative numbers uniformly, without the need for special hardware circuits for subtraction, and there is no ambiguity of positive and negative zero.
    • The encoding of floating-point numbers consists of 1 sign bit, 8 exponent bits, and 23 fraction bits. Due to the presence of the exponent bit, the range of floating-point numbers is much greater than that of integers, but at the cost of sacrificing precision.
    • ASCII is the earliest English character set, 1 byte in length, and includes 127 characters. The GBK character set is a commonly used Chinese character set, including more than 20,000 Chinese characters. Unicode strives to provide a complete character set standard, including characters from various languages worldwide, thus solving the problem of garbled characters caused by inconsistent character encoding methods.
    • UTF-8 is the most popular Unicode encoding method, with excellent universality. It is a variable-length encoding method with good scalability and effectively improves the efficiency of space usage. UTF-16 and UTF-32 are fixed-length encoding methods. When encoding Chinese characters, UTF-16 occupies less space than UTF-8. Programming languages like Java and C# use UTF-16 encoding by default.
    "},{"location":"chapter_data_structure/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Why does a hash table contain both linear and non-linear data structures?

    The underlying structure of a hash table is an array. To resolve hash collisions, we may use \"chaining\": each bucket in the array points to a linked list, which, when exceeding a certain threshold, might be transformed into a tree (usually a red-black tree). From a storage perspective, the foundation of a hash table is an array, where each bucket slot might contain a value, a linked list, or a tree. Therefore, hash tables may contain both linear data structures (arrays, linked lists) and non-linear data structures (trees).

    Q: Is the length of the char type 1 byte?

    The length of the char type is determined by the encoding method used by the programming language. For example, Java, JavaScript, TypeScript, and C# all use UTF-16 encoding (to save Unicode code points), so the length of the char type is 2 bytes.

    Q: Is there ambiguity in calling data structures based on arrays \"static data structures\"? Because operations like push and pop on stacks are \"dynamic\".

    While stacks indeed allow for dynamic data operations, the data structure itself remains \"static\" (with unchangeable length). Even though data structures based on arrays can dynamically add or remove elements, their capacity is fixed. If the data volume exceeds the pre-allocated size, a new, larger array needs to be created, and the contents of the old array copied into it.

    Q: When building stacks (queues) without specifying their size, why are they considered \"static data structures\"?

    In high-level programming languages, we don't need to manually specify the initial capacity of stacks (queues); this task is automatically handled internally by the class. For example, the initial capacity of Java's ArrayList is usually 10. Furthermore, the expansion operation is also implemented automatically. See the subsequent \"List\" chapter for details.

    "},{"location":"chapter_graph/","title":"Chapter 9. \u00a0 Graph","text":"

    Abstract

    In the journey of life, we are like individual nodes, connected by countless invisible edges.

    Each encounter and parting leaves a distinctive imprint on this vast network graph.

    "},{"location":"chapter_graph/#chapter-contents","title":"Chapter contents","text":"
    • 9.1 \u00a0 Graph
    • 9.2 \u00a0 Basic graph operations
    • 9.3 \u00a0 Graph traversal
    • 9.4 \u00a0 Summary
    "},{"location":"chapter_graph/graph/","title":"9.1 \u00a0 Graph","text":"

    A \"graph\" is a type of nonlinear data structure, consisting of \"vertices\" and \"edges\". A graph \\(G\\) can be abstractly represented as a collection of a set of vertices \\(V\\) and a set of edges \\(E\\). The following example shows a graph containing 5 vertices and 7 edges.

    \\[ \\begin{aligned} V & = \\{ 1, 2, 3, 4, 5 \\} \\newline E & = \\{ (1,2), (1,3), (1,5), (2,3), (2,4), (2,5), (4,5) \\} \\newline G & = \\{ V, E \\} \\newline \\end{aligned} \\]

    If vertices are viewed as nodes and edges as references (pointers) connecting the nodes, graphs can be seen as a data structure that extends from linked lists. As shown below, compared to linear relationships (linked lists) and divide-and-conquer relationships (trees), network relationships (graphs) are more complex due to their higher degree of freedom.

    Figure 9-1 \u00a0 Relationship between linked lists, trees, and graphs

    "},{"location":"chapter_graph/graph/#911-common-types-of-graphs","title":"9.1.1 \u00a0 Common types of graphs","text":"

    Based on whether edges have direction, graphs can be divided into \"undirected graphs\" and \"directed graphs\", as shown below.

    • In undirected graphs, edges represent a \"bidirectional\" connection between two vertices, for example, the \"friendship\" in WeChat or QQ.
    • In directed graphs, edges have directionality, that is, the edges \\(A \\rightarrow B\\) and \\(A \\leftarrow B\\) are independent of each other, for example, the \"follow\" and \"be followed\" relationship on Weibo or TikTok.

    Figure 9-2 \u00a0 Directed and undirected graphs

    Based on whether all vertices are connected, graphs can be divided into \"connected graphs\" and \"disconnected graphs\", as shown below.

    • For connected graphs, it is possible to reach any other vertex starting from a certain vertex.
    • For disconnected graphs, there is at least one vertex that cannot be reached from a certain starting vertex.

    Figure 9-3 \u00a0 Connected and disconnected graphs

    We can also add a \"weight\" variable to edges, resulting in \"weighted graphs\" as shown below. For example, in mobile games like \"Honor of Kings\", the system calculates the \"closeness\" between players based on shared gaming time, and this closeness network can be represented with a weighted graph.

    Figure 9-4 \u00a0 Weighted and unweighted graphs

    Graph data structures include the following commonly used terms.

    • \"Adjacency\": When there is an edge connecting two vertices, these two vertices are said to be \"adjacent\". In the above figure, the adjacent vertices of vertex 1 are vertices 2, 3, and 5.
    • \"Path\": The sequence of edges passed from vertex A to vertex B is called a \"path\" from A to B. In the above figure, the edge sequence 1-5-2-4 is a path from vertex 1 to vertex 4.
    • \"Degree\": The number of edges a vertex has. For directed graphs, \"in-degree\" refers to how many edges point to the vertex, and \"out-degree\" refers to how many edges point out from the vertex.
    "},{"location":"chapter_graph/graph/#912-representation-of-graphs","title":"9.1.2 \u00a0 Representation of graphs","text":"

    Common representations of graphs include \"adjacency matrices\" and \"adjacency lists\". The following examples use undirected graphs.

    "},{"location":"chapter_graph/graph/#1-adjacency-matrix","title":"1. \u00a0 Adjacency matrix","text":"

    Let the number of vertices in the graph be \\(n\\), the \"adjacency matrix\" uses an \\(n \\times n\\) matrix to represent the graph, where each row (column) represents a vertex, and the matrix elements represent edges, with \\(1\\) or \\(0\\) indicating whether there is an edge between two vertices.

    As shown below, let the adjacency matrix be \\(M\\), and the list of vertices be \\(V\\), then the matrix element \\(M[i, j] = 1\\) indicates there is an edge between vertex \\(V[i]\\) and vertex \\(V[j]\\), conversely \\(M[i, j] = 0\\) indicates there is no edge between the two vertices.

    Figure 9-5 \u00a0 Representation of a graph with an adjacency matrix

    Adjacency matrices have the following characteristics.

    • A vertex cannot be connected to itself, so the elements on the main diagonal of the adjacency matrix are meaningless.
    • For undirected graphs, edges in both directions are equivalent, thus the adjacency matrix is symmetric about the main diagonal.
    • By replacing the elements of the adjacency matrix from \\(1\\) and \\(0\\) to weights, it can represent weighted graphs.

    When representing graphs with adjacency matrices, it is possible to directly access matrix elements to obtain edges, thus operations of addition, deletion, lookup, and modification are very efficient, all with a time complexity of \\(O(1)\\). However, the space complexity of the matrix is \\(O(n^2)\\), which consumes more memory.

    "},{"location":"chapter_graph/graph/#2-adjacency-list","title":"2. \u00a0 Adjacency list","text":"

    The \"adjacency list\" uses \\(n\\) linked lists to represent the graph, with each linked list node representing a vertex. The \\(i\\)-th linked list corresponds to vertex \\(i\\) and contains all adjacent vertices (vertices connected to that vertex). The Figure 9-6 shows an example of a graph stored using an adjacency list.

    Figure 9-6 \u00a0 Representation of a graph with an adjacency list

    The adjacency list only stores actual edges, and the total number of edges is often much less than \\(n^2\\), making it more space-efficient. However, finding edges in the adjacency list requires traversing the linked list, so its time efficiency is not as good as that of the adjacency matrix.

    Observing the above figure, the structure of the adjacency list is very similar to the \"chaining\" in hash tables, hence we can use similar methods to optimize efficiency. For example, when the linked list is long, it can be transformed into an AVL tree or red-black tree, thus optimizing the time efficiency from \\(O(n)\\) to \\(O(\\log n)\\); the linked list can also be transformed into a hash table, thus reducing the time complexity to \\(O(1)\\).

    "},{"location":"chapter_graph/graph/#913-common-applications-of-graphs","title":"9.1.3 \u00a0 Common applications of graphs","text":"

    As shown in the Table 9-1 , many real-world systems can be modeled with graphs, and corresponding problems can be reduced to graph computing problems.

    Table 9-1 \u00a0 Common graphs in real life

    Vertices Edges Graph Computing Problem Social Networks Users Friendships Potential Friend Recommendations Subway Lines Stations Connectivity Between Stations Shortest Route Recommendations Solar System Celestial Bodies Gravitational Forces Between Celestial Bodies Planetary Orbit Calculations"},{"location":"chapter_graph/graph_operations/","title":"9.2 \u00a0 Basic operations on graphs","text":"

    The basic operations on graphs can be divided into operations on \"edges\" and operations on \"vertices\". Under the two representation methods of \"adjacency matrix\" and \"adjacency list\", the implementation methods are different.

    "},{"location":"chapter_graph/graph_operations/#921-implementation-based-on-adjacency-matrix","title":"9.2.1 \u00a0 Implementation based on adjacency matrix","text":"

    Given an undirected graph with \\(n\\) vertices, the various operations are implemented as shown in the Figure 9-7 .

    • Adding or removing an edge: Directly modify the specified edge in the adjacency matrix, using \\(O(1)\\) time. Since it is an undirected graph, it is necessary to update the edges in both directions simultaneously.
    • Adding a vertex: Add a row and a column at the end of the adjacency matrix and fill them all with \\(0\\)s, using \\(O(n)\\) time.
    • Removing a vertex: Delete a row and a column in the adjacency matrix. The worst case is when the first row and column are removed, requiring \\((n-1)^2\\) elements to be \"moved up and to the left\", thus using \\(O(n^2)\\) time.
    • Initialization: Pass in \\(n\\) vertices, initialize a vertex list vertices of length \\(n\\), using \\(O(n)\\) time; initialize an \\(n \\times n\\) size adjacency matrix adjMat, using \\(O(n^2)\\) time.
    Initialize adjacency matrixAdd an edgeRemove an edgeAdd a vertexRemove a vertex

    Figure 9-7 \u00a0 Initialization, adding and removing edges, adding and removing vertices in adjacency matrix

    Below is the implementation code for graphs represented using an adjacency matrix:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_matrix.py
    class GraphAdjMat:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, vertices: list[int], edges: list[list[int]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.vertices: list[int] = []\n        # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.adj_mat: list[list[int]] = []\n        # \u6dfb\u52a0\u9876\u70b9\n        for val in vertices:\n            self.add_vertex(val)\n        # \u6dfb\u52a0\u8fb9\n        # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges:\n            self.add_edge(e[0], e[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.vertices)\n\n    def add_vertex(self, val: int):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        n = self.size()\n        # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.append(val)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        new_row = [0] * n\n        self.adj_mat.append(new_row)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in self.adj_mat:\n            row.append(0)\n\n    def remove_vertex(self, index: int):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if index >= self.size():\n            raise IndexError()\n        # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in self.adj_mat:\n            row.pop(index)\n\n    def add_edge(self, i: int, j: int):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1\n        self.adj_mat[j][i] = 1\n\n    def remove_edge(self, i: int, j: int):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        self.adj_mat[i][j] = 0\n        self.adj_mat[j][i] = 0\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u77e9\u9635\"\"\"\n        print(\"\u9876\u70b9\u5217\u8868 =\", self.vertices)\n        print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        print_matrix(self.adj_mat)\n
    graph_adjacency_matrix.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vector<int> vertices;       // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vector<vector<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjMat(const vector<int> &vertices, const vector<vector<int>> &edges) {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const vector<int> &edge : edges) {\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() const {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.push_back(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        adjMat.emplace_back(vector<int>(n, 0));\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (vector<int> &row : adjMat) {\n            row.push_back(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(int index) {\n        if (index >= size()) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.erase(vertices.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.erase(adjMat.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (vector<int> &row : adjMat) {\n            row.erase(row.begin() + index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    void print() {\n        cout << \"\u9876\u70b9\u5217\u8868 = \";\n        printVector(vertices);\n        cout << \"\u90bb\u63a5\u77e9\u9635 =\" << endl;\n        printVectorMatrix(adjMat);\n    }\n};\n
    graph_adjacency_matrix.java
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<Integer> vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<Integer>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = new ArrayList<>();\n        this.adjMat = new ArrayList<>();\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (int[] e : edges) {\n            addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<Integer> newRow = new ArrayList<>(n);\n        for (int j = 0; j < n; j++) {\n            newRow.add(0);\n        }\n        adjMat.add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (List<Integer> row : adjMat) {\n            row.add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(int index) {\n        if (index >= size())\n            throw new IndexOutOfBoundsException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (List<Integer> row : adjMat) {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat.get(i).set(j, 1);\n        adjMat.get(j).set(i, 1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        adjMat.get(i).set(j, 0);\n        adjMat.get(j).set(i, 0);\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void print() {\n        System.out.print(\"\u9876\u70b9\u5217\u8868 = \");\n        System.out.println(vertices);\n        System.out.println(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.printMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<int> vertices;     // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        foreach (int val in vertices) {\n            AddVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        foreach (int[] e in edges) {\n            AddEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return vertices.Count;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(int val) {\n        int n = Size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.Add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<int> newRow = new(n);\n        for (int j = 0; j < n; j++) {\n            newRow.Add(0);\n        }\n        adjMat.Add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        foreach (List<int> row in adjMat) {\n            row.Add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(int index) {\n        if (index >= Size())\n            throw new IndexOutOfRangeException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        foreach (List<int> row in adjMat) {\n            row.RemoveAt(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void AddEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void RemoveEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void Print() {\n        Console.Write(\"\u9876\u70b9\u5217\u8868 = \");\n        PrintUtil.PrintList(vertices);\n        Console.WriteLine(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.PrintMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.go
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjMat struct {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vertices []int\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat [][]int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjMat(vertices []int, edges [][]int) *graphAdjMat {\n    // \u6dfb\u52a0\u9876\u70b9\n    n := len(vertices)\n    adjMat := make([][]int, n)\n    for i := range adjMat {\n        adjMat[i] = make([]int, n)\n    }\n    // \u521d\u59cb\u5316\u56fe\n    g := &graphAdjMat{\n        vertices: vertices,\n        adjMat:   adjMat,\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for i := range edges {\n        g.addEdge(edges[i][0], edges[i][1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjMat) size() int {\n    return len(g.vertices)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjMat) addVertex(val int) {\n    n := g.size()\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    g.vertices = append(g.vertices, val)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    newRow := make([]int, n)\n    g.adjMat = append(g.adjMat, newRow)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i], 0)\n    }\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjMat) removeVertex(index int) {\n    if index >= g.size() {\n        return\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    g.vertices = append(g.vertices[:index], g.vertices[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    g.adjMat = append(g.adjMat[:index], g.adjMat[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i][:index], g.adjMat[i][index+1:]...)\n    }\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) addEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    g.adjMat[i][j] = 1\n    g.adjMat[j][i] = 1\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) removeEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    g.adjMat[i][j] = 0\n    g.adjMat[j][i] = 0\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nfunc (g *graphAdjMat) print() {\n    fmt.Printf(\"\\t\u9876\u70b9\u5217\u8868 = %v\\n\", g.vertices)\n    fmt.Printf(\"\\t\u90bb\u63a5\u77e9\u9635 = \\n\")\n    for i := range g.adjMat {\n        fmt.Printf(\"\\t\\t\\t%v\\n\", g.adjMat[i])\n    }\n}\n
    graph_adjacency_matrix.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    private var vertices: [Int] // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    private var adjMat: [[Int]] // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(vertices: [Int], edges: [[Int]]) {\n        self.vertices = []\n        adjMat = []\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            addVertex(val: val)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges {\n            addEdge(i: e[0], j: e[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    func size() -> Int {\n        vertices.count\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    func addVertex(val: Int) {\n        let n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.append(val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        let newRow = Array(repeating: 0, count: n)\n        adjMat.append(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for i in adjMat.indices {\n            adjMat[i].append(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    func removeVertex(index: Int) {\n        if index >= size() {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for i in adjMat.indices {\n            adjMat[i].remove(at: index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    func print() {\n        Swift.print(\"\u9876\u70b9\u5217\u8868 = \", terminator: \"\")\n        Swift.print(vertices)\n        Swift.print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        PrintUtil.printMatrix(matrix: adjMat)\n    }\n}\n
    graph_adjacency_matrix.js
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices, edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val) {\n        const n = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow = [];\n        for (let j = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index) {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print() {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices: number[]; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat: number[][]; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices: number[], edges: number[][]) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val: number): void {\n        const n: number = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow: number[] = [];\n        for (let j: number = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index: number): void {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print(): void {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n  List<int> vertices = []; // \u9876\u70b9\u5143\u7d20\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n  List<List<int>> adjMat = []; //\u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjMat(List<int> vertices, List<List<int>> edges) {\n    this.vertices = [];\n    this.adjMat = [];\n    // \u6dfb\u52a0\u9876\u70b9\n    for (int val in vertices) {\n      addVertex(val);\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for (List<int> e in edges) {\n      addEdge(e[0], e[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return vertices.length;\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(int val) {\n    int n = size();\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    vertices.add(val);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    List<int> newRow = List.filled(n, 0, growable: true);\n    adjMat.add(newRow);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for (List<int> row in adjMat) {\n      row.add(0);\n    }\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(int index) {\n    if (index >= size()) {\n      throw IndexError;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    vertices.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    adjMat.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (List<int> row in adjMat) {\n      row.removeAt(index);\n    }\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void addEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    adjMat[i][j] = 1;\n    adjMat[j][i] = 1;\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void removeEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    adjMat[i][j] = 0;\n    adjMat[j][i] = 0;\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n  void printAdjMat() {\n    print(\"\u9876\u70b9\u5217\u8868 = $vertices\");\n    print(\"\u90bb\u63a5\u77e9\u9635 = \");\n    printMatrix(adjMat);\n  }\n}\n
    graph_adjacency_matrix.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjMat {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub vertices: Vec<i32>,\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub adj_mat: Vec<Vec<i32>>,\n}\n\nimpl GraphAdjMat {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(vertices: Vec<i32>, edges: Vec<[usize; 2]>) -> Self {\n        let mut graph = GraphAdjMat {\n            vertices: vec![],\n            adj_mat: vec![],\n        };\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            graph.add_vertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for edge in edges {\n            graph.add_edge(edge[0], edge[1])\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    pub fn size(&self) -> usize {\n        self.vertices.len()\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, val: i32) {\n        let n = self.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        self.adj_mat.push(vec![0; n]);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in &mut self.adj_mat {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    pub fn remove_vertex(&mut self, index: usize) {\n        if index >= self.size() {\n            panic!(\"index error\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in &mut self.adj_mat {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1;\n        self.adj_mat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    pub fn remove_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        self.adj_mat[i][j] = 0;\n        self.adj_mat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    pub fn print(&self) {\n        println!(\"\u9876\u70b9\u5217\u8868 = {:?}\", self.vertices);\n        println!(\"\u90bb\u63a5\u77e9\u9635 =\");\n        println!(\"[\");\n        for row in &self.adj_mat {\n            println!(\"  {:?},\", row);\n        }\n        println!(\"]\")\n    }\n}\n
    graph_adjacency_matrix.c
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int vertices[MAX_SIZE];\n    int adjMat[MAX_SIZE][MAX_SIZE];\n    int size;\n} GraphAdjMat;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjMat *newGraphAdjMat() {\n    GraphAdjMat *graph = (GraphAdjMat *)malloc(sizeof(GraphAdjMat));\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        for (int j = 0; j < MAX_SIZE; j++) {\n            graph->adjMat[i][j] = 0;\n        }\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjMat(GraphAdjMat *graph) {\n    free(graph);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjMat *graph, int val) {\n    if (graph->size == MAX_SIZE) {\n        fprintf(stderr, \"\u56fe\u7684\u9876\u70b9\u6570\u91cf\u5df2\u8fbe\u6700\u5927\u503c\\n\");\n        return;\n    }\n    // \u6dfb\u52a0\u7b2c n \u4e2a\u9876\u70b9\uff0c\u5e76\u5c06\u7b2c n \u884c\u548c\u5217\u7f6e\u96f6\n    int n = graph->size;\n    graph->vertices[n] = val;\n    for (int i = 0; i <= n; i++) {\n        graph->adjMat[n][i] = graph->adjMat[i][n] = 0;\n    }\n    graph->size++;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjMat *graph, int index) {\n    if (index < 0 || index >= graph->size) {\n        fprintf(stderr, \"\u9876\u70b9\u7d22\u5f15\u8d8a\u754c\\n\");\n        return;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    for (int i = index; i < graph->size - 1; i++) {\n        graph->vertices[i] = graph->vertices[i + 1];\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    for (int i = index; i < graph->size - 1; i++) {\n        for (int j = 0; j < graph->size; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i + 1][j];\n        }\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (int i = 0; i < graph->size; i++) {\n        for (int j = index; j < graph->size - 1; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i][j + 1];\n        }\n    }\n    graph->size--;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid addEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 1;\n    graph->adjMat[j][i] = 1;\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid removeEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 0;\n    graph->adjMat[j][i] = 0;\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nvoid printGraphAdjMat(GraphAdjMat *graph) {\n    printf(\"\u9876\u70b9\u5217\u8868 = \");\n    printArray(graph->vertices, graph->size);\n    printf(\"\u90bb\u63a5\u77e9\u9635 =\\n\");\n    for (int i = 0; i < graph->size; i++) {\n        printArray(graph->adjMat[i], graph->size);\n    }\n}\n
    graph_adjacency_matrix.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat(vertices: IntArray, edges: Array<IntArray>) {\n    val vertices = mutableListOf<Int>() // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    val adjMat = mutableListOf<MutableList<Int>>() // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (vertex in vertices) {\n            addVertex(vertex)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (edge in edges) {\n            addEdge(edge[0], edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return vertices.size\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(_val: Int) {\n        val n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(_val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        val newRow = mutableListOf<Int>()\n        for (j in 0..<n) {\n            newRow.add(0)\n        }\n        adjMat.add(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (row in adjMat) {\n            row.add(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(index: Int) {\n        if (index >= size())\n            throw IndexOutOfBoundsException()\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (row in adjMat) {\n            row.removeAt(index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    fun print() {\n        print(\"\u9876\u70b9\u5217\u8868 = \")\n        println(vertices)\n        println(\"\u90bb\u63a5\u77e9\u9635 =\")\n        printMatrix(adjMat)\n    }\n}\n
    graph_adjacency_matrix.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjMat\n  def initialize(vertices, edges)\n    ### \u6784\u9020\u65b9\u6cd5 ###\n    # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @vertices = []\n    # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @adj_mat = []\n    # \u6dfb\u52a0\u9876\u70b9\n    vertices.each { |val| add_vertex(val) }\n    # \u6dfb\u52a0\u8fb9\n    # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    edges.each { |e| add_edge(e[0], e[1]) }\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @vertices.length\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(val)\n    n = size\n    # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    @vertices << val\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    new_row = Array.new(n, 0)\n    @adj_mat << new_row\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    @adj_mat.each { |row| row << 0 }\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(index)\n    raise IndexError if index >= size\n\n    # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    @vertices.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    @adj_mat.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    @adj_mat.each { |row| row.delete_at(index) }\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    @adj_mat[i][j] = 1\n    @adj_mat[j][i] = 1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    @adj_mat[i][j] = 0\n    @adj_mat[j][i] = 0\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u77e9\u9635 ###\n  def __print__\n    puts \"\u9876\u70b9\u5217\u8868 = #{@vertices}\"\n    puts '\u90bb\u63a5\u77e9\u9635 ='\n    print_matrix(@adj_mat)\n  end\nend\n
    graph_adjacency_matrix.zig
    [class]{GraphAdjMat}-[func]{}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_graph/graph_operations/#922-implementation-based-on-adjacency-list","title":"9.2.2 \u00a0 Implementation based on adjacency list","text":"

    Given an undirected graph with a total of \\(n\\) vertices and \\(m\\) edges, the various operations can be implemented as shown in the Figure 9-8 .

    • Adding an edge: Simply add the edge at the end of the corresponding vertex's linked list, using \\(O(1)\\) time. Because it is an undirected graph, it is necessary to add edges in both directions simultaneously.
    • Removing an edge: Find and remove the specified edge in the corresponding vertex's linked list, using \\(O(m)\\) time. In an undirected graph, it is necessary to remove edges in both directions simultaneously.
    • Adding a vertex: Add a linked list in the adjacency list and make the new vertex the head node of the list, using \\(O(1)\\) time.
    • Removing a vertex: It is necessary to traverse the entire adjacency list, removing all edges that include the specified vertex, using \\(O(n + m)\\) time.
    • Initialization: Create \\(n\\) vertices and \\(2m\\) edges in the adjacency list, using \\(O(n + m)\\) time.
    Initialize adjacency listAdd an edgeRemove an edgeAdd a vertexRemove a vertex

    Figure 9-8 \u00a0 Initialization, adding and removing edges, adding and removing vertices in adjacency list

    Below is the adjacency list code implementation. Compared to the above diagram, the actual code has the following differences.

    • For convenience in adding and removing vertices, and to simplify the code, we use lists (dynamic arrays) instead of linked lists.
    • Use a hash table to store the adjacency list, key being the vertex instance, value being the list (linked list) of adjacent vertices of that vertex.

    Additionally, we use the Vertex class to represent vertices in the adjacency list. The reason for this is: if, like with the adjacency matrix, list indexes were used to distinguish different vertices, then suppose you want to delete the vertex at index \\(i\\), you would need to traverse the entire adjacency list and decrement all indexes greater than \\(i\\) by \\(1\\), which is very inefficient. However, if each vertex is a unique Vertex instance, then deleting a vertex does not require any changes to other vertices.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_list.py
    class GraphAdjList:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, edges: list[list[Vertex]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        self.adj_list = dict[Vertex, list[Vertex]]()\n        # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges:\n            self.add_vertex(edge[0])\n            self.add_vertex(edge[1])\n            self.add_edge(edge[0], edge[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.adj_list)\n\n    def add_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list[vet1].append(vet2)\n        self.adj_list[vet2].append(vet1)\n\n    def remove_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list[vet1].remove(vet2)\n        self.adj_list[vet2].remove(vet1)\n\n    def add_vertex(self, vet: Vertex):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        if vet in self.adj_list:\n            return\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list[vet] = []\n\n    def remove_vertex(self, vet: Vertex):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if vet not in self.adj_list:\n            raise ValueError()\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.pop(vet)\n        # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for vertex in self.adj_list:\n            if vet in self.adj_list[vertex]:\n                self.adj_list[vertex].remove(vet)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u8868\"\"\"\n        print(\"\u90bb\u63a5\u8868 =\")\n        for vertex in self.adj_list:\n            tmp = [v.val for v in self.adj_list[vertex]]\n            print(f\"{vertex.val}: {tmp},\")\n
    graph_adjacency_list.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  public:\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    unordered_map<Vertex *, vector<Vertex *>> adjList;\n\n    /* \u5728 vector \u4e2d\u5220\u9664\u6307\u5b9a\u8282\u70b9 */\n    void remove(vector<Vertex *> &vec, Vertex *vet) {\n        for (int i = 0; i < vec.size(); i++) {\n            if (vec[i] == vet) {\n                vec.erase(vec.begin() + i);\n                break;\n            }\n        }\n    }\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjList(const vector<vector<Vertex *>> &edges) {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const vector<Vertex *> &edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    void addEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].push_back(vet2);\n        adjList[vet2].push_back(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    void removeEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        remove(adjList[vet1], vet2);\n        remove(adjList[vet2], vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(Vertex *vet) {\n        if (adjList.count(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = vector<Vertex *>();\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(Vertex *vet) {\n        if (!adjList.count(vet))\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.erase(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (auto &adj : adjList) {\n            remove(adj.second, vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    void print() {\n        cout << \"\u90bb\u63a5\u8868 =\" << endl;\n        for (auto &adj : adjList) {\n            const auto &key = adj.first;\n            const auto &vec = adj.second;\n            cout << key->val << \": \";\n            printVector(vetsToVals(vec));\n        }\n    }\n};\n
    graph_adjacency_list.java
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    Map<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjList(Vertex[][] edges) {\n        this.adjList = new HashMap<>();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (Vertex[] edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void addEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList.get(vet1).add(vet2);\n        adjList.get(vet2).add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void removeEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList.get(vet1).remove(vet2);\n        adjList.get(vet2).remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(Vertex vet) {\n        if (adjList.containsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.put(vet, new ArrayList<>());\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(Vertex vet) {\n        if (!adjList.containsKey(vet))\n            throw new IllegalArgumentException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (List<Vertex> list : adjList.values()) {\n            list.remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void print() {\n        System.out.println(\"\u90bb\u63a5\u8868 =\");\n        for (Map.Entry<Vertex, List<Vertex>> pair : adjList.entrySet()) {\n            List<Integer> tmp = new ArrayList<>();\n            for (Vertex vertex : pair.getValue())\n                tmp.add(vertex.val);\n            System.out.println(pair.getKey().val + \": \" + tmp + \",\");\n        }\n    }\n}\n
    graph_adjacency_list.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public Dictionary<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjList(Vertex[][] edges) {\n        adjList = [];\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        foreach (Vertex[] edge in edges) {\n            AddVertex(edge[0]);\n            AddVertex(edge[1]);\n            AddEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return adjList.Count;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void AddEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].Add(vet2);\n        adjList[vet2].Add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void RemoveEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1].Remove(vet2);\n        adjList[vet2].Remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(Vertex vet) {\n        if (adjList.ContainsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.Add(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(Vertex vet) {\n        if (!adjList.ContainsKey(vet))\n            throw new InvalidOperationException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.Remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        foreach (List<Vertex> list in adjList.Values) {\n            list.Remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void Print() {\n        Console.WriteLine(\"\u90bb\u63a5\u8868 =\");\n        foreach (KeyValuePair<Vertex, List<Vertex>> pair in adjList) {\n            List<int> tmp = [];\n            foreach (Vertex vertex in pair.Value)\n                tmp.Add(vertex.val);\n            Console.WriteLine(pair.Key.val + \": [\" + string.Join(\", \", tmp) + \"],\");\n        }\n    }\n}\n
    graph_adjacency_list.go
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjList struct {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList map[Vertex][]Vertex\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjList(edges [][]Vertex) *graphAdjList {\n    g := &graphAdjList{\n        adjList: make(map[Vertex][]Vertex),\n    }\n    // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for _, edge := range edges {\n        g.addVertex(edge[0])\n        g.addVertex(edge[1])\n        g.addEdge(edge[0], edge[1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjList) size() int {\n    return len(g.adjList)\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nfunc (g *graphAdjList) addEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2, \u6dfb\u52a0\u533f\u540d struct{},\n    g.adjList[vet1] = append(g.adjList[vet1], vet2)\n    g.adjList[vet2] = append(g.adjList[vet2], vet1)\n}\n\n/* \u5220\u9664\u8fb9 */\nfunc (g *graphAdjList) removeEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    g.adjList[vet1] = DeleteSliceElms(g.adjList[vet1], vet2)\n    g.adjList[vet2] = DeleteSliceElms(g.adjList[vet2], vet1)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjList) addVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if ok {\n        return\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    g.adjList[vet] = make([]Vertex, 0)\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjList) removeVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if !ok {\n        panic(\"error\")\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    delete(g.adjList, vet)\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for v, list := range g.adjList {\n        g.adjList[v] = DeleteSliceElms(list, vet)\n    }\n}\n\n/* \u6253\u5370\u90bb\u63a5\u8868 */\nfunc (g *graphAdjList) print() {\n    var builder strings.Builder\n    fmt.Printf(\"\u90bb\u63a5\u8868 = \\n\")\n    for k, v := range g.adjList {\n        builder.WriteString(\"\\t\\t\" + strconv.Itoa(k.Val) + \": \")\n        for _, vet := range v {\n            builder.WriteString(strconv.Itoa(vet.Val) + \" \")\n        }\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    graph_adjacency_list.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public private(set) var adjList: [Vertex: [Vertex]]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public init(edges: [[Vertex]]) {\n        adjList = [:]\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            addVertex(vet: edge[0])\n            addVertex(vet: edge[1])\n            addEdge(vet1: edge[0], vet2: edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public func size() -> Int {\n        adjList.count\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public func addEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.append(vet2)\n        adjList[vet2]?.append(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public func removeEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.removeAll { $0 == vet2 }\n        adjList[vet2]?.removeAll { $0 == vet1 }\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public func addVertex(vet: Vertex) {\n        if adjList[vet] != nil {\n            return\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = []\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public func removeVertex(vet: Vertex) {\n        if adjList[vet] == nil {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.removeValue(forKey: vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for key in adjList.keys {\n            adjList[key]?.removeAll { $0 == vet }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public func print() {\n        Swift.print(\"\u90bb\u63a5\u8868 =\")\n        for (vertex, list) in adjList {\n            let list = list.map { $0.val }\n            Swift.print(\"\\(vertex.val): \\(list),\")\n        }\n    }\n}\n
    graph_adjacency_list.js
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet) {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet) {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print() {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList: Map<Vertex, Vertex[]>;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges: Vertex[][]) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet: Vertex): void {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet: Vertex): void {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index: number = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print(): void {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList.entries()) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  Map<Vertex, List<Vertex>> adjList = {};\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjList(List<List<Vertex>> edges) {\n    for (List<Vertex> edge in edges) {\n      addVertex(edge[0]);\n      addVertex(edge[1]);\n      addEdge(edge[0], edge[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return adjList.length;\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  void addEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    adjList[vet1]!.add(vet2);\n    adjList[vet2]!.add(vet1);\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  void removeEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    adjList[vet1]!.remove(vet2);\n    adjList[vet2]!.remove(vet1);\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(Vertex vet) {\n    if (adjList.containsKey(vet)) return;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    adjList[vet] = [];\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(Vertex vet) {\n    if (!adjList.containsKey(vet)) {\n      throw ArgumentError;\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    adjList.remove(vet);\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    adjList.forEach((key, value) {\n      value.remove(vet);\n    });\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u8868 */\n  void printAdjList() {\n    print(\"\u90bb\u63a5\u8868 =\");\n    adjList.forEach((key, value) {\n      List<int> tmp = [];\n      for (Vertex vertex in value) {\n        tmp.add(vertex.val);\n      }\n      print(\"${key.val}: $tmp,\");\n    });\n  }\n}\n
    graph_adjacency_list.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    pub adj_list: HashMap<Vertex, Vec<Vertex>>,\n}\n\nimpl GraphAdjList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(edges: Vec<[Vertex; 2]>) -> Self {\n        let mut graph = GraphAdjList {\n            adj_list: HashMap::new(),\n        };\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            graph.add_vertex(edge[0]);\n            graph.add_vertex(edge[1]);\n            graph.add_edge(edge[0], edge[1]);\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    #[allow(unused)]\n    pub fn size(&self) -> usize {\n        self.adj_list.len()\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list.get_mut(&vet1).unwrap().push(vet2);\n        self.adj_list.get_mut(&vet2).unwrap().push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    #[allow(unused)]\n    pub fn remove_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list\n            .get_mut(&vet1)\n            .unwrap()\n            .retain(|&vet| vet != vet2);\n        self.adj_list\n            .get_mut(&vet2)\n            .unwrap()\n            .retain(|&vet| vet != vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, vet: Vertex) {\n        if self.adj_list.contains_key(&vet) {\n            return;\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list.insert(vet, vec![]);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    #[allow(unused)]\n    pub fn remove_vertex(&mut self, vet: Vertex) {\n        if !self.adj_list.contains_key(&vet) {\n            panic!(\"value error\");\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.remove(&vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for list in self.adj_list.values_mut() {\n            list.retain(|&v| v != vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    pub fn print(&self) {\n        println!(\"\u90bb\u63a5\u8868 =\");\n        for (vertex, list) in &self.adj_list {\n            let list = list.iter().map(|vertex| vertex.val).collect::<Vec<i32>>();\n            println!(\"{}: {:?},\", vertex.val, list);\n        }\n    }\n}\n
    graph_adjacency_list.c
    /* \u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct AdjListNode {\n    Vertex *vertex;           // \u9876\u70b9\n    struct AdjListNode *next; // \u540e\u7ee7\u8282\u70b9\n} AdjListNode;\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid addEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *node = (AdjListNode *)malloc(sizeof(AdjListNode));\n    node->vertex = vet;\n    // \u5934\u63d2\u6cd5\n    node->next = head->next;\n    head->next = node;\n}\n\n/* \u5220\u9664\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid removeEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *pre = head;\n    AdjListNode *cur = head->next;\n    // \u5728\u94fe\u8868\u4e2d\u641c\u7d22 vet \u5bf9\u5e94\u8282\u70b9\n    while (cur != NULL && cur->vertex != vet) {\n        pre = cur;\n        cur = cur->next;\n    }\n    if (cur == NULL)\n        return;\n    // \u5c06 vet \u5bf9\u5e94\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u5220\u9664\n    pre->next = cur->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(cur);\n}\n\n/* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntypedef struct {\n    AdjListNode *heads[MAX_SIZE]; // \u8282\u70b9\u6570\u7ec4\n    int size;                     // \u8282\u70b9\u6570\u91cf\n} GraphAdjList;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjList *newGraphAdjList() {\n    GraphAdjList *graph = (GraphAdjList *)malloc(sizeof(GraphAdjList));\n    if (!graph) {\n        return NULL;\n    }\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        graph->heads[i] = NULL;\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjList(GraphAdjList *graph) {\n    for (int i = 0; i < graph->size; i++) {\n        AdjListNode *cur = graph->heads[i];\n        while (cur != NULL) {\n            AdjListNode *next = cur->next;\n            if (cur != graph->heads[i]) {\n                free(cur);\n            }\n            cur = next;\n        }\n        free(graph->heads[i]->vertex);\n        free(graph->heads[i]);\n    }\n    free(graph);\n}\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nvoid addEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL && head1 != head2);\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    addEdgeHelper(head1, vet2);\n    addEdgeHelper(head2, vet1);\n}\n\n/* \u5220\u9664\u8fb9 */\nvoid removeEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL);\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    removeEdgeHelper(head1, head2->vertex);\n    removeEdgeHelper(head2, head1->vertex);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjList *graph, Vertex *vet) {\n    assert(graph != NULL && graph->size < MAX_SIZE);\n    AdjListNode *head = (AdjListNode *)malloc(sizeof(AdjListNode));\n    head->vertex = vet;\n    head->next = NULL;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    graph->heads[graph->size++] = head;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjList *graph, Vertex *vet) {\n    AdjListNode *node = findNode(graph, vet);\n    assert(node != NULL);\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    AdjListNode *cur = node, *pre = NULL;\n    while (cur) {\n        pre = cur;\n        cur = cur->next;\n        free(pre);\n    }\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for (int i = 0; i < graph->size; i++) {\n        cur = graph->heads[i];\n        pre = NULL;\n        while (cur) {\n            pre = cur;\n            cur = cur->next;\n            if (cur && cur->vertex == vet) {\n                pre->next = cur->next;\n                free(cur);\n                break;\n            }\n        }\n    }\n    // \u5c06\u8be5\u9876\u70b9\u4e4b\u540e\u7684\u9876\u70b9\u5411\u524d\u79fb\u52a8\uff0c\u4ee5\u586b\u8865\u7a7a\u7f3a\n    int i;\n    for (i = 0; i < graph->size; i++) {\n        if (graph->heads[i] == node)\n            break;\n    }\n    for (int j = i; j < graph->size - 1; j++) {\n        graph->heads[j] = graph->heads[j + 1];\n    }\n    graph->size--;\n    free(vet);\n}\n
    graph_adjacency_list.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList(edges: Array<Array<Vertex?>>) {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    val adjList = HashMap<Vertex, MutableList<Vertex>>()\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (edge in edges) {\n            addVertex(edge[0]!!)\n            addVertex(edge[1]!!)\n            addEdge(edge[0]!!, edge[1]!!)\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return adjList.size\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    fun addEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.add(vet2)\n        adjList[vet2]?.add(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    fun removeEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.remove(vet2)\n        adjList[vet2]?.remove(vet1)\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(vet: Vertex) {\n        if (adjList.containsKey(vet))\n            return\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = mutableListOf()\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(vet: Vertex) {\n        if (!adjList.containsKey(vet))\n            throw IllegalArgumentException()\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (list in adjList.values) {\n            list.remove(vet)\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    fun print() {\n        println(\"\u90bb\u63a5\u8868 =\")\n        for (pair in adjList.entries) {\n            val tmp = mutableListOf<Int>()\n            for (vertex in pair.value) {\n                tmp.add(vertex._val)\n            }\n            println(\"${pair.key._val}: $tmp,\")\n        }\n    }\n}\n
    graph_adjacency_list.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjList\n  attr_reader :adj_list\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(edges)\n    # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    @adj_list = {}\n    # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for edge in edges\n      add_vertex(edge[0])\n      add_vertex(edge[1])\n      add_edge(edge[0], edge[1])\n    end\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @adj_list.length\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    @adj_list[vet1] << vet2\n    @adj_list[vet2] << vet1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    # \u5220\u9664\u8fb9 vet1 - vet2\n    @adj_list[vet1].delete(vet2)\n    @adj_list[vet2].delete(vet1)\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(vet)\n    return if @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    @adj_list[vet] = []\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(vet)\n    raise ArgumentError unless @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    @adj_list.delete(vet)\n    # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for vertex in @adj_list\n      @adj_list[vertex.first].delete(vet) if @adj_list[vertex.first].include?(vet)\n    end\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u8868 ###\n  def __print__\n    puts '\u90bb\u63a5\u8868 ='\n    for vertex in @adj_list\n      tmp = @adj_list[vertex.first].map { |v| v.val }\n      puts \"#{vertex.first.val}: #{tmp},\"\n    end\n  end\nend\n
    graph_adjacency_list.zig
    [class]{GraphAdjList}-[func]{}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_graph/graph_operations/#923-efficiency-comparison","title":"9.2.3 \u00a0 Efficiency comparison","text":"

    Assuming there are \\(n\\) vertices and \\(m\\) edges in the graph, the Table 9-2 compares the time efficiency and space efficiency of the adjacency matrix and adjacency list.

    Table 9-2 \u00a0 Comparison of adjacency matrix and adjacency list

    Adjacency matrix Adjacency list (Linked list) Adjacency list (Hash table) Determine adjacency \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) Add an edge \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) Remove an edge \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) Add a vertex \\(O(n)\\) \\(O(1)\\) \\(O(1)\\) Remove a vertex \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n)\\) Memory space usage \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n + m)\\)

    Observing the Table 9-2 , it seems that the adjacency list (hash table) has the best time efficiency and space efficiency. However, in practice, operating on edges in the adjacency matrix is more efficient, requiring only a single array access or assignment operation. Overall, the adjacency matrix exemplifies the principle of \"space for time\", while the adjacency list exemplifies \"time for space\".

    "},{"location":"chapter_graph/graph_traversal/","title":"9.3 \u00a0 Graph traversal","text":"

    Trees represent a \"one-to-many\" relationship, while graphs have a higher degree of freedom and can represent any \"many-to-many\" relationship. Therefore, we can consider trees as a special case of graphs. Clearly, tree traversal operations are also a special case of graph traversal operations.

    Both graphs and trees require the application of search algorithms to implement traversal operations. Graph traversal can be divided into two types: \"Breadth-First Search (BFS)\" and \"Depth-First Search (DFS)\".

    "},{"location":"chapter_graph/graph_traversal/#931-breadth-first-search","title":"9.3.1 \u00a0 Breadth-first search","text":"

    Breadth-first search is a near-to-far traversal method, starting from a certain node, always prioritizing the visit to the nearest vertices and expanding outwards layer by layer. As shown in the Figure 9-9 , starting from the top left vertex, first traverse all adjacent vertices of that vertex, then traverse all adjacent vertices of the next vertex, and so on, until all vertices have been visited.

    Figure 9-9 \u00a0 Breadth-first traversal of a graph

    "},{"location":"chapter_graph/graph_traversal/#1-algorithm-implementation","title":"1. \u00a0 Algorithm implementation","text":"

    BFS is usually implemented with the help of a queue, as shown in the code below. The queue has a \"first in, first out\" property, which aligns with the BFS idea of traversing \"from near to far\".

    1. Add the starting vertex startVet to the queue and start the loop.
    2. In each iteration of the loop, pop the vertex at the front of the queue and record it as visited, then add all adjacent vertices of that vertex to the back of the queue.
    3. Repeat step 2. until all vertices have been visited.

    To prevent revisiting vertices, we use a hash table visited to record which nodes have been visited.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_bfs.py
    def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]([start_vet])\n    # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    que = deque[Vertex]([start_vet])\n    # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while len(que) > 0:\n        vet = que.popleft()  # \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adj_vet in graph.adj_list[vet]:\n            if adj_vet in visited:\n                continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.append(adj_vet)  # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adj_vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n
    graph_bfs.cpp
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphBFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited = {startVet};\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    queue<Vertex *> que;\n    que.push(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.empty()) {\n        Vertex *vet = que.front();\n        que.pop();          // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push_back(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (auto adjVet : graph.adjList[vet]) {\n            if (visited.count(adjVet))\n                continue;            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.push(adjVet);        // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.emplace(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.java
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new LinkedList<>();\n    que.offer(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        Vertex vet = que.poll(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet);            // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (Vertex adjVet : graph.adjList.get(vet)) {\n            if (visited.contains(adjVet))\n                continue;        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.cs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [startVet];\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new();\n    que.Enqueue(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.Count > 0) {\n        Vertex vet = que.Dequeue(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.Add(vet);               // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        foreach (Vertex adjVet in graph.adjList[vet]) {\n            if (visited.Contains(adjVet)) {\n                continue;          // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.Enqueue(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.Add(adjVet);   // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.go
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    visited[startVet] = struct{}{}\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS, \u4f7f\u7528\u5207\u7247\u6a21\u62df\u961f\u5217\n    queue := make([]Vertex, 0)\n    queue = append(queue, startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    for len(queue) > 0 {\n        // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        vet := queue[0]\n        queue = queue[1:]\n        // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        res = append(res, vet)\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for _, adjVet := range g.adjList[vet] {\n            _, isExist := visited[adjVet]\n            // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            if !isExist {\n                queue = append(queue, adjVet)\n                visited[adjVet] = struct{}{}\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.swift
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = [startVet]\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    var que: [Vertex] = [startVet]\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.isEmpty {\n        let vet = que.removeFirst() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adjVet in graph.adjList[vet] ?? [] {\n            if visited.contains(adjVet) {\n                continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.append(adjVet) // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.insert(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.js
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.ts
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.dart
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n  // \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  visited.add(startVet);\n  // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  Queue<Vertex> que = Queue();\n  que.add(startVet);\n  // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while (que.isNotEmpty) {\n    Vertex vet = que.removeFirst(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet in graph.adjList[vet]!) {\n      if (visited.contains(adjVet)) {\n        continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      }\n      que.add(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    }\n  }\n  // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  return res;\n}\n
    graph_bfs.rs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    visited.insert(start_vet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    let mut que = VecDeque::new();\n    que.push_back(start_vet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.is_empty() {\n        let vet = que.pop_front().unwrap(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        if let Some(adj_vets) = graph.adj_list.get(&vet) {\n            for &adj_vet in adj_vets {\n                if visited.contains(&adj_vet) {\n                    continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n                }\n                que.push_back(adj_vet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited.insert(adj_vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res\n}\n
    graph_bfs.c
    /* \u8282\u70b9\u961f\u5217\u7ed3\u6784\u4f53 */\ntypedef struct {\n    Vertex *vertices[MAX_SIZE];\n    int front, rear, size;\n} Queue;\n\n/* \u6784\u9020\u51fd\u6570 */\nQueue *newQueue() {\n    Queue *q = (Queue *)malloc(sizeof(Queue));\n    q->front = q->rear = q->size = 0;\n    return q;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nint isEmpty(Queue *q) {\n    return q->size == 0;\n}\n\n/* \u5165\u961f\u64cd\u4f5c */\nvoid enqueue(Queue *q, Vertex *vet) {\n    q->vertices[q->rear] = vet;\n    q->rear = (q->rear + 1) % MAX_SIZE;\n    q->size++;\n}\n\n/* \u51fa\u961f\u64cd\u4f5c */\nVertex *dequeue(Queue *q) {\n    Vertex *vet = q->vertices[q->front];\n    q->front = (q->front + 1) % MAX_SIZE;\n    q->size--;\n    return vet;\n}\n\n/* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **visited, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (visited[i] == vet)\n            return 1;\n    }\n    return 0;\n}\n\n/* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphBFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize, Vertex **visited, int *visitedSize) {\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue *queue = newQueue();\n    enqueue(queue, startVet);\n    visited[(*visitedSize)++] = startVet;\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!isEmpty(queue)) {\n        Vertex *vet = dequeue(queue); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res[(*resSize)++] = vet;      // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        AdjListNode *node = findNode(graph, vet);\n        while (node != NULL) {\n            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            if (!isVisited(visited, *visitedSize, node->vertex)) {\n                enqueue(queue, node->vertex);             // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited[(*visitedSize)++] = node->vertex; // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n            node = node->next;\n        }\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(queue);\n}\n
    graph_bfs.kt
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphBFS(graph: GraphAdjList, startVet: Vertex): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex>()\n    visited.add(startVet)\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    val que = LinkedList<Vertex>()\n    que.offer(startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        val vet = que.poll() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet)         // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (adjVet in graph.adjList[vet]!!) {\n            if (visited.contains(adjVet))\n                continue        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet)   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.rb
    ### \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_bfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new([start_vet])\n  # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  que = [start_vet]\n  # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while que.length > 0\n    vet = que.shift # \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adj_vet in graph.adj_list[vet]\n      next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      que << adj_vet # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adj_vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    end\n  end\n  # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res\nend\n
    graph_bfs.zig
    [class]{}-[func]{graphBFS}\n
    Code Visualization

    Full Screen >

    The code is relatively abstract, it is suggested to compare with the following figure to deepen the understanding.

    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 9-10 \u00a0 Steps of breadth-first search of a graph

    Is the sequence of breadth-first traversal unique?

    Not unique. Breadth-first traversal only requires traversing in a \"from near to far\" order, and the traversal order of multiple vertices at the same distance can be arbitrarily shuffled. For example, in the above figure, the visitation order of vertices \\(1\\) and \\(3\\) can be switched, as can the order of vertices \\(2\\), \\(4\\), and \\(6\\).

    "},{"location":"chapter_graph/graph_traversal/#2-complexity-analysis","title":"2. \u00a0 Complexity analysis","text":"

    Time complexity: All vertices will be enqueued and dequeued once, using \\(O(|V|)\\) time; in the process of traversing adjacent vertices, since it is an undirected graph, all edges will be visited \\(2\\) times, using \\(O(2|E|)\\) time; overall using \\(O(|V| + |E|)\\) time.

    Space complexity: The maximum number of vertices in list res, hash table visited, and queue que is \\(|V|\\), using \\(O(|V|)\\) space.

    "},{"location":"chapter_graph/graph_traversal/#932-depth-first-search","title":"9.3.2 \u00a0 Depth-first search","text":"

    Depth-first search is a traversal method that prioritizes going as far as possible and then backtracks when no further paths are available. As shown in the Figure 9-11 , starting from the top left vertex, visit some adjacent vertex of the current vertex until no further path is available, then return and continue until all vertices are traversed.

    Figure 9-11 \u00a0 Depth-first traversal of a graph

    "},{"location":"chapter_graph/graph_traversal/#1-algorithm-implementation_1","title":"1. \u00a0 Algorithm implementation","text":"

    This \"go as far as possible and then return\" algorithm paradigm is usually implemented based on recursion. Similar to breadth-first search, in depth-first search, we also need the help of a hash table visited to record the visited vertices to avoid revisiting.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_dfs.py
    def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570\"\"\"\n    res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adj_list[vet]:\n        if adjVet in visited:\n            continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n\ndef graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]()\n    dfs(graph, visited, res, start_vet)\n    return res\n
    graph_dfs.cpp
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList &graph, unordered_set<Vertex *> &visited, vector<Vertex *> &res, Vertex *vet) {\n    res.push_back(vet);   // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.emplace(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex *adjVet : graph.adjList[vet]) {\n        if (visited.count(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphDFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited;\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.java
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList graph, Set<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet : graph.adjList.get(vet)) {\n        if (visited.contains(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.cs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid DFS(GraphAdjList graph, HashSet<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.Add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.Add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    foreach (Vertex adjVet in graph.adjList[vet]) {\n        if (visited.Contains(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9                             \n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        DFS(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [];\n    DFS(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.go
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(g *graphAdjList, visited map[Vertex]struct{}, res *[]Vertex, vet Vertex) {\n    // append \u64cd\u4f5c\u4f1a\u8fd4\u56de\u65b0\u7684\u7684\u5f15\u7528\uff0c\u5fc5\u987b\u8ba9\u539f\u5f15\u7528\u91cd\u65b0\u8d4b\u503c\u4e3a\u65b0slice\u7684\u5f15\u7528\n    *res = append(*res, vet)\n    visited[vet] = struct{}{}\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for _, adjVet := range g.adjList[vet] {\n        _, isExist := visited[adjVet]\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        if !isExist {\n            dfs(g, visited, res, adjVet)\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    dfs(g, visited, &res, startVet)\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_dfs.swift
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], vet: Vertex) {\n    res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adjList[vet] ?? [] {\n        if visited.contains(adjVet) {\n            continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph: graph, visited: &visited, res: &res, vet: adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = []\n    dfs(graph: graph, visited: &visited, res: &res, vet: startVet)\n    return res\n}\n
    graph_dfs.js
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction dfs(graph, visited, res, vet) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.ts
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunction dfs(\n    graph: GraphAdjList,\n    visited: Set<Vertex>,\n    res: Vertex[],\n    vet: Vertex\n): void {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.dart
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(\n  GraphAdjList graph,\n  Set<Vertex> visited,\n  List<Vertex> res,\n  Vertex vet,\n) {\n  res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for (Vertex adjVet in graph.adjList[vet]!) {\n    if (visited.contains(adjVet)) {\n      continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    }\n    // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adjVet);\n  }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  dfs(graph, visited, res, startVet);\n  return res;\n}\n
    graph_dfs.rs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex>, vet: Vertex) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n                         // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    if let Some(adj_vets) = graph.adj_list.get(&vet) {\n        for &adj_vet in adj_vets {\n            if visited.contains(&adj_vet) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, visited, res, adj_vet);\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    dfs(&graph, &mut visited, &mut res, start_vet);\n\n    res\n}\n
    graph_dfs.c
    /* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **res, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (res[i] == vet) {\n            return 1;\n        }\n    }\n    return 0;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList *graph, Vertex **res, int *resSize, Vertex *vet) {\n    // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    res[(*resSize)++] = vet;\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    AdjListNode *node = findNode(graph, vet);\n    while (node != NULL) {\n        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        if (!isVisited(res, *resSize, node->vertex)) {\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, res, resSize, node->vertex);\n        }\n        node = node->next;\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphDFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize) {\n    dfs(graph, res, resSize, startVet);\n}\n
    graph_dfs.kt
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfun dfs(\n    graph: GraphAdjList,\n    visited: MutableSet<Vertex?>,\n    res: MutableList<Vertex?>,\n    vet: Vertex?\n) {\n    res.add(vet)     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (adjVet in graph.adjList[vet]!!) {\n        if (visited.contains(adjVet))\n            continue  // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphDFS(graph: GraphAdjList, startVet: Vertex?): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex?>()\n    dfs(graph, visited, res, startVet)\n    return res\n}\n
    graph_dfs.rb
    ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 ###\ndef dfs(graph, visited, res, vet)\n  res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for adj_vet in graph.adj_list[vet]\n    next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adj_vet)\n  end\nend\n\n### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_dfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new\n  dfs(graph, visited, res, start_vet)\n  res\nend\n
    graph_dfs.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{graphDFS}\n
    Code Visualization

    Full Screen >

    The algorithm process of depth-first search is shown in the following figure.

    • Dashed lines represent downward recursion, indicating that a new recursive method has been initiated to visit a new vertex.
    • Curved dashed lines represent upward backtracking, indicating that this recursive method has returned to the position where this method was initiated.

    To deepen the understanding, it is suggested to combine the following figure with the code to simulate (or draw) the entire DFS process in your mind, including when each recursive method is initiated and when it returns.

    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 9-12 \u00a0 Steps of depth-first search of a graph

    Is the sequence of depth-first traversal unique?

    Similar to breadth-first traversal, the order of the depth-first traversal sequence is also not unique. Given a certain vertex, exploring in any direction first is possible, that is, the order of adjacent vertices can be arbitrarily shuffled, all being part of depth-first traversal.

    Taking tree traversal as an example, \"root \\(\\rightarrow\\) left \\(\\rightarrow\\) right\", \"left \\(\\rightarrow\\) root \\(\\rightarrow\\) right\", \"left \\(\\rightarrow\\) right \\(\\rightarrow\\) root\" correspond to preorder, inorder, and postorder traversals, respectively. They showcase three types of traversal priorities, yet all three are considered depth-first traversal.

    "},{"location":"chapter_graph/graph_traversal/#2-complexity-analysis_1","title":"2. \u00a0 Complexity analysis","text":"

    Time complexity: All vertices will be visited once, using \\(O(|V|)\\) time; all edges will be visited twice, using \\(O(2|E|)\\) time; overall using \\(O(|V| + |E|)\\) time.

    Space complexity: The maximum number of vertices in list res, hash table visited is \\(|V|\\), and the maximum recursion depth is \\(|V|\\), therefore using \\(O(|V|)\\) space.

    "},{"location":"chapter_graph/summary/","title":"9.4 \u00a0 Summary","text":""},{"location":"chapter_graph/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • A graph consists of vertices and edges and can be represented as a set comprising a group of vertices and a group of edges.
    • Compared to linear relationships (linked lists) and divide-and-conquer relationships (trees), network relationships (graphs) have a higher degree of freedom and are therefore more complex.
    • The edges of a directed graph have directionality, any vertex in a connected graph is reachable, and each edge in a weighted graph contains a weight variable.
    • Adjacency matrices use matrices to represent graphs, with each row (column) representing a vertex and matrix elements representing edges, using \\(1\\) or \\(0\\) to indicate the presence or absence of an edge between two vertices. Adjacency matrices are highly efficient for add, delete, find, and modify operations, but they consume more space.
    • Adjacency lists use multiple linked lists to represent graphs, with the \\(i^{th}\\) list corresponding to vertex \\(i\\), containing all its adjacent vertices. Adjacency lists save more space compared to adjacency matrices, but since it is necessary to traverse the list to find edges, their time efficiency is lower.
    • When the linked lists in the adjacency list are too long, they can be converted into red-black trees or hash tables to improve query efficiency.
    • From the perspective of algorithmic thinking, adjacency matrices embody the principle of \"space for time,\" while adjacency lists embody \"time for space.\"
    • Graphs can be used to model various real systems, such as social networks, subway routes, etc.
    • A tree is a special case of a graph, and tree traversal is also a special case of graph traversal.
    • Breadth-first traversal of a graph is a search method that expands layer by layer from near to far, usually implemented with a queue.
    • Depth-first traversal of a graph is a search method that prefers to go as deep as possible and backtracks when no further paths are available, often based on recursion.
    "},{"location":"chapter_graph/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is a path defined as a sequence of vertices or a sequence of edges?

    Definitions vary between different language versions on Wikipedia: the English version defines a path as \"a sequence of edges,\" while the Chinese version defines it as \"a sequence of vertices.\" Here is the original text from the English version: In graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices.

    In this document, a path is considered a sequence of edges, rather than a sequence of vertices. This is because there might be multiple edges connecting two vertices, in which case each edge corresponds to a path.

    Q: In a disconnected graph, are there points that cannot be traversed to?

    In a disconnected graph, starting from a certain vertex, there is at least one vertex that cannot be reached. Traversing a disconnected graph requires setting multiple starting points to traverse all connected components of the graph.

    Q: In an adjacency list, does the order of \"all vertices connected to that vertex\" matter?

    It can be in any order. However, in practical applications, it might be necessary to sort according to certain rules, such as the order in which vertices are added, or the order of vertex values, etc., to facilitate the quick search for vertices with certain extremal values.

    "},{"location":"chapter_hashing/","title":"Chapter 6. \u00a0 Hash table","text":"

    Abstract

    In the world of computing, a hash table is akin to an intelligent librarian.

    It understands how to compute index numbers, enabling swift retrieval of the desired book.

    "},{"location":"chapter_hashing/#chapter-contents","title":"Chapter contents","text":"
    • 6.1 \u00a0 Hash table
    • 6.2 \u00a0 Hash collision
    • 6.3 \u00a0 Hash algorithm
    • 6.4 \u00a0 Summary
    "},{"location":"chapter_hashing/hash_algorithm/","title":"6.3 \u00a0 Hash algorithms","text":"

    The previous two sections introduced the working principle of hash tables and the methods to handle hash collisions. However, both open addressing and chaining can only ensure that the hash table functions normally when collisions occur, but cannot reduce the frequency of hash collisions.

    If hash collisions occur too frequently, the performance of the hash table will deteriorate drastically. As shown in the Figure 6-8 , for a chaining hash table, in the ideal case, the key-value pairs are evenly distributed across the buckets, achieving optimal query efficiency; in the worst case, all key-value pairs are stored in the same bucket, degrading the time complexity to \\(O(n)\\).

    Figure 6-8 \u00a0 Ideal and worst cases of hash collisions

    The distribution of key-value pairs is determined by the hash function. Recalling the steps of calculating a hash function, first compute the hash value, then modulo it by the array length:

    index = hash(key) % capacity\n

    Observing the above formula, when the hash table capacity capacity is fixed, the hash algorithm hash() determines the output value, thereby determining the distribution of key-value pairs in the hash table.

    This means that, to reduce the probability of hash collisions, we should focus on the design of the hash algorithm hash().

    "},{"location":"chapter_hashing/hash_algorithm/#631-goals-of-hash-algorithms","title":"6.3.1 \u00a0 Goals of hash algorithms","text":"

    To achieve a \"fast and stable\" hash table data structure, hash algorithms should have the following characteristics:

    • Determinism: For the same input, the hash algorithm should always produce the same output. Only then can the hash table be reliable.
    • High efficiency: The process of computing the hash value should be fast enough. The smaller the computational overhead, the more practical the hash table.
    • Uniform distribution: The hash algorithm should ensure that key-value pairs are evenly distributed in the hash table. The more uniform the distribution, the lower the probability of hash collisions.

    In fact, hash algorithms are not only used to implement hash tables but are also widely applied in other fields.

    • Password storage: To protect the security of user passwords, systems usually do not store the plaintext passwords but rather the hash values of the passwords. When a user enters a password, the system calculates the hash value of the input and compares it with the stored hash value. If they match, the password is considered correct.
    • Data integrity check: The data sender can calculate the hash value of the data and send it along; the receiver can recalculate the hash value of the received data and compare it with the received hash value. If they match, the data is considered intact.

    For cryptographic applications, to prevent reverse engineering such as deducing the original password from the hash value, hash algorithms need higher-level security features.

    • Unidirectionality: It should be impossible to deduce any information about the input data from the hash value.
    • Collision resistance: It should be extremely difficult to find two different inputs that produce the same hash value.
    • Avalanche effect: Minor changes in the input should lead to significant and unpredictable changes in the output.

    Note that \"Uniform Distribution\" and \"Collision Resistance\" are two separate concepts. Satisfying uniform distribution does not necessarily mean collision resistance. For example, under random input key, the hash function key % 100 can produce a uniformly distributed output. However, this hash algorithm is too simple, and all key with the same last two digits will have the same output, making it easy to deduce a usable key from the hash value, thereby cracking the password.

    "},{"location":"chapter_hashing/hash_algorithm/#632-design-of-hash-algorithms","title":"6.3.2 \u00a0 Design of hash algorithms","text":"

    The design of hash algorithms is a complex issue that requires consideration of many factors. However, for some less demanding scenarios, we can also design some simple hash algorithms.

    • Additive hash: Add up the ASCII codes of each character in the input and use the total sum as the hash value.
    • Multiplicative hash: Utilize the non-correlation of multiplication, multiplying each round by a constant, accumulating the ASCII codes of each character into the hash value.
    • XOR hash: Accumulate the hash value by XORing each element of the input data.
    • Rotating hash: Accumulate the ASCII code of each character into a hash value, performing a rotation operation on the hash value before each accumulation.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig simple_hash.py
    def add_hash(key: str) -> int:\n    \"\"\"\u52a0\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash += ord(c)\n    return hash % modulus\n\ndef mul_hash(key: str) -> int:\n    \"\"\"\u4e58\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = 31 * hash + ord(c)\n    return hash % modulus\n\ndef xor_hash(key: str) -> int:\n    \"\"\"\u5f02\u6216\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash ^= ord(c)\n    return hash % modulus\n\ndef rot_hash(key: str) -> int:\n    \"\"\"\u65cb\u8f6c\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = (hash << 4) ^ (hash >> 28) ^ ord(c)\n    return hash % modulus\n
    simple_hash.cpp
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (31 * hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash ^= (int)c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.java
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (31 * hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n    int hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash ^= (int) c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n
    simple_hash.cs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint AddHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint MulHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (31 * hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint XorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash ^= c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint RotHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.go
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (31*hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key string) int {\n    hash := 0\n    modulus := 1000000007\n    for _, b := range []byte(key) {\n        fmt.Println(int(b))\n        hash ^= int(b)\n        hash = (31*hash + int(b)) % modulus\n    }\n    return hash & modulus\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ int64(b)) % modulus\n    }\n    return int(hash)\n}\n
    simple_hash.swift
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (31 * hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash ^= Int(scalar.value)\n        }\n    }\n    return hash & MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = ((hash << 4) ^ (hash >> 28) ^ Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n
    simple_hash.js
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.ts
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.dart
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (31 * hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash ^= key.codeUnitAt(i);\n  }\n  return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = ((hash << 4) ^ (hash >> 28) ^ key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n
    simple_hash.rs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfn add_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfn mul_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (31 * hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfn xor_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash ^= c as i64;\n    }\n\n    (hash & MODULUS) as i32\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfn rot_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n
    simple_hash.c
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (31 * hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(char *key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n\n    for (int i = 0; i < strlen(key); i++) {\n        hash ^= (unsigned char)key[i];\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (unsigned char)key[i]) % MODULUS;\n    }\n\n    return (int)hash;\n}\n
    simple_hash.kt
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfun addHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfun mulHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (31 * hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfun xorHash(key: String): Int {\n    var hash = 0\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = hash xor c.code\n    }\n    return hash and MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfun rotHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = ((hash shl 4) xor (hash shr 28) xor c.code.toLong()) % MODULUS\n    }\n    return hash.toInt()\n}\n
    simple_hash.rb
    ### \u52a0\u6cd5\u54c8\u5e0c ###\ndef add_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash += c.ord }\n\n  hash % modulus\nend\n\n### \u4e58\u6cd5\u54c8\u5e0c ###\ndef mul_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = 31 * hash + c.ord }\n\n  hash % modulus\nend\n\n### \u5f02\u6216\u54c8\u5e0c ###\ndef xor_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash ^= c.ord }\n\n  hash % modulus\nend\n\n### \u65cb\u8f6c\u54c8\u5e0c ###\ndef rot_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = (hash << 4) ^ (hash >> 28) ^ c.ord }\n\n  hash % modulus\nend\n
    simple_hash.zig
    [class]{}-[func]{addHash}\n\n[class]{}-[func]{mulHash}\n\n[class]{}-[func]{xorHash}\n\n[class]{}-[func]{rotHash}\n
    Code Visualization

    Full Screen >

    It is observed that the last step of each hash algorithm is to take the modulus of the large prime number \\(1000000007\\) to ensure that the hash value is within an appropriate range. It is worth pondering why emphasis is placed on modulo a prime number, or what are the disadvantages of modulo a composite number? This is an interesting question.

    To conclude: Using a large prime number as the modulus can maximize the uniform distribution of hash values. Since a prime number does not share common factors with other numbers, it can reduce the periodic patterns caused by the modulo operation, thus avoiding hash collisions.

    For example, suppose we choose the composite number \\(9\\) as the modulus, which can be divided by \\(3\\), then all key divisible by \\(3\\) will be mapped to hash values \\(0\\), \\(3\\), \\(6\\).

    \\[ \\begin{aligned} \\text{modulus} & = 9 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 0, 3, 6, 0, 3, 6, 0, 3, 6,\\dots \\} \\end{aligned} \\]

    If the input key happens to have this kind of arithmetic sequence distribution, then the hash values will cluster, thereby exacerbating hash collisions. Now, suppose we replace modulus with the prime number \\(13\\), since there are no common factors between key and modulus, the uniformity of the output hash values will be significantly improved.

    \\[ \\begin{aligned} \\text{modulus} & = 13 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 9, 12, 2, 5, 8, 11, 1, 4, 7, \\dots \\} \\end{aligned} \\]

    It is worth noting that if the key is guaranteed to be randomly and uniformly distributed, then choosing a prime number or a composite number as the modulus can both produce uniformly distributed hash values. However, when the distribution of key has some periodicity, modulo a composite number is more likely to result in clustering.

    In summary, we usually choose a prime number as the modulus, and this prime number should be large enough to eliminate periodic patterns as much as possible, enhancing the robustness of the hash algorithm.

    "},{"location":"chapter_hashing/hash_algorithm/#633-common-hash-algorithms","title":"6.3.3 \u00a0 Common hash algorithms","text":"

    It is not hard to see that the simple hash algorithms mentioned above are quite \"fragile\" and far from reaching the design goals of hash algorithms. For example, since addition and XOR obey the commutative law, additive hash and XOR hash cannot distinguish strings with the same content but in different order, which may exacerbate hash collisions and cause security issues.

    In practice, we usually use some standard hash algorithms, such as MD5, SHA-1, SHA-2, and SHA-3. They can map input data of any length to a fixed-length hash value.

    Over the past century, hash algorithms have been in a continuous process of upgrading and optimization. Some researchers strive to improve the performance of hash algorithms, while others, including hackers, are dedicated to finding security issues in hash algorithms. The Table 6-2 shows hash algorithms commonly used in practical applications.

    • MD5 and SHA-1 have been successfully attacked multiple times and are thus abandoned in various security applications.
    • SHA-2 series, especially SHA-256, is one of the most secure hash algorithms to date, with no successful attacks reported, hence commonly used in various security applications and protocols.
    • SHA-3 has lower implementation costs and higher computational efficiency compared to SHA-2, but its current usage coverage is not as extensive as the SHA-2 series.

    Table 6-2 \u00a0 Common hash algorithms

    MD5 SHA-1 SHA-2 SHA-3 Release Year 1992 1995 2002 2008 Output Length 128 bit 160 bit 256/512 bit 224/256/384/512 bit Hash Collisions Frequent Frequent Rare Rare Security Level Low, has been successfully attacked Low, has been successfully attacked High High Applications Abandoned, still used for data integrity checks Abandoned Cryptocurrency transaction verification, digital signatures, etc. Can be used to replace SHA-2"},{"location":"chapter_hashing/hash_algorithm/#hash-values-in-data-structures","title":"Hash values in data structures","text":"

    We know that the keys in a hash table can be of various data types such as integers, decimals, or strings. Programming languages usually provide built-in hash algorithms for these data types to calculate the bucket indices in the hash table. Taking Python as an example, we can use the hash() function to compute the hash values for various data types.

    • The hash values of integers and booleans are their own values.
    • The calculation of hash values for floating-point numbers and strings is more complex, and interested readers are encouraged to study this on their own.
    • The hash value of a tuple is a combination of the hash values of each of its elements, resulting in a single hash value.
    • The hash value of an object is generated based on its memory address. By overriding the hash method of an object, hash values can be generated based on content.

    Tip

    Be aware that the definition and methods of the built-in hash value calculation functions in different programming languages vary.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig built_in_hash.py
    num = 3\nhash_num = hash(num)\n# Hash value of integer 3 is 3\n\nbol = True\nhash_bol = hash(bol)\n# Hash value of boolean True is 1\n\ndec = 3.14159\nhash_dec = hash(dec)\n# Hash value of decimal 3.14159 is 326484311674566659\n\nstr = \"Hello \u7b97\u6cd5\"\nhash_str = hash(str)\n# Hash value of string \"Hello \u7b97\u6cd5\" is 4617003410720528961\n\ntup = (12836, \"\u5c0f\u54c8\")\nhash_tup = hash(tup)\n# Hash value of tuple (12836, '\u5c0f\u54c8') is 1029005403108185979\n\nobj = ListNode(0)\nhash_obj = hash(obj)\n# Hash value of ListNode object at 0x1058fd810 is 274267521\n
    built_in_hash.cpp
    int num = 3;\nsize_t hashNum = hash<int>()(num);\n// Hash value of integer 3 is 3\n\nbool bol = true;\nsize_t hashBol = hash<bool>()(bol);\n// Hash value of boolean 1 is 1\n\ndouble dec = 3.14159;\nsize_t hashDec = hash<double>()(dec);\n// Hash value of decimal 3.14159 is 4614256650576692846\n\nstring str = \"Hello \u7b97\u6cd5\";\nsize_t hashStr = hash<string>()(str);\n// Hash value of string \"Hello \u7b97\u6cd5\" is 15466937326284535026\n\n// In C++, built-in std::hash() only provides hash values for basic data types\n// Hash values for arrays and objects need to be implemented separately\n
    built_in_hash.java
    int num = 3;\nint hashNum = Integer.hashCode(num);\n// Hash value of integer 3 is 3\n\nboolean bol = true;\nint hashBol = Boolean.hashCode(bol);\n// Hash value of boolean true is 1231\n\ndouble dec = 3.14159;\nint hashDec = Double.hashCode(dec);\n// Hash value of decimal 3.14159 is -1340954729\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode();\n// Hash value of string \"Hello \u7b97\u6cd5\" is -727081396\n\nObject[] arr = { 12836, \"\u5c0f\u54c8\" };\nint hashTup = Arrays.hashCode(arr);\n// Hash value of array [12836, \u5c0f\u54c8] is 1151158\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode();\n// Hash value of ListNode object utils.ListNode@7dc5e7b4 is 2110121908\n
    built_in_hash.cs
    int num = 3;\nint hashNum = num.GetHashCode();\n// Hash value of integer 3 is 3;\n\nbool bol = true;\nint hashBol = bol.GetHashCode();\n// Hash value of boolean true is 1;\n\ndouble dec = 3.14159;\nint hashDec = dec.GetHashCode();\n// Hash value of decimal 3.14159 is -1340954729;\n\nstring str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.GetHashCode();\n// Hash value of string \"Hello \u7b97\u6cd5\" is -586107568;\n\nobject[] arr = [12836, \"\u5c0f\u54c8\"];\nint hashTup = arr.GetHashCode();\n// Hash value of array [12836, \u5c0f\u54c8] is 42931033;\n\nListNode obj = new(0);\nint hashObj = obj.GetHashCode();\n// Hash value of ListNode object 0 is 39053774;\n
    built_in_hash.go
    // Go does not provide built-in hash code functions\n
    built_in_hash.swift
    let num = 3\nlet hashNum = num.hashValue\n// Hash value of integer 3 is 9047044699613009734\n\nlet bol = true\nlet hashBol = bol.hashValue\n// Hash value of boolean true is -4431640247352757451\n\nlet dec = 3.14159\nlet hashDec = dec.hashValue\n// Hash value of decimal 3.14159 is -2465384235396674631\n\nlet str = \"Hello \u7b97\u6cd5\"\nlet hashStr = str.hashValue\n// Hash value of string \"Hello \u7b97\u6cd5\" is -7850626797806988787\n\nlet arr = [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")]\nlet hashTup = arr.hashValue\n// Hash value of array [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")] is -2308633508154532996\n\nlet obj = ListNode(x: 0)\nlet hashObj = obj.hashValue\n// Hash value of ListNode object utils.ListNode is -2434780518035996159\n
    built_in_hash.js
    // JavaScript does not provide built-in hash code functions\n
    built_in_hash.ts
    // TypeScript does not provide built-in hash code functions\n
    built_in_hash.dart
    int num = 3;\nint hashNum = num.hashCode;\n// Hash value of integer 3 is 34803\n\nbool bol = true;\nint hashBol = bol.hashCode;\n// Hash value of boolean true is 1231\n\ndouble dec = 3.14159;\nint hashDec = dec.hashCode;\n// Hash value of decimal 3.14159 is 2570631074981783\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode;\n// Hash value of string \"Hello \u7b97\u6cd5\" is 468167534\n\nList arr = [12836, \"\u5c0f\u54c8\"];\nint hashArr = arr.hashCode;\n// Hash value of array [12836, \u5c0f\u54c8] is 976512528\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode;\n// Hash value of ListNode object Instance of 'ListNode' is 1033450432\n
    built_in_hash.rs
    use std::collections::hash_map::DefaultHasher;\nuse std::hash::{Hash, Hasher};\n\nlet num = 3;\nlet mut num_hasher = DefaultHasher::new();\nnum.hash(&mut num_hasher);\nlet hash_num = num_hasher.finish();\n// Hash value of integer 3 is 568126464209439262\n\nlet bol = true;\nlet mut bol_hasher = DefaultHasher::new();\nbol.hash(&mut bol_hasher);\nlet hash_bol = bol_hasher.finish();\n// Hash value of boolean true is 4952851536318644461\n\nlet dec: f32 = 3.14159;\nlet mut dec_hasher = DefaultHasher::new();\ndec.to_bits().hash(&mut dec_hasher);\nlet hash_dec = dec_hasher.finish();\n// Hash value of decimal 3.14159 is 2566941990314602357\n\nlet str = \"Hello \u7b97\u6cd5\";\nlet mut str_hasher = DefaultHasher::new();\nstr.hash(&mut str_hasher);\nlet hash_str = str_hasher.finish();\n// Hash value of string \"Hello \u7b97\u6cd5\" is 16092673739211250988\n\nlet arr = (&12836, &\"\u5c0f\u54c8\");\nlet mut tup_hasher = DefaultHasher::new();\narr.hash(&mut tup_hasher);\nlet hash_tup = tup_hasher.finish();\n// Hash value of tuple (12836, \"\u5c0f\u54c8\") is 1885128010422702749\n\nlet node = ListNode::new(42);\nlet mut hasher = DefaultHasher::new();\nnode.borrow().val.hash(&mut hasher);\nlet hash = hasher.finish();\n// Hash value of ListNode object RefCell { value: ListNode { val: 42, next: None } } is 15387811073369036852\n
    built_in_hash.c
    // C does not provide built-in hash code functions\n
    built_in_hash.kt
    \n
    built_in_hash.zig
    \n
    Code Visualization

    Full Screen >

    In many programming languages, only immutable objects can serve as the key in a hash table. If we use a list (dynamic array) as a key, when the contents of the list change, its hash value also changes, and we would no longer be able to find the original value in the hash table.

    Although the member variables of a custom object (such as a linked list node) are mutable, it is hashable. This is because the hash value of an object is usually generated based on its memory address, and even if the contents of the object change, the memory address remains the same, so the hash value remains unchanged.

    You might have noticed that the hash values output in different consoles are different. This is because the Python interpreter adds a random salt to the string hash function each time it starts up. This approach effectively prevents HashDoS attacks and enhances the security of the hash algorithm.

    "},{"location":"chapter_hashing/hash_collision/","title":"6.2 \u00a0 Hash collision","text":"

    As mentioned in the previous section, usually the input space of a hash function is much larger than its output space, making hash collisions theoretically inevitable. For example, if the input space consists of all integers and the output space is the size of the array capacity, multiple integers will inevitably map to the same bucket index.

    Hash collisions can lead to incorrect query results, severely affecting the usability of hash tables. To solve this problem, we expand the hash table whenever a hash collision occurs, until the collision is resolved. This method is simple and effective but inefficient due to the extensive data transfer and hash value computation involved in resizing the hash table. To improve efficiency, we can adopt the following strategies:

    1. Improve the data structure of the hash table, allowing it to function normally in the event of a hash collision.
    2. Only perform resizing when necessary, i.e., when hash collisions are severe.

    There are mainly two methods for improving the structure of hash tables: \"Separate Chaining\" and \"Open Addressing\".

    "},{"location":"chapter_hashing/hash_collision/#621-separate-chaining","title":"6.2.1 \u00a0 Separate chaining","text":"

    In the original hash table, each bucket can store only one key-value pair. \"Separate chaining\" transforms individual elements into a linked list, with key-value pairs as list nodes, storing all colliding key-value pairs in the same list. The Figure 6-5 shows an example of a hash table with separate chaining.

    Figure 6-5 \u00a0 Separate chaining hash table

    The operations of a hash table implemented with separate chaining have changed as follows:

    • Querying elements: Input key, pass through the hash function to obtain the bucket index, access the head node of the list, then traverse the list and compare key to find the target key-value pair.
    • Adding elements: First access the list head node via the hash function, then add the node (key-value pair) to the list.
    • Deleting elements: Access the list head based on the hash function's result, then traverse the list to find and remove the target node.

    Separate chaining has the following limitations:

    • Increased space usage: The linked list contains node pointers, which consume more memory space than arrays.
    • Reduced query efficiency: Due to the need for linear traversal of the list to find the corresponding element.

    The code below provides a simple implementation of a separate chaining hash table, with two things to note:

    • Lists (dynamic arrays) are used instead of linked lists for simplicity. In this setup, the hash table (array) contains multiple buckets, each of which is a list.
    • This implementation includes a method for resizing the hash table. When the load factor exceeds \\(\\frac{2}{3}\\), we resize the hash table to twice its original size.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_chaining.py
    class HashMapChaining:\n    \"\"\"\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets = [[] for _ in range(self.capacity)]  # \u6876\u6570\u7ec4\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def get(self, key: int) -> str | None:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket:\n            if pair.key == key:\n                return pair.val\n        # \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket:\n            if pair.key == key:\n                pair.val = val\n                return\n        # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        pair = Pair(key, val)\n        bucket.append(pair)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for pair in bucket:\n            if pair.key == key:\n                bucket.remove(pair)\n                self.size -= 1\n                break\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [[] for _ in range(self.capacity)]\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets:\n            for pair in bucket:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for bucket in self.buckets:\n            res = []\n            for pair in bucket:\n                res.append(str(pair.key) + \" -> \" + pair.val)\n            print(res)\n
    hash_map_chaining.cpp
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  private:\n    int size;                       // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;                   // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres;               // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;                // \u6269\u5bb9\u500d\u6570\n    vector<vector<Pair *>> buckets; // \u6876\u6570\u7ec4\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapChaining() : size(0), capacity(4), loadThres(2.0 / 3.0), extendRatio(2) {\n        buckets.resize(capacity);\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapChaining() {\n        for (auto &bucket : buckets) {\n            for (Pair *pair : bucket) {\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / (double)capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                return pair->val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                pair->val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].push_back(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        auto &bucket = buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (int i = 0; i < bucket.size(); i++) {\n            if (bucket[i]->key == key) {\n                Pair *tmp = bucket[i];\n                bucket.erase(bucket.begin() + i); // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n                delete tmp;                       // \u91ca\u653e\u5185\u5b58\n                size--;\n                return;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<vector<Pair *>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets.clear();\n        buckets.resize(capacity);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (auto &bucket : bucketsTmp) {\n            for (Pair *pair : bucket) {\n                put(pair->key, pair->val);\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (auto &bucket : buckets) {\n            cout << \"[\";\n            for (Pair *pair : bucket) {\n                cout << pair->key << \" -> \" << pair->val << \", \";\n            }\n            cout << \"]\\n\";\n        }\n    }\n};\n
    hash_map_chaining.java
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    String get(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        Pair pair = new Pair(key, val);\n        bucket.add(pair);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (List<Pair> bucket : bucketsTmp) {\n            for (Pair pair : bucket) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (List<Pair> bucket : buckets) {\n            List<String> res = new ArrayList<>();\n            for (Pair pair : bucket) {\n                res.add(pair.key + \" -> \" + pair.val);\n            }\n            System.out.println(res);\n        }\n    }\n}\n
    hash_map_chaining.cs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].Add(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        foreach (Pair pair in buckets[index].ToList()) {\n            if (pair.key == key) {\n                buckets[index].Remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (List<Pair> bucket in bucketsTmp) {\n            foreach (Pair pair in bucket) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (List<Pair> bucket in buckets) {\n            List<string> res = [];\n            foreach (Pair pair in bucket) {\n                res.Add(pair.key + \" -> \" + pair.val);\n            }\n            foreach (string kv in res) {\n                Console.WriteLine(kv);\n            }\n        }\n    }\n}\n
    hash_map_chaining.go
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntype hashMapChaining struct {\n    size        int      // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int      // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64  // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int      // \u6269\u5bb9\u500d\u6570\n    buckets     [][]pair // \u6876\u6570\u7ec4\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapChaining() *hashMapChaining {\n    buckets := make([][]pair, 4)\n    for i := 0; i < 4; i++ {\n        buckets[i] = make([]pair, 0)\n    }\n    return &hashMapChaining{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     buckets,\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (m *hashMapChaining) hashFunc(key int) int {\n    return key % m.capacity\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (m *hashMapChaining) loadFactor() float64 {\n    return float64(m.size) / float64(m.capacity)\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (m *hashMapChaining) get(key int) string {\n    idx := m.hashFunc(key)\n    bucket := m.buckets[idx]\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for _, p := range bucket {\n        if p.key == key {\n            return p.val\n        }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (m *hashMapChaining) put(key int, val string) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if m.loadFactor() > m.loadThres {\n        m.extend()\n    }\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for i := range m.buckets[idx] {\n        if m.buckets[idx][i].key == key {\n            m.buckets[idx][i].val = val\n            return\n        }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    p := pair{\n        key: key,\n        val: val,\n    }\n    m.buckets[idx] = append(m.buckets[idx], p)\n    m.size += 1\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (m *hashMapChaining) remove(key int) {\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for i, p := range m.buckets[idx] {\n        if p.key == key {\n            // \u5207\u7247\u5220\u9664\n            m.buckets[idx] = append(m.buckets[idx][:i], m.buckets[idx][i+1:]...)\n            m.size -= 1\n            break\n        }\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    tmpBuckets := make([][]pair, len(m.buckets))\n    for i := 0; i < len(m.buckets); i++ {\n        tmpBuckets[i] = make([]pair, len(m.buckets[i]))\n        copy(tmpBuckets[i], m.buckets[i])\n    }\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    m.capacity *= m.extendRatio\n    m.buckets = make([][]pair, m.capacity)\n    for i := 0; i < m.capacity; i++ {\n        m.buckets[i] = make([]pair, 0)\n    }\n    m.size = 0\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, bucket := range tmpBuckets {\n        for _, p := range bucket {\n            m.put(p.key, p.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) print() {\n    var builder strings.Builder\n\n    for _, bucket := range m.buckets {\n        builder.WriteString(\"[\")\n        for _, p := range bucket {\n            builder.WriteString(strconv.Itoa(p.key) + \" -> \" + p.val + \" \")\n        }\n        builder.WriteString(\"]\")\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    hash_map_chaining.swift
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [[Pair]] // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: [], count: capacity)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return pair.val\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de nil\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair(key: key, val: val)\n        buckets[index].append(pair)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pairIndex, pair) in bucket.enumerated() {\n            if pair.key == key {\n                buckets[index].remove(at: pairIndex)\n                size -= 1\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: [], count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in bucketsTmp {\n            for pair in bucket {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for bucket in buckets {\n            let res = bucket.map { \"\\($0.key) -> \\($0.val)\" }\n            Swift.print(res)\n        }\n    }\n}\n
    hash_map_chaining.js
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.ts
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    #buckets: Pair[][]; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key: number): number {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor(): number {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.dart
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  late int size; // \u952e\u503c\u5bf9\u6570\u91cf\n  late int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  late double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  late int extendRatio; // \u6269\u5bb9\u500d\u6570\n  late List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapChaining() {\n    size = 0;\n    capacity = 4;\n    loadThres = 2.0 / 3.0;\n    extendRatio = 2;\n    buckets = List.generate(capacity, (_) => []);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return size / capacity;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        return pair.val;\n      }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > loadThres) {\n      extend();\n    }\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        pair.val = val;\n        return;\n      }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    Pair pair = Pair(key, val);\n    bucket.add(pair);\n    size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        bucket.remove(pair);\n        size--;\n        break;\n      }\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<List<Pair>> bucketsTmp = buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    capacity *= extendRatio;\n    buckets = List.generate(capacity, (_) => []);\n    size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (List<Pair> bucket in bucketsTmp) {\n      for (Pair pair in bucket) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (List<Pair> bucket in buckets) {\n      List<String> res = [];\n      for (Pair pair in bucket) {\n        res.add(\"${pair.key} -> ${pair.val}\");\n      }\n      print(res);\n    }\n  }\n}\n
    hash_map_chaining.rs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapChaining {\n    size: i32,\n    capacity: i32,\n    load_thres: f32,\n    extend_ratio: i32,\n    buckets: Vec<Vec<Pair>>,\n}\n\nimpl HashMapChaining {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![vec![]; 4],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % self.capacity as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f32 {\n        self.size as f32 / self.capacity as f32\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) -> Option<String> {\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for i in 0..bucket.len() {\n            if bucket[i].key == key {\n                let pair = bucket.remove(i);\n                self.size -= 1;\n                return Some(pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = std::mem::replace(&mut self.buckets, vec![]);\n\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![Vec::new(); self.capacity as usize];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets_tmp {\n            for pair in bucket {\n                self.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for bucket in &self.buckets {\n            let mut res = Vec::new();\n            for pair in bucket {\n                res.push(format!(\"{} -> {}\", pair.key, pair.val));\n            }\n            println!(\"{:?}\", res);\n        }\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val;\n                return;\n            }\n        }\n        let bucket = &mut self.buckets[index];\n\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair { key, val };\n        bucket.push(pair);\n        self.size += 1;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&self, key: i32) -> Option<&str> {\n        let index = self.hash_func(key);\n        let bucket = &self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return Some(&pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n}\n
    hash_map_chaining.c
    /* \u94fe\u8868\u8282\u70b9 */\ntypedef struct Node {\n    Pair *pair;\n    struct Node *next;\n} Node;\n\n/* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Node **buckets;   // \u6876\u6570\u7ec4\n} HashMapChaining;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapChaining *newHashMapChaining() {\n    HashMapChaining *hashMap = (HashMapChaining *)malloc(sizeof(HashMapChaining));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapChaining(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        while (cur) {\n            Node *tmp = cur;\n            cur = cur->next;\n            free(tmp->pair);\n            free(tmp);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapChaining *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapChaining *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            return cur->pair->val;\n        }\n        cur = cur->next;\n    }\n    return \"\"; // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapChaining *hashMap, int key, const char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            strcpy(cur->pair->val, val); // \u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n            return;\n        }\n        cur = cur->next;\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n    Pair *newPair = (Pair *)malloc(sizeof(Pair));\n    newPair->key = key;\n    strcpy(newPair->val, val);\n    Node *newNode = (Node *)malloc(sizeof(Node));\n    newNode->pair = newPair;\n    newNode->next = hashMap->buckets[index];\n    hashMap->buckets[index] = newNode;\n    hashMap->size++;\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapChaining *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    int oldCapacity = hashMap->capacity;\n    Node **oldBuckets = hashMap->buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Node *cur = oldBuckets[i];\n        while (cur) {\n            put(hashMap, cur->pair->key, cur->pair->val);\n            Node *temp = cur;\n            cur = cur->next;\n            // \u91ca\u653e\u5185\u5b58\n            free(temp->pair);\n            free(temp);\n        }\n    }\n\n    free(oldBuckets);\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    Node *cur = hashMap->buckets[index];\n    Node *pre = NULL;\n    while (cur) {\n        if (cur->pair->key == key) {\n            // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n            if (pre) {\n                pre->next = cur->next;\n            } else {\n                hashMap->buckets[index] = cur->next;\n            }\n            // \u91ca\u653e\u5185\u5b58\n            free(cur->pair);\n            free(cur);\n            hashMap->size--;\n            return;\n        }\n        pre = cur;\n        cur = cur->next;\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        printf(\"[\");\n        while (cur) {\n            printf(\"%d -> %s, \", cur->pair->key, cur->pair->val);\n            cur = cur->next;\n        }\n        printf(\"]\\n\");\n    }\n}\n
    hash_map_chaining.kt
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    val loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    val extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: MutableList<MutableList<Pair>> // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (pair in bucket) {\n            if (pair.key == key) return pair._val\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (pair in bucket) {\n            if (pair.key == key) {\n                pair._val = _val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        val pair = Pair(key, _val)\n        bucket.add(pair)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pair in bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair)\n                size--\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        // mutablelist \u65e0\u56fa\u5b9a\u5927\u5c0f\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (bucket in bucketsTmp) {\n            for (pair in bucket) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (bucket in buckets) {\n            val res = mutableListOf<String>()\n            for (pair in bucket) {\n                val k = pair.key\n                val v = pair._val\n                res.add(\"$k -> $v\")\n            }\n            println(res)\n        }\n    }\n}\n
    hash_map_chaining.rb
    ### \u952e\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapChaining\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) { [] } # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for pair in bucket\n      return pair.val if pair.key == key\n    end\n    # \u82e5\u672a\u627e\u5230 key , \u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for pair in bucket\n      if pair.key == key\n        pair.val = val\n        return\n      end\n    end\n    # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    pair = Pair.new(key, val)\n    bucket << pair\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for pair in bucket\n      if pair.key == key\n        bucket.delete(pair)\n        @size -= 1\n        break\n      end\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u66ab\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity) { [] }\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for bucket in buckets\n      for pair in bucket\n        put(pair.key, pair.val)\n      end\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for bucket in @buckets\n      res = []\n      for pair in bucket\n        res << \"#{pair.key} -> #{pair.val}\"\n      end\n      pp res\n    end\n  end\nend\n
    hash_map_chaining.zig
    [class]{HashMapChaining}-[func]{}\n
    Code Visualization

    Full Screen >

    It's worth noting that when the list is very long, the query efficiency \\(O(n)\\) is poor. At this point, the list can be converted to an \"AVL tree\" or \"Red-Black tree\" to optimize the time complexity of the query operation to \\(O(\\log n)\\).

    "},{"location":"chapter_hashing/hash_collision/#622-open-addressing","title":"6.2.2 \u00a0 Open addressing","text":"

    \"Open addressing\" does not introduce additional data structures but uses \"multiple probes\" to handle hash collisions. The probing methods mainly include linear probing, quadratic probing, and double hashing.

    Let's use linear probing as an example to introduce the mechanism of open addressing hash tables.

    "},{"location":"chapter_hashing/hash_collision/#1-linear-probing","title":"1. \u00a0 Linear probing","text":"

    Linear probing uses a fixed-step linear search for probing, differing from ordinary hash tables.

    • Inserting elements: Calculate the bucket index using the hash function. If the bucket already contains an element, linearly traverse forward from the conflict position (usually with a step size of \\(1\\)) until an empty bucket is found, then insert the element.
    • Searching for elements: If a hash collision is found, use the same step size to linearly traverse forward until the corresponding element is found and return value; if an empty bucket is encountered, it means the target element is not in the hash table, so return None.

    The Figure 6-6 shows the distribution of key-value pairs in an open addressing (linear probing) hash table. According to this hash function, keys with the same last two digits will be mapped to the same bucket. Through linear probing, they are stored consecutively in that bucket and the buckets below it.

    Figure 6-6 \u00a0 Distribution of key-value pairs in open addressing (linear probing) hash table

    However, linear probing tends to create \"clustering\". Specifically, the longer a continuous position in the array is occupied, the more likely these positions are to encounter hash collisions, further promoting the growth of these clusters and eventually leading to deterioration in the efficiency of operations.

    It's important to note that we cannot directly delete elements in an open addressing hash table. Deleting an element creates an empty bucket None in the array. When searching for elements, if linear probing encounters this empty bucket, it will return, making the elements below this bucket inaccessible. The program may incorrectly assume these elements do not exist, as shown in the Figure 6-7 .

    Figure 6-7 \u00a0 Query issues caused by deletion in open addressing

    To solve this problem, we can use a \"lazy deletion\" mechanism: instead of directly removing elements from the hash table, use a constant TOMBSTONE to mark the bucket. In this mechanism, both None and TOMBSTONE represent empty buckets and can hold key-value pairs. However, when linear probing encounters TOMBSTONE, it should continue traversing since there may still be key-value pairs below it.

    However, lazy deletion may accelerate the degradation of hash table performance. Every deletion operation produces a delete mark, and as TOMBSTONE increases, so does the search time, as linear probing may have to skip multiple TOMBSTONE to find the target element.

    Therefore, consider recording the index of the first TOMBSTONE encountered during linear probing and swapping the target element found with this TOMBSTONE. The advantage of this is that each time a query or addition is performed, the element is moved to a bucket closer to the ideal position (starting point of probing), thereby optimizing the query efficiency.

    The code below implements an open addressing (linear probing) hash table with lazy deletion. To make fuller use of the hash table space, we treat the hash table as a \"circular array,\" continuing to traverse from the beginning when the end of the array is passed.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_open_addressing.py
    class HashMapOpenAddressing:\n    \"\"\"\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets: list[Pair | None] = [None] * self.capacity  # \u6876\u6570\u7ec4\n        self.TOMBSTONE = Pair(-1, \"-1\")  # \u5220\u9664\u6807\u8bb0\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def find_bucket(self, key: int) -> int:\n        \"\"\"\u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\"\"\"\n        index = self.hash_func(key)\n        first_tombstone = -1\n        # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index] is not None:\n            # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].key == key:\n                # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if first_tombstone != -1:\n                    self.buckets[first_tombstone] = self.buckets[index]\n                    self.buckets[index] = self.TOMBSTONE\n                    return first_tombstone  # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                return index  # \u8fd4\u56de\u6876\u7d22\u5f15\n            # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 and self.buckets[index] is self.TOMBSTONE:\n                first_tombstone = index\n            # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity\n        # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return index if first_tombstone == -1 else first_tombstone\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            return self.buckets[index].val\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index].val = val\n            return\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Pair(key, val)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index] = self.TOMBSTONE\n            self.size -= 1\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets_tmp = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [None] * self.capacity\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp:\n            if pair not in [None, self.TOMBSTONE]:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is None:\n                print(\"None\")\n            elif pair is self.TOMBSTONE:\n                print(\"TOMBSTONE\")\n            else:\n                print(pair.key, \"->\", pair.val)\n
    hash_map_open_addressing.cpp
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  private:\n    int size;                             // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4;                     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    const double loadThres = 2.0 / 3.0;     // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    const int extendRatio = 2;            // \u6269\u5bb9\u500d\u6570\n    vector<Pair *> buckets;               // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapOpenAddressing() : size(0), buckets(capacity, nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapOpenAddressing() {\n        for (Pair *pair : buckets) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                delete pair;\n            }\n        }\n        delete TOMBSTONE;\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != nullptr) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]->key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            return buckets[index]->val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            buckets[index]->val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            delete buckets[index];\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<Pair *> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = vector<Pair *>(capacity, nullptr);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair *pair : bucketsTmp) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                put(pair->key, pair->val);\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *pair : buckets) {\n            if (pair == nullptr) {\n                cout << \"nullptr\" << endl;\n            } else if (pair == TOMBSTONE) {\n                cout << \"TOMBSTONE\" << endl;\n            } else {\n                cout << pair->key << \" -> \" << pair->val << endl;\n            }\n        }\n    }\n};\n
    hash_map_open_addressing.java
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    private int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private final double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private final int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    private Pair[] buckets; // \u6876\u6570\u7ec4\n    private final Pair TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair pair : bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair pair : buckets) {\n            if (pair == null) {\n                System.out.println(\"null\");\n            } else if (pair == TOMBSTONE) {\n                System.out.println(\"TOMBSTONE\");\n            } else {\n                System.out.println(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.cs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    Pair[] buckets; // \u6876\u6570\u7ec4\n    Pair TOMBSTONE = new(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int FindBucket(int key) {\n        int index = HashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (Pair pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair pair in buckets) {\n            if (pair == null) {\n                Console.WriteLine(\"null\");\n            } else if (pair == TOMBSTONE) {\n                Console.WriteLine(\"TOMBSTONE\");\n            } else {\n                Console.WriteLine(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.go
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntype hashMapOpenAddressing struct {\n    size        int     // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64 // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int     // \u6269\u5bb9\u500d\u6570\n    buckets     []*pair // \u6876\u6570\u7ec4\n    TOMBSTONE   *pair   // \u5220\u9664\u6807\u8bb0\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapOpenAddressing() *hashMapOpenAddressing {\n    return &hashMapOpenAddressing{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     make([]*pair, 4),\n        TOMBSTONE:   &pair{-1, \"-1\"},\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (h *hashMapOpenAddressing) hashFunc(key int) int {\n    return key % h.capacity // \u6839\u636e\u952e\u8ba1\u7b97\u54c8\u5e0c\u503c\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (h *hashMapOpenAddressing) loadFactor() float64 {\n    return float64(h.size) / float64(h.capacity) // \u8ba1\u7b97\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nfunc (h *hashMapOpenAddressing) findBucket(key int) int {\n    index := h.hashFunc(key) // \u83b7\u53d6\u521d\u59cb\u7d22\u5f15\n    firstTombstone := -1     // \u8bb0\u5f55\u9047\u5230\u7684\u7b2c\u4e00\u4e2aTOMBSTONE\u7684\u4f4d\u7f6e\n    for h.buckets[index] != nil {\n        if h.buckets[index].key == key {\n            if firstTombstone != -1 {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                h.buckets[firstTombstone] = h.buckets[index]\n                h.buckets[index] = h.TOMBSTONE\n                return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index // \u8fd4\u56de\u627e\u5230\u7684\u7d22\u5f15\n        }\n        if firstTombstone == -1 && h.buckets[index] == h.TOMBSTONE {\n            firstTombstone = index // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\u7684\u4f4d\u7f6e\n        }\n        index = (index + 1) % h.capacity // \u7ebf\u6027\u63a2\u6d4b\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    if firstTombstone != -1 {\n        return firstTombstone\n    }\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) get(key int) string {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        return h.buckets[index].val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    }\n    return \"\" // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) put(key int, val string) {\n    if h.loadFactor() > h.loadThres {\n        h.extend() // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    }\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] == nil || h.buckets[index] == h.TOMBSTONE {\n        h.buckets[index] = &pair{key, val} // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        h.size++\n    } else {\n        h.buckets[index].val = val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val\n    }\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) remove(key int) {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        h.buckets[index] = h.TOMBSTONE // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        h.size--\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) extend() {\n    oldBuckets := h.buckets               // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    h.capacity *= h.extendRatio           // \u66f4\u65b0\u5bb9\u91cf\n    h.buckets = make([]*pair, h.capacity) // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    h.size = 0                            // \u91cd\u7f6e\u5927\u5c0f\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, pair := range oldBuckets {\n        if pair != nil && pair != h.TOMBSTONE {\n            h.put(pair.key, pair.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) print() {\n    for _, pair := range h.buckets {\n        if pair == nil {\n            fmt.Println(\"nil\")\n        } else if pair == h.TOMBSTONE {\n            fmt.Println(\"TOMBSTONE\")\n        } else {\n            fmt.Printf(\"%d -> %s\\n\", pair.key, pair.val)\n        }\n    }\n}\n
    hash_map_open_addressing.swift
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [Pair?] // \u6876\u6570\u7ec4\n    var TOMBSTONE: Pair // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: nil, count: capacity)\n        TOMBSTONE = Pair(key: -1, val: \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    func findBucket(key: Int) -> Int {\n        var index = hashFunc(key: key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while buckets[index] != nil {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if buckets[index]!.key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if firstTombstone != -1 {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if firstTombstone == -1 && buckets[index] == TOMBSTONE {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            return buckets[index]!.val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index]!.val = val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key: key, val: val)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index] = TOMBSTONE\n            size -= 1\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: nil, count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in bucketsTmp {\n            if let pair, pair != TOMBSTONE {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in buckets {\n            if pair == nil {\n                Swift.print(\"null\")\n            } else if pair == TOMBSTONE {\n                Swift.print(\"TOMBSTONE\")\n            } else {\n                Swift.print(\"\\(pair!.key) -> \\(pair!.val)\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.js
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n    #TOMBSTONE; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.#capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.#loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.#extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.#buckets = Array(this.#capacity).fill(null); // \u6876\u6570\u7ec4\n        this.#TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    #findBucket(key) {\n        let index = this.#hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.#buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.#buckets[index].key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.#buckets[firstTombstone] = this.#buckets[index];\n                    this.#buckets[index] = this.#TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.#buckets[index] === this.#TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.#capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            return this.#buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.#buckets[index] = new Pair(key, val);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index] = this.#TOMBSTONE;\n            this.#size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = Array(this.#capacity).fill(null);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.#TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const pair of this.#buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.#TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.ts
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    private capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    private buckets: Array<Pair | null>; // \u6876\u6570\u7ec4\n    private TOMBSTONE: Pair; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.buckets = Array(this.capacity).fill(null); // \u6876\u6570\u7ec4\n        this.TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % this.capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private loadFactor(): number {\n        return this.size / this.capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private findBucket(key: number): number {\n        let index = this.hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.buckets[index]!.key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.buckets[firstTombstone] = this.buckets[index];\n                    this.buckets[index] = this.TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.buckets[index] === this.TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            return this.buckets[index]!.val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.loadFactor() > this.loadThres) {\n            this.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index]!.val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.buckets[index] = new Pair(key, val);\n        this.size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index] = this.TOMBSTONE;\n            this.size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.capacity *= this.extendRatio;\n        this.buckets = Array(this.capacity).fill(null);\n        this.size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const pair of this.buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.dart
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  late int _size; // \u952e\u503c\u5bf9\u6570\u91cf\n  int _capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  double _loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  int _extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n  late List<Pair?> _buckets; // \u6876\u6570\u7ec4\n  Pair _TOMBSTONE = Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapOpenAddressing() {\n    _size = 0;\n    _buckets = List.generate(_capacity, (index) => null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % _capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return _size / _capacity;\n  }\n\n  /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n  int findBucket(int key) {\n    int index = hashFunc(key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (_buckets[index] != null) {\n      // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if (_buckets[index]!.key == key) {\n        // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if (firstTombstone != -1) {\n          _buckets[firstTombstone] = _buckets[index];\n          _buckets[index] = _TOMBSTONE;\n          return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        }\n        return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n      }\n      // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      if (firstTombstone == -1 && _buckets[index] == _TOMBSTONE) {\n        firstTombstone = index;\n      }\n      // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % _capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      return _buckets[index]!.val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > _loadThres) {\n      extend();\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index]!.val = val;\n      return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    _buckets[index] = new Pair(key, val);\n    _size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index] = _TOMBSTONE;\n      _size--;\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<Pair?> bucketsTmp = _buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    _capacity *= _extendRatio;\n    _buckets = List.generate(_capacity, (index) => null);\n    _size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (Pair? pair in bucketsTmp) {\n      if (pair != null && pair != _TOMBSTONE) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (Pair? pair in _buckets) {\n      if (pair == null) {\n        print(\"null\");\n      } else if (pair == _TOMBSTONE) {\n        print(\"TOMBSTONE\");\n      } else {\n        print(\"${pair.key} -> ${pair.val}\");\n      }\n    }\n  }\n}\n
    hash_map_open_addressing.rs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapOpenAddressing {\n    size: usize,                // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity: usize,            // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    load_thres: f64,            // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extend_ratio: usize,        // \u6269\u5bb9\u500d\u6570\n    buckets: Vec<Option<Pair>>, // \u6876\u6570\u7ec4\n    TOMBSTONE: Option<Pair>,    // \u5220\u9664\u6807\u8bb0\n}\n\nimpl HashMapOpenAddressing {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![None; 4],\n            TOMBSTONE: Some(Pair {\n                key: -1,\n                val: \"-1\".to_string(),\n            }),\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        (key % self.capacity as i32) as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f64 {\n        self.size as f64 / self.capacity as f64\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fn find_bucket(&mut self, key: i32) -> usize {\n        let mut index = self.hash_func(key);\n        let mut first_tombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index].is_some() {\n            // \u82e5\u9047\u5230 key\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].as_ref().unwrap().key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u5efa\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\n                if first_tombstone != -1 {\n                    self.buckets[first_tombstone as usize] = self.buckets[index].take();\n                    self.buckets[index] = self.TOMBSTONE.clone();\n                    return first_tombstone as usize; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 && self.buckets[index] == self.TOMBSTONE {\n                first_tombstone = index as i32;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        if first_tombstone == -1 {\n            index\n        } else {\n            first_tombstone as usize\n        }\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&mut self, key: i32) -> Option<&str> {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            return self.buckets[index].as_ref().map(|pair| &pair.val as &str);\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        None\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index].as_mut().unwrap().val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Some(Pair { key, val });\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index] = self.TOMBSTONE.clone();\n            self.size -= 1;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = self.buckets.clone();\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![None; self.capacity];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp {\n            if pair.is_none() || pair == self.TOMBSTONE {\n                continue;\n            }\n            let pair = pair.unwrap();\n\n            self.put(pair.key, pair.val);\n        }\n    }\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for pair in &self.buckets {\n            if pair.is_none() {\n                println!(\"null\");\n            } else if pair == &self.TOMBSTONE {\n                println!(\"TOMBSTONE\");\n            } else {\n                let pair = pair.as_ref().unwrap();\n                println!(\"{} -> {}\", pair.key, pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.c
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Pair **buckets;   // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE;  // \u5220\u9664\u6807\u8bb0\n} HashMapOpenAddressing;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapOpenAddressing *newHashMapOpenAddressing() {\n    HashMapOpenAddressing *hashMap = (HashMapOpenAddressing *)malloc(sizeof(HashMapOpenAddressing));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->TOMBSTONE = (Pair *)malloc(sizeof(Pair));\n    hashMap->TOMBSTONE->key = -1;\n    hashMap->TOMBSTONE->val = \"-1\";\n\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapOpenAddressing(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap->TOMBSTONE);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapOpenAddressing *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapOpenAddressing *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nint findBucket(HashMapOpenAddressing *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (hashMap->buckets[index] != NULL) {\n        // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        if (hashMap->buckets[index]->key == key) {\n            // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n            if (firstTombstone != -1) {\n                hashMap->buckets[firstTombstone] = hashMap->buckets[index];\n                hashMap->buckets[index] = hashMap->TOMBSTONE;\n                return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n        }\n        // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n        if (firstTombstone == -1 && hashMap->buckets[index] == hashMap->TOMBSTONE) {\n            firstTombstone = index;\n        }\n        // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n        index = (index + 1) % hashMap->capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        return hashMap->buckets[index]->val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\";\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapOpenAddressing *hashMap, int key, char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        free(hashMap->buckets[index]->val);\n        hashMap->buckets[index]->val = (char *)malloc(sizeof(strlen(val) + 1));\n        strcpy(hashMap->buckets[index]->val, val);\n        hashMap->buckets[index]->val[strlen(val)] = '\\0';\n        return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    Pair *pair = (Pair *)malloc(sizeof(Pair));\n    pair->key = key;\n    pair->val = (char *)malloc(sizeof(strlen(val) + 1));\n    strcpy(pair->val, val);\n    pair->val[strlen(val)] = '\\0';\n\n    hashMap->buckets[index] = pair;\n    hashMap->size++;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        Pair *pair = hashMap->buckets[index];\n        free(pair->val);\n        free(pair);\n        hashMap->buckets[index] = hashMap->TOMBSTONE;\n        hashMap->size--;\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapOpenAddressing *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    Pair **bucketsTmp = hashMap->buckets;\n    int oldCapacity = hashMap->capacity;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Pair *pair = bucketsTmp[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            put(hashMap, pair->key, pair->val);\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(bucketsTmp);\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair == NULL) {\n            printf(\"NULL\\n\");\n        } else if (pair == hashMap->TOMBSTONE) {\n            printf(\"TOMBSTONE\\n\");\n        } else {\n            printf(\"%d -> %s\\n\", pair->key, pair->val);\n        }\n    }\n}\n
    hash_map_open_addressing.kt
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private var size: Int               // \u952e\u503c\u5bf9\u6570\u91cf\n    private var capacity: Int           // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private val loadThres: Double       // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private val extendRatio: Int        // \u6269\u5bb9\u500d\u6570\n    private var buckets: Array<Pair?>   // \u6876\u6570\u7ec4\n    private val TOMBSTONE: Pair         // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = arrayOfNulls(capacity)\n        TOMBSTONE = Pair(-1, \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fun findBucket(key: Int): Int {\n        var index = hashFunc(key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]?.key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return if (firstTombstone == -1) index else firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index]?._val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index]!!._val = _val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key, _val)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE\n            size--\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = arrayOfNulls(capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (pair in buckets) {\n            if (pair == null) {\n                println(\"null\")\n            } else if (pair == TOMBSTONE) {\n                println(\"TOMESTOME\")\n            } else {\n                println(\"${pair.key} -> ${pair._val}\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.rb
    ### \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapOpenAddressing\n  TOMBSTONE = Pair.new(-1, '-1') # \u5220\u9664\u6807\u8bb0\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 ###\n  def find_bucket(key)\n    index = hash_func(key)\n    first_tombstone = -1\n    # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while !@buckets[index].nil?\n      # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if @buckets[index].key == key\n        # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if first_tombstone != -1\n          @buckets[first_tombstone] = @buckets[index]\n          @buckets[index] = TOMBSTONE\n          return first_tombstone # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        end\n        return index # \u8fd4\u56de\u6876\u7d22\u5f15\n      end\n      # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      first_tombstone = index if first_tombstone == -1 && @buckets[index] == TOMBSTONE\n      # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % @capacity\n    end\n    # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    first_tombstone == -1 ? index : first_tombstone\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    return @buckets[index].val unless [nil, TOMBSTONE].include?(@buckets[index])\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5f00\u8fd4\u56de\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index].val = val\n      return\n    end\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    @buckets[index] = Pair.new(key, val)\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index] = TOMBSTONE\n      @size -= 1\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets_tmp = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity)\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for pair in buckets_tmp\n      put(pair.key, pair.val) unless [nil, TOMBSTONE].include?(pair)\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for pair in @buckets\n      if pair.nil?\n        puts \"Nil\"\n      elsif pair == TOMBSTONE\n        puts \"TOMBSTONE\"\n      else\n        puts \"#{pair.key} -> #{pair.val}\"\n      end\n    end\n  end\nend\n
    hash_map_open_addressing.zig
    [class]{HashMapOpenAddressing}-[func]{}\n
    "},{"location":"chapter_hashing/hash_collision/#2-quadratic-probing","title":"2. \u00a0 Quadratic probing","text":"

    Quadratic probing is similar to linear probing and is one of the common strategies of open addressing. When a collision occurs, quadratic probing does not simply skip a fixed number of steps but skips \"the square of the number of probes,\" i.e., \\(1, 4, 9, \\dots\\) steps.

    Quadratic probing has the following advantages:

    • Quadratic probing attempts to alleviate the clustering effect of linear probing by skipping the distance of the square of the number of probes.
    • Quadratic probing skips larger distances to find empty positions, helping to distribute data more evenly.

    However, quadratic probing is not perfect:

    • Clustering still exists, i.e., some positions are more likely to be occupied than others.
    • Due to the growth of squares, quadratic probing may not probe the entire hash table, meaning it might not access empty buckets even if they exist in the hash table.
    "},{"location":"chapter_hashing/hash_collision/#3-double-hashing","title":"3. \u00a0 Double hashing","text":"

    As the name suggests, the double hashing method uses multiple hash functions \\(f_1(x)\\), \\(f_2(x)\\), \\(f_3(x)\\), \\(\\dots\\) for probing.

    • Inserting elements: If hash function \\(f_1(x)\\) encounters a conflict, try \\(f_2(x)\\), and so on, until an empty position is found and the element is inserted.
    • Searching for elements: Search in the same order of hash functions until the target element is found and returned; if an empty position is encountered or all hash functions have been tried, it indicates the element is not in the hash table, then return None.

    Compared to linear probing, double hashing is less prone to clustering but involves additional computation for multiple hash functions.

    Tip

    Please note that open addressing (linear probing, quadratic probing, and double hashing) hash tables all have the issue of \"not being able to directly delete elements.\"

    "},{"location":"chapter_hashing/hash_collision/#623-choice-of-programming-languages","title":"6.2.3 \u00a0 Choice of programming languages","text":"

    Various programming languages have adopted different hash table implementation strategies, here are a few examples:

    • Python uses open addressing. The dict dictionary uses pseudo-random numbers for probing.
    • Java uses separate chaining. Since JDK 1.8, when the array length in HashMap reaches 64 and the length of a linked list reaches 8, the linked list is converted to a red-black tree to improve search performance.
    • Go uses separate chaining. Go stipulates that each bucket can store up to 8 key-value pairs, and if the capacity is exceeded, an overflow bucket is connected; when there are too many overflow buckets, a special equal-size expansion operation is performed to ensure performance.
    "},{"location":"chapter_hashing/hash_map/","title":"6.1 \u00a0 Hash table","text":"

    A \"hash table\", also known as a \"hash map\", achieves efficient element querying by establishing a mapping between keys and values. Specifically, when we input a key into the hash table, we can retrieve the corresponding value in \\(O(1)\\) time.

    As shown in the Figure 6-1 , given \\(n\\) students, each with two pieces of data: \"name\" and \"student number\". If we want to implement a query feature that returns the corresponding name when given a student number, we can use the hash table shown in the Figure 6-1 .

    Figure 6-1 \u00a0 Abstract representation of a hash table

    Apart from hash tables, arrays and linked lists can also be used to implement querying functions. Their efficiency is compared in the Table 6-1 .

    • Adding elements: Simply add the element to the end of the array (or linked list), using \\(O(1)\\) time.
    • Querying elements: Since the array (or linked list) is unordered, it requires traversing all the elements, using \\(O(n)\\) time.
    • Deleting elements: First, locate the element, then delete it from the array (or linked list), using \\(O(n)\\) time.

    Table 6-1 \u00a0 Comparison of element query efficiency

    Array Linked List Hash Table Find Element \\(O(n)\\) \\(O(n)\\) \\(O(1)\\) Add Element \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) Delete Element \\(O(n)\\) \\(O(n)\\) \\(O(1)\\)

    Observations reveal that the time complexity for adding, deleting, and querying in a hash table is \\(O(1)\\), which is highly efficient.

    "},{"location":"chapter_hashing/hash_map/#611-common-operations-of-hash-table","title":"6.1.1 \u00a0 Common operations of hash table","text":"

    Common operations of a hash table include initialization, querying, adding key-value pairs, and deleting key-value pairs, etc. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig hash_map.py
    # Initialize hash table\nhmap: dict = {}\n\n# Add operation\n# Add key-value pair (key, value) to the hash table\nhmap[12836] = \"Xiao Ha\"\nhmap[15937] = \"Xiao Luo\"\nhmap[16750] = \"Xiao Suan\"\nhmap[13276] = \"Xiao Fa\"\nhmap[10583] = \"Xiao Ya\"\n\n# Query operation\n# Input key into hash table, get value\nname: str = hmap[15937]\n\n# Delete operation\n# Delete key-value pair (key, value) from hash table\nhmap.pop(10583)\n
    hash_map.cpp
    /* Initialize hash table */\nunordered_map<int, string> map;\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap[12836] = \"Xiao Ha\";\nmap[15937] = \"Xiao Luo\";\nmap[16750] = \"Xiao Suan\";\nmap[13276] = \"Xiao Fa\";\nmap[10583] = \"Xiao Ya\";\n\n/* Query operation */\n// Input key into hash table, get value\nstring name = map[15937];\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.erase(10583);\n
    hash_map.java
    /* Initialize hash table */\nMap<Integer, String> map = new HashMap<>();\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.put(12836, \"Xiao Ha\");   \nmap.put(15937, \"Xiao Luo\");   \nmap.put(16750, \"Xiao Suan\");   \nmap.put(13276, \"Xiao Fa\");\nmap.put(10583, \"Xiao Ya\");\n\n/* Query operation */\n// Input key into hash table, get value\nString name = map.get(15937);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.remove(10583);\n
    hash_map.cs
    /* Initialize hash table */\nDictionary<int, string> map = new() {\n    /* Add operation */\n    // Add key-value pair (key, value) to the hash table\n    { 12836, \"Xiao Ha\" },\n    { 15937, \"Xiao Luo\" },\n    { 16750, \"Xiao Suan\" },\n    { 13276, \"Xiao Fa\" },\n    { 10583, \"Xiao Ya\" }\n};\n\n/* Query operation */\n// Input key into hash table, get value\nstring name = map[15937];\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.Remove(10583);\n
    hash_map_test.go
    /* Initialize hash table */\nhmap := make(map[int]string)\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nhmap[12836] = \"Xiao Ha\"\nhmap[15937] = \"Xiao Luo\"\nhmap[16750] = \"Xiao Suan\"\nhmap[13276] = \"Xiao Fa\"\nhmap[10583] = \"Xiao Ya\"\n\n/* Query operation */\n// Input key into hash table, get value\nname := hmap[15937]\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\ndelete(hmap, 10583)\n
    hash_map.swift
    /* Initialize hash table */\nvar map: [Int: String] = [:]\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap[12836] = \"Xiao Ha\"\nmap[15937] = \"Xiao Luo\"\nmap[16750] = \"Xiao Suan\"\nmap[13276] = \"Xiao Fa\"\nmap[10583] = \"Xiao Ya\"\n\n/* Query operation */\n// Input key into hash table, get value\nlet name = map[15937]!\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.removeValue(forKey: 10583)\n
    hash_map.js
    /* Initialize hash table */\nconst map = new Map();\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.set(12836, 'Xiao Ha');\nmap.set(15937, 'Xiao Luo');\nmap.set(16750, 'Xiao Suan');\nmap.set(13276, 'Xiao Fa');\nmap.set(10583, 'Xiao Ya');\n\n/* Query operation */\n// Input key into hash table, get value\nlet name = map.get(15937);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.delete(10583);\n
    hash_map.ts
    /* Initialize hash table */\nconst map = new Map<number, string>();\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.set(12836, 'Xiao Ha');\nmap.set(15937, 'Xiao Luo');\nmap.set(16750, 'Xiao Suan');\nmap.set(13276, 'Xiao Fa');\nmap.set(10583, 'Xiao Ya');\nconsole.info('\\nAfter adding, the hash table is\\nKey -> Value');\nconsole.info(map);\n\n/* Query operation */\n// Input key into hash table, get value\nlet name = map.get(15937);\nconsole.info('\\nInput student number 15937, query name ' + name);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.delete(10583);\nconsole.info('\\nAfter deleting 10583, the hash table is\\nKey -> Value');\nconsole.info(map);\n
    hash_map.dart
    /* Initialize hash table */\nMap<int, String> map = {};\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap[12836] = \"Xiao Ha\";\nmap[15937] = \"Xiao Luo\";\nmap[16750] = \"Xiao Suan\";\nmap[13276] = \"Xiao Fa\";\nmap[10583] = \"Xiao Ya\";\n\n/* Query operation */\n// Input key into hash table, get value\nString name = map[15937];\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.remove(10583);\n
    hash_map.rs
    use std::collections::HashMap;\n\n/* Initialize hash table */\nlet mut map: HashMap<i32, String> = HashMap::new();\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.insert(12836, \"Xiao Ha\".to_string());\nmap.insert(15937, \"Xiao Luo\".to_string());\nmap.insert(16750, \"Xiao Suan\".to_string());\nmap.insert(13279, \"Xiao Fa\".to_string());\nmap.insert(10583, \"Xiao Ya\".to_string());\n\n/* Query operation */\n// Input key into hash table, get value\nlet _name: Option<&String> = map.get(&15937);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nlet _removed_value: Option<String> = map.remove(&10583);\n
    hash_map.c
    // C does not provide a built-in hash table\n
    hash_map.kt
    \n
    hash_map.zig
    \n
    Code Visualization

    Full Screen >

    There are three common ways to traverse a hash table: traversing key-value pairs, keys, and values. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig hash_map.py
    # Traverse hash table\n# Traverse key-value pairs key->value\nfor key, value in hmap.items():\n    print(key, \"->\", value)\n# Traverse keys only\nfor key in hmap.keys():\n    print(key)\n# Traverse values only\nfor value in hmap.values():\n    print(value)\n
    hash_map.cpp
    /* Traverse hash table */\n// Traverse key-value pairs key->value\nfor (auto kv: map) {\n    cout << kv.first << \" -> \" << kv.second << endl;\n}\n// Traverse using iterator key->value\nfor (auto iter = map.begin(); iter != map.end(); iter++) {\n    cout << iter->first << \"->\" << iter->second << endl;\n}\n
    hash_map.java
    /* Traverse hash table */\n// Traverse key-value pairs key->value\nfor (Map.Entry<Integer, String> kv: map.entrySet()) {\n    System.out.println(kv.getKey() + \" -> \" + kv.getValue());\n}\n// Traverse keys only\nfor (int key: map.keySet()) {\n    System.out.println(key);\n}\n// Traverse values only\nfor (String val: map.values()) {\n    System.out.println(val);\n}\n
    hash_map.cs
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nforeach (var kv in map) {\n    Console.WriteLine(kv.Key + \" -> \" + kv.Value);\n}\n// Traverse keys only\nforeach (int key in map.Keys) {\n    Console.WriteLine(key);\n}\n// Traverse values only\nforeach (string val in map.Values) {\n    Console.WriteLine(val);\n}\n
    hash_map_test.go
    /* Traverse hash table */\n// Traverse key-value pairs key->value\nfor key, value := range hmap {\n    fmt.Println(key, \"->\", value)\n}\n// Traverse keys only\nfor key := range hmap {\n    fmt.Println(key)\n}\n// Traverse values only\nfor _, value := range hmap {\n    fmt.Println(value)\n}\n
    hash_map.swift
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nfor (key, value) in map {\n    print(\"\\(key) -> \\(value)\")\n}\n// Traverse keys only\nfor key in map.keys {\n    print(key)\n}\n// Traverse values only\nfor value in map.values {\n    print(value)\n}\n
    hash_map.js
    /* Traverse hash table */\nconsole.info('\\nTraverse key-value pairs Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\nTraverse keys only Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\nTraverse values only Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.ts
    /* Traverse hash table */\nconsole.info('\\nTraverse key-value pairs Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\nTraverse keys only Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\nTraverse values only Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.dart
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nmap.forEach((key, value) {\nprint('$key -> $value');\n});\n\n// Traverse keys only Key\nmap.keys.forEach((key) {\nprint(key);\n});\n\n// Traverse values only Value\nmap.values.forEach((value) {\nprint(value);\n});\n
    hash_map.rs
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nfor (key, value) in &map {\n    println!(\"{key} -> {value}\");\n}\n\n// Traverse keys only Key\nfor key in map.keys() {\n    println!(\"{key}\"); \n}\n\n// Traverse values only Value\nfor value in map.values() {\n    println!(\"{value}\");\n}\n
    hash_map.c
    // C does not provide a built-in hash table\n
    hash_map.kt
    \n
    hash_map.zig
    // Zig example is not provided\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_hashing/hash_map/#612-simple-implementation-of-hash-table","title":"6.1.2 \u00a0 Simple implementation of hash table","text":"

    First, let's consider the simplest case: implementing a hash table using just an array. In the hash table, each empty slot in the array is called a \"bucket\", and each bucket can store one key-value pair. Therefore, the query operation involves finding the bucket corresponding to the key and retrieving the value from it.

    So, how do we locate the appropriate bucket based on the key? This is achieved through a \"hash function\". The role of the hash function is to map a larger input space to a smaller output space. In a hash table, the input space is all possible keys, and the output space is all buckets (array indices). In other words, input a key, and we can use the hash function to determine the storage location of the corresponding key-value pair in the array.

    The calculation process of the hash function for a given key is divided into the following two steps:

    1. Calculate the hash value using a certain hash algorithm hash().
    2. Take the modulus of the hash value with the number of buckets (array length) capacity to obtain the array index index.
    index = hash(key) % capacity\n

    Afterward, we can use index to access the corresponding bucket in the hash table and thereby retrieve the value.

    Assuming array length capacity = 100 and hash algorithm hash(key) = key, the hash function is key % 100. The Figure 6-2 uses key as the student number and value as the name to demonstrate the working principle of the hash function.

    Figure 6-2 \u00a0 Working principle of hash function

    The following code implements a simple hash table. Here, we encapsulate key and value into a class Pair to represent the key-value pair.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_hash_map.py
    class Pair:\n    \"\"\"\u952e\u503c\u5bf9\"\"\"\n\n    def __init__(self, key: int, val: str):\n        self.key = key\n        self.val = val\n\nclass ArrayHashMap:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        self.buckets: list[Pair | None] = [None] * 100\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        index = key % 100\n        return index\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        pair: Pair = self.buckets[index]\n        if pair is None:\n            return None\n        return pair.val\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        pair = Pair(key, val)\n        index: int = self.hash_func(key)\n        self.buckets[index] = pair\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        # \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None\n\n    def entry_set(self) -> list[Pair]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\"\"\"\n        result: list[Pair] = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair)\n        return result\n\n    def key_set(self) -> list[int]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.key)\n        return result\n\n    def value_set(self) -> list[str]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u503c\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.val)\n        return result\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is not None:\n                print(pair.key, \"->\", pair.val)\n
    array_hash_map.cpp
    /* \u952e\u503c\u5bf9 */\nstruct Pair {\n  public:\n    int key;\n    string val;\n    Pair(int key, string val) {\n        this->key = key;\n        this->val = val;\n    }\n};\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  private:\n    vector<Pair *> buckets;\n\n  public:\n    ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = vector<Pair *>(100);\n    }\n\n    ~ArrayHashMap() {\n        // \u91ca\u653e\u5185\u5b58\n        for (const auto &bucket : buckets) {\n            delete bucket;\n        }\n        buckets.clear();\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        Pair *pair = buckets[index];\n        if (pair == nullptr)\n            return \"\";\n        return pair->val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        Pair *pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        // \u91ca\u653e\u5185\u5b58\u5e76\u7f6e\u4e3a nullptr\n        delete buckets[index];\n        buckets[index] = nullptr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    vector<Pair *> pairSet() {\n        vector<Pair *> pairSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                pairSet.push_back(pair);\n            }\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    vector<int> keySet() {\n        vector<int> keySet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                keySet.push_back(pair->key);\n            }\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    vector<string> valueSet() {\n        vector<string> valueSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                valueSet.push_back(pair->val);\n            }\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *kv : pairSet()) {\n            cout << kv->key << \" -> \" << kv->val << endl;\n        }\n    }\n};\n
    array_hash_map.java
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n    public int key;\n    public String val;\n\n    public Pair(int key, String val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private List<Pair> buckets;\n\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = new ArrayList<>();\n        for (int i = 0; i < 100; i++) {\n            buckets.add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        int index = hashFunc(key);\n        Pair pair = buckets.get(index);\n        if (pair == null)\n            return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        Pair pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets.set(index, pair);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        int index = hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets.set(index, null);\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> pairSet() {\n        List<Pair> pairSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                pairSet.add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<Integer> keySet() {\n        List<Integer> keySet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                keySet.add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<String> valueSet() {\n        List<String> valueSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                valueSet.add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair kv : pairSet()) {\n            System.out.println(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.cs
    /* \u952e\u503c\u5bf9 int->string */\nclass Pair(int key, string val) {\n    public int key = key;\n    public string val = val;\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    List<Pair?> buckets;\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = [];\n        for (int i = 0; i < 100; i++) {\n            buckets.Add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        Pair? pair = buckets[index];\n        if (pair == null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        Pair pair = new(key, val);\n        int index = HashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> PairSet() {\n        List<Pair> pairSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                pairSet.Add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<int> KeySet() {\n        List<int> keySet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                keySet.Add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<string> ValueSet() {\n        List<string> valueSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                valueSet.Add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair kv in PairSet()) {\n            Console.WriteLine(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.go
    /* \u952e\u503c\u5bf9 */\ntype pair struct {\n    key int\n    val string\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntype arrayHashMap struct {\n    buckets []*pair\n}\n\n/* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nfunc newArrayHashMap() *arrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    buckets := make([]*pair, 100)\n    return &arrayHashMap{buckets: buckets}\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (a *arrayHashMap) hashFunc(key int) int {\n    index := key % 100\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (a *arrayHashMap) get(key int) string {\n    index := a.hashFunc(key)\n    pair := a.buckets[index]\n    if pair == nil {\n        return \"Not Found\"\n    }\n    return pair.val\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (a *arrayHashMap) put(key int, val string) {\n    pair := &pair{key: key, val: val}\n    index := a.hashFunc(key)\n    a.buckets[index] = pair\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (a *arrayHashMap) remove(key int) {\n    index := a.hashFunc(key)\n    // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    a.buckets[index] = nil\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u5bf9 */\nfunc (a *arrayHashMap) pairSet() []*pair {\n    var pairs []*pair\n    for _, pair := range a.buckets {\n        if pair != nil {\n            pairs = append(pairs, pair)\n        }\n    }\n    return pairs\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nfunc (a *arrayHashMap) keySet() []int {\n    var keys []int\n    for _, pair := range a.buckets {\n        if pair != nil {\n            keys = append(keys, pair.key)\n        }\n    }\n    return keys\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nfunc (a *arrayHashMap) valueSet() []string {\n    var values []string\n    for _, pair := range a.buckets {\n        if pair != nil {\n            values = append(values, pair.val)\n        }\n    }\n    return values\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (a *arrayHashMap) print() {\n    for _, pair := range a.buckets {\n        if pair != nil {\n            fmt.Println(pair.key, \"->\", pair.val)\n        }\n    }\n}\n
    array_hash_map.swift
    /* \u952e\u503c\u5bf9 */\nclass Pair: Equatable {\n    public var key: Int\n    public var val: String\n\n    public init(key: Int, val: String) {\n        self.key = key\n        self.val = val\n    }\n\n    public static func == (lhs: Pair, rhs: Pair) -> Bool {\n        lhs.key == rhs.key && lhs.val == rhs.val\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private var buckets: [Pair?]\n\n    init() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = Array(repeating: nil, count: 100)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private func hashFunc(key: Int) -> Int {\n        let index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let pair = buckets[index]\n        return pair?.val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        let pair = Pair(key: key, val: val)\n        let index = hashFunc(key: key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = nil\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    func pairSet() -> [Pair] {\n        buckets.compactMap { $0 }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    func keySet() -> [Int] {\n        buckets.compactMap { $0?.key }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    func valueSet() -> [String] {\n        buckets.compactMap { $0?.val }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in pairSet() {\n            Swift.print(\"\\(pair.key) -> \\(pair.val)\")\n        }\n    }\n}\n
    array_hash_map.js
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    constructor(key, val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    #buckets;\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.#buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        let index = this.#hashFunc(key);\n        let pair = this.#buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    set(key, val) {\n        let index = this.#hashFunc(key);\n        this.#buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    delete(key) {\n        let index = this.#hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.#buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    entries() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    keys() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    values() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.ts
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    public key: number;\n    public val: string;\n\n    constructor(key: number, val: string) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private readonly buckets: (Pair | null)[];\n\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public get(key: number): string | null {\n        let index = this.hashFunc(key);\n        let pair = this.buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public set(key: number, val: string) {\n        let index = this.hashFunc(key);\n        this.buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public delete(key: number) {\n        let index = this.hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public entries(): (Pair | null)[] {\n        let arr: (Pair | null)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public keys(): (number | undefined)[] {\n        let arr: (number | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public values(): (string | undefined)[] {\n        let arr: (string | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.dart
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n  int key;\n  String val;\n  Pair(this.key, this.val);\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  late List<Pair?> _buckets;\n\n  ArrayHashMap() {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    _buckets = List.filled(100, null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int _hashFunc(int key) {\n    final int index = key % 100;\n    return index;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    final int index = _hashFunc(key);\n    final Pair? pair = _buckets[index];\n    if (pair == null) {\n      return null;\n    }\n    return pair.val;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    final Pair pair = Pair(key, val);\n    final int index = _hashFunc(key);\n    _buckets[index] = pair;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    final int index = _hashFunc(key);\n    _buckets[index] = null;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n  List<Pair> pairSet() {\n    List<Pair> pairSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        pairSet.add(pair);\n      }\n    }\n    return pairSet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e */\n  List<int> keySet() {\n    List<int> keySet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        keySet.add(pair.key);\n      }\n    }\n    return keySet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u503c */\n  List<String> values() {\n    List<String> valueSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        valueSet.add(pair.val);\n      }\n    }\n    return valueSet;\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (final Pair kv in pairSet()) {\n      print(\"${kv.key} -> ${kv.val}\");\n    }\n  }\n}\n
    array_hash_map.rs
    /* \u952e\u503c\u5bf9 */\n#[derive(Debug, Clone, PartialEq)]\npub struct Pair {\n    pub key: i32,\n    pub val: String,\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\npub struct ArrayHashMap {\n    buckets: Vec<Option<Pair>>,\n}\n\nimpl ArrayHashMap {\n    pub fn new() -> ArrayHashMap {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        Self {\n            buckets: vec![None; 100],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % 100\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    pub fn get(&self, key: i32) -> Option<&String> {\n        let index = self.hash_func(key);\n        self.buckets[index].as_ref().map(|pair| &pair.val)\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    pub fn put(&mut self, key: i32, val: &str) {\n        let index = self.hash_func(key);\n        self.buckets[index] = Some(Pair {\n            key,\n            val: val.to_string(),\n        });\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    pub fn remove(&mut self, key: i32) {\n        let index = self.hash_func(key);\n        // \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    pub fn entry_set(&self) -> Vec<&Pair> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref())\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    pub fn key_set(&self) -> Vec<&i32> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.key))\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    pub fn value_set(&self) -> Vec<&String> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.val))\n            .collect()\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    pub fn print(&self) {\n        for pair in self.entry_set() {\n            println!(\"{} -> {}\", pair.key, pair.val);\n        }\n    }\n}\n
    array_hash_map.c
    /* \u952e\u503c\u5bf9 int->string */\ntypedef struct {\n    int key;\n    char *val;\n} Pair;\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntypedef struct {\n    Pair *buckets[MAX_SIZE];\n} ArrayHashMap;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayHashMap *newArrayHashMap() {\n    ArrayHashMap *hmap = malloc(sizeof(ArrayHashMap));\n    for (int i=0; i < MAX_SIZE; i++) {\n        hmap->buckets[i] = NULL;\n    }\n    return hmap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayHashMap(ArrayHashMap *hmap) {\n    for (int i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            free(hmap->buckets[i]->val);\n            free(hmap->buckets[i]);\n        }\n    }\n    free(hmap);\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(ArrayHashMap *hmap, const int key, const char *val) {\n    Pair *Pair = malloc(sizeof(Pair));\n    Pair->key = key;\n    Pair->val = malloc(strlen(val) + 1);\n    strcpy(Pair->val, val);\n\n    int index = hashFunc(key);\n    hmap->buckets[index] = Pair;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(ArrayHashMap *hmap, const int key) {\n    int index = hashFunc(key);\n    free(hmap->buckets[index]->val);\n    free(hmap->buckets[index]);\n    hmap->buckets[index] = NULL;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\nvoid pairSet(ArrayHashMap *hmap, MapSet *set) {\n    Pair *entries;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    entries = malloc(sizeof(Pair) * total);\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            entries[index].key = hmap->buckets[i]->key;\n            entries[index].val = malloc(strlen(hmap->buckets[i]->val) + 1);\n            strcpy(entries[index].val, hmap->buckets[i]->val);\n            index++;\n        }\n    }\n    set->set = entries;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nvoid keySet(ArrayHashMap *hmap, MapSet *set) {\n    int *keys;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    keys = malloc(total * sizeof(int));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            keys[index] = hmap->buckets[i]->key;\n            index++;\n        }\n    }\n    set->set = keys;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nvoid valueSet(ArrayHashMap *hmap, MapSet *set) {\n    char **vals;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    vals = malloc(total * sizeof(char *));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            vals[index] = hmap->buckets[i]->val;\n            index++;\n        }\n    }\n    set->set = vals;\n    set->len = total;\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(ArrayHashMap *hmap) {\n    int i;\n    MapSet set;\n    pairSet(hmap, &set);\n    Pair *entries = (Pair *)set.set;\n    for (i = 0; i < set.len; i++) {\n        printf(\"%d -> %s\\n\", entries[i].key, entries[i].val);\n    }\n    free(set.set);\n}\n
    array_hash_map.kt
    /* \u952e\u503c\u5bf9 */\nclass Pair(\n    var key: Int,\n    var _val: String\n)\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    private val buckets = arrayOfNulls<Pair>(100)\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        val index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val pair = buckets[index] ?: return null\n        return pair._val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        val pair = Pair(key, _val)\n        val index = hashFunc(key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    fun pairSet(): MutableList<Pair> {\n        val pairSet = mutableListOf<Pair>()\n        for (pair in buckets) {\n            if (pair != null)\n                pairSet.add(pair)\n        }\n        return pairSet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    fun keySet(): MutableList<Int> {\n        val keySet = mutableListOf<Int>()\n        for (pair in buckets) {\n            if (pair != null)\n                keySet.add(pair.key)\n        }\n        return keySet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    fun valueSet(): MutableList<String> {\n        val valueSet = mutableListOf<String>()\n        for (pair in buckets) {\n            if (pair != null)\n                valueSet.add(pair._val)\n        }\n        return valueSet\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (kv in pairSet()) {\n            val key = kv.key\n            val _val = kv._val\n            println(\"$key -> $_val\")\n        }\n    }\n}\n
    array_hash_map.rb
    ### \u952e\u503c\u5bf9 ###\nclass Pair\n  attr_accessor :key, :val\n\n  def initialize(key, val)\n    @key = key\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 ###\nclass ArrayHashMap\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    @buckets = Array.new(100)\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    index = key % 100\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    pair = @buckets[index]\n\n    return if pair.nil?\n    pair.val\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    pair = Pair.new(key, val)\n    index = hash_func(key)\n    @buckets[index] = pair\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    # \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    @buckets[index] = nil\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 ###\n  def entry_set\n    result = []\n    @buckets.each { |pair| result << pair unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e ###\n  def key_set\n    result = []\n    @buckets.each { |pair| result << pair.key unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u503c ###\n  def value_set\n    result = []\n    @buckets.each { |pair| result << pair.val unless pair.nil? }\n    result\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    @buckets.each { |pair| puts \"#{pair.key} -> #{pair.val}\" unless pair.nil? }\n  end\nend\n
    array_hash_map.zig
    // \u952e\u503c\u5bf9\nconst Pair = struct {\n    key: usize = undefined,\n    val: []const u8 = undefined,\n\n   pub fn init(key: usize, val: []const u8) Pair {\n        return Pair {\n            .key = key,\n            .val = val,\n        };\n    }\n};\n\n// \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\nfn ArrayHashMap(comptime T: type) type {\n    return struct {\n        bucket: ?std.ArrayList(?T) = null,\n        mem_allocator: std.mem.Allocator = undefined,\n\n        const Self = @This();\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            self.mem_allocator = allocator;\n            // \u521d\u59cb\u5316\u4e00\u4e2a\u957f\u5ea6\u4e3a 100 \u7684\u6876\uff08\u6570\u7ec4\uff09\n            self.bucket = std.ArrayList(?T).init(self.mem_allocator);\n            var i: i32 = 0;\n            while (i < 100) : (i += 1) {\n                try self.bucket.?.append(null);\n            }\n        }\n\n        // \u6790\u6784\u51fd\u6570\n        pub fn deinit(self: *Self) void {\n            if (self.bucket != null) self.bucket.?.deinit();\n        }\n\n        // \u54c8\u5e0c\u51fd\u6570\n        fn hashFunc(key: usize) usize {\n            var index = key % 100;\n            return index;\n        }\n\n        // \u67e5\u8be2\u64cd\u4f5c\n        pub fn get(self: *Self, key: usize) []const u8 {\n            var index = hashFunc(key);\n            var pair = self.bucket.?.items[index];\n            return pair.?.val;\n        }\n\n        // \u6dfb\u52a0\u64cd\u4f5c\n        pub fn put(self: *Self, key: usize, val: []const u8) !void {\n            var pair = Pair.init(key, val);\n            var index = hashFunc(key);\n            self.bucket.?.items[index] = pair;\n        }\n\n        // \u5220\u9664\u64cd\u4f5c\n        pub fn remove(self: *Self, key: usize) !void {\n            var index = hashFunc(key);\n            // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n            self.bucket.?.items[index] = null;\n        }       \n\n        // \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\n        pub fn pairSet(self: *Self) !std.ArrayList(T) {\n            var entry_set = std.ArrayList(T).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try entry_set.append(item.?);\n            }\n            return entry_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u952e\n        pub fn keySet(self: *Self) !std.ArrayList(usize) {\n            var key_set = std.ArrayList(usize).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try key_set.append(item.?.key);\n            }\n            return key_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u503c\n        pub fn valueSet(self: *Self) !std.ArrayList([]const u8) {\n            var value_set = std.ArrayList([]const u8).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try value_set.append(item.?.val);\n            }\n            return value_set;\n        }\n\n        // \u6253\u5370\u54c8\u5e0c\u8868\n        pub fn print(self: *Self) !void {\n            var entry_set = try self.pairSet();\n            defer entry_set.deinit();\n            for (entry_set.items) |item| {\n                std.debug.print(\"{} -> {s}\\n\", .{item.key, item.val});\n            }\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_hashing/hash_map/#613-hash-collision-and-resizing","title":"6.1.3 \u00a0 Hash collision and resizing","text":"

    Fundamentally, the role of the hash function is to map the entire input space of all keys to the output space of all array indices. However, the input space is often much larger than the output space. Therefore, theoretically, there must be situations where \"multiple inputs correspond to the same output\".

    For the hash function in the above example, if the last two digits of the input key are the same, the output of the hash function will also be the same. For example, when querying for students with student numbers 12836 and 20336, we find:

    12836 % 100 = 36\n20336 % 100 = 36\n

    As shown in the Figure 6-3 , both student numbers point to the same name, which is obviously incorrect. This situation where multiple inputs correspond to the same output is known as \"hash collision\".

    Figure 6-3 \u00a0 Example of hash collision

    It is easy to understand that the larger the capacity \\(n\\) of the hash table, the lower the probability of multiple keys being allocated to the same bucket, and the fewer the collisions. Therefore, expanding the capacity of the hash table can reduce hash collisions.

    As shown in the Figure 6-4 , before expansion, key-value pairs (136, A) and (236, D) collided; after expansion, the collision is resolved.

    Figure 6-4 \u00a0 Hash table expansion

    Similar to array expansion, resizing a hash table requires migrating all key-value pairs from the original hash table to the new one, which is time-consuming. Furthermore, since the capacity capacity of the hash table changes, we need to recalculate the storage positions of all key-value pairs using the hash function, which adds to the computational overhead of the resizing process. Therefore, programming languages often reserve a sufficiently large capacity for the hash table to prevent frequent resizing.

    The \"load factor\" is an important concept for hash tables. It is defined as the ratio of the number of elements in the hash table to the number of buckets. It is used to measure the severity of hash collisions and is often used as a trigger for resizing the hash table. For example, in Java, when the load factor exceeds \\(0.75\\), the system will resize the hash table to twice its original size.

    "},{"location":"chapter_hashing/summary/","title":"6.4 \u00a0 Summary","text":""},{"location":"chapter_hashing/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Given an input key, a hash table can retrieve the corresponding value in \\(O(1)\\) time, which is highly efficient.
    • Common hash table operations include querying, adding key-value pairs, deleting key-value pairs, and traversing the hash table.
    • The hash function maps a key to an array index, allowing access to the corresponding bucket and retrieval of the value.
    • Two different keys may end up with the same array index after hashing, leading to erroneous query results. This phenomenon is known as hash collision.
    • The larger the capacity of the hash table, the lower the probability of hash collisions. Therefore, hash table resizing can mitigate hash collisions. Similar to array resizing, hash table resizing is costly.
    • The load factor, defined as the number of elements divided by the number of buckets, reflects the severity of hash collisions and is often used as a condition to trigger hash table resizing.
    • Chaining addresses hash collisions by converting each element into a linked list, storing all colliding elements in the same list. However, excessively long lists can reduce query efficiency, which can be improved by converting the lists into red-black trees.
    • Open addressing handles hash collisions through multiple probes. Linear probing uses a fixed step size but it cannot delete elements and is prone to clustering. Multiple hashing uses several hash functions for probing which reduces clustering compared to linear probing but increases computational overhead.
    • Different programming languages adopt various hash table implementations. For example, Java's HashMap uses chaining, while Python's dict employs open addressing.
    • In hash tables, we desire hash algorithms with determinism, high efficiency, and uniform distribution. In cryptography, hash algorithms should also possess collision resistance and the avalanche effect.
    • Hash algorithms typically use large prime numbers as moduli to ensure uniform distribution of hash values and reduce hash collisions.
    • Common hash algorithms include MD5, SHA-1, SHA-2, and SHA-3. MD5 is often used for file integrity checks, while SHA-2 is commonly used in secure applications and protocols.
    • Programming languages usually provide built-in hash algorithms for data types to calculate bucket indices in hash tables. Generally, only immutable objects are hashable.
    "},{"location":"chapter_hashing/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: When does the time complexity of a hash table degrade to \\(O(n)\\)?

    The time complexity of a hash table can degrade to \\(O(n)\\) when hash collisions are severe. When the hash function is well-designed, the capacity is set appropriately, and collisions are evenly distributed, the time complexity is \\(O(1)\\). We usually consider the time complexity to be \\(O(1)\\) when using built-in hash tables in programming languages.

    Q: Why not use the hash function \\(f(x) = x\\)? This would eliminate collisions.

    Under the hash function \\(f(x) = x\\), each element corresponds to a unique bucket index, which is equivalent to an array. However, the input space is usually much larger than the output space (array length), so the last step of a hash function is often to take the modulo of the array length. In other words, the goal of a hash table is to map a larger state space to a smaller one while providing \\(O(1)\\) query efficiency.

    Q: Why can hash tables be more efficient than arrays, linked lists, or binary trees, even though hash tables are implemented using these structures?

    Firstly, hash tables have higher time efficiency but lower space efficiency. A significant portion of memory in hash tables remains unused.

    Secondly, hash tables are only more time-efficient in specific use cases. If a feature can be implemented with the same time complexity using an array or a linked list, it's usually faster than using a hash table. This is because the computation of the hash function incurs overhead, making the constant factor in the time complexity larger.

    Lastly, the time complexity of hash tables can degrade. For example, in chaining, we perform search operations in a linked list or red-black tree, which still risks degrading to \\(O(n)\\) time.

    Q: Does multiple hashing also have the flaw of not being able to delete elements directly? Can space marked as deleted be reused?

    Multiple hashing is a form of open addressing, and all open addressing methods have the drawback of not being able to delete elements directly; they require marking elements as deleted. Marked spaces can be reused. When inserting new elements into the hash table, and the hash function points to a position marked as deleted, that position can be used by the new element. This maintains the probing sequence of the hash table while ensuring efficient use of space.

    Q: Why do hash collisions occur during the search process in linear probing?

    During the search process, the hash function points to the corresponding bucket and key-value pair. If the key doesn't match, it indicates a hash collision. Therefore, linear probing will search downwards at a predetermined step size until the correct key-value pair is found or the search fails.

    Q: Why can resizing a hash table alleviate hash collisions?

    The last step of a hash function often involves taking the modulo of the array length \\(n\\), to keep the output within the array index range. When resizing, the array length \\(n\\) changes, and the indices corresponding to the keys may also change. Keys that were previously mapped to the same bucket might be distributed across multiple buckets after resizing, thereby mitigating hash collisions.

    "},{"location":"chapter_heap/","title":"Chapter 8. \u00a0 Heap","text":"

    Abstract

    The heap is like mountain peaks, stacked and undulating, each with its unique shape.

    Among these peaks, the highest one always catches the eye first.

    "},{"location":"chapter_heap/#chapter-contents","title":"Chapter contents","text":"
    • 8.1 \u00a0 Heap
    • 8.2 \u00a0 Building a heap
    • 8.3 \u00a0 Top-k problem
    • 8.4 \u00a0 Summary
    "},{"location":"chapter_heap/build_heap/","title":"8.2 \u00a0 Heap construction operation","text":"

    In some cases, we want to build a heap using all elements of a list, and this process is known as \"heap construction operation.\"

    "},{"location":"chapter_heap/build_heap/#821-implementing-with-heap-insertion-operation","title":"8.2.1 \u00a0 Implementing with heap insertion operation","text":"

    First, we create an empty heap and then iterate through the list, performing the \"heap insertion operation\" on each element in turn. This means adding the element to the end of the heap and then \"heapifying\" it from bottom to top.

    Each time an element is added to the heap, the length of the heap increases by one. Since nodes are added to the binary tree from top to bottom, the heap is constructed \"from top to bottom.\"

    Let the number of elements be \\(n\\), and each element's insertion operation takes \\(O(\\log{n})\\) time, thus the time complexity of this heap construction method is \\(O(n \\log n)\\).

    "},{"location":"chapter_heap/build_heap/#822-implementing-by-heapifying-through-traversal","title":"8.2.2 \u00a0 Implementing by heapifying through traversal","text":"

    In fact, we can implement a more efficient method of heap construction in two steps.

    1. Add all elements of the list as they are into the heap, at this point the properties of the heap are not yet satisfied.
    2. Traverse the heap in reverse order (reverse of level-order traversal), and perform \"top to bottom heapify\" on each non-leaf node.

    After heapifying a node, the subtree with that node as the root becomes a valid sub-heap. Since the traversal is in reverse order, the heap is built \"from bottom to top.\"

    The reason for choosing reverse traversal is that it ensures the subtree below the current node is already a valid sub-heap, making the heapification of the current node effective.

    It's worth mentioning that since leaf nodes have no children, they naturally form valid sub-heaps and do not need to be heapified. As shown in the following code, the last non-leaf node is the parent of the last node; we start from it and traverse in reverse order to perform heapification:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def __init__(self, nums: list[int]):\n    \"\"\"\u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\"\"\"\n    # \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    self.max_heap = nums\n    # \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(self.parent(self.size() - 1), -1, -1):\n        self.sift_down(i)\n
    my_heap.cpp
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(vector<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums;\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.java
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<Integer> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new ArrayList<>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.cs
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(IEnumerable<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new List<int>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var size = Parent(this.Size() - 1);\n    for (int i = size; i >= 0; i--) {\n        SiftDown(i);\n    }\n}\n
    my_heap.go
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nfunc newMaxHeap(nums []any) *maxHeap {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    h := &maxHeap{data: nums}\n    for i := h.parent(len(h.data) - 1); i >= 0; i-- {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        h.siftDown(i)\n    }\n    return h\n}\n
    my_heap.swift
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\ninit(nums: [Int]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0 ... parent(i: size() - 1)).reversed() {\n        siftDown(i: i)\n    }\n}\n
    my_heap.js
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.#maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.#parent(this.size() - 1); i >= 0; i--) {\n        this.#siftDown(i);\n    }\n}\n
    my_heap.ts
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums?: number[]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.parent(this.size() - 1); i >= 0; i--) {\n        this.siftDown(i);\n    }\n}\n
    my_heap.dart
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<int> nums) {\n  // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n  _maxHeap = nums;\n  // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = _parent(size() - 1); i >= 0; i--) {\n    siftDown(i);\n  }\n}\n
    my_heap.rs
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nfn new(nums: Vec<i32>) -> Self {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    let mut heap = MaxHeap { max_heap: nums };\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=Self::parent(heap.size() - 1)).rev() {\n        heap.sift_down(i);\n    }\n    heap\n}\n
    my_heap.c
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nMaxHeap *newMaxHeap(int nums[], int size) {\n    // \u6240\u6709\u5143\u7d20\u5165\u5806\n    MaxHeap *maxHeap = (MaxHeap *)malloc(sizeof(MaxHeap));\n    maxHeap->size = size;\n    memcpy(maxHeap->data, nums, size * sizeof(int));\n    for (int i = parent(maxHeap, size - 1); i >= 0; i--) {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        siftDown(maxHeap, i);\n    }\n    return maxHeap;\n}\n
    my_heap.kt
    /* \u5927\u9876\u5806 */\nclass MaxHeap(nums: MutableList<Int>?) {\n    // \u4f7f\u7528\u5217\u8868\u800c\u975e\u6570\u7ec4\uff0c\u8fd9\u6837\u65e0\u987b\u8003\u8651\u6269\u5bb9\u95ee\u9898\n    private val maxHeap = mutableListOf<Int>()\n\n    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\n    init {\n        // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n        maxHeap.addAll(nums!!)\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        for (i in parent(size() - 1) downTo 0) {\n            siftDown(i)\n        }\n    }\n\n    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun parent(i: Int): Int {\n        return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u4ea4\u6362\u5143\u7d20 */\n    private fun swap(i: Int, j: Int) {\n        val temp = maxHeap[i]\n        maxHeap[i] = maxHeap[j]\n        maxHeap[j] = temp\n    }\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    fun size(): Int {\n        return maxHeap.size\n    }\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n        return size() == 0\n    }\n\n    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        return maxHeap[0]\n    }\n\n    /* \u5143\u7d20\u5165\u5806 */\n    fun push(_val: Int) {\n        // \u6dfb\u52a0\u8282\u70b9\n        maxHeap.add(_val)\n        // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n        siftUp(size() - 1)\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n    private fun siftUp(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n            val p = parent(i)\n            // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n            if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, p)\n            // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n            i = p\n        }\n    }\n\n    /* \u5143\u7d20\u51fa\u5806 */\n    fun pop(): Int {\n        // \u5224\u7a7a\u5904\u7406\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(0, size() - 1)\n        // \u5220\u9664\u8282\u70b9\n        val _val = maxHeap.removeAt(size() - 1)\n        // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n        siftDown(0)\n        // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n        return _val\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n    private fun siftDown(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n            val l = left(i)\n            val r = right(i)\n            var ma = i\n            if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n            if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n            // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n            if (ma == i) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, ma)\n            // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n            i = ma\n        }\n    }\n\n    /* \u6253\u5370\u5806\uff08\u4e8c\u53c9\u6811\uff09 */\n    fun print() {\n        val queue = PriorityQueue { a: Int, b: Int -> b - a }\n        queue.addAll(maxHeap)\n        printHeap(queue)\n    }\n}\n
    my_heap.rb
    [class]{MaxHeap}-[func]{__init__}\n
    my_heap.zig
    // \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\nfn init(self: *Self, allocator: std.mem.Allocator, nums: []const T) !void {\n    if (self.max_heap != null) return;\n    self.max_heap = std.ArrayList(T).init(allocator);\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    try self.max_heap.?.appendSlice(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var i: usize = parent(self.size() - 1) + 1;\n    while (i > 0) : (i -= 1) {\n        try self.siftDown(i - 1);\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/build_heap/#823-complexity-analysis","title":"8.2.3 \u00a0 Complexity analysis","text":"

    Next, let's attempt to calculate the time complexity of this second method of heap construction.

    • Assuming the number of nodes in the complete binary tree is \\(n\\), then the number of leaf nodes is \\((n + 1) / 2\\), where \\(/\\) is integer division. Therefore, the number of nodes that need to be heapified is \\((n - 1) / 2\\).
    • In the process of \"top to bottom heapification,\" each node is heapified to the leaf nodes at most, so the maximum number of iterations is the height of the binary tree \\(\\log n\\).

    Multiplying the two, we get the time complexity of the heap construction process as \\(O(n \\log n)\\). But this estimate is not accurate, because it does not take into account the nature of the binary tree having far more nodes at the lower levels than at the top.

    Let's perform a more accurate calculation. To simplify the calculation, assume a \"perfect binary tree\" with \\(n\\) nodes and height \\(h\\); this assumption does not affect the correctness of the result.

    Figure 8-5 \u00a0 Node counts at each level of a perfect binary tree

    As shown in the Figure 8-5 , the maximum number of iterations for a node \"to be heapified from top to bottom\" is equal to the distance from that node to the leaf nodes, which is precisely \"node height.\" Therefore, we can sum the \"number of nodes \\(\\times\\) node height\" at each level, to get the total number of heapification iterations for all nodes.

    \\[ T(h) = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{(h-1)}\\times1 \\]

    To simplify the above equation, we need to use knowledge of sequences from high school, first multiply \\(T(h)\\) by \\(2\\), to get:

    \\[ \\begin{aligned} T(h) & = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{h-1}\\times1 \\newline 2T(h) & = 2^1h + 2^2(h-1) + 2^3(h-2) + \\dots + 2^h\\times1 \\newline \\end{aligned} \\]

    By subtracting \\(T(h)\\) from \\(2T(h)\\) using the method of displacement, we get:

    \\[ 2T(h) - T(h) = T(h) = -2^0h + 2^1 + 2^2 + \\dots + 2^{h-1} + 2^h \\]

    Observing the equation, \\(T(h)\\) is an geometric series, which can be directly calculated using the sum formula, resulting in a time complexity of:

    \\[ \\begin{aligned} T(h) & = 2 \\frac{1 - 2^h}{1 - 2} - h \\newline & = 2^{h+1} - h - 2 \\newline & = O(2^h) \\end{aligned} \\]

    Further, a perfect binary tree with height \\(h\\) has \\(n = 2^{h+1} - 1\\) nodes, thus the complexity is \\(O(2^h) = O(n)\\). This calculation shows that the time complexity of inputting a list and constructing a heap is \\(O(n)\\), which is very efficient.

    "},{"location":"chapter_heap/heap/","title":"8.1 \u00a0 Heap","text":"

    A \"heap\" is a complete binary tree that satisfies specific conditions and can be mainly divided into two types, as shown in the Figure 8-1 .

    • \"Min heap\": The value of any node \\(\\leq\\) the values of its child nodes.
    • \"Max heap\": The value of any node \\(\\geq\\) the values of its child nodes.

    Figure 8-1 \u00a0 Min heap and max heap

    As a special case of a complete binary tree, heaps have the following characteristics:

    • The bottom layer nodes are filled from left to right, and nodes in other layers are fully filled.
    • The root node of the binary tree is called the \"heap top,\" and the bottom-rightmost node is called the \"heap bottom.\"
    • For max heaps (min heaps), the value of the heap top element (root node) is the largest (smallest).
    "},{"location":"chapter_heap/heap/#811-common-operations-on-heaps","title":"8.1.1 \u00a0 Common operations on heaps","text":"

    It should be noted that many programming languages provide a \"priority queue,\" which is an abstract data structure defined as a queue with priority sorting.

    In fact, heaps are often used to implement priority queues, with max heaps equivalent to priority queues where elements are dequeued in descending order. From a usage perspective, we can consider \"priority queue\" and \"heap\" as equivalent data structures. Therefore, this book does not make a special distinction between the two, uniformly referring to them as \"heap.\"

    Common operations on heaps are shown in the Table 8-1 , and the method names depend on the programming language.

    Table 8-1 \u00a0 Efficiency of Heap Operations

    Method name Description Time complexity push() Add an element to the heap \\(O(\\log n)\\) pop() Remove the top element from the heap \\(O(\\log n)\\) peek() Access the top element (for max/min heap, the max/min value) \\(O(1)\\) size() Get the number of elements in the heap \\(O(1)\\) isEmpty() Check if the heap is empty \\(O(1)\\)

    In practice, we can directly use the heap class (or priority queue class) provided by programming languages.

    Similar to sorting algorithms where we have \"ascending order\" and \"descending order,\" we can switch between \"min heap\" and \"max heap\" by setting a flag or modifying the Comparator. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap.py
    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\nmin_heap, flag = [], 1\n# \u521d\u59cb\u5316\u5927\u9876\u5806\nmax_heap, flag = [], -1\n\n# Python \u7684 heapq \u6a21\u5757\u9ed8\u8ba4\u5b9e\u73b0\u5c0f\u9876\u5806\n# \u8003\u8651\u5c06\u201c\u5143\u7d20\u53d6\u8d1f\u201d\u540e\u518d\u5165\u5806\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u5927\u5c0f\u5173\u7cfb\u98a0\u5012\uff0c\u4ece\u800c\u5b9e\u73b0\u5927\u9876\u5806\n# \u5728\u672c\u793a\u4f8b\u4e2d\uff0cflag = 1 \u65f6\u5bf9\u5e94\u5c0f\u9876\u5806\uff0cflag = -1 \u65f6\u5bf9\u5e94\u5927\u9876\u5806\n\n# \u5143\u7d20\u5165\u5806\nheapq.heappush(max_heap, flag * 1)\nheapq.heappush(max_heap, flag * 3)\nheapq.heappush(max_heap, flag * 2)\nheapq.heappush(max_heap, flag * 5)\nheapq.heappush(max_heap, flag * 4)\n\n# \u83b7\u53d6\u5806\u9876\u5143\u7d20\npeek: int = flag * max_heap[0] # 5\n\n# \u5806\u9876\u5143\u7d20\u51fa\u5806\n# \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nval = flag * heapq.heappop(max_heap) # 5\nval = flag * heapq.heappop(max_heap) # 4\nval = flag * heapq.heappop(max_heap) # 3\nval = flag * heapq.heappop(max_heap) # 2\nval = flag * heapq.heappop(max_heap) # 1\n\n# \u83b7\u53d6\u5806\u5927\u5c0f\nsize: int = len(max_heap)\n\n# \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = not max_heap\n\n# \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806\nmin_heap: list[int] = [1, 3, 2, 5, 4]\nheapq.heapify(min_heap)\n
    heap.cpp
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\npriority_queue<int, vector<int>, greater<int>> minHeap;\n// \u521d\u59cb\u5316\u5927\u9876\u5806\npriority_queue<int, vector<int>, less<int>> maxHeap;\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.push(1);\nmaxHeap.push(3);\nmaxHeap.push(2);\nmaxHeap.push(5);\nmaxHeap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.top(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nmaxHeap.pop(); // 5\nmaxHeap.pop(); // 4\nmaxHeap.pop(); // 3\nmaxHeap.pop(); // 2\nmaxHeap.pop(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nvector<int> input{1, 3, 2, 5, 4};\npriority_queue<int, vector<int>, greater<int>> minHeap(input.begin(), input.end());\n
    heap.java
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nQueue<Integer> minHeap = new PriorityQueue<>();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1);\nmaxHeap.offer(3);\nmaxHeap.offer(2);\nmaxHeap.offer(5);\nmaxHeap.offer(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.peek(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll(); // 5\npeek = maxHeap.poll(); // 4\npeek = maxHeap.poll(); // 3\npeek = maxHeap.poll(); // 2\npeek = maxHeap.poll(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = maxHeap.isEmpty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<>(Arrays.asList(1, 3, 2, 5, 4));\n
    heap.cs
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nPriorityQueue<int, int> minHeap = new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nPriorityQueue<int, int> maxHeap = new(Comparer<int>.Create((x, y) => y - x));\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.Enqueue(1, 1);\nmaxHeap.Enqueue(3, 3);\nmaxHeap.Enqueue(2, 2);\nmaxHeap.Enqueue(5, 5);\nmaxHeap.Enqueue(4, 4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.Peek();//5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.Dequeue();  // 5\npeek = maxHeap.Dequeue();  // 4\npeek = maxHeap.Dequeue();  // 3\npeek = maxHeap.Dequeue();  // 2\npeek = maxHeap.Dequeue();  // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.Count;\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.Count == 0;\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<int, int>([(1, 1), (3, 3), (2, 2), (5, 5), (4, 4)]);\n
    heap.go
    // Go \u8bed\u8a00\u4e2d\u53ef\u4ee5\u901a\u8fc7\u5b9e\u73b0 heap.Interface \u6765\u6784\u5efa\u6574\u6570\u5927\u9876\u5806\n// \u5b9e\u73b0 heap.Interface \u9700\u8981\u540c\u65f6\u5b9e\u73b0 sort.Interface\ntype intHeap []any\n\n// Push heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u63a8\u5165\u5143\u7d20\u5230\u5806\nfunc (h *intHeap) Push(x any) {\n    // Push \u548c Pop \u4f7f\u7528 pointer receiver \u4f5c\u4e3a\u53c2\u6570\n    // \u56e0\u4e3a\u5b83\u4eec\u4e0d\u4ec5\u4f1a\u5bf9\u5207\u7247\u7684\u5185\u5bb9\u8fdb\u884c\u8c03\u6574\uff0c\u8fd8\u4f1a\u4fee\u6539\u5207\u7247\u7684\u957f\u5ea6\u3002\n    *h = append(*h, x.(int))\n}\n\n// Pop heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u5f39\u51fa\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Pop() any {\n    // \u5f85\u51fa\u5806\u5143\u7d20\u5b58\u653e\u5728\u6700\u540e\n    last := (*h)[len(*h)-1]\n    *h = (*h)[:len(*h)-1]\n    return last\n}\n\n// Len sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Len() int {\n    return len(*h)\n}\n\n// Less sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Less(i, j int) bool {\n    // \u5982\u679c\u5b9e\u73b0\u5c0f\u9876\u5806\uff0c\u5219\u9700\u8981\u8c03\u6574\u4e3a\u5c0f\u4e8e\u53f7\n    return (*h)[i].(int) > (*h)[j].(int)\n}\n\n// Swap sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Swap(i, j int) {\n    (*h)[i], (*h)[j] = (*h)[j], (*h)[i]\n}\n\n// Top \u83b7\u53d6\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Top() any {\n    return (*h)[0]\n}\n\n/* Driver Code */\nfunc TestHeap(t *testing.T) {\n    /* \u521d\u59cb\u5316\u5806 */\n    // \u521d\u59cb\u5316\u5927\u9876\u5806\n    maxHeap := &intHeap{}\n    heap.Init(maxHeap)\n    /* \u5143\u7d20\u5165\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u6dfb\u52a0\u5143\u7d20\n    heap.Push(maxHeap, 1)\n    heap.Push(maxHeap, 3)\n    heap.Push(maxHeap, 2)\n    heap.Push(maxHeap, 4)\n    heap.Push(maxHeap, 5)\n\n    /* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\n    top := maxHeap.Top()\n    fmt.Printf(\"\u5806\u9876\u5143\u7d20\u4e3a %d\\n\", top)\n\n    /* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u79fb\u9664\u5143\u7d20\n    heap.Pop(maxHeap) // 5\n    heap.Pop(maxHeap) // 4\n    heap.Pop(maxHeap) // 3\n    heap.Pop(maxHeap) // 2\n    heap.Pop(maxHeap) // 1\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    size := len(*maxHeap)\n    fmt.Printf(\"\u5806\u5143\u7d20\u6570\u91cf\u4e3a %d\\n\", size)\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    isEmpty := len(*maxHeap) == 0\n    fmt.Printf(\"\u5806\u662f\u5426\u4e3a\u7a7a %t\\n\", isEmpty)\n}\n
    heap.swift
    /* \u521d\u59cb\u5316\u5806 */\n// Swift \u7684 Heap \u7c7b\u578b\u540c\u65f6\u652f\u6301\u6700\u5927\u5806\u548c\u6700\u5c0f\u5806\uff0c\u4e14\u9700\u8981\u5f15\u5165 swift-collections\nvar heap = Heap<Int>()\n\n/* \u5143\u7d20\u5165\u5806 */\nheap.insert(1)\nheap.insert(3)\nheap.insert(2)\nheap.insert(5)\nheap.insert(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = heap.max()!\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\npeek = heap.removeMax() // 5\npeek = heap.removeMax() // 4\npeek = heap.removeMax() // 3\npeek = heap.removeMax() // 2\npeek = heap.removeMax() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = heap.count\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = heap.isEmpty\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet heap2 = Heap([1, 3, 2, 5, 4])\n
    heap.js
    // JavaScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.ts
    // TypeScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.dart
    // Dart \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.rs
    use std::collections::BinaryHeap;\nuse std::cmp::Reverse;\n\n/* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nlet mut min_heap = BinaryHeap::<Reverse<i32>>::new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\nlet mut max_heap = BinaryHeap::new();\n\n/* \u5143\u7d20\u5165\u5806 */\nmax_heap.push(1);\nmax_heap.push(3);\nmax_heap.push(2);\nmax_heap.push(5);\nmax_heap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nlet peek = max_heap.peek().unwrap();  // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nlet peek = max_heap.pop().unwrap();   // 5\nlet peek = max_heap.pop().unwrap();   // 4\nlet peek = max_heap.pop().unwrap();   // 3\nlet peek = max_heap.pop().unwrap();   // 2\nlet peek = max_heap.pop().unwrap();   // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = max_heap.len();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = max_heap.is_empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet min_heap = BinaryHeap::from(vec![Reverse(1), Reverse(3), Reverse(2), Reverse(5), Reverse(4)]);\n
    heap.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.kt
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nvar minHeap = PriorityQueue<Int>()\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nval maxHeap = PriorityQueue { a: Int, b: Int -> b - a }\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1)\nmaxHeap.offer(3)\nmaxHeap.offer(2)\nmaxHeap.offer(5)\nmaxHeap.offer(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = maxHeap.peek() // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll() // 5\npeek = maxHeap.poll() // 4\npeek = maxHeap.poll() // 3\npeek = maxHeap.poll() // 2\npeek = maxHeap.poll() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nval size = maxHeap.size\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = maxHeap.isEmpty()\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = PriorityQueue(mutableListOf(1, 3, 2, 5, 4))\n
    heap.rb
    \n
    heap.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    https://pythontutor.com/render.html#code=import%20heapq%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B0%8F%E9%A1%B6%E5%A0%86%0A%20%20%20%20min_heap,%20flag%20%3D%20%5B%5D,%201%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%A4%A7%E9%A1%B6%E5%A0%86%0A%20%20%20%20max_heap,%20flag%20%3D%20%5B%5D,%20-1%0A%20%20%20%20%0A%20%20%20%20%23%20Python%20%E7%9A%84%20heapq%20%E6%A8%A1%E5%9D%97%E9%BB%98%E8%AE%A4%E5%AE%9E%E7%8E%B0%E5%B0%8F%E9%A1%B6%E5%A0%86%0A%20%20%20%20%23%20%E8%80%83%E8%99%91%E5%B0%86%E2%80%9C%E5%85%83%E7%B4%A0%E5%8F%96%E8%B4%9F%E2%80%9D%E5%90%8E%E5%86%8D%E5%85%A5%E5%A0%86%EF%BC%8C%E8%BF%99%E6%A0%B7%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%B0%86%E5%A4%A7%E5%B0%8F%E5%85%B3%E7%B3%BB%E9%A2%A0%E5%80%92%EF%BC%8C%E4%BB%8E%E8%80%8C%E5%AE%9E%E7%8E%B0%E5%A4%A7%E9%A1%B6%E5%A0%86%0A%20%20%20%20%23%20%E5%9C%A8%E6%9C%AC%E7%A4%BA%E4%BE%8B%E4%B8%AD%EF%BC%8Cflag%20%3D%201%20%E6%97%B6%E5%AF%B9%E5%BA%94%E5%B0%8F%E9%A1%B6%E5%A0%86%EF%BC%8Cflag%20%3D%20-1%20%E6%97%B6%E5%AF%B9%E5%BA%94%E5%A4%A7%E9%A1%B6%E5%A0%86%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%85%A5%E5%A0%86%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%201%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%203%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%202%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%205%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%204%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E5%A0%86%E9%A1%B6%E5%85%83%E7%B4%A0%0A%20%20%20%20peek%20%3D%20flag%20*%20max_heap%5B0%5D%20%23%205%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%A0%86%E9%A1%B6%E5%85%83%E7%B4%A0%E5%87%BA%E5%A0%86%0A%20%20%20%20%23%20%E5%87%BA%E5%A0%86%E5%85%83%E7%B4%A0%E4%BC%9A%E5%BD%A2%E6%88%90%E4%B8%80%E4%B8%AA%E4%BB%8E%E5%A4%A7%E5%88%B0%E5%B0%8F%E7%9A%84%E5%BA%8F%E5%88%97%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%205%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%204%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%203%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%202%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%201%0A%20%20%20%20%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E5%A0%86%E5%A4%A7%E5%B0%8F%0A%20%20%20%20size%20%3D%20len%28max_heap%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%88%A4%E6%96%AD%E5%A0%86%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%0A%20%20%20%20is_empty%20%3D%20not%20max_heap%0A%20%20%20%20%0A%20%20%20%20%23%20%E8%BE%93%E5%85%A5%E5%88%97%E8%A1%A8%E5%B9%B6%E5%BB%BA%E5%A0%86%0A%20%20%20%20min_heap%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%20%20%20%20heapq.heapify%28min_heap%29&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    "},{"location":"chapter_heap/heap/#812-implementation-of-heaps","title":"8.1.2 \u00a0 Implementation of heaps","text":"

    The following implementation is of a max heap. To convert it into a min heap, simply invert all size logic comparisons (for example, replace \\(\\geq\\) with \\(\\leq\\)). Interested readers are encouraged to implement it on their own.

    "},{"location":"chapter_heap/heap/#1-storage-and-representation-of-heaps","title":"1. \u00a0 Storage and representation of heaps","text":"

    As mentioned in the \"Binary Trees\" section, complete binary trees are well-suited for array representation. Since heaps are a type of complete binary tree, we will use arrays to store heaps.

    When using an array to represent a binary tree, elements represent node values, and indexes represent node positions in the binary tree. Node pointers are implemented through an index mapping formula.

    As shown in the Figure 8-2 , given an index \\(i\\), the index of its left child is \\(2i + 1\\), the index of its right child is \\(2i + 2\\), and the index of its parent is \\((i - 1) / 2\\) (floor division). When the index is out of bounds, it signifies a null node or the node does not exist.

    Figure 8-2 \u00a0 Representation and storage of heaps

    We can encapsulate the index mapping formula into functions for convenient later use:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def left(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 1\n\ndef right(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 2\n\ndef parent(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return (i - 1) // 2  # \u5411\u4e0b\u6574\u9664\n
    my_heap.cpp
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.java
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.cs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint Parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.go
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) parent(i int) int {\n    // \u5411\u4e0b\u6574\u9664\n    return (i - 1) / 2\n}\n
    my_heap.swift
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc left(i: Int) -> Int {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc right(i: Int) -> Int {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc parent(i: Int) -> Int {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.js
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#left(i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#right(i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n#parent(i) {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.ts
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nleft(i: number): number {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nright(i: number): number {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nparent(i: number): number {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.dart
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _left(int i) {\n  return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _right(int i) {\n  return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint _parent(int i) {\n  return (i - 1) ~/ 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn left(i: usize) -> usize {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn right(i: usize) -> usize {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfn parent(i: usize) -> usize {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.c
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(MaxHeap *maxHeap, int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(MaxHeap *maxHeap, int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(MaxHeap *maxHeap, int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u53d6\u6574\n}\n
    my_heap.kt
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun left(i: Int): Int {\n    return 2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun right(i: Int): Int {\n    return 2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfun parent(i: Int): Int {\n    return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rb
    ### \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef left(i)\n  2 * i + 1\nend\n\n### \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef right(i)\n  2 * i + 2\nend\n\n### \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef parent(i)\n  (i - 1) / 2     # \u5411\u4e0b\u6574\u9664\nend\n
    my_heap.zig
    // \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn left(i: usize) usize {\n    return 2 * i + 1;\n}\n\n// \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn right(i: usize) usize {\n    return 2 * i + 2;\n}\n\n// \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\nfn parent(i: usize) usize {\n    // return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n    return @divFloor(i - 1, 2);\n}\n
    "},{"location":"chapter_heap/heap/#2-accessing-the-top-element-of-the-heap","title":"2. \u00a0 Accessing the top element of the heap","text":"

    The top element of the heap is the root node of the binary tree, which is also the first element of the list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def peek(self) -> int:\n    \"\"\"\u8bbf\u95ee\u5806\u9876\u5143\u7d20\"\"\"\n    return self.max_heap[0]\n
    my_heap.cpp
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap[0];\n}\n
    my_heap.java
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap.get(0);\n}\n
    my_heap.cs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint Peek() {\n    return maxHeap[0];\n}\n
    my_heap.go
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc (h *maxHeap) peek() any {\n    return h.data[0]\n}\n
    my_heap.swift
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc peek() -> Int {\n    maxHeap[0]\n}\n
    my_heap.js
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek() {\n    return this.#maxHeap[0];\n}\n
    my_heap.ts
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek(): number {\n    return this.maxHeap[0];\n}\n
    my_heap.dart
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n  return _maxHeap[0];\n}\n
    my_heap.rs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfn peek(&self) -> Option<i32> {\n    self.max_heap.first().copied()\n}\n
    my_heap.c
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek(MaxHeap *maxHeap) {\n    return maxHeap->data[0];\n}\n
    my_heap.kt
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfun peek(): Int {\n    return maxHeap[0]\n}\n
    my_heap.rb
    ### \u8bbf\u95ee\u5806\u9876\u5143\u7d20 ###\ndef peek\n  @max_heap[0]\nend\n
    my_heap.zig
    // \u8bbf\u95ee\u5806\u9876\u5143\u7d20\nfn peek(self: *Self) T {\n    return self.max_heap.?.items[0];\n}  \n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/heap/#3-inserting-an-element-into-the-heap","title":"3. \u00a0 Inserting an element into the heap","text":"

    Given an element val, we first add it to the bottom of the heap. After addition, since val may be larger than other elements in the heap, the heap's integrity might be compromised, thus it's necessary to repair the path from the inserted node to the root node. This operation is called \"heapifying\".

    Considering starting from the node inserted, perform heapify from bottom to top. As shown in the Figure 8-3 , we compare the value of the inserted node with its parent node, and if the inserted node is larger, we swap them. Then continue this operation, repairing each node in the heap from bottom to top until passing the root node or encountering a node that does not need to be swapped.

    <1><2><3><4><5><6><7><8><9>

    Figure 8-3 \u00a0 Steps of element insertion into the heap

    Given a total of \\(n\\) nodes, the height of the tree is \\(O(\\log n)\\). Hence, the loop iterations for the heapify operation are at most \\(O(\\log n)\\), making the time complexity of the element insertion operation \\(O(\\log n)\\). The code is as shown:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def push(self, val: int):\n    \"\"\"\u5143\u7d20\u5165\u5806\"\"\"\n    # \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.append(val)\n    # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1)\n\ndef sift_up(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\"\"\"\n    while True:\n        # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p = self.parent(i)\n        # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 or self.max_heap[i] <= self.max_heap[p]:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p)\n        # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n
    my_heap.cpp
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.push_back(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap[i], maxHeap[p]);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap.get(i) <= maxHeap.get(p))\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u5165\u5806 */\nvoid Push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.Add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    SiftUp(Size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid SiftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = Parent(i);\n        // \u82e5\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u5165\u5806 */\nfunc (h *maxHeap) push(val any) {\n    // \u6dfb\u52a0\u8282\u70b9\n    h.data = append(h.data, val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    h.siftUp(len(h.data) - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc (h *maxHeap) siftUp(i int) {\n    for true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p := h.parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || h.data[i].(int) <= h.data[p].(int) {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u5165\u5806 */\nfunc push(val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.append(val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(i: size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc siftUp(i: Int) {\n    var i = i\n    while true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = parent(i: i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || maxHeap[i] <= maxHeap[p] {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u5165\u5806 */\npush(val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.#maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.#siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n#siftUp(i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.#parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.#maxHeap[i] <= this.#maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u5165\u5806 */\npush(val: number): void {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nsiftUp(i: number): void {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n  // \u6dfb\u52a0\u8282\u70b9\n  _maxHeap.add(val);\n  // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n  while (true) {\n    // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    int p = _parent(i);\n    // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    if (p < 0 || _maxHeap[i] <= _maxHeap[p]) {\n      break;\n    }\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, p);\n    // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u5165\u5806 */\nfn push(&mut self, val: i32) {\n    // \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfn sift_up(&mut self, mut i: usize) {\n    loop {\n        // \u8282\u70b9 i \u5df2\u7ecf\u662f\u5806\u9876\u8282\u70b9\u4e86\uff0c\u7ed3\u675f\u5806\u5316\n        if i == 0 {\n            break;\n        }\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = Self::parent(i);\n        // \u5f53\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if self.max_heap[i] <= self.max_heap[p] {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(MaxHeap *maxHeap, int val) {\n    // \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u4e0d\u5e94\u8be5\u6dfb\u52a0\u8fd9\u4e48\u591a\u8282\u70b9\n    if (maxHeap->size == MAX_SIZE) {\n        printf(\"heap is full!\");\n        return;\n    }\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap->data[maxHeap->size] = val;\n    maxHeap->size++;\n\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(maxHeap, maxHeap->size - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(maxHeap, i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap->data[i] <= maxHeap->data[p]) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u5165\u5806 */\nfun push(_val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(_val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfun siftUp(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        val p = parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u5165\u5806 ###\ndef push(val)\n  # \u6dfb\u52a0\u8282\u70b9\n  @max_heap << val\n  # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  sift_up(size - 1)\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 ###\ndef sift_up(i)\n  loop do\n    # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    p = parent(i)\n    # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    break if p < 0 || @max_heap[i] <= @max_heap[p]\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, p)\n    # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u5165\u5806\nfn push(self: *Self, val: T) !void {\n    // \u6dfb\u52a0\u8282\u70b9\n    try self.max_heap.?.append(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    try self.siftUp(self.size() - 1);\n}  \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\nfn siftUp(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        var p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 or self.max_heap.?.items[i] <= self.max_heap.?.items[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/heap/#4-removing-the-top-element-from-the-heap","title":"4. \u00a0 Removing the top element from the heap","text":"

    The top element of the heap is the root node of the binary tree, that is, the first element of the list. If we directly remove the first element from the list, all node indexes in the binary tree would change, making it difficult to use heapify for repairs subsequently. To minimize changes in element indexes, we use the following steps.

    1. Swap the top element with the bottom element of the heap (swap the root node with the rightmost leaf node).
    2. After swapping, remove the bottom of the heap from the list (note, since it has been swapped, what is actually being removed is the original top element).
    3. Starting from the root node, perform heapify from top to bottom.

    As shown in the Figure 8-4 , the direction of \"heapify from top to bottom\" is opposite to \"heapify from bottom to top\". We compare the value of the root node with its two children and swap it with the largest child. Then repeat this operation until passing the leaf node or encountering a node that does not need to be swapped.

    <1><2><3><4><5><6><7><8><9><10>

    Figure 8-4 \u00a0 Steps of removing the top element from the heap

    Similar to the element insertion operation, the time complexity of the top element removal operation is also \\(O(\\log n)\\). The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def pop(self) -> int:\n    \"\"\"\u5143\u7d20\u51fa\u5806\"\"\"\n    # \u5224\u7a7a\u5904\u7406\n    if self.is_empty():\n        raise IndexError(\"\u5806\u4e3a\u7a7a\")\n    # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1)\n    # \u5220\u9664\u8282\u70b9\n    val = self.max_heap.pop()\n    # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0)\n    # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n\ndef sift_down(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l, r, ma = self.left(i), self.right(i), i\n        if l < self.size() and self.max_heap[l] > self.max_heap[ma]:\n            ma = l\n        if r < self.size() and self.max_heap[r] > self.max_heap[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma)\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n
    my_heap.cpp
    /* \u5143\u7d20\u51fa\u5806 */\nvoid pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) {\n        throw out_of_range(\"\u5806\u4e3a\u7a7a\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap[0], maxHeap[size() - 1]);\n    // \u5220\u9664\u8282\u70b9\n    maxHeap.pop_back();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        swap(maxHeap[i], maxHeap[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty())\n        throw new IndexOutOfBoundsException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.remove(size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap.get(l) > maxHeap.get(ma))\n            ma = l;\n        if (r < size() && maxHeap.get(r) > maxHeap.get(ma))\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u51fa\u5806 */\nint Pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (IsEmpty())\n        throw new IndexOutOfRangeException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    Swap(0, Size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.Last();\n    maxHeap.RemoveAt(Size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    SiftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = Left(i), r = Right(i), ma = i;\n        if (l < Size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < Size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u201c\u8282\u70b9 i \u6700\u5927\u201d\u6216\u201c\u8d8a\u8fc7\u53f6\u8282\u70b9\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u51fa\u5806 */\nfunc (h *maxHeap) pop() any {\n    // \u5224\u7a7a\u5904\u7406\n    if h.isEmpty() {\n        fmt.Println(\"error\")\n        return nil\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    h.swap(0, h.size()-1)\n    // \u5220\u9664\u8282\u70b9\n    val := h.data[len(h.data)-1]\n    h.data = h.data[:len(h.data)-1]\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    h.siftDown(0)\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc (h *maxHeap) siftDown(i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        l, r, max := h.left(i), h.right(i), i\n        if l < h.size() && h.data[l].(int) > h.data[max].(int) {\n            max = l\n        }\n        if r < h.size() && h.data[r].(int) > h.data[max].(int) {\n            max = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if max == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, max)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u51fa\u5806 */\nfunc pop() -> Int {\n    // \u5224\u7a7a\u5904\u7406\n    if isEmpty() {\n        fatalError(\"\u5806\u4e3a\u7a7a\")\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(i: 0, j: size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    let val = maxHeap.remove(at: size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(i: 0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = left(i: i)\n        let r = right(i: i)\n        var ma = i\n        if l < size(), maxHeap[l] > maxHeap[ma] {\n            ma = l\n        }\n        if r < size(), maxHeap[r] > maxHeap[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u51fa\u5806 */\npop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new Error('\u5806\u4e3a\u7a7a');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.#swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.#maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.#siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n#siftDown(i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.#left(i),\n            r = this.#right(i);\n        let ma = i;\n        if (l < this.size() && this.#maxHeap[l] > this.#maxHeap[ma]) ma = l;\n        if (r < this.size() && this.#maxHeap[r] > this.#maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u51fa\u5806 */\npop(): number {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new RangeError('Heap is empty.');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nsiftDown(i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.left(i),\n            r = this.right(i);\n        let ma = i;\n        if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;\n        if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n  // \u5224\u7a7a\u5904\u7406\n  if (isEmpty()) throw Exception('\u5806\u4e3a\u7a7a');\n  // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  _swap(0, size() - 1);\n  // \u5220\u9664\u8282\u70b9\n  int val = _maxHeap.removeLast();\n  // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  siftDown(0);\n  // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = _left(i);\n    int r = _right(i);\n    int ma = i;\n    if (l < size() && _maxHeap[l] > _maxHeap[ma]) ma = l;\n    if (r < size() && _maxHeap[r] > _maxHeap[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, ma);\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u51fa\u5806 */\nfn pop(&mut self) -> i32 {\n    // \u5224\u7a7a\u5904\u7406\n    if self.is_empty() {\n        panic!(\"index out of bounds\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    let val = self.max_heap.pop().unwrap();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(&mut self, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let (l, r, mut ma) = (Self::left(i), Self::right(i), i);\n        if l < self.size() && self.max_heap[l] > self.max_heap[ma] {\n            ma = l;\n        }\n        if r < self.size() && self.max_heap[r] > self.max_heap[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u51fa\u5806 */\nint pop(MaxHeap *maxHeap) {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty(maxHeap)) {\n        printf(\"heap is empty!\");\n        return INT_MAX;\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap, 0, size(maxHeap) - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap->data[maxHeap->size - 1];\n    maxHeap->size--;\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(maxHeap, 0);\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        int l = left(maxHeap, i);\n        int r = right(maxHeap, i);\n        int max = i;\n        if (l < size(maxHeap) && maxHeap->data[l] > maxHeap->data[max]) {\n            max = l;\n        }\n        if (r < size(maxHeap) && maxHeap->data[r] > maxHeap->data[max]) {\n            max = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (max == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, max);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u51fa\u5806 */\nfun pop(): Int {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) throw IndexOutOfBoundsException()\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    val _val = maxHeap.removeAt(size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return _val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = left(i)\n        val r = right(i)\n        var ma = i\n        if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n        if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u51fa\u5806 ###\ndef pop\n  # \u5224\u7a7a\u5904\u7406\n  raise IndexError, \"\u5806\u4e3a\u7a7a\" if is_empty?\n  # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  swap(0, size - 1)\n  # \u5220\u9664\u8282\u70b9\n  val = @max_heap.pop\n  # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  sift_down(0)\n  # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  val\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 ###\ndef sift_down(i)\n  loop do\n    # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    l, r, ma = left(i), right(i), i\n    ma = l if l < size && @max_heap[l] > @max_heap[ma]\n    ma = r if r < size && @max_heap[r] > @max_heap[ma]\n\n    # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    break if ma == i\n\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, ma)\n    # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u51fa\u5806\nfn pop(self: *Self) !T {\n    // \u5224\u65ad\u5904\u7406\n    if (self.isEmpty()) unreachable;\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    try self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    var val = self.max_heap.?.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    try self.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n} \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\nfn siftDown(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        var l = left(i);\n        var r = right(i);\n        var ma = i;\n        if (l < self.size() and self.max_heap.?.items[l] > self.max_heap.?.items[ma]) ma = l;\n        if (r < self.size() and self.max_heap.?.items[r] > self.max_heap.?.items[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/heap/#813-common-applications-of-heaps","title":"8.1.3 \u00a0 Common applications of heaps","text":"
    • Priority Queue: Heaps are often the preferred data structure for implementing priority queues, with both enqueue and dequeue operations having a time complexity of \\(O(\\log n)\\), and building a queue having a time complexity of \\(O(n)\\), all of which are very efficient.
    • Heap Sort: Given a set of data, we can create a heap from them and then continually perform element removal operations to obtain ordered data. However, we usually use a more elegant method to implement heap sort, as detailed in the \"Heap Sort\" section.
    • Finding the Largest \\(k\\) Elements: This is a classic algorithm problem and also a typical application, such as selecting the top 10 hot news for Weibo hot search, picking the top 10 selling products, etc.
    "},{"location":"chapter_heap/summary/","title":"8.4 \u00a0 Summary","text":""},{"location":"chapter_heap/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • A heap is a complete binary tree, which can be divided into a max heap and a min heap based on its property. The top element of a max (min) heap is the largest (smallest).
    • A priority queue is defined as a queue with dequeue priority, usually implemented using a heap.
    • Common operations of a heap and their corresponding time complexities include: element insertion into the heap \\(O(\\log n)\\), removing the top element from the heap \\(O(\\log n)\\), and accessing the top element of the heap \\(O(1)\\).
    • A complete binary tree is well-suited to be represented by an array, thus heaps are commonly stored using arrays.
    • Heapify operations are used to maintain the properties of the heap and are used in both heap insertion and removal operations.
    • The time complexity of inserting \\(n\\) elements into a heap and building the heap can be optimized to \\(O(n)\\), which is highly efficient.
    • Top-k is a classic algorithm problem that can be efficiently solved using the heap data structure, with a time complexity of \\(O(n \\log k)\\).
    "},{"location":"chapter_heap/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is the \"heap\" in data structures the same concept as the \"heap\" in memory management?

    The two are not the same concept, even though they are both referred to as \"heap\". The heap in computer system memory is part of dynamic memory allocation, where the program can use it to store data during execution. The program can request a certain amount of heap memory to store complex structures like objects and arrays. When these data are no longer needed, the program needs to release this memory to prevent memory leaks. Compared to stack memory, the management and usage of heap memory need to be more cautious, as improper use may lead to memory leaks and dangling pointers.

    "},{"location":"chapter_heap/top_k/","title":"8.3 \u00a0 Top-k problem","text":"

    Question

    Given an unordered array nums of length \\(n\\), return the largest \\(k\\) elements in the array.

    For this problem, we will first introduce two straightforward solutions, then explain a more efficient heap-based method.

    "},{"location":"chapter_heap/top_k/#831-method-1-iterative-selection","title":"8.3.1 \u00a0 Method 1: Iterative selection","text":"

    We can perform \\(k\\) rounds of iterations as shown in the Figure 8-6 , extracting the \\(1^{st}\\), \\(2^{nd}\\), \\(\\dots\\), \\(k^{th}\\) largest elements in each round, with a time complexity of \\(O(nk)\\).

    This method is only suitable when \\(k \\ll n\\), as the time complexity approaches \\(O(n^2)\\) when \\(k\\) is close to \\(n\\), which is very time-consuming.

    Figure 8-6 \u00a0 Iteratively finding the largest k elements

    Tip

    When \\(k = n\\), we can obtain a complete ordered sequence, which is equivalent to the \"selection sort\" algorithm.

    "},{"location":"chapter_heap/top_k/#832-method-2-sorting","title":"8.3.2 \u00a0 Method 2: Sorting","text":"

    As shown in the Figure 8-7 , we can first sort the array nums and then return the last \\(k\\) elements, with a time complexity of \\(O(n \\log n)\\).

    Clearly, this method \"overachieves\" the task, as we only need to find the largest \\(k\\) elements, without the need to sort the other elements.

    Figure 8-7 \u00a0 Sorting to find the largest k elements

    "},{"location":"chapter_heap/top_k/#833-method-3-heap","title":"8.3.3 \u00a0 Method 3: Heap","text":"

    We can solve the Top-k problem more efficiently based on heaps, as shown in the following process.

    1. Initialize a min heap, where the top element is the smallest.
    2. First, insert the first \\(k\\) elements of the array into the heap.
    3. Starting from the \\(k + 1^{th}\\) element, if the current element is greater than the top element of the heap, remove the top element of the heap and insert the current element into the heap.
    4. After completing the traversal, the heap contains the largest \\(k\\) elements.
    <1><2><3><4><5><6><7><8><9>

    Figure 8-8 \u00a0 Find the largest k elements based on heap

    Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig top_k.py
    def top_k_heap(nums: list[int], k: int) -> list[int]:\n    \"\"\"\u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\"\"\"\n    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    heap = []\n    # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i in range(k):\n        heapq.heappush(heap, nums[i])\n    # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in range(k, len(nums)):\n        # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap[0]:\n            heapq.heappop(heap)\n            heapq.heappush(heap, nums[i])\n    return heap\n
    top_k.cpp
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\npriority_queue<int, vector<int>, greater<int>> topKHeap(vector<int> &nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    priority_queue<int, vector<int>, greater<int>> heap;\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.push(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.size(); i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.top()) {\n            heap.pop();\n            heap.push(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.java
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nQueue<Integer> topKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    Queue<Integer> heap = new PriorityQueue<Integer>();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.offer(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll();\n            heap.offer(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.cs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nPriorityQueue<int, int> TopKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    PriorityQueue<int, int> heap = new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.Enqueue(nums[i], nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.Length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.Peek()) {\n            heap.Dequeue();\n            heap.Enqueue(nums[i], nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.go
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums []int, k int) *minHeap {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    h := &minHeap{}\n    heap.Init(h)\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i := 0; i < k; i++ {\n        heap.Push(h, nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i := k; i < len(nums); i++ {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > h.Top().(int) {\n            heap.Pop(h)\n            heap.Push(h, nums[i])\n        }\n    }\n    return h\n}\n
    top_k.swift
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums: [Int], k: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5c0f\u9876\u5806\uff0c\u5e76\u5c06\u524d k \u4e2a\u5143\u7d20\u5efa\u5806\n    var heap = Heap(nums.prefix(k))\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in nums.indices.dropFirst(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap.min()! {\n            _ = heap.removeMin()\n            heap.insert(nums[i])\n        }\n    }\n    return heap.unordered\n}\n
    top_k.js
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap, val) {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums, k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.ts
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap: MaxHeap, val: number): void {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap: MaxHeap): number[] {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num: number) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums: number[], k: number): number[] {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.dart
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nMinHeap topKHeap(List<int> nums, int k) {\n  // \u521d\u59cb\u5316\u5c0f\u9876\u5806\uff0c\u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  MinHeap heap = MinHeap(nums.sublist(0, k));\n  // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for (int i = k; i < nums.length; i++) {\n    // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if (nums[i] > heap.peek()) {\n      heap.pop();\n      heap.push(nums[i]);\n    }\n  }\n  return heap;\n}\n
    top_k.rs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfn top_k_heap(nums: Vec<i32>, k: usize) -> BinaryHeap<Reverse<i32>> {\n    // BinaryHeap \u662f\u5927\u9876\u5806\uff0c\u4f7f\u7528 Reverse \u5c06\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u5b9e\u73b0\u5c0f\u9876\u5806\n    let mut heap = BinaryHeap::<Reverse<i32>>::new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for &num in nums.iter().take(k) {\n        heap.push(Reverse(num));\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for &num in nums.iter().skip(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if num > heap.peek().unwrap().0 {\n            heap.pop();\n            heap.push(Reverse(num));\n        }\n    }\n    heap\n}\n
    top_k.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid pushMinHeap(MaxHeap *maxHeap, int val) {\n    // \u5143\u7d20\u53d6\u53cd\n    push(maxHeap, -val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nint popMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -pop(maxHeap);\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peekMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -peek(maxHeap);\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n// \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\u7684\u51fd\u6570\nint *topKHeap(int *nums, int sizeNums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    int *empty = (int *)malloc(0);\n    MaxHeap *maxHeap = newMaxHeap(empty, 0);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < sizeNums; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    int *res = getMinHeap(maxHeap);\n    // \u91ca\u653e\u5185\u5b58\n    delMaxHeap(maxHeap);\n    return res;\n}\n
    top_k.kt
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfun topKHeap(nums: IntArray, k: Int): Queue<Int> {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    val heap = PriorityQueue<Int>()\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (i in 0..<k) {\n        heap.offer(nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (i in k..<nums.size) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll()\n            heap.offer(nums[i])\n        }\n    }\n    return heap\n}\n
    top_k.rb
    ### \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 ###\ndef top_k_heap(nums, k)\n  # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n  # \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n  max_heap = MaxHeap.new([])\n\n  # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  for i in 0...k\n    push_min_heap(max_heap, nums[i])\n  end\n\n  # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for i in k...nums.length\n    # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if nums[i] > peek_min_heap(max_heap)\n      pop_min_heap(max_heap)\n      push_min_heap(max_heap, nums[i])\n    end\n  end\n\n  get_min_heap(max_heap)\nend\n
    top_k.zig
    [class]{}-[func]{topKHeap}\n
    Code Visualization

    Full Screen >

    A total of \\(n\\) rounds of heap insertions and deletions are performed, with the maximum heap size being \\(k\\), hence the time complexity is \\(O(n \\log k)\\). This method is very efficient; when \\(k\\) is small, the time complexity tends towards \\(O(n)\\); when \\(k\\) is large, the time complexity will not exceed \\(O(n \\log n)\\).

    Additionally, this method is suitable for scenarios with dynamic data streams. By continuously adding data, we can maintain the elements within the heap, thereby achieving dynamic updates of the largest \\(k\\) elements.

    "},{"location":"chapter_hello_algo/","title":"Before starting","text":"

    A few years ago, I shared the \"Sword for Offer\" problem solutions on LeetCode, receiving encouragement and support from many readers. During interactions with readers, the most common question I encountered was \"how to get started with algorithms.\" Gradually, I developed a keen interest in this question.

    Directly solving problems seems to be the most popular method \u2014 it's simple, direct, and effective. However, problem-solving is like playing a game of Minesweeper: those with strong self-study abilities can defuse the mines one by one, but those with insufficient basics might end up metaphorically bruised from explosions, retreating step by step in frustration. Going through textbooks is also common, but for those aiming for job applications, the energy spent on thesis writing, resume submissions, and preparation for written tests and interviews leaves little for tackling thick books, turning it into a daunting challenge.

    If you're facing similar troubles, then this book are lucky to have found you. This book is my answer to the question. While it may not be the best solution, it is at least a positive attempt. This book may not directly land you an offer, but it will guide you through the \"knowledge map\" in data structures and algorithms, help you understand the shapes, sizes, and locations of different \"mines,\" and enable you to master various \"demining methods.\" With these skills, I believe you can solve problems and read literature more comfortably, gradually building a knowledge system.

    I deeply agree with Professor Feynman's statement: \"Knowledge isn't free. You have to pay attention.\" In this sense, this book is not entirely \"free.\" To not disappoint the precious \"attention\" you pay for this book, I will do my best, dedicating my utmost \"attention\" to this book.

    Knowing my limitations, although the content of this book has been refined over time, there are surely many errors remaining. I sincerely request critiques and corrections from all teachers and students.

    Hello, Algo!

    The advent of computers has brought significant changes to the world. With their high-speed computing power and excellent programmability, they have become the ideal medium for executing algorithms and processing data. Whether it's the realistic graphics of video games, the intelligent decisions in autonomous driving, the brilliant Go games of AlphaGo, or the natural interactions of ChatGPT, these applications are all exquisite demonstrations of algorithms at work on computers.

    In fact, before the advent of computers, algorithms and data structures already existed in every corner of the world. Early algorithms were relatively simple, such as ancient counting methods and tool-making procedures. As civilization progressed, algorithms became more refined and complex. From the exquisite craftsmanship of artisans, to industrial products that liberate productive forces, to the scientific laws governing the universe, almost every ordinary or astonishing thing has behind it the ingenious thought of algorithms.

    Similarly, data structures are everywhere: from social networks to subway lines, many systems can be modeled as \"graphs\"; from a country to a family, the main forms of social organization exhibit characteristics of \"trees\"; winter clothes are like a \"stack\", where the first item worn is the last to be taken off; a badminton shuttle tube resembles a \"queue\", with one end for insertion and the other for retrieval; a dictionary is like a \"hash table\", enabling quick search for target entries.

    This book aims to help readers understand the core concepts of algorithms and data structures through clear, easy-to-understand animated illustrations and runnable code examples, and to be able to implement them through programming. On this basis, this book strives to reveal the vivid manifestations of algorithms in the complex world, showcasing the beauty of algorithms. I hope this book can help you!

    "},{"location":"chapter_introduction/","title":"Chapter 1. \u00a0 Encounter with algorithms","text":"

    Abstract

    A graceful maiden dances, intertwined with the data, her skirt swaying to the melody of algorithms.

    She invites you to a dance, follow her steps, and enter the world of algorithms full of logic and beauty.

    "},{"location":"chapter_introduction/#chapter-contents","title":"Chapter contents","text":"
    • 1.1 \u00a0 Algorithms are everywhere
    • 1.2 \u00a0 What is an algorithm
    • 1.3 \u00a0 Summary
    "},{"location":"chapter_introduction/algorithms_are_everywhere/","title":"1.1 \u00a0 Algorithms are everywhere","text":"

    When we hear the word \"algorithm,\" we naturally think of mathematics. However, many algorithms do not involve complex mathematics but rely more on basic logic, which can be seen everywhere in our daily lives.

    Before formally discussing algorithms, there's an interesting fact worth sharing: you have already unconsciously learned many algorithms and have become accustomed to applying them in your daily life. Here, I will give a few specific examples to prove this point.

    Example 1: Looking Up a Dictionary. In an English dictionary, words are listed alphabetically. Suppose we're searching for a word that starts with the letter \\(r\\). This is typically done in the following way:

    1. Open the dictionary to about halfway and check the first letter on the page, let's say the letter is \\(m\\).
    2. Since \\(r\\) comes after \\(m\\) in the alphabet, we can ignore the first half of the dictionary and focus on the latter half.
    3. Repeat steps 1. and 2. until you find the page where the word starts with \\(r\\).
    <1><2><3><4><5>

    Figure 1-1 \u00a0 Process of Looking Up a Dictionary

    This essential skill for elementary students, looking up a dictionary, is actually the famous \"Binary Search\" algorithm. From a data structure perspective, we can consider the dictionary as a sorted \"array\"; from an algorithmic perspective, the series of actions taken to look up a word in the dictionary can be viewed as \"Binary Search.\"

    Example 2: Organizing Playing Cards. When playing cards, we need to arrange the cards in our hand in ascending order, as shown in the following process.

    1. Divide the playing cards into \"ordered\" and \"unordered\" sections, assuming initially the leftmost card is already in order.
    2. Take out a card from the unordered section and insert it into the correct position in the ordered section; after this, the leftmost two cards are in order.
    3. Continue to repeat step 2. until all cards are in order.

    Figure 1-2 \u00a0 Playing cards sorting process

    The above method of organizing playing cards is essentially the \"Insertion Sort\" algorithm, which is very efficient for small datasets. Many programming languages' sorting functions include the insertion sort.

    Example 3: Making Change. Suppose we buy goods worth \\(69\\) yuan at a supermarket and give the cashier \\(100\\) yuan, then the cashier needs to give us \\(31\\) yuan in change. They would naturally complete the thought process as shown below.

    1. The options are currencies smaller than \\(31\\), including \\(1\\), \\(5\\), \\(10\\), and \\(20\\).
    2. Take out the largest \\(20\\) from the options, leaving \\(31 - 20 = 11\\).
    3. Take out the largest \\(10\\) from the remaining options, leaving \\(11 - 10 = 1\\).
    4. Take out the largest \\(1\\) from the remaining options, leaving \\(1 - 1 = 0\\).
    5. Complete the change-making, with the solution being \\(20 + 10 + 1 = 31\\).

    Figure 1-3 \u00a0 Change making process

    In the above steps, we make the best choice at each step (using the largest denomination possible), ultimately resulting in a feasible change-making plan. From the perspective of data structures and algorithms, this method is essentially a \"Greedy\" algorithm.

    From cooking a meal to interstellar travel, almost all problem-solving involves algorithms. The advent of computers allows us to store data structures in memory and write code to call the CPU and GPU to execute algorithms. In this way, we can transfer real-life problems to computers, solving various complex issues more efficiently.

    Tip

    If concepts such as data structures, algorithms, arrays, and binary search still seem somewhat obsecure, I encourage you to continue reading. This book will gently guide you into the realm of understanding data structures and algorithms.

    "},{"location":"chapter_introduction/summary/","title":"1.3 \u00a0 Summary","text":"
    • Algorithms are ubiquitous in daily life and are not as inaccessible and complex as they might seem. In fact, we have already unconsciously learned many algorithms to solve various problems in life.
    • The principle of looking up a word in a dictionary is consistent with the binary search algorithm. The binary search algorithm embodies the important algorithmic concept of divide and conquer.
    • The process of organizing playing cards is very similar to the insertion sort algorithm. The insertion sort algorithm is suitable for sorting small datasets.
    • The steps of making change in currency essentially follow the greedy algorithm, where each step involves making the best possible choice at the moment.
    • An algorithm is a set of instructions or steps used to solve a specific problem within a finite amount of time, while a data structure is the way data is organized and stored in a computer.
    • Data structures and algorithms are closely linked. Data structures are the foundation of algorithms, and algorithms are the stage to utilize the functions of data structures.
    • We can liken data structures and algorithms to building blocks. The blocks represent data, the shape and connection method of the blocks represent data structures, and the steps of assembling the blocks correspond to algorithms.
    "},{"location":"chapter_introduction/what_is_dsa/","title":"1.2 \u00a0 What is an algorithm","text":""},{"location":"chapter_introduction/what_is_dsa/#121-definition-of-an-algorithm","title":"1.2.1 \u00a0 Definition of an algorithm","text":"

    An \"algorithm\" is a set of instructions or steps to solve a specific problem within a finite amount of time. It has the following characteristics:

    • The problem is clearly defined, including unambiguous definitions of input and output.
    • The algorithm is feasible, meaning it can be completed within a finite number of steps, time, and memory space.
    • Each step has a definitive meaning. The output is consistently the same under the same inputs and conditions.
    "},{"location":"chapter_introduction/what_is_dsa/#122-definition-of-a-data-structure","title":"1.2.2 \u00a0 Definition of a data structure","text":"

    A \"data structure\" is a way of organizing and storing data in a computer, with the following design goals:

    • Minimize space occupancy to save computer memory.
    • Make data operations as fast as possible, covering data access, addition, deletion, updating, etc.
    • Provide concise data representation and logical information to enable efficient algorithm execution.

    Designing data structures is a balancing act, often requiring trade-offs. If you want to improve in one aspect, you often need to compromise in another. Here are two examples:

    • Compared to arrays, linked lists offer more convenience in data addition and deletion but sacrifice data access speed.
    • Graphs, compared to linked lists, provide richer logical information but require more memory space.
    "},{"location":"chapter_introduction/what_is_dsa/#123-relationship-between-data-structures-and-algorithms","title":"1.2.3 \u00a0 Relationship between data structures and algorithms","text":"

    As shown in the Figure 1-4 , data structures and algorithms are highly related and closely integrated, specifically in the following three aspects:

    • Data structures are the foundation of algorithms. They provide structured data storage and methods for manipulating data for algorithms.
    • Algorithms are the stage where data structures come into play. The data structure alone only stores data information; it is through the application of algorithms that specific problems can be solved.
    • Algorithms can often be implemented based on different data structures, but their execution efficiency can vary greatly. Choosing the right data structure is key.

    Figure 1-4 \u00a0 Relationship between data structures and algorithms

    Data structures and algorithms can be likened to a set of building blocks, as illustrated in the Figure 1-5 . A building block set includes numerous pieces, accompanied by detailed assembly instructions. Following these instructions step by step allows us to construct an intricate block model.

    Figure 1-5 \u00a0 Assembling blocks

    The detailed correspondence between the two is shown in the Table 1-1 .

    Table 1-1 \u00a0 Comparing data structures and algorithms to building blocks

    Data Structures and Algorithms Building Blocks Input data Unassembled blocks Data structure Organization of blocks, including shape, size, connections, etc Algorithm A series of steps to assemble the blocks into the desired shape Output data Completed Block model

    It's worth noting that data structures and algorithms are independent of programming languages. For this reason, this book is able to provide implementations in multiple programming languages.

    Conventional Abbreviation

    In real-life discussions, we often refer to \"Data Structures and Algorithms\" simply as \"Algorithms\". For example, the well-known LeetCode algorithm problems actually test both data structure and algorithm knowledge.

    "},{"location":"chapter_preface/","title":"Chapter 0. \u00a0 Preface","text":"

    Abstract

    Algorithms are like a beautiful symphony, with each line of code flowing like a rhythm.

    May this book ring softly in your mind, leaving a unique and profound melody.

    "},{"location":"chapter_preface/#chapter-contents","title":"Chapter contents","text":"
    • 0.1 \u00a0 About this book
    • 0.2 \u00a0 How to read
    • 0.3 \u00a0 Summary
    "},{"location":"chapter_preface/about_the_book/","title":"0.1 \u00a0 About this book","text":"

    This open-source project aims to create a free, and beginner-friendly crash course on data structures and algorithms.

    • Using animated illustrations, it delivers structured insights into data structures and algorithmic concepts, ensuring comprehensibility and a smooth learning curve.
    • Run code with just one click, supporting Java, C++, Python, Go, JS, TS, C#, Swift, Rust, Dart, Zig and other languages.
    • Readers are encouraged to engage with each other in the discussion area for each section, questions and comments are usually answered within two days.
    "},{"location":"chapter_preface/about_the_book/#011-target-audience","title":"0.1.1 \u00a0 Target audience","text":"

    If you are new to algorithms with limited exposure, or you have accumulated some experience in algorithms, but you only have a vague understanding of data structures and algorithms, and you are constantly jumping between \"yep\" and \"hmm\", then this book is for you!

    If you have already accumulated a certain amount of problem-solving experience, and are familiar with most types of problems, then this book can help you review and organize your algorithm knowledge system. The repository's source code can be used as a \"problem-solving toolkit\" or an \"algorithm cheat sheet\".

    If you are an algorithm expert, we look forward to receiving your valuable suggestions, or join us and collaborate.

    Prerequisites

    You should know how to write and read simple code in at least one programming language.

    "},{"location":"chapter_preface/about_the_book/#012-content-structure","title":"0.1.2 \u00a0 Content structure","text":"

    The main content of the book is shown in the following figure.

    • Complexity analysis: explores aspects and methods for evaluating data structures and algorithms. Covers methods of deriving time complexity and space complexity, along with common types and examples.
    • Data structures: focuses on fundamental data types, classification methods, definitions, pros and cons, common operations, types, applications, and implementation methods of data structures such as array, linked list, stack, queue, hash table, tree, heap, graph, etc.
    • Algorithms: defines algorithms, discusses their pros and cons, efficiency, application scenarios, problem-solving steps, and includes sample questions for various algorithms such as search, sorting, divide and conquer, backtracking, dynamic programming, greedy algorithms, and more.

    Figure 0-1 \u00a0 Main content of the book

    "},{"location":"chapter_preface/about_the_book/#013-acknowledgements","title":"0.1.3 \u00a0 Acknowledgements","text":"

    This book is continuously improved with the joint efforts of many contributors from the open-source community. Thanks to each writer who invested their time and energy, listed in the order generated by GitHub: krahets, codingonion, nuomi1, Gonglja, Reanon, justin-tse, danielsss, hpstory, S-N-O-R-L-A-X, night-cruise, msk397, gvenusleo, RiverTwilight, gyt95, zhuoqinyue, Zuoxun, Xia-Sang, mingXta, FangYuan33, GN-Yu, IsChristina, xBLACKICEx, guowei-gong, Cathay-Chen, mgisr, JoseHung, qualifier1024, pengchzn, Guanngxu, longsizhuo, L-Super, what-is-me, yuan0221, lhxsm, Slone123c, WSL0809, longranger2, theNefelibatas, xiongsp, JeffersonHuang, hongyun-robot, K3v123, yuelinxin, a16su, gaofer, malone6, Wonderdch, xjr7670, DullSword, Horbin-Magician, NI-SW, reeswell, XC-Zero, XiaChuerwu, yd-j, iron-irax, huawuque404, MolDuM, Nigh, KorsChen, foursevenlove, 52coder, bubble9um, youshaoXG, curly210102, gltianwen, fanchenggang, Transmigration-zhou, FloranceYeh, FreddieLi, ShiMaRing, lipusheng, Javesun99, JackYang-hellobobo, shanghai-Jerry, 0130w, Keynman, psychelzh, logan-qiu, ZnYang2018, MwumLi, 1ch0, Phoenix0415, qingpeng9802, Richard-Zhang1019, QiLOL, Suremotoo, Turing-1024-Lee, Evilrabbit520, GaochaoZhu, ZJKung, linzeyan, hezhizhen, ZongYangL, beintentional, czruby, coderlef, dshlstarr, szu17dmy, fbigm, gledfish, hts0000, boloboloda, iStig, jiaxianhua, wenjianmin, keshida, kilikilikid, lclc6, lwbaptx, liuxjerry, lucaswangdev, lyl625760, chadyi, noobcodemaker, selear, siqyka, syd168, 4yDX3906, tao363, wangwang105, weibk, yabo083, yi427, yishangzhang, zhouLion, baagod, ElaBosak233, xb534, luluxia, yanedie, thomasq0, YangXuanyi and th1nk3r-ing.

    The code review work for this book was completed by codingonion, Gonglja, gvenusleo, hpstory, justin\u2010tse, krahets, night-cruise, nuomi1, and Reanon (listed in alphabetical order). Thanks to them for their time and effort, ensuring the standardization and uniformity of the code in various languages.

    Throughout the creation of this book, numerous individuals provided invaluable assistance, including but not limited to:

    • Thanks to my mentor at the company, Dr. Xi Li, who encouraged me in a conversation to \"get moving fast,\" which solidified my determination to write this book;
    • Thanks to my girlfriend Bubble, as the first reader of this book, for offering many valuable suggestions from the perspective of a beginner in algorithms, making this book more suitable for newbies;
    • Thanks to Tengbao, Qibao, and Feibao for coming up with a creative name for this book, evoking everyone's fond memories of writing their first line of code \"Hello World!\";
    • Thanks to Xiaoquan for providing professional help in intellectual property, which has played a significant role in the development of this open-source book;
    • Thanks to Sutong for designing a beautiful cover and logo for this book, and for patiently making multiple revisions under my insistence;
    • Thanks to @squidfunk for providing writing and typesetting suggestions, as well as his developed open-source documentation theme Material-for-MkDocs.

    Throughout the writing journey, I delved into numerous textbooks and articles on data structures and algorithms. These works served as exemplary models, ensuring the accuracy and quality of this book's content. I extend my gratitude to all who preceded me for their invaluable contributions!

    This book advocates a combination of hands-on and minds-on learning, inspired in this regard by \"Dive into Deep Learning\". I highly recommend this excellent book to all readers.

    Heartfelt thanks to my parents, whose ongoing support and encouragement have allowed me to do this interesting work.

    "},{"location":"chapter_preface/suggestions/","title":"0.2 \u00a0 How to read","text":"

    Tip

    For the best reading experience, it is recommended that you read through this section.

    "},{"location":"chapter_preface/suggestions/#021-writing-conventions","title":"0.2.1 \u00a0 Writing conventions","text":"
    • Chapters marked with '*' after the title are optional and contain relatively challenging content. If you are short on time, it is advisable to skip them.
    • Technical terms will be in boldface (in the print and PDF versions) or underlined (in the web version), for instance, array. It's advisable to familiarize yourself with these for better comprehension of technical texts.
    • Bolded text indicates key content or summary statements, which deserve special attention.
    • Words and phrases with specific meanings are indicated with \u201cquotation marks\u201d to avoid ambiguity.
    • When it comes to terms that are inconsistent between programming languages, this book follows Python, for example using None to mean null.
    • This book partially ignores the comment conventions for programming languages in exchange for a more compact layout of the content. The comments primarily consist of three types: title comments, content comments, and multi-line comments.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    \"\"\"Header comments for labeling functions, classes, test samples, etc\"\"\"\n\n# Comments for explaining details\n\n\"\"\"\nMultiline\ncomments\n\"\"\"\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    // Header comments for labeling functions, classes, test samples, etc\n\n// Comments for explaining details.\n\n// Multiline\n// comments\n
    "},{"location":"chapter_preface/suggestions/#022-efficient-learning-via-animated-illustrations","title":"0.2.2 \u00a0 Efficient learning via animated illustrations","text":"

    Compared with text, videos and pictures have a higher density of information and are more structured, making them easier to understand. In this book, key and difficult concepts are mainly presented through animations and illustrations, with text serving as explanations and supplements.

    When encountering content with animations or illustrations as shown in the Figure 0-2 , prioritize understanding the figure, with text as supplementary, integrating both for a comprehensive understanding.

    Figure 0-2 \u00a0 Animated illustration example

    "},{"location":"chapter_preface/suggestions/#023-deepen-understanding-through-coding-practice","title":"0.2.3 \u00a0 Deepen understanding through coding practice","text":"

    The source code of this book is hosted on the GitHub Repository. As shown in the Figure 0-3 , the source code comes with test examples and can be executed with just a single click.

    If time permits, it's recommended to type out the code yourself. If pressed for time, at least read and run all the codes.

    Compared to just reading code, writing code often yields more learning. Learning by doing is the real way to learn.

    Figure 0-3 \u00a0 Running code example

    Setting up to run the code involves three main steps.

    Step 1: Install a local programming environment. Follow the tutorial in the appendix for installation, or skip this step if already installed.

    Step 2: Clone or download the code repository. Visit the GitHub Repository.

    If Git is installed, use the following command to clone the repository:

    git clone https://github.com/krahets/hello-algo.git\n

    Alternatively, you can also click the \"Download ZIP\" button at the location shown in the Figure 0-4 to directly download the code as a compressed ZIP file. Then, you can simply extract it locally.

    Figure 0-4 \u00a0 Cloning repository and downloading code

    Step 3: Run the source code. As shown in the Figure 0-5 , for the code block labeled with the file name at the top, we can find the corresponding source code file in the codes folder of the repository. These files can be executed with a single click, which will help you save unnecessary debugging time and allow you to focus on learning.

    Figure 0-5 \u00a0 Code block and corresponding source code file

    "},{"location":"chapter_preface/suggestions/#024-learning-together-in-discussion","title":"0.2.4 \u00a0 Learning together in discussion","text":"

    While reading this book, please don't skip over the points that you didn't learn. Feel free to post your questions in the comment section. We will be happy to answer them and can usually respond within two days.

    As illustrated in the Figure 0-6 , each chapter features a comment section at the bottom. I encourage you to pay attention to these comments. They not only expose you to others' encountered problems, aiding in identifying knowledge gaps and sparking deeper contemplation, but also invite you to generously contribute by answering fellow readers' inquiries, sharing insights, and fostering mutual improvement.

    Figure 0-6 \u00a0 Comment section example

    "},{"location":"chapter_preface/suggestions/#025-algorithm-learning-path","title":"0.2.5 \u00a0 Algorithm learning path","text":"

    Overall, the journey of mastering data structures and algorithms can be divided into three stages:

    1. Stage 1: Introduction to algorithms. We need to familiarize ourselves with the characteristics and usage of various data structures and learn about the principles, processes, uses, and efficiency of different algorithms.
    2. Stage 2: Practicing algorithm problems. It is recommended to start from popular problems, such as Sword for Offer and LeetCode Hot 100, and accumulate at least 100 questions to familiarize yourself with mainstream algorithmic problems. Forgetfulness can be a challenge when you start practicing, but rest assured that this is normal. We can follow the \"Ebbinghaus Forgetting Curve\" to review the questions, and usually after 3~5 rounds of repetitions, we will be able to memorize them.
    3. Stage 3: Building the knowledge system. In terms of learning, we can read algorithm column articles, solution frameworks, and algorithm textbooks to continuously enrich the knowledge system. In terms of practicing, we can try advanced strategies, such as categorizing by topic, multiple solutions for a single problem, and one solution for multiple problems, etc. Insights on these strategies can be found in various communities.

    As shown in the Figure 0-7 , this book mainly covers \u201cStage 1,\u201d aiming to help you more efficiently embark on Stages 2 and 3.

    Figure 0-7 \u00a0 Algorithm learning path

    "},{"location":"chapter_preface/summary/","title":"0.3 \u00a0 Summary","text":"
    • The main audience of this book is beginners in algorithm. If you already have some basic knowledge, this book can help you systematically review your algorithm knowledge, and the source code in this book can also be used as a \"Coding Toolkit\".
    • The book consists of three main sections, Complexity Analysis, Data Structures, and Algorithms, covering most of the topics in the field.
    • For newcomers to algorithms, it is crucial to read an introductory book in the beginning stages to avoid many detours or common pitfalls.
    • Animations and figures within the book are usually used to introduce key points and difficult knowledge. These should be given more attention when reading the book.
    • Practice is the best way to learn programming. It is highly recommended that you run the source code and type in the code yourself.
    • Each chapter in the web version of this book features a discussion section, and you are welcome to share your questions and insights at any time.
    "},{"location":"chapter_stack_and_queue/","title":"Chapter 5. \u00a0 Stack and queue","text":"

    Abstract

    A stack is like cats placed on top of each other, while a queue is like cats lined up one by one.

    They represent the logical relationships of Last-In-First-Out (LIFO) and First-In-First-Out (FIFO), respectively.

    "},{"location":"chapter_stack_and_queue/#chapter-contents","title":"Chapter contents","text":"
    • 5.1 \u00a0 Stack
    • 5.2 \u00a0 Queue
    • 5.3 \u00a0 Double-ended queue
    • 5.4 \u00a0 Summary
    "},{"location":"chapter_stack_and_queue/deque/","title":"5.3 \u00a0 Double-ended queue","text":"

    In a queue, we can only delete elements from the head or add elements to the tail. As shown in the following diagram, a \"double-ended queue (deque)\" offers more flexibility, allowing the addition or removal of elements at both the head and the tail.

    Figure 5-7 \u00a0 Operations in double-ended queue

    "},{"location":"chapter_stack_and_queue/deque/#531-common-operations-in-double-ended-queue","title":"5.3.1 \u00a0 Common operations in double-ended queue","text":"

    The common operations in a double-ended queue are listed below, and the names of specific methods depend on the programming language used.

    Table 5-3 \u00a0 Efficiency of double-ended queue operations

    Method Name Description Time Complexity pushFirst() Add an element to the head \\(O(1)\\) pushLast() Add an element to the tail \\(O(1)\\) popFirst() Remove the first element \\(O(1)\\) popLast() Remove the last element \\(O(1)\\) peekFirst() Access the first element \\(O(1)\\) peekLast() Access the last element \\(O(1)\\)

    Similarly, we can directly use the double-ended queue classes implemented in programming languages:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig deque.py
    from collections import deque\n\n# Initialize the deque\ndeq: deque[int] = deque()\n\n# Enqueue elements\ndeq.append(2)      # Add to the tail\ndeq.append(5)\ndeq.append(4)\ndeq.appendleft(3)  # Add to the head\ndeq.appendleft(1)\n\n# Access elements\nfront: int = deq[0]  # The first element\nrear: int = deq[-1]  # The last element\n\n# Dequeue elements\npop_front: int = deq.popleft()  # The first element dequeued\npop_rear: int = deq.pop()       # The last element dequeued\n\n# Get the length of the deque\nsize: int = len(deq)\n\n# Check if the deque is empty\nis_empty: bool = len(deq) == 0\n
    deque.cpp
    /* Initialize the deque */\ndeque<int> deque;\n\n/* Enqueue elements */\ndeque.push_back(2);   // Add to the tail\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3);  // Add to the head\ndeque.push_front(1);\n\n/* Access elements */\nint front = deque.front(); // The first element\nint back = deque.back();   // The last element\n\n/* Dequeue elements */\ndeque.pop_front();  // The first element dequeued\ndeque.pop_back();   // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.size();\n\n/* Check if the deque is empty */\nbool empty = deque.empty();\n
    deque.java
    /* Initialize the deque */\nDeque<Integer> deque = new LinkedList<>();\n\n/* Enqueue elements */\ndeque.offerLast(2);   // Add to the tail\ndeque.offerLast(5);\ndeque.offerLast(4);\ndeque.offerFirst(3);  // Add to the head\ndeque.offerFirst(1);\n\n/* Access elements */\nint peekFirst = deque.peekFirst();  // The first element\nint peekLast = deque.peekLast();    // The last element\n\n/* Dequeue elements */\nint popFirst = deque.pollFirst();  // The first element dequeued\nint popLast = deque.pollLast();    // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.size();\n\n/* Check if the deque is empty */\nboolean isEmpty = deque.isEmpty();\n
    deque.cs
    /* Initialize the deque */\n// In C#, LinkedList is used as a deque\nLinkedList<int> deque = new();\n\n/* Enqueue elements */\ndeque.AddLast(2);   // Add to the tail\ndeque.AddLast(5);\ndeque.AddLast(4);\ndeque.AddFirst(3);  // Add to the head\ndeque.AddFirst(1);\n\n/* Access elements */\nint peekFirst = deque.First.Value;  // The first element\nint peekLast = deque.Last.Value;    // The last element\n\n/* Dequeue elements */\ndeque.RemoveFirst();  // The first element dequeued\ndeque.RemoveLast();   // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.Count;\n\n/* Check if the deque is empty */\nbool isEmpty = deque.Count == 0;\n
    deque_test.go
    /* Initialize the deque */\n// In Go, use list as a deque\ndeque := list.New()\n\n/* Enqueue elements */\ndeque.PushBack(2)      // Add to the tail\ndeque.PushBack(5)\ndeque.PushBack(4)\ndeque.PushFront(3)     // Add to the head\ndeque.PushFront(1)\n\n/* Access elements */\nfront := deque.Front() // The first element\nrear := deque.Back()   // The last element\n\n/* Dequeue elements */\ndeque.Remove(front)    // The first element dequeued\ndeque.Remove(rear)     // The last element dequeued\n\n/* Get the length of the deque */\nsize := deque.Len()\n\n/* Check if the deque is empty */\nisEmpty := deque.Len() == 0\n
    deque.swift
    /* Initialize the deque */\n// Swift does not have a built-in deque class, so Array can be used as a deque\nvar deque: [Int] = []\n\n/* Enqueue elements */\ndeque.append(2) // Add to the tail\ndeque.append(5)\ndeque.append(4)\ndeque.insert(3, at: 0) // Add to the head\ndeque.insert(1, at: 0)\n\n/* Access elements */\nlet peekFirst = deque.first! // The first element\nlet peekLast = deque.last!   // The last element\n\n/* Dequeue elements */\n// Using Array, popFirst has a complexity of O(n)\nlet popFirst = deque.removeFirst() // The first element dequeued\nlet popLast = deque.removeLast()   // The last element dequeued\n\n/* Get the length of the deque */\nlet size = deque.count\n\n/* Check if the deque is empty */\nlet isEmpty = deque.isEmpty\n
    deque.js
    /* Initialize the deque */\n// JavaScript does not have a built-in deque, so Array is used as a deque\nconst deque = [];\n\n/* Enqueue elements */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// Note that unshift() has a time complexity of O(n) as it's an array\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* Access elements */\nconst peekFirst = deque[0]; // The first element\nconst peekLast = deque[deque.length - 1]; // The last element\n\n/* Dequeue elements */\n// Note that shift() has a time complexity of O(n) as it's an array\nconst popFront = deque.shift(); // The first element dequeued\nconst popBack = deque.pop();    // The last element dequeued\n\n/* Get the length of the deque */\nconst size = deque.length;\n\n/* Check if the deque is empty */\nconst isEmpty = size === 0;\n
    deque.ts
    /* Initialize the deque */\n// TypeScript does not have a built-in deque, so Array is used as a deque\nconst deque: number[] = [];\n\n/* Enqueue elements */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// Note that unshift() has a time complexity of O(n) as it's an array\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* Access elements */\nconst peekFirst: number = deque[0]; // The first element\nconst peekLast: number = deque[deque.length - 1]; // The last element\n\n/* Dequeue elements */\n// Note that shift() has a time complexity of O(n) as it's an array\nconst popFront: number = deque.shift() as number; // The first element dequeued\nconst popBack: number = deque.pop() as number;    // The last element dequeued\n\n/* Get the length of the deque */\nconst size: number = deque.length;\n\n/* Check if the deque is empty */\nconst isEmpty: boolean = size === 0;\n
    deque.dart
    /* Initialize the deque */\n// In Dart, Queue is defined as a deque\nQueue<int> deque = Queue<int>();\n\n/* Enqueue elements */\ndeque.addLast(2);  // Add to the tail\ndeque.addLast(5);\ndeque.addLast(4);\ndeque.addFirst(3); // Add to the head\ndeque.addFirst(1);\n\n/* Access elements */\nint peekFirst = deque.first; // The first element\nint peekLast = deque.last;   // The last element\n\n/* Dequeue elements */\nint popFirst = deque.removeFirst(); // The first element dequeued\nint popLast = deque.removeLast();   // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.length;\n\n/* Check if the deque is empty */\nbool isEmpty = deque.isEmpty;\n
    deque.rs
    /* Initialize the deque */\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* Enqueue elements */\ndeque.push_back(2);  // Add to the tail\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3); // Add to the head\ndeque.push_front(1);\n\n/* Access elements */\nif let Some(front) = deque.front() { // The first element\n}\nif let Some(rear) = deque.back() {   // The last element\n}\n\n/* Dequeue elements */\nif let Some(pop_front) = deque.pop_front() { // The first element dequeued\n}\nif let Some(pop_rear) = deque.pop_back() {   // The last element dequeued\n}\n\n/* Get the length of the deque */\nlet size = deque.len();\n\n/* Check if the deque is empty */\nlet is_empty = deque.is_empty();\n
    deque.c
    // C does not provide a built-in deque\n
    deque.kt
    \n
    deque.zig
    \n
    Visualizing Code

    https://pythontutor.com/render.html#code=from%20collections%20import%20deque%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%0A%20%20%20%20deq%20%3D%20deque%28%29%0A%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%85%A5%E9%98%9F%0A%20%20%20%20deq.append%282%29%20%20%23%20%E6%B7%BB%E5%8A%A0%E8%87%B3%E9%98%9F%E5%B0%BE%0A%20%20%20%20deq.append%285%29%0A%20%20%20%20deq.append%284%29%0A%20%20%20%20deq.appendleft%283%29%20%20%23%20%E6%B7%BB%E5%8A%A0%E8%87%B3%E9%98%9F%E9%A6%96%0A%20%20%20%20deq.appendleft%281%29%0A%20%20%20%20print%28%22%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%20deque%20%3D%22,%20deq%29%0A%0A%20%20%20%20%23%20%E8%AE%BF%E9%97%AE%E5%85%83%E7%B4%A0%0A%20%20%20%20front%20%3D%20deq%5B0%5D%20%20%23%20%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%20front%20%3D%22,%20front%29%0A%20%20%20%20rear%20%3D%20deq%5B-1%5D%20%20%23%20%E9%98%9F%E5%B0%BE%E5%85%83%E7%B4%A0%0A%20%20%20%20print%28%22%E9%98%9F%E5%B0%BE%E5%85%83%E7%B4%A0%20rear%20%3D%22,%20rear%29%0A%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20pop_front%20%3D%20deq.popleft%28%29%20%20%23%20%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%87%BA%E9%98%9F%E5%85%83%E7%B4%A0%20%20pop_front%20%3D%22,%20pop_front%29%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%87%BA%E9%98%9F%E5%90%8E%20deque%20%3D%22,%20deq%29%0A%20%20%20%20pop_rear%20%3D%20deq.pop%28%29%20%20%23%20%E9%98%9F%E5%B0%BE%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20print%28%22%E9%98%9F%E5%B0%BE%E5%87%BA%E9%98%9F%E5%85%83%E7%B4%A0%20%20pop_rear%20%3D%22,%20pop_rear%29%0A%20%20%20%20print%28%22%E9%98%9F%E5%B0%BE%E5%87%BA%E9%98%9F%E5%90%8E%20deque%20%3D%22,%20deq%29%0A%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E7%9A%84%E9%95%BF%E5%BA%A6%0A%20%20%20%20size%20%3D%20len%28deq%29%0A%20%20%20%20print%28%22%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E9%95%BF%E5%BA%A6%20size%20%3D%22,%20size%29%0A%0A%20%20%20%20%23%20%E5%88%A4%E6%96%AD%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%0A%20%20%20%20is_empty%20%3D%20len%28deq%29%20%3D%3D%200%0A%20%20%20%20print%28%22%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%20%3D%22,%20is_empty%29&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    "},{"location":"chapter_stack_and_queue/deque/#532-implementing-a-double-ended-queue","title":"5.3.2 \u00a0 Implementing a double-ended queue *","text":"

    The implementation of a double-ended queue is similar to that of a regular queue, it can be based on either a linked list or an array as the underlying data structure.

    "},{"location":"chapter_stack_and_queue/deque/#1-implementation-based-on-doubly-linked-list","title":"1. \u00a0 Implementation based on doubly linked list","text":"

    Recall from the previous section that we used a regular singly linked list to implement a queue, as it conveniently allows for deleting from the head (corresponding to the dequeue operation) and adding new elements after the tail (corresponding to the enqueue operation).

    For a double-ended queue, both the head and the tail can perform enqueue and dequeue operations. In other words, a double-ended queue needs to implement operations in the opposite direction as well. For this, we use a \"doubly linked list\" as the underlying data structure of the double-ended queue.

    As shown in the Figure 5-8 , we treat the head and tail nodes of the doubly linked list as the front and rear of the double-ended queue, respectively, and implement the functionality to add and remove nodes at both ends.

    LinkedListDequepushLast()pushFirst()popLast()popFirst()

    Figure 5-8 \u00a0 Implementing Double-Ended Queue with Doubly Linked List for Enqueue and Dequeue Operations

    The implementation code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_deque.py
    class ListNode:\n    \"\"\"\u53cc\u5411\u94fe\u8868\u8282\u70b9\"\"\"\n\n    def __init__(self, val: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.val: int = val\n        self.next: ListNode | None = None  # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n        self.prev: ListNode | None = None  # \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\nclass LinkedListDeque:\n    \"\"\"\u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0  # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int, is_front: bool):\n        \"\"\"\u5165\u961f\u64cd\u4f5c\"\"\"\n        node = ListNode(num)\n        # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if self.is_empty():\n            self._front = self._rear = node\n        # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        elif is_front:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            self._front.prev = node\n            node.next = self._front\n            self._front = node  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            self._rear.next = node\n            node.prev = self._rear\n            self._rear = node  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size += 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        self.push(num, True)\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        self.push(num, False)\n\n    def pop(self, is_front: bool) -> int:\n        \"\"\"\u51fa\u961f\u64cd\u4f5c\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front:\n            val: int = self._front.val  # \u6682\u5b58\u5934\u8282\u70b9\u503c\n            # \u5220\u9664\u5934\u8282\u70b9\n            fnext: ListNode | None = self._front.next\n            if fnext != None:\n                fnext.prev = None\n                self._front.next = None\n            self._front = fnext  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else:\n            val: int = self._rear.val  # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            # \u5220\u9664\u5c3e\u8282\u70b9\n            rprev: ListNode | None = self._rear.prev\n            if rprev != None:\n                rprev.next = None\n                self._rear.prev = None\n            self._rear = rprev  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size -= 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        return self.pop(True)\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        return self.pop(False)\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._rear.val\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        node = self._front\n        res = [0] * self.size()\n        for i in range(self.size()):\n            res[i] = node.val\n            node = node.next\n        return res\n
    linkedlist_deque.cpp
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nstruct DoublyListNode {\n    int val;              // \u8282\u70b9\u503c\n    DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\u6307\u9488\n    DoublyListNode(int val) : val(val), prev(nullptr), next(nullptr) {\n    }\n};\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n  private:\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize = 0;              // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    LinkedListDeque() : front(nullptr), rear(nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~LinkedListDeque() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        DoublyListNode *pre, *cur = front;\n        while (cur != nullptr) {\n            pre = cur;\n            cur = cur->next;\n            delete pre;\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void push(int num, bool isFront) {\n        DoublyListNode *node = new DoublyListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front->prev = node;\n            node->next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear->next = node;\n            node->prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int pop(bool isFront) {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front->val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            DoublyListNode *fNext = front->next;\n            if (fNext != nullptr) {\n                fNext->prev = nullptr;\n                front->next = nullptr;\n            }\n            delete front;\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear->val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            DoublyListNode *rPrev = rear->prev;\n            if (rPrev != nullptr) {\n                rPrev->next = nullptr;\n                rear->prev = nullptr;\n            }\n            delete rear;\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return rear->val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        DoublyListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_deque.java
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    int val; // \u8282\u70b9\u503c\n    ListNode next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    ListNode prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    ListNode(int val) {\n        this.val = val;\n        prev = next = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private void push(int num, boolean isFront) {\n        ListNode node = new ListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear.next = node;\n            node.prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private int pop(boolean isFront) {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode fNext = front.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front.next = null;\n            }\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode rPrev = rear.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear.prev = null;\n            }\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return rear.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_deque.cs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(int val) {\n    public int val = val;       // \u8282\u70b9\u503c\n    public ListNode? next = null; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    public ListNode? prev = null; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    ListNode? front, rear; // \u5934\u8282\u70b9 front, \u5c3e\u8282\u70b9 rear\n    int queSize = 0;      // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void Push(int num, bool isFront) {\n        ListNode node = new(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (IsEmpty()) {\n            front = node;\n            rear = node;\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front!.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9                           \n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear!.next = node;\n            node.prev = rear;\n            rear = node;  // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        Push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        Push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int? Pop(bool isFront) {\n        if (IsEmpty())\n            throw new Exception();\n        int? val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front?.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode? fNext = front?.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front!.next = null;\n            }\n            front = fNext;   // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear?.val;  // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode? rPrev = rear?.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear!.prev = null;\n            }\n            rear = rPrev;    // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int? PopFirst() {\n        return Pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int? PopLast() {\n        return Pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int? PeekFirst() {\n        if (IsEmpty())\n            throw new Exception();\n        return front?.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int? PeekLast() {\n        if (IsEmpty())\n            throw new Exception();\n        return rear?.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int?[] ToArray() {\n        ListNode? node = front;\n        int?[] res = new int?[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node?.val;\n            node = node?.next;\n        }\n\n        return res;\n    }\n}\n
    linkedlist_deque.go
    /* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype linkedListDeque struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u53cc\u7aef\u961f\u5217 */\nfunc newLinkedListDeque() *linkedListDeque {\n    return &linkedListDeque{\n        data: list.New(),\n    }\n}\n\n/* \u961f\u9996\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushFirst(value any) {\n    s.data.PushFront(value)\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushLast(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u961f\u9996\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListDeque) peekFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (s *linkedListDeque) peekLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListDeque) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListDeque) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListDeque) toList() *list.List {\n    return s.data\n}\n
    linkedlist_deque.swift
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    weak var prev: ListNode? // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    init(val: Int) {\n        self.val = val\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? // \u5934\u8282\u70b9 front\n    private var rear: ListNode? // \u5c3e\u8282\u70b9 rear\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private func push(num: Int, isFront: Bool) {\n        let node = ListNode(val: num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if isEmpty() {\n            front = node\n            rear = node\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if isFront {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size += 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        push(num: num, isFront: true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        push(num: num, isFront: false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private func pop(isFront: Bool) -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        let val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if isFront {\n            val = front!.val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            let fNext = front?.next\n            if fNext != nil {\n                fNext?.prev = nil\n                front?.next = nil\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear!.val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            let rPrev = rear?.prev\n            if rPrev != nil {\n                rPrev?.next = nil\n                rear?.prev = nil\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size -= 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        pop(isFront: true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        pop(isFront: false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return rear!.val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.js
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val; // \u8282\u70b9\u503c\n\n    constructor(val) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    #front; // \u5934\u8282\u70b9 front\n    #rear; // \u5c3e\u8282\u70b9 rear\n    #queSize; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n        this.#queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.#rear.next = node;\n            node.prev = this.#rear;\n            this.#rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.#front.prev = node;\n            node.next = this.#front;\n            this.#front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp = this.#rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.#rear.prev = null;\n        }\n        this.#rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp = this.#front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.#front.next = null;\n        }\n        this.#front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        return this.#queSize === 0 ? null : this.#rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        return this.#queSize === 0 ? null : this.#front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print() {\n        const arr = [];\n        let temp = this.#front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.ts
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev: ListNode; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next: ListNode; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val: number; // \u8282\u70b9\u503c\n\n    constructor(val: number) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private front: ListNode; // \u5934\u8282\u70b9 front\n    private rear: ListNode; // \u5c3e\u8282\u70b9 rear\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n        this.queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.rear.next = node;\n            node.prev = this.rear;\n            this.rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.front.prev = node;\n            node.next = this.front;\n            this.front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp: ListNode = this.rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.rear.prev = null;\n        }\n        this.rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp: ListNode = this.front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.front.next = null;\n        }\n        this.front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        return this.queSize === 0 ? null : this.rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        return this.queSize === 0 ? null : this.front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print(): void {\n        const arr: number[] = [];\n        let temp: ListNode = this.front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.dart
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n  int val; // \u8282\u70b9\u503c\n  ListNode? next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  ListNode? prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n  ListNode(this.val, {this.next, this.prev});\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u5bf9\u5217 */\nclass LinkedListDeque {\n  late ListNode? _front; // \u5934\u8282\u70b9 _front\n  late ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  LinkedListDeque() {\n    this._front = null;\n    this._rear = null;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u957f\u5ea6 */\n  int size() {\n    return this._queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return size() == 0;\n  }\n\n  /* \u5165\u961f\u64cd\u4f5c */\n  void push(int _num, bool isFront) {\n    final ListNode node = ListNode(_num);\n    if (isEmpty()) {\n      // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 _front \u548c _rear \u90fd\u6307\u5411 node\n      _front = _rear = node;\n    } else if (isFront) {\n      // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      _front!.prev = node;\n      node.next = _front;\n      _front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      _rear!.next = node;\n      node.prev = _rear;\n      _rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    push(_num, true);\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    push(_num, false);\n  }\n\n  /* \u51fa\u961f\u64cd\u4f5c */\n  int? pop(bool isFront) {\n    // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de null\n    if (isEmpty()) {\n      return null;\n    }\n    final int val;\n    if (isFront) {\n      // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n      val = _front!.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n      // \u5220\u9664\u5934\u8282\u70b9\n      ListNode? fNext = _front!.next;\n      if (fNext != null) {\n        fNext.prev = null;\n        _front!.next = null;\n      }\n      _front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n      val = _rear!.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      // \u5220\u9664\u5c3e\u8282\u70b9\n      ListNode? rPrev = _rear!.prev;\n      if (rPrev != null) {\n        rPrev.next = null;\n        _rear!.prev = null;\n      }\n      _rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int? popFirst() {\n    return pop(true);\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int? popLast() {\n    return pop(false);\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int? peekFirst() {\n    return _front?.val;\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int? peekLast() {\n    return _rear?.val;\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> res = [];\n    for (int i = 0; i < _queSize; i++) {\n      res.add(node!.val);\n      node = node.next;\n    }\n    return res;\n  }\n}\n
    linkedlist_deque.rs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\npub struct ListNode<T> {\n    pub val: T,                                 // \u8282\u70b9\u503c\n    pub next: Option<Rc<RefCell<ListNode<T>>>>, // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    pub prev: Option<Rc<RefCell<ListNode<T>>>>, // \u524d\u9a71\u8282\u70b9\u6307\u9488\n}\n\nimpl<T> ListNode<T> {\n    pub fn new(val: T) -> Rc<RefCell<ListNode<T>>> {\n        Rc::new(RefCell::new(ListNode {\n            val,\n            next: None,\n            prev: None,\n        }))\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListDeque<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListDeque<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    pub fn push(&mut self, num: T, is_front: bool) {\n        let node = ListNode::new(num);\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        if is_front {\n            match self.front.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.rear = Some(node.clone());\n                    self.front = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                Some(old_front) => {\n                    old_front.borrow_mut().prev = Some(node.clone());\n                    node.borrow_mut().next = Some(old_front);\n                    self.front = Some(node); // \u66f4\u65b0\u5934\u8282\u70b9\n                }\n            }\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            match self.rear.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.front = Some(node.clone());\n                    self.rear = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                Some(old_rear) => {\n                    old_rear.borrow_mut().next = Some(node.clone());\n                    node.borrow_mut().prev = Some(old_rear);\n                    self.rear = Some(node); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                }\n            }\n        }\n        self.que_size += 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: T) {\n        self.push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: T) {\n        self.push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    pub fn pop(&mut self, is_front: bool) -> Option<T> {\n        // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de None\n        if self.is_empty() {\n            return None;\n        };\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front {\n            self.front.take().map(|old_front| {\n                match old_front.borrow_mut().next.take() {\n                    Some(new_front) => {\n                        new_front.borrow_mut().prev.take();\n                        self.front = Some(new_front); // \u66f4\u65b0\u5934\u8282\u70b9\n                    }\n                    None => {\n                        self.rear.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n            })\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            self.rear.take().map(|old_rear| {\n                match old_rear.borrow_mut().prev.take() {\n                    Some(new_rear) => {\n                        new_rear.borrow_mut().next.take();\n                        self.rear = Some(new_rear); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                    }\n                    None => {\n                        self.front.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_rear).ok().unwrap().into_inner().val\n            })\n        }\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    pub fn pop_first(&mut self) -> Option<T> {\n        return self.pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    pub fn pop_last(&mut self) -> Option<T> {\n        return self.pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek_first(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    pub fn peek_last(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.rear.as_ref()\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_deque.c
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\ntypedef struct DoublyListNode {\n    int val;                     // \u8282\u70b9\u503c\n    struct DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\n    struct DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\n} DoublyListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nDoublyListNode *newDoublyListNode(int num) {\n    DoublyListNode *new = (DoublyListNode *)malloc(sizeof(DoublyListNode));\n    new->val = num;\n    new->next = NULL;\n    new->prev = NULL;\n    return new;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delDoublyListNode(DoublyListNode *node) {\n    free(node);\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;                  // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n} LinkedListDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListDeque *newLinkedListDeque() {\n    LinkedListDeque *deque = (LinkedListDeque *)malloc(sizeof(LinkedListDeque));\n    deque->front = NULL;\n    deque->rear = NULL;\n    deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListdeque(LinkedListDeque *deque) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    for (int i = 0; i < deque->queSize && deque->front != NULL; i++) {\n        DoublyListNode *tmp = deque->front;\n        deque->front = deque->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e deque \u7ed3\u6784\u4f53\n    free(deque);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListDeque *deque) {\n    return (size(deque) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListDeque *deque, int num, bool isFront) {\n    DoublyListNode *node = newDoublyListNode(num);\n    // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411node\n    if (empty(deque)) {\n        deque->front = deque->rear = node;\n    }\n    // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    else if (isFront) {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n        deque->front->prev = node;\n        node->next = deque->front;\n        deque->front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n        deque->rear->next = node;\n        node->prev = deque->rear;\n        deque->rear = node;\n    }\n    deque->queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(LinkedListDeque *deque, int num) {\n    push(deque, num, true);\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(LinkedListDeque *deque, int num) {\n    push(deque, num, false);\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(LinkedListDeque *deque) {\n    assert(size(deque) && deque->front);\n    return deque->front->val;\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(LinkedListDeque *deque) {\n    assert(size(deque) && deque->rear);\n    return deque->rear->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListDeque *deque, bool isFront) {\n    if (empty(deque))\n        return -1;\n    int val;\n    // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if (isFront) {\n        val = peekFirst(deque); // \u6682\u5b58\u5934\u8282\u70b9\u503c\n        DoublyListNode *fNext = deque->front->next;\n        if (fNext) {\n            fNext->prev = NULL;\n            deque->front->next = NULL;\n        }\n        delDoublyListNode(deque->front);\n        deque->front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else {\n        val = peekLast(deque); // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n        DoublyListNode *rPrev = deque->rear->prev;\n        if (rPrev) {\n            rPrev->next = NULL;\n            deque->rear->prev = NULL;\n        }\n        delDoublyListNode(deque->rear);\n        deque->rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    deque->queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(LinkedListDeque *deque) {\n    return pop(deque, true);\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(LinkedListDeque *deque) {\n    return pop(deque, false);\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListDeque(LinkedListDeque *deque) {\n    int *arr = malloc(sizeof(int) * deque->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    DoublyListNode *node;\n    for (i = 0, node = deque->front; i < deque->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, deque->queSize);\n    free(arr);\n}\n
    linkedlist_deque.kt
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(var _val: Int) {\n    // \u8282\u70b9\u503c\n    var next: ListNode? = null // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    var prev: ListNode? = null // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? = null // \u5934\u8282\u70b9 front\n    private var rear: ListNode? = null // \u5c3e\u8282\u70b9 rear\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    fun push(num: Int, isFront: Boolean) {\n        val node = ListNode(num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty()) {\n            rear = node\n            front = rear\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        } else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++ // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        push(num, true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        push(num, false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    fun pop(isFront: Boolean): Int {\n        if (isEmpty()) \n            throw IndexOutOfBoundsException()\n        val _val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            _val = front!!._val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            val fNext = front!!.next\n            if (fNext != null) {\n                fNext.prev = null\n                front!!.next = null\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            _val = rear!!._val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            val rPrev = rear!!.prev\n            if (rPrev != null) {\n                rPrev.next = null\n                rear!!.prev = null\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize-- // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return _val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        return pop(true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        return pop(false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return rear!!._val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.rb
    =begin\nFile: linkedlist_deque.rb\nCreated Time: 2024-04-06\nAuthor: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)\n=end\n\n### \u53cc\u5411\u94fe\u8868\u8282\u70b9\nclass ListNode\n  attr_accessor :val\n  attr_accessor :next # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  attr_accessor :prev # \u524d\u8eaf\u8282\u70b9\u5f15\u7528\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(val)\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass LinkedListDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0     # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f\u64cd\u4f5c ###\n  def push(num, is_front)\n    node = ListNode.new(num)\n    # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c \u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n    if is_empty?\n      @front = @rear = node\n    # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    elsif is_front\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      @front.prev = node\n      node.next = @front\n      @front = node # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      @rear.next = node\n      node.prev = @rear\n      @rear = node # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size += 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    push(num, true)\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    push(num, false)\n  end\n\n  ### \u51fa\u961f\u64cd\u4f5c ###\n  def pop(is_front)\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if is_front\n      val = @front.val # \u6682\u5b58\u5934\u8282\u70b9\u503c\n      # \u5220\u9664\u5934\u8282\u70b9\n      fnext = @front.next\n      unless fnext.nil?\n        fnext.prev = nil\n        @front.next = nil\n      end\n      @front = fnext # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else\n      val = @rear.val # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      # \u5220\u9664\u5c3e\u8282\u70b9\n      rprev = @rear.prev\n      unless rprev.nil?\n        rprev.next = nil\n        @rear.prev = nil\n      end\n      @rear = rprev # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size -= 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    val\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    pop(true)\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_last\n    pop(false)\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @rear.val\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    node = @front\n    res = Array.new(size, 0)\n    for i in 0...size\n      res[i] = node.val\n      node = node.next\n    end\n    res\n  end\nend\n
    linkedlist_deque.zig
    // \u53cc\u5411\u94fe\u8868\u8282\u70b9\nfn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = undefined,     // \u8282\u70b9\u503c\n        next: ?*Self = null,    // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n        prev: ?*Self = null,    // \u524d\u9a71\u8282\u70b9\u6307\u9488\n\n        // Initialize a list node with specific value\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n\n// \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\nfn LinkedListDeque(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*ListNode(T) = null,                    // \u5934\u8282\u70b9 front\n        rear: ?*ListNode(T) = null,                     // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                             // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u5165\u961f\u64cd\u4f5c\n        pub fn push(self: *Self, num: T, is_front: bool) !void {\n            var node = try self.mem_allocator.create(ListNode(T));\n            node.init(num);\n            // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n            if (self.isEmpty()) {\n                self.front = node;\n                self.rear = node;\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n            } else if (is_front) {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                self.front.?.prev = node;\n                node.next = self.front;\n                self.front = node;  // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n            } else {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                self.rear.?.next = node;\n                node.prev = self.rear;\n                self.rear = node;   // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size += 1;      // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        } \n\n        // \u961f\u9996\u5165\u961f\n        pub fn pushFirst(self: *Self, num: T) !void {\n            try self.push(num, true);\n        } \n\n        // \u961f\u5c3e\u5165\u961f\n        pub fn pushLast(self: *Self, num: T) !void {\n            try self.push(num, false);\n        } \n\n        // \u51fa\u961f\u64cd\u4f5c\n        pub fn pop(self: *Self, is_front: bool) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            var val: T = undefined;\n            // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n            if (is_front) {\n                val = self.front.?.val;     // \u6682\u5b58\u5934\u8282\u70b9\u503c\n                // \u5220\u9664\u5934\u8282\u70b9\n                var fNext = self.front.?.next;\n                if (fNext != null) {\n                    fNext.?.prev = null;\n                    self.front.?.next = null;\n                }\n                self.front = fNext;         // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n            } else {\n                val = self.rear.?.val;      // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n                // \u5220\u9664\u5c3e\u8282\u70b9\n                var rPrev = self.rear.?.prev;\n                if (rPrev != null) {\n                    rPrev.?.next = null;\n                    self.rear.?.prev = null;\n                }\n                self.rear = rPrev;          // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size -= 1;              // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n            return val;\n        } \n\n        // \u961f\u9996\u51fa\u961f\n        pub fn popFirst(self: *Self) T {\n            return self.pop(true);\n        } \n\n        // \u961f\u5c3e\u51fa\u961f\n        pub fn popLast(self: *Self) T {\n            return self.pop(false);\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peekFirst(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\n        pub fn peekLast(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.rear.?.val;\n        }\n\n        // \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    "},{"location":"chapter_stack_and_queue/deque/#2-implementation-based-on-array","title":"2. \u00a0 Implementation based on array","text":"

    As shown in the Figure 5-9 , similar to implementing a queue with an array, we can also use a circular array to implement a double-ended queue.

    ArrayDequepushLast()pushFirst()popLast()popFirst()

    Figure 5-9 \u00a0 Implementing Double-Ended Queue with Array for Enqueue and Dequeue Operations

    The implementation only needs to add methods for \"front enqueue\" and \"rear dequeue\":

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_deque.py
    class ArrayDeque:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self, capacity: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * capacity\n        self._front: int = 0\n        self._size: int = 0\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def index(self, i: int) -> int:\n        \"\"\"\u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15\"\"\"\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + self.capacity()) % self.capacity()\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self._front = self.index(self._front - 1)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self._nums[self._front] = num\n        self._size += 1\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        rear = self.index(self._front + self._size)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        num = self.peek_first()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self._front = self.index(self._front + 1)\n        self._size -= 1\n        return num\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        num = self.peek_last()\n        self._size -= 1\n        return num\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        last = self.index(self._front + self._size - 1)\n        return self._nums[last]\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        res = []\n        for i in range(self._size):\n            res.append(self._nums[self.index(self._front + i)])\n        return res\n
    array_deque.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  private:\n    vector<int> nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;      // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayDeque(int capacity) {\n        nums.resize(capacity);\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return nums.size();\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> res(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n};\n
    array_deque.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        this.nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int Index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + Capacity()) % Capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = Index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = Index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int PopFirst() {\n        int num = PeekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = Index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int PopLast() {\n        int num = PeekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int PeekFirst() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int PeekLast() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = Index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[Index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype arrayDeque struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayDeque(queCapacity int) *arrayDeque {\n    return &arrayDeque{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayDeque) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayDeque) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nfunc (q *arrayDeque) index(i int) int {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + q.queCapacity) % q.queCapacity\n}\n\n/* \u961f\u9996\u5165\u961f */\nfunc (q *arrayDeque) pushFirst(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    q.front = q.index(q.front - 1)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    q.nums[q.front] = num\n    q.queSize++\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nfunc (q *arrayDeque) pushLast(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear := q.index(q.front + q.queSize)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u961f\u9996\u51fa\u961f */\nfunc (q *arrayDeque) popFirst() any {\n    num := q.peekFirst()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    q.front = q.index(q.front + 1)\n    q.queSize--\n    return num\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nfunc (q *arrayDeque) popLast() any {\n    num := q.peekLast()\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayDeque) peekFirst() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (q *arrayDeque) peekLast() any {\n    if q.isEmpty() {\n        return nil\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last := q.index(q.front + q.queSize - 1)\n    return q.nums[last]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayDeque) toSlice() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res := make([]int, q.queSize)\n    for i, j := 0, q.front; i < q.queSize; i++ {\n        res[i] = q.nums[q.index(j)]\n        j++\n    }\n    return res\n}\n
    array_deque.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(capacity: Int) {\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private func index(i: Int) -> Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(i: front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        _size += 1\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = index(i: front + size())\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        let num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(i: front + 1)\n        _size -= 1\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        let num = peekLast()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = index(i: front + size() - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[index(i: $0)] }\n    }\n}\n
    array_deque.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n        this.#front = 0;\n        this.#queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.#front = this.index(this.#front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.#nums[this.#front] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear = this.index(this.#front + this.#queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst() {\n        const num = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.#front = this.index(this.#front + 1);\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast() {\n        const num = this.peekLast();\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.#front + this.#queSize - 1);\n        return this.#nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res = [];\n        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {\n            res[i] = this.#nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = 0;\n        this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i: number): number {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.front = this.index(this.front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.nums[this.front] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear: number = this.index(this.front + this.queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst(): number {\n        const num: number = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.front = this.index(this.front + 1);\n        this.queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast(): number {\n        const num: number = this.peekLast();\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.nums[this.front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.front + this.queSize - 1);\n        return this.nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res: number[] = [];\n        for (let i = 0, j = this.front; i < this.queSize; i++, j++) {\n            res[i] = this.nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  late List<int> _nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayDeque(int capacity) {\n    this._nums = List.filled(capacity, 0);\n    this._front = this._queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n  int capacity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n  int index(int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + capacity()) % capacity();\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 _front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    _front = index(_front - 1);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u9996\n    _nums[_front] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = index(_front + _queSize);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int popFirst() {\n    int _num = peekFirst();\n    // \u961f\u9996\u6307\u9488\u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n    _front = index(_front + 1);\n    _queSize--;\n    return _num;\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int popLast() {\n    int _num = peekLast();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peekFirst() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int peekLast() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    int last = index(_front + _queSize - 1);\n    return _nums[last];\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[index(j)];\n    }\n    return res;\n  }\n}\n
    array_deque.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nstruct ArrayDeque {\n    nums: Vec<i32>,  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: usize,    // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: usize, // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n}\n\nimpl ArrayDeque {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        Self {\n            nums: vec![0; capacity],\n            front: 0,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        self.nums.len()\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    fn index(&self, i: i32) -> usize {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return ((i + self.capacity() as i32) % self.capacity() as i32) as usize;\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self.front = self.index(self.front as i32 - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self.nums[self.front] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = self.index(self.front as i32 + self.que_size as i32);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fn pop_first(&mut self) -> i32 {\n        let num = self.peek_first();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self.front = self.index(self.front as i32 + 1);\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fn pop_last(&mut self) -> i32 {\n        let num = self.peek_last();\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek_first(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        self.nums[self.front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fn peek_last(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = self.index(self.front as i32 + self.que_size as i32 - 1);\n        self.nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fn to_array(&self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut res = vec![0; self.que_size];\n        let mut j = self.front;\n        for i in 0..self.que_size {\n            res[i] = self.nums[self.index(j as i32)];\n            j += 1;\n        }\n        res\n    }\n}\n
    array_deque.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayDeque *newArrayDeque(int capacity) {\n    ArrayDeque *deque = (ArrayDeque *)malloc(sizeof(ArrayDeque));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    deque->queCapacity = capacity;\n    deque->nums = (int *)malloc(sizeof(int) * deque->queCapacity);\n    deque->front = deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayDeque(ArrayDeque *deque) {\n    free(deque->nums);\n    free(deque);\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayDeque *deque) {\n    return deque->queCapacity;\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayDeque *deque) {\n    return deque->queSize == 0;\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nint dequeIndex(ArrayDeque *deque, int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return ((i + capacity(deque)) % capacity(deque));\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u56de\u5230\u5c3e\u90e8\n    deque->front = dequeIndex(deque, deque->front - 1);\n    // \u5c06 num \u6dfb\u52a0\u5230\u961f\u9996\n    deque->nums[deque->front] = num;\n    deque->queSize++;\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = dequeIndex(deque, deque->front + deque->queSize);\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    deque->nums[rear] = num;\n    deque->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    return deque->nums[deque->front];\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    int last = dequeIndex(deque, deque->front + deque->queSize - 1);\n    return deque->nums[last];\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(ArrayDeque *deque) {\n    int num = peekFirst(deque);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    deque->front = dequeIndex(deque, deque->front + 1);\n    deque->queSize--;\n    return num;\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(ArrayDeque *deque) {\n    int num = peekLast(deque);\n    deque->queSize--;\n    return num;\n}\n
    array_deque.kt
    /* \u6784\u9020\u65b9\u6cd5 */\nclass ArrayDeque(capacity: Int) {\n    private var nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private fun index(i: Int): Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        queSize++\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        val rear = index(front + queSize)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        val num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1)\n        queSize--\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        val num = peekLast()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        val last = index(front + queSize - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[index(j)]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_deque.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass ArrayDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(capacity)\n    @nums = Array.new(capacity, 0)\n    @front = 0\n    @size = 0\n  end\n\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    @front = index(@front - 1)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    @nums[@front] = num\n    @size += 1\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear = index(@front + size)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    num = peek_first\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    @front = index(@front + 1)\n    @size -= 1\n    num\n  end\n\n  ### \u961f\u5c3e\u51fa\u961f ###\n  def pop_last\n    num = peek_last\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last = index(@front + size - 1)\n    @nums[last]\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res = []\n    for i in 0...size\n      res << @nums[index(@front + i)]\n    end\n    res\n  end\n\n  private\n\n  ### \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 ###\n  def index(i)\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    (i + capacity) % capacity\n  end\nend\n
    array_deque.zig
    [class]{ArrayDeque}-[func]{}\n
    "},{"location":"chapter_stack_and_queue/deque/#533-applications-of-double-ended-queue","title":"5.3.3 \u00a0 Applications of double-ended queue","text":"

    The double-ended queue combines the logic of both stacks and queues, thus, it can implement all their respective use cases while offering greater flexibility.

    We know that software's \"undo\" feature is typically implemented using a stack: the system pushes each change operation onto the stack and then pops to implement undoing. However, considering the limitations of system resources, software often restricts the number of undo steps (for example, only allowing the last 50 steps). When the stack length exceeds 50, the software needs to perform a deletion operation at the bottom of the stack (the front of the queue). But a regular stack cannot perform this function, where a double-ended queue becomes necessary. Note that the core logic of \"undo\" still follows the Last-In-First-Out principle of a stack, but a double-ended queue can more flexibly implement some additional logic.

    "},{"location":"chapter_stack_and_queue/queue/","title":"5.2 \u00a0 Queue","text":"

    \"Queue\" is a linear data structure that follows the First-In-First-Out (FIFO) rule. As the name suggests, a queue simulates the phenomenon of lining up, where newcomers join the queue at the rear, and the person at the front leaves the queue first.

    As shown in the Figure 5-4 , we call the front of the queue the \"head\" and the back the \"tail.\" The operation of adding elements to the rear of the queue is termed \"enqueue,\" and the operation of removing elements from the front is termed \"dequeue.\"

    Figure 5-4 \u00a0 Queue's first-in-first-out rule

    "},{"location":"chapter_stack_and_queue/queue/#521-common-operations-on-queue","title":"5.2.1 \u00a0 Common operations on queue","text":"

    The common operations on a queue are shown in the Table 5-2 . Note that method names may vary across different programming languages. Here, we use the same naming convention as that used for stacks.

    Table 5-2 \u00a0 Efficiency of queue operations

    Method Name Description Time Complexity push() Enqueue an element, add it to the tail \\(O(1)\\) pop() Dequeue the head element \\(O(1)\\) peek() Access the head element \\(O(1)\\)

    We can directly use the ready-made queue classes in programming languages:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig queue.py
    from collections import deque\n\n# Initialize the queue\n# In Python, we generally use the deque class as a queue\n# Although queue.Queue() is a pure queue class, it's not very user-friendly, so it's not recommended\nque: deque[int] = deque()\n\n# Enqueue elements\nque.append(1)\nque.append(3)\nque.append(2)\nque.append(5)\nque.append(4)\n\n# Access the first element\nfront: int = que[0]\n\n# Dequeue an element\npop: int = que.popleft()\n\n# Get the length of the queue\nsize: int = len(que)\n\n# Check if the queue is empty\nis_empty: bool = len(que) == 0\n
    queue.cpp
    /* Initialize the queue */\nqueue<int> queue;\n\n/* Enqueue elements */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* Access the first element*/\nint front = queue.front();\n\n/* Dequeue an element */\nqueue.pop();\n\n/* Get the length of the queue */\nint size = queue.size();\n\n/* Check if the queue is empty */\nbool empty = queue.empty();\n
    queue.java
    /* Initialize the queue */\nQueue<Integer> queue = new LinkedList<>();\n\n/* Enqueue elements */\nqueue.offer(1);\nqueue.offer(3);\nqueue.offer(2);\nqueue.offer(5);\nqueue.offer(4);\n\n/* Access the first element */\nint peek = queue.peek();\n\n/* Dequeue an element */\nint pop = queue.poll();\n\n/* Get the length of the queue */\nint size = queue.size();\n\n/* Check if the queue is empty */\nboolean isEmpty = queue.isEmpty();\n
    queue.cs
    /* Initialize the queue */\nQueue<int> queue = new();\n\n/* Enqueue elements */\nqueue.Enqueue(1);\nqueue.Enqueue(3);\nqueue.Enqueue(2);\nqueue.Enqueue(5);\nqueue.Enqueue(4);\n\n/* Access the first element */\nint peek = queue.Peek();\n\n/* Dequeue an element */\nint pop = queue.Dequeue();\n\n/* Get the length of the queue */\nint size = queue.Count;\n\n/* Check if the queue is empty */\nbool isEmpty = queue.Count == 0;\n
    queue_test.go
    /* Initialize the queue */\n// In Go, use list as a queue\nqueue := list.New()\n\n/* Enqueue elements */\nqueue.PushBack(1)\nqueue.PushBack(3)\nqueue.PushBack(2)\nqueue.PushBack(5)\nqueue.PushBack(4)\n\n/* Access the first element */\npeek := queue.Front()\n\n/* Dequeue an element */\npop := queue.Front()\nqueue.Remove(pop)\n\n/* Get the length of the queue */\nsize := queue.Len()\n\n/* Check if the queue is empty */\nisEmpty := queue.Len() == 0\n
    queue.swift
    /* Initialize the queue */\n// Swift does not have a built-in queue class, so Array can be used as a queue\nvar queue: [Int] = []\n\n/* Enqueue elements */\nqueue.append(1)\nqueue.append(3)\nqueue.append(2)\nqueue.append(5)\nqueue.append(4)\n\n/* Access the first element */\nlet peek = queue.first!\n\n/* Dequeue an element */\n// Since it's an array, removeFirst has a complexity of O(n)\nlet pool = queue.removeFirst()\n\n/* Get the length of the queue */\nlet size = queue.count\n\n/* Check if the queue is empty */\nlet isEmpty = queue.isEmpty\n
    queue.js
    /* Initialize the queue */\n// JavaScript does not have a built-in queue, so Array can be used as a queue\nconst queue = [];\n\n/* Enqueue elements */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* Access the first element */\nconst peek = queue[0];\n\n/* Dequeue an element */\n// Since the underlying structure is an array, shift() method has a time complexity of O(n)\nconst pop = queue.shift();\n\n/* Get the length of the queue */\nconst size = queue.length;\n\n/* Check if the queue is empty */\nconst empty = queue.length === 0;\n
    queue.ts
    /* Initialize the queue */\n// TypeScript does not have a built-in queue, so Array can be used as a queue \nconst queue: number[] = [];\n\n/* Enqueue elements */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* Access the first element */\nconst peek = queue[0];\n\n/* Dequeue an element */\n// Since the underlying structure is an array, shift() method has a time complexity of O(n)\nconst pop = queue.shift();\n\n/* Get the length of the queue */\nconst size = queue.length;\n\n/* Check if the queue is empty */\nconst empty = queue.length === 0;\n
    queue.dart
    /* Initialize the queue */\n// In Dart, the Queue class is a double-ended queue but can be used as a queue\nQueue<int> queue = Queue();\n\n/* Enqueue elements */\nqueue.add(1);\nqueue.add(3);\nqueue.add(2);\nqueue.add(5);\nqueue.add(4);\n\n/* Access the first element */\nint peek = queue.first;\n\n/* Dequeue an element */\nint pop = queue.removeFirst();\n\n/* Get the length of the queue */\nint size = queue.length;\n\n/* Check if the queue is empty */\nbool isEmpty = queue.isEmpty;\n
    queue.rs
    /* Initialize the double-ended queue */\n// In Rust, use a double-ended queue as a regular queue\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* Enqueue elements */\ndeque.push_back(1);\ndeque.push_back(3);\ndeque.push_back(2);\ndeque.push_back(5);\ndeque.push_back(4);\n\n/* Access the first element */\nif let Some(front) = deque.front() {\n}\n\n/* Dequeue an element */\nif let Some(pop) = deque.pop_front() {\n}\n\n/* Get the length of the queue */\nlet size = deque.len();\n\n/* Check if the queue is empty */\nlet is_empty = deque.is_empty();\n
    queue.c
    // C does not provide a built-in queue\n
    queue.kt
    \n
    queue.zig
    \n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/queue/#522-implementing-a-queue","title":"5.2.2 \u00a0 Implementing a queue","text":"

    To implement a queue, we need a data structure that allows adding elements at one end and removing them at the other. Both linked lists and arrays meet this requirement.

    "},{"location":"chapter_stack_and_queue/queue/#1-implementation-based-on-a-linked-list","title":"1. \u00a0 Implementation based on a linked list","text":"

    As shown in the Figure 5-5 , we can consider the \"head node\" and \"tail node\" of a linked list as the \"front\" and \"rear\" of the queue, respectively. It is stipulated that nodes can only be added at the rear and removed at the front.

    LinkedListQueuepush()pop()

    Figure 5-5 \u00a0 Implementing Queue with Linked List for Enqueue and Dequeue Operations

    Below is the code for implementing a queue using a linked list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_queue.py
    class LinkedListQueue:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        node = ListNode(num)\n        # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if self._front is None:\n            self._front = node\n            self._rear = node\n        # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else:\n            self._rear.next = node\n            self._rear = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num = self.peek()\n        # \u5220\u9664\u5934\u8282\u70b9\n        self._front = self._front.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        queue = []\n        temp = self._front\n        while temp:\n            queue.append(temp.val)\n            temp = temp.next\n        return queue\n
    linkedlist_queue.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  private:\n    ListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;\n\n  public:\n    LinkedListQueue() {\n        front = nullptr;\n        rear = nullptr;\n        queSize = 0;\n    }\n\n    ~LinkedListQueue() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(front);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode *node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == nullptr) {\n            front = node;\n            rear = node;\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear->next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        ListNode *tmp = front;\n        front = front->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (size() == 0)\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_queue.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    ListNode? front, rear;  // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear \n    int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else if (rear != null) {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (front == null)\n            return [];\n\n        ListNode? node = front;\n        int[] res = new int[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntype linkedListQueue struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u961f\u5217\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newLinkedListQueue() *linkedListQueue {\n    return &linkedListQueue{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u961f */\nfunc (s *linkedListQueue) push(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u961f */\nfunc (s *linkedListQueue) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListQueue) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListQueue) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListQueue) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListQueue) toList() *list.List {\n    return s.data\n}\n
    linkedlist_queue.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private var front: ListNode? // \u5934\u8282\u70b9\n    private var rear: ListNode? // \u5c3e\u8282\u70b9\n    private var _size: Int\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let node = ListNode(x: num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if front == nil {\n            front = node\n            rear = node\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear?.next = node\n            rear = node\n        }\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    #front; // \u5934\u8282\u70b9 #front\n    #rear; // \u5c3e\u8282\u70b9 #rear\n    #queSize = 0;\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.#front) {\n            this.#front = node;\n            this.#rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.#rear.next = node;\n            this.#rear = node;\n        }\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.#front = this.#front.next;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#front;\n        const res = new Array(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private front: ListNode | null; // \u5934\u8282\u70b9 front\n    private rear: ListNode | null; // \u5c3e\u8282\u70b9 rear\n    private queSize: number = 0;\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.front) {\n            this.front = node;\n            this.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.rear!.next = node;\n            this.rear = node;\n        }\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        if (!this.front) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.front = this.front.next;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.front;\n        const res = new Array<number>(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.dart
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  ListNode? _front; // \u5934\u8282\u70b9 _front\n  ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n  LinkedListQueue() {\n    _front = null;\n    _rear = null;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 _num\n    final node = ListNode(_num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (_front == null) {\n      _front = node;\n      _rear = node;\n    } else {\n      // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n      _rear!.next = node;\n      _rear = node;\n    }\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    final int _num = peek();\n    // \u5220\u9664\u5934\u8282\u70b9\n    _front = _front!.next;\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (_queSize == 0) {\n      throw Exception('\u961f\u5217\u4e3a\u7a7a');\n    }\n    return _front!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> queue = [];\n    while (node != null) {\n      queue.add(node.val);\n      node = node.next;\n    }\n    return queue;\n  }\n}\n
    linkedlist_queue.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListQueue<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListQueue<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f */\n    pub fn push(&mut self, num: T) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let new_rear = ListNode::new(num);\n        match self.rear.take() {\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            Some(old_rear) => {\n                old_rear.borrow_mut().next = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            None => {\n                self.front = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n        }\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    pub fn pop(&mut self) -> Option<T> {\n        self.front.take().map(|old_front| {\n            match old_front.borrow_mut().next.take() {\n                Some(new_front) => {\n                    self.front = Some(new_front);\n                }\n                None => {\n                    self.rear.take();\n                }\n            }\n            self.que_size -= 1;\n            Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_queue.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    ListNode *front, *rear;\n    int queSize;\n} LinkedListQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListQueue *newLinkedListQueue() {\n    LinkedListQueue *queue = (LinkedListQueue *)malloc(sizeof(LinkedListQueue));\n    queue->front = NULL;\n    queue->rear = NULL;\n    queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListQueue(LinkedListQueue *queue) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    while (queue->front != NULL) {\n        ListNode *tmp = queue->front;\n        queue->front = queue->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e queue \u7ed3\u6784\u4f53\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListQueue *queue) {\n    return (size(queue) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListQueue *queue, int num) {\n    // \u5c3e\u8282\u70b9\u5904\u6dfb\u52a0 node\n    ListNode *node = newListNode(num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (queue->front == NULL) {\n        queue->front = node;\n        queue->rear = node;\n    }\n    // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else {\n        queue->rear->next = node;\n        queue->rear = node;\n    }\n    queue->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(LinkedListQueue *queue) {\n    assert(size(queue) && queue->front);\n    return queue->front->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListQueue *queue) {\n    int num = peek(queue);\n    ListNode *tmp = queue->front;\n    queue->front = queue->front->next;\n    free(tmp);\n    queue->queSize--;\n    return num;\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListQueue(LinkedListQueue *queue) {\n    int *arr = malloc(sizeof(int) * queue->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    ListNode *node;\n    for (i = 0, node = queue->front; i < queue->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, queue->queSize);\n    free(arr);\n}\n
    linkedlist_queue.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue(\n    // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private var front: ListNode? = null,\n    private var rear: ListNode? = null,\n    private var queSize: Int = 0\n) {\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        val node = ListNode(num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node\n            rear = node\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear?.next = node\n            rear = node\n        }\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5934\u73b0\u7684\u961f\u5217 ###\nclass LinkedListQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @front.nil?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n    node = ListNode.new(num)\n\n    # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\uff0c\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if @front.nil?\n      @front = node\n      @rear = node\n    # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u4ee4\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else\n      @rear.next = node\n      @rear = node\n    end\n\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u5220\u9664\u5934\u8282\u70b9\n    @front = @front.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u5c06\u94fe\u8868\u4e3a Array \u5e76\u8fd4\u56de ###\n  def to_array\n    queue = []\n    temp = @front\n    while temp\n      queue << temp.val\n      temp = temp.next\n    end\n    queue\n  end\nend\n
    linkedlist_queue.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\nfn LinkedListQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*inc.ListNode(T) = null,                // \u5934\u8282\u70b9 front\n        rear: ?*inc.ListNode(T) = null,                 // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                            // \u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            if (self.front == null) {\n                self.front = node;\n                self.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            } else {\n                self.rear.?.next = node;\n                self.rear = node;\n            }\n            self.que_size += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u5220\u9664\u5934\u8282\u70b9\n            self.front = self.front.?.next;\n            self.que_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/queue/#2-implementation-based-on-an-array","title":"2. \u00a0 Implementation based on an array","text":"

    Deleting the first element in an array has a time complexity of \\(O(n)\\), which would make the dequeue operation inefficient. However, this problem can be cleverly avoided as follows.

    We use a variable front to indicate the index of the front element and maintain a variable size to record the queue's length. Define rear = front + size, which points to the position immediately following the tail element.

    With this design, the effective interval of elements in the array is [front, rear - 1]. The implementation methods for various operations are shown in the Figure 5-6 .

    • Enqueue operation: Assign the input element to the rear index and increase size by 1.
    • Dequeue operation: Simply increase front by 1 and decrease size by 1.

    Both enqueue and dequeue operations only require a single operation, each with a time complexity of \\(O(1)\\).

    ArrayQueuepush()pop()

    Figure 5-6 \u00a0 Implementing Queue with Array for Enqueue and Dequeue Operations

    You might notice a problem: as enqueue and dequeue operations are continuously performed, both front and rear move to the right and will eventually reach the end of the array and can't move further. To resolve this, we can treat the array as a \"circular array\" where connecting the end of the array back to its beginning.

    In a circular array, front or rear needs to loop back to the start of the array upon reaching the end. This cyclical pattern can be achieved with a \"modulo operation\" as shown in the code below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_queue.py
    class ArrayQueue:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self, size: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * size  # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n        self._front: int = 0  # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        self._size: int = 0  # \u961f\u5217\u957f\u5ea6\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            raise IndexError(\"\u961f\u5217\u5df2\u6ee1\")\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        rear: int = (self._front + self._size) % self.capacity()\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num: int = self.peek()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self._front = (self._front + 1) % self.capacity()\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        res = [0] * self.size()\n        j: int = self._front\n        for i in range(self.size()):\n            res[i] = self._nums[(j % self.capacity())]\n            j += 1\n        return res\n
    array_queue.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  private:\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u961f\u5217\u957f\u5ea6\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n\n  public:\n    ArrayQueue(int capacity) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = new int[capacity];\n        queCapacity = capacity;\n        front = queSize = 0;\n    }\n\n    ~ArrayQueue() {\n        delete[] nums;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return queCapacity;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        if (queSize == queCapacity) {\n            cout << \"\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % queCapacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % queCapacity;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u5c06\u6570\u7ec4\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> arr(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            arr[i] = nums[j % queCapacity];\n        }\n        return arr;\n    }\n};\n
    array_queue.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % Capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % Capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % this.Capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntype arrayQueue struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayQueue(queCapacity int) *arrayQueue {\n    return &arrayQueue{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayQueue) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayQueue) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u5165\u961f */\nfunc (q *arrayQueue) push(num int) {\n    // \u5f53 rear == queCapacity \u8868\u793a\u961f\u5217\u5df2\u6ee1\n    if q.queSize == q.queCapacity {\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear := (q.front + q.queSize) % q.queCapacity\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u51fa\u961f */\nfunc (q *arrayQueue) pop() any {\n    num := q.peek()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    q.front = (q.front + 1) % q.queCapacity\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayQueue) peek() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayQueue) toSlice() []int {\n    rear := (q.front + q.queSize)\n    if rear >= q.queCapacity {\n        rear %= q.queCapacity\n        return append(q.nums[q.front:], q.nums[:rear]...)\n    }\n    return q.nums[q.front:rear]\n}\n
    array_queue.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u961f\u5217\u957f\u5ea6\n\n    init(capacity: Int) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        if size() == capacity() {\n            print(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (front + size()) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[$0 % capacity()] }\n    }\n}\n
    array_queue.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front = 0; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.#front + this.size) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.#front = (this.#front + 1) % this.capacity;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.#front; i < this.size; i++, j++) {\n            arr[i] = this.#nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.front + this.queSize) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.front = (this.front + 1) % this.capacity;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.nums[this.front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.front; i < this.size; i++, j++) {\n            arr[i] = this.nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  late List<int> _nums; // \u7528\u4e8e\u50a8\u5b58\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u961f\u5217\u957f\u5ea6\n\n  ArrayQueue(int capacity) {\n    _nums = List.filled(capacity, 0);\n    _front = _queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n  int capaCity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    if (_queSize == capaCity()) {\n      throw Exception(\"\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (_front + _queSize) % capaCity();\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    int _num = peek();\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    _front = (_front + 1) % capaCity();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8fd4\u56de Array */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    final List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[j % capaCity()];\n    }\n    return res;\n  }\n}\n
    array_queue.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nstruct ArrayQueue {\n    nums: Vec<i32>,    // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: i32,        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: i32,     // \u961f\u5217\u957f\u5ea6\n    que_capacity: i32, // \u961f\u5217\u5bb9\u91cf\n}\n\nimpl ArrayQueue {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(capacity: i32) -> ArrayQueue {\n        ArrayQueue {\n            nums: vec![0; capacity as usize],\n            front: 0,\n            que_size: 0,\n            que_capacity: capacity,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fn capacity(&self) -> i32 {\n        self.que_capacity\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fn size(&self) -> i32 {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u5165\u961f */\n    fn push(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (self.front + self.que_size) % self.que_capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear as usize] = num;\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    fn pop(&mut self) -> i32 {\n        let num = self.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self.front = (self.front + 1) % self.que_capacity;\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"index out of bounds\");\n        }\n        self.nums[self.front as usize]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fn to_vector(&self) -> Vec<i32> {\n        let cap = self.que_capacity;\n        let mut j = self.front;\n        let mut arr = vec![0; self.que_size as usize];\n        for i in 0..self.que_size {\n            arr[i as usize] = self.nums[(j % cap) as usize];\n            j += 1;\n        }\n        arr\n    }\n}\n
    array_queue.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayQueue *newArrayQueue(int capacity) {\n    ArrayQueue *queue = (ArrayQueue *)malloc(sizeof(ArrayQueue));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    queue->queCapacity = capacity;\n    queue->nums = (int *)malloc(sizeof(int) * queue->queCapacity);\n    queue->front = queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayQueue(ArrayQueue *queue) {\n    free(queue->nums);\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayQueue *queue) {\n    return queue->queCapacity;\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayQueue *queue) {\n    return queue->queSize == 0;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(ArrayQueue *queue) {\n    assert(size(queue) != 0);\n    return queue->nums[queue->front];\n}\n\n/* \u5165\u961f */\nvoid push(ArrayQueue *queue, int num) {\n    if (size(queue) == capacity(queue)) {\n        printf(\"\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (queue->front + queue->queSize) % queue->queCapacity;\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    queue->nums[rear] = num;\n    queue->queSize++;\n}\n\n/* \u51fa\u961f */\nint pop(ArrayQueue *queue) {\n    int num = peek(queue);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    queue->front = (queue->front + 1) % queue->queCapacity;\n    queue->queSize--;\n    return num;\n}\n
    array_queue.kt
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue(capacity: Int) {\n    private val nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        val rear = (front + queSize) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[j % capacity()]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_queue.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 ###\nclass ArrayQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(size)\n    @nums = Array.new(size, 0) # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    @front = 0 # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    @size = 0 # \u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    raise IndexError, '\u961f\u5217\u5df2\u6ee1' if size == capacity\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear = (@front + size) % capacity\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    @front = (@front + 1) % capacity\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    res = Array.new(size, 0)\n    j = @front\n\n    for i in 0...size\n      res[i] = @nums[j % capacity]\n      j += 1\n    end\n\n    res\n  end\nend\n
    array_queue.zig
    // \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\nfn ArrayQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        nums: []T = undefined,                          // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4     \n        cap: usize = 0,                                 // \u961f\u5217\u5bb9\u91cf\n        front: usize = 0,                               // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        queSize: usize = 0,                             // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6570\u7ec4\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator, cap: usize) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.cap = cap;\n            self.nums = try self.mem_allocator.alloc(T, self.cap);\n            @memset(self.nums, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.cap;\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.queSize;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.queSize == 0;\n        }\n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            if (self.size() == self.capacity()) {\n                std.debug.print(\"\u961f\u5217\u5df2\u6ee1\\n\", .{});\n                return;\n            }\n            // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n            // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n            var rear = (self.front + self.queSize) % self.capacity();\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            self.nums[rear] = num;\n            self.queSize += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n            self.front = (self.front + 1) % self.capacity();\n            self.queSize -= 1;\n            return num;\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.nums[self.front];\n        } \n\n        // \u8fd4\u56de\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            var j: usize = self.front;\n            while (i < self.size()) : ({ i += 1; j += 1; }) {\n                res[i] = self.nums[j % self.capacity()];\n            }\n            return res;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    The above implementation of the queue still has its limitations: its length is fixed. However, this issue is not difficult to resolve. We can replace the array with a dynamic array that can expand itself if needed. Interested readers can try to implement this themselves.

    The comparison of the two implementations is consistent with that of the stack and is not repeated here.

    "},{"location":"chapter_stack_and_queue/queue/#523-typical-applications-of-queue","title":"5.2.3 \u00a0 Typical applications of queue","text":"
    • Amazon orders: After shoppers place orders, these orders join a queue, and the system processes them in order. During events like Singles' Day, a massive number of orders are generated in a short time, making high concurrency a key challenge for engineers.
    • Various to-do lists: Any scenario requiring a \"first-come, first-served\" functionality, such as a printer's task queue or a restaurant's food delivery queue, can effectively maintain the order of processing with a queue.
    "},{"location":"chapter_stack_and_queue/stack/","title":"5.1 \u00a0 Stack","text":"

    A \"Stack\" is a linear data structure that follows the principle of Last-In-First-Out (LIFO).

    We can compare a stack to a pile of plates on a table. To access the bottom plate, one must first remove the plates on top. By replacing the plates with various types of elements (such as integers, characters, objects, etc.), we obtain the data structure known as a stack.

    As shown in the Figure 5-1 , we refer to the top of the pile of elements as the \"top of the stack\" and the bottom as the \"bottom of the stack.\" The operation of adding elements to the top of the stack is called \"push,\" and the operation of removing the top element is called \"pop.\"

    Figure 5-1 \u00a0 Stack's last-in-first-out rule

    "},{"location":"chapter_stack_and_queue/stack/#511-common-operations-on-stack","title":"5.1.1 \u00a0 Common operations on stack","text":"

    The common operations on a stack are shown in the Table 5-1 . The specific method names depend on the programming language used. Here, we use push(), pop(), and peek() as examples.

    Table 5-1 \u00a0 Efficiency of stack operations

    Method Description Time Complexity push() Push an element onto the stack (add to the top) \\(O(1)\\) pop() Pop the top element from the stack \\(O(1)\\) peek() Access the top element of the stack \\(O(1)\\)

    Typically, we can directly use the stack class built into the programming language. However, some languages may not specifically provide a stack class. In these cases, we can use the language's \"array\" or \"linked list\" as a stack and ignore operations that are not related to stack logic in the program.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig stack.py
    # Initialize the stack\n# Python does not have a built-in stack class, so a list can be used as a stack\nstack: list[int] = []\n\n# Push elements onto the stack\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n# Access the top element of the stack\npeek: int = stack[-1]\n\n# Pop an element from the stack\npop: int = stack.pop()\n\n# Get the length of the stack\nsize: int = len(stack)\n\n# Check if the stack is empty\nis_empty: bool = len(stack) == 0\n
    stack.cpp
    /* Initialize the stack */\nstack<int> stack;\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nint top = stack.top();\n\n/* Pop an element from the stack */\nstack.pop(); // No return value\n\n/* Get the length of the stack */\nint size = stack.size();\n\n/* Check if the stack is empty */\nbool empty = stack.empty();\n
    stack.java
    /* Initialize the stack */\nStack<Integer> stack = new Stack<>();\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nint peek = stack.peek();\n\n/* Pop an element from the stack */\nint pop = stack.pop();\n\n/* Get the length of the stack */\nint size = stack.size();\n\n/* Check if the stack is empty */\nboolean isEmpty = stack.isEmpty();\n
    stack.cs
    /* Initialize the stack */\nStack<int> stack = new();\n\n/* Push elements onto the stack */\nstack.Push(1);\nstack.Push(3);\nstack.Push(2);\nstack.Push(5);\nstack.Push(4);\n\n/* Access the top element of the stack */\nint peek = stack.Peek();\n\n/* Pop an element from the stack */\nint pop = stack.Pop();\n\n/* Get the length of the stack */\nint size = stack.Count;\n\n/* Check if the stack is empty */\nbool isEmpty = stack.Count == 0;\n
    stack_test.go
    /* Initialize the stack */\n// In Go, it is recommended to use a Slice as a stack\nvar stack []int\n\n/* Push elements onto the stack */\nstack = append(stack, 1)\nstack = append(stack, 3)\nstack = append(stack, 2)\nstack = append(stack, 5)\nstack = append(stack, 4)\n\n/* Access the top element of the stack */\npeek := stack[len(stack)-1]\n\n/* Pop an element from the stack */\npop := stack[len(stack)-1]\nstack = stack[:len(stack)-1]\n\n/* Get the length of the stack */\nsize := len(stack)\n\n/* Check if the stack is empty */\nisEmpty := len(stack) == 0\n
    stack.swift
    /* Initialize the stack */\n// Swift does not have a built-in stack class, so Array can be used as a stack\nvar stack: [Int] = []\n\n/* Push elements onto the stack */\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n/* Access the top element of the stack */\nlet peek = stack.last!\n\n/* Pop an element from the stack */\nlet pop = stack.removeLast()\n\n/* Get the length of the stack */\nlet size = stack.count\n\n/* Check if the stack is empty */\nlet isEmpty = stack.isEmpty\n
    stack.js
    /* Initialize the stack */\n// JavaScript does not have a built-in stack class, so Array can be used as a stack\nconst stack = [];\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nconst peek = stack[stack.length-1];\n\n/* Pop an element from the stack */\nconst pop = stack.pop();\n\n/* Get the length of the stack */\nconst size = stack.length;\n\n/* Check if the stack is empty */\nconst is_empty = stack.length === 0;\n
    stack.ts
    /* Initialize the stack */\n// TypeScript does not have a built-in stack class, so Array can be used as a stack\nconst stack: number[] = [];\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nconst peek = stack[stack.length - 1];\n\n/* Pop an element from the stack */\nconst pop = stack.pop();\n\n/* Get the length of the stack */\nconst size = stack.length;\n\n/* Check if the stack is empty */\nconst is_empty = stack.length === 0;\n
    stack.dart
    /* Initialize the stack */\n// Dart does not have a built-in stack class, so List can be used as a stack\nList<int> stack = [];\n\n/* Push elements onto the stack */\nstack.add(1);\nstack.add(3);\nstack.add(2);\nstack.add(5);\nstack.add(4);\n\n/* Access the top element of the stack */\nint peek = stack.last;\n\n/* Pop an element from the stack */\nint pop = stack.removeLast();\n\n/* Get the length of the stack */\nint size = stack.length;\n\n/* Check if the stack is empty */\nbool isEmpty = stack.isEmpty;\n
    stack.rs
    /* Initialize the stack */\n// Use Vec as a stack\nlet mut stack: Vec<i32> = Vec::new();\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nlet top = stack.last().unwrap();\n\n/* Pop an element from the stack */\nlet pop = stack.pop().unwrap();\n\n/* Get the length of the stack */\nlet size = stack.len();\n\n/* Check if the stack is empty */\nlet is_empty = stack.is_empty();\n
    stack.c
    // C does not provide a built-in stack\n
    stack.kt
    \n
    stack.zig
    \n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/stack/#512-implementing-a-stack","title":"5.1.2 \u00a0 Implementing a stack","text":"

    To gain a deeper understanding of how a stack operates, let's try implementing a stack class ourselves.

    A stack follows the principle of Last-In-First-Out, which means we can only add or remove elements at the top of the stack. However, both arrays and linked lists allow adding and removing elements at any position, therefore a stack can be seen as a restricted array or linked list. In other words, we can \"shield\" certain irrelevant operations of an array or linked list, aligning their external behavior with the characteristics of a stack.

    "},{"location":"chapter_stack_and_queue/stack/#1-implementation-based-on-a-linked-list","title":"1. \u00a0 Implementation based on a linked list","text":"

    When implementing a stack using a linked list, we can consider the head node of the list as the top of the stack and the tail node as the bottom of the stack.

    As shown in the Figure 5-2 , for the push operation, we simply insert elements at the head of the linked list. This method of node insertion is known as \"head insertion.\" For the pop operation, we just need to remove the head node from the list.

    LinkedListStackpush()pop()

    Figure 5-2 \u00a0 Implementing Stack with Linked List for Push and Pop Operations

    Below is an example code for implementing a stack based on a linked list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_stack.py
    class LinkedListStack:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._peek: ListNode | None = None\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, val: int):\n        \"\"\"\u5165\u6808\"\"\"\n        node = ListNode(val)\n        node.next = self._peek\n        self._peek = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        num = self.peek()\n        self._peek = self._peek.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._peek.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        arr = []\n        node = self._peek\n        while node:\n            arr.append(node.val)\n            node = node.next\n        arr.reverse()\n        return arr\n
    linkedlist_stack.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  private:\n    ListNode *stackTop; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize;        // \u6808\u7684\u957f\u5ea6\n\n  public:\n    LinkedListStack() {\n        stackTop = nullptr;\n        stkSize = 0;\n    }\n\n    ~LinkedListStack() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(stackTop);\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        ListNode *node = new ListNode(num);\n        node->next = stackTop;\n        stackTop = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        ListNode *tmp = stackTop;\n        stackTop = stackTop->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stackTop->val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = stackTop;\n        vector<int> res(size());\n        for (int i = res.size() - 1; i >= 0; i--) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_stack.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private ListNode stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private int stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        ListNode node = new ListNode(num);\n        node.next = stackPeek;\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        int num = peek();\n        stackPeek = stackPeek.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stackPeek.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = stackPeek;\n        int[] res = new int[size()];\n        for (int i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    ListNode? stackPeek;  // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize = 0;   // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        ListNode node = new(num) {\n            next = stackPeek\n        };\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        int num = Peek();\n        stackPeek = stackPeek!.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stackPeek!.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (stackPeek == null)\n            return [];\n\n        ListNode? node = stackPeek;\n        int[] res = new int[Size()];\n        for (int i = res.Length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntype linkedListStack struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u6808\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newLinkedListStack() *linkedListStack {\n    return &linkedListStack{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u6808 */\nfunc (s *linkedListStack) push(value int) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u6808 */\nfunc (s *linkedListStack) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nfunc (s *linkedListStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nfunc (s *linkedListStack) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListStack) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListStack) toList() *list.List {\n    return s.data\n}\n
    linkedlist_stack.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private var _peek: ListNode? // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var _size: Int // \u6808\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        let node = ListNode(x: num)\n        node.next = _peek\n        _peek = node\n        _size += 1\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        _peek = _peek?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return _peek!.val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = _peek\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices.reversed() {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    #stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    #stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        const node = new ListNode(num);\n        node.next = this.#stackPeek;\n        this.#stackPeek = node;\n        this.#stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        const num = this.peek();\n        this.#stackPeek = this.#stackPeek.next;\n        this.#stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek() {\n        if (!this.#stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#stackPeek;\n        const res = new Array(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private stackPeek: ListNode | null; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private stkSize: number = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        const node = new ListNode(num);\n        node.next = this.stackPeek;\n        this.stackPeek = node;\n        this.stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        this.stackPeek = this.stackPeek.next;\n        this.stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek(): number {\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.stackPeek;\n        const res = new Array<number>(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.dart
    /* \u57fa\u4e8e\u94fe\u8868\u7c7b\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  ListNode? _stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n  int _stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n  LinkedListStack() {\n    _stackPeek = null;\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stkSize;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stkSize == 0;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    final ListNode node = ListNode(_num);\n    node.next = _stackPeek;\n    _stackPeek = node;\n    _stkSize++;\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    final int _num = peek();\n    _stackPeek = _stackPeek!.next;\n    _stkSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (_stackPeek == null) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stackPeek!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a List \u5e76\u8fd4\u56de */\n  List<int> toList() {\n    ListNode? node = _stackPeek;\n    List<int> list = [];\n    while (node != null) {\n      list.add(node.val);\n      node = node.next;\n    }\n    list = list.reversed.toList();\n    return list;\n  }\n}\n
    linkedlist_stack.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\n#[allow(dead_code)]\npub struct LinkedListStack<T> {\n    stack_peek: Option<Rc<RefCell<ListNode<T>>>>, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    stk_size: usize,                              // \u6808\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListStack<T> {\n    pub fn new() -> Self {\n        Self {\n            stack_peek: None,\n            stk_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.stk_size;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    pub fn push(&mut self, num: T) {\n        let node = ListNode::new(num);\n        node.borrow_mut().next = self.stack_peek.take();\n        self.stack_peek = Some(node);\n        self.stk_size += 1;\n    }\n\n    /* \u51fa\u6808 */\n    pub fn pop(&mut self) -> Option<T> {\n        self.stack_peek.take().map(|old_head| {\n            match old_head.borrow_mut().next.take() {\n                Some(new_head) => {\n                    self.stack_peek = Some(new_head);\n                }\n                None => {\n                    self.stack_peek = None;\n                }\n            }\n            self.stk_size -= 1;\n            Rc::try_unwrap(old_head).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.stack_peek.as_ref()\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.push(node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_stack.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    ListNode *top; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int size;      // \u6808\u7684\u957f\u5ea6\n} LinkedListStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListStack *newLinkedListStack() {\n    LinkedListStack *s = malloc(sizeof(LinkedListStack));\n    s->top = NULL;\n    s->size = 0;\n    return s;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListStack(LinkedListStack *s) {\n    while (s->top) {\n        ListNode *n = s->top->next;\n        free(s->top);\n        s->top = n;\n    }\n    free(s);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(LinkedListStack *s) {\n    return s->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(LinkedListStack *s) {\n    return size(s) == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(LinkedListStack *s, int num) {\n    ListNode *node = (ListNode *)malloc(sizeof(ListNode));\n    node->next = s->top; // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6307\u9488\u57df\n    node->val = num;     // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6570\u636e\u57df\n    s->top = node;       // \u66f4\u65b0\u6808\u9876\n    s->size++;           // \u66f4\u65b0\u6808\u5927\u5c0f\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(LinkedListStack *s) {\n    if (s->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return s->top->val;\n}\n\n/* \u51fa\u6808 */\nint pop(LinkedListStack *s) {\n    int val = peek(s);\n    ListNode *tmp = s->top;\n    s->top = s->top->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n    s->size--;\n    return val;\n}\n
    linkedlist_stack.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack(\n    private var stackPeek: ListNode? = null, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var stkSize: Int = 0 // \u6808\u7684\u957f\u5ea6\n) {\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stkSize\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        val node = ListNode(num)\n        node.next = stackPeek\n        stackPeek = node\n        stkSize++\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int? {\n        val num = peek()\n        stackPeek = stackPeek?.next\n        stkSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int? {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stackPeek?._val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = stackPeek\n        val res = IntArray(size())\n        for (i in res.size - 1 downTo 0) {\n            res[i] = node?._val!!\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 ###\nclass LinkedListStack\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @peek.nil?\n  end\n\n  ### \u5165\u6808 ###\n  def push(val)\n    node = ListNode.new(val)\n    node.next = @peek\n    @peek = node\n    @size += 1\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    num = peek\n    @peek = @peek.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @peek.val\n  end\n\n  ### \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u53cd\u56de ###\n  def to_array\n    arr = []\n    node = @peek\n    while node\n      arr << node.val\n      node = node.next\n    end\n    arr.reverse\n  end\nend\n
    linkedlist_stack.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\nfn LinkedListStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack_top: ?*inc.ListNode(T) = null,             // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n        stk_size: usize = 0,                             // \u6808\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,    // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.stack_top = null;\n            self.stk_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stk_size;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack_top.?.val;\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            node.next = self.stack_top;\n            self.stack_top = node;\n            self.stk_size += 1;\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            self.stack_top = self.stack_top.?.next;\n            self.stk_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u6808\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.stack_top;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[res.len - i - 1] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/stack/#2-implementation-based-on-an-array","title":"2. \u00a0 Implementation based on an array","text":"

    When implementing a stack using an array, we can consider the end of the array as the top of the stack. As shown in the Figure 5-3 , push and pop operations correspond to adding and removing elements at the end of the array, respectively, both with a time complexity of \\(O(1)\\).

    ArrayStackpush()pop()

    Figure 5-3 \u00a0 Implementing Stack with Array for Push and Pop Operations

    Since the elements to be pushed onto the stack may continuously increase, we can use a dynamic array, thus avoiding the need to handle array expansion ourselves. Here is an example code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_stack.py
    class ArrayStack:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._stack: list[int] = []\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return len(self._stack)\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self.size() == 0\n\n    def push(self, item: int):\n        \"\"\"\u5165\u6808\"\"\"\n        self._stack.append(item)\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack.pop()\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack[-1]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        return self._stack\n
    array_stack.cpp
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  private:\n    vector<int> stack;\n\n  public:\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return stack.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        stack.push_back(num);\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        stack.pop_back();\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stack.back();\n    }\n\n    /* \u8fd4\u56de Vector */\n    vector<int> toVector() {\n        return stack;\n    }\n};\n
    array_stack.java
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private ArrayList<Integer> stack;\n\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = new ArrayList<>();\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        stack.add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.remove(size() - 1);\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.get(size() - 1);\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public Object[] toArray() {\n        return stack.toArray();\n    }\n}\n
    array_stack.cs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    List<int> stack;\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stack.Count;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        stack.Add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        if (IsEmpty())\n            throw new Exception();\n        var val = Peek();\n        stack.RemoveAt(Size() - 1);\n        return val;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stack[Size() - 1];\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        return [.. stack];\n    }\n}\n
    array_stack.go
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntype arrayStack struct {\n    data []int // \u6570\u636e\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newArrayStack() *arrayStack {\n    return &arrayStack{\n        // \u8bbe\u7f6e\u6808\u7684\u957f\u5ea6\u4e3a 0\uff0c\u5bb9\u91cf\u4e3a 16\n        data: make([]int, 0, 16),\n    }\n}\n\n/* \u6808\u7684\u957f\u5ea6 */\nfunc (s *arrayStack) size() int {\n    return len(s.data)\n}\n\n/* \u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *arrayStack) isEmpty() bool {\n    return s.size() == 0\n}\n\n/* \u5165\u6808 */\nfunc (s *arrayStack) push(v int) {\n    // \u5207\u7247\u4f1a\u81ea\u52a8\u6269\u5bb9\n    s.data = append(s.data, v)\n}\n\n/* \u51fa\u6808 */\nfunc (s *arrayStack) pop() any {\n    val := s.peek()\n    s.data = s.data[:len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6\u6808\u9876\u5143\u7d20 */\nfunc (s *arrayStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    val := s.data[len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (s *arrayStack) toSlice() []int {\n    return s.data\n}\n
    array_stack.swift
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private var stack: [Int]\n\n    init() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = []\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        stack.count\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        stack.isEmpty\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        stack.append(num)\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.removeLast()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.last!\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        stack\n    }\n}\n
    array_stack.js
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    #stack;\n    constructor() {\n        this.#stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        this.#stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack[this.#stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.#stack;\n    }\n}\n
    array_stack.ts
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private stack: number[];\n    constructor() {\n        this.stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        this.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack[this.stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.stack;\n    }\n}\n
    array_stack.dart
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  late List<int> _stack;\n  ArrayStack() {\n    _stack = [];\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stack.length;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stack.isEmpty;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    _stack.add(_num);\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.removeLast();\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.last;\n  }\n\n  /* \u5c06\u6808\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() => _stack;\n}\n
    array_stack.rs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nstruct ArrayStack<T> {\n    stack: Vec<T>,\n}\n\nimpl<T> ArrayStack<T> {\n    /* \u521d\u59cb\u5316\u6808 */\n    fn new() -> ArrayStack<T> {\n        ArrayStack::<T> {\n            stack: Vec::<T>::new(),\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fn size(&self) -> usize {\n        self.stack.len()\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fn push(&mut self, num: T) {\n        self.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    fn pop(&mut self) -> Option<T> {\n        self.stack.pop()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fn peek(&self) -> Option<&T> {\n        if self.is_empty() {\n            panic!(\"\u6808\u4e3a\u7a7a\")\n        };\n        self.stack.last()\n    }\n\n    /* \u8fd4\u56de &Vec */\n    fn to_array(&self) -> &Vec<T> {\n        &self.stack\n    }\n}\n
    array_stack.c
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    int *data;\n    int size;\n} ArrayStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayStack *newArrayStack() {\n    ArrayStack *stack = malloc(sizeof(ArrayStack));\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5927\u5bb9\u91cf\uff0c\u907f\u514d\u6269\u5bb9\n    stack->data = malloc(sizeof(int) * MAX_SIZE);\n    stack->size = 0;\n    return stack;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayStack(ArrayStack *stack) {\n    free(stack->data);\n    free(stack);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(ArrayStack *stack) {\n    return stack->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(ArrayStack *stack) {\n    return stack->size == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(ArrayStack *stack, int num) {\n    if (stack->size == MAX_SIZE) {\n        printf(\"\u6808\u5df2\u6ee1\\n\");\n        return;\n    }\n    stack->data[stack->size] = num;\n    stack->size++;\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(ArrayStack *stack) {\n    if (stack->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return stack->data[stack->size - 1];\n}\n\n/* \u51fa\u6808 */\nint pop(ArrayStack *stack) {\n    int val = peek(stack);\n    stack->size--;\n    return val;\n}\n
    array_stack.kt
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n    private val stack = mutableListOf<Int>()\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stack.size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        stack.add(num)\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack.removeAt(size() - 1)\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack[size() - 1]\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): Array<Any> {\n        return stack.toTypedArray()\n    }\n}\n
    array_stack.rb
    ### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 ###\nclass ArrayStack\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @stack = []\n  end\n\n  ### \u83b7\u53d6\u6808\u7684\u957f\u5ea6 ###\n  def size\n    @stack.length\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @stack.empty?\n  end\n\n  ### \u5165\u6808 ###\n  def push(item)\n    @stack << item\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.pop\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.last\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    @stack\n  end\nend\n
    array_stack.zig
    // \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\nfn ArrayStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack: ?std.ArrayList(T) = null,     \n\n        // \u6784\u9020\u65b9\u6cd5\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) void {\n            if (self.stack == null) {\n                self.stack = std.ArrayList(T).init(allocator);\n            }\n        }\n\n        // \u6790\u6784\u65b9\u6cd5\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.stack == null) return;\n            self.stack.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stack.?.items.len;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack.?.items[self.size() - 1];\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            try self.stack.?.append(num);\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.stack.?.pop();\n            return num;\n        } \n\n        // \u8fd4\u56de ArrayList\n        pub fn toList(self: *Self) std.ArrayList(T) {\n            return self.stack.?;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/stack/#513-comparison-of-the-two-implementations","title":"5.1.3 \u00a0 Comparison of the two implementations","text":"

    Supported Operations

    Both implementations support all the operations defined in a stack. The array implementation additionally supports random access, but this is beyond the scope of a stack definition and is generally not used.

    Time Efficiency

    In the array-based implementation, both push and pop operations occur in pre-allocated contiguous memory, which has good cache locality and therefore higher efficiency. However, if the push operation exceeds the array capacity, it triggers a resizing mechanism, making the time complexity of that push operation \\(O(n)\\).

    In the linked list implementation, list expansion is very flexible, and there is no efficiency decrease issue as in array expansion. However, the push operation requires initializing a node object and modifying pointers, so its efficiency is relatively lower. If the elements being pushed are already node objects, then the initialization step can be skipped, improving efficiency.

    Thus, when the elements for push and pop operations are basic data types like int or double, we can draw the following conclusions:

    • The array-based stack implementation's efficiency decreases during expansion, but since expansion is a low-frequency operation, its average efficiency is higher.
    • The linked list-based stack implementation provides more stable efficiency performance.

    Space Efficiency

    When initializing a list, the system allocates an \"initial capacity,\" which might exceed the actual need; moreover, the expansion mechanism usually increases capacity by a specific factor (like doubling), which may also exceed the actual need. Therefore, the array-based stack might waste some space.

    However, since linked list nodes require extra space for storing pointers, the space occupied by linked list nodes is relatively larger.

    In summary, we cannot simply determine which implementation is more memory-efficient. It requires analysis based on specific circumstances.

    "},{"location":"chapter_stack_and_queue/stack/#514-typical-applications-of-stack","title":"5.1.4 \u00a0 Typical applications of stack","text":"
    • Back and forward in browsers, undo and redo in software. Every time we open a new webpage, the browser pushes the previous page onto the stack, allowing us to go back to the previous page through the back operation, which is essentially a pop operation. To support both back and forward, two stacks are needed to work together.
    • Memory management in programs. Each time a function is called, the system adds a stack frame at the top of the stack to record the function's context information. In recursive functions, the downward recursion phase keeps pushing onto the stack, while the upward backtracking phase keeps popping from the stack.
    "},{"location":"chapter_stack_and_queue/summary/","title":"5.4 \u00a0 Summary","text":""},{"location":"chapter_stack_and_queue/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Stack is a data structure that follows the Last-In-First-Out (LIFO) principle and can be implemented using arrays or linked lists.
    • In terms of time efficiency, the array implementation of the stack has a higher average efficiency. However, during expansion, the time complexity for a single push operation can degrade to \\(O(n)\\). In contrast, the linked list implementation of a stack offers more stable efficiency.
    • Regarding space efficiency, the array implementation of the stack may lead to a certain degree of space wastage. However, it's important to note that the memory space occupied by nodes in a linked list is generally larger than that for elements in an array.
    • A queue is a data structure that follows the First-In-First-Out (FIFO) principle, and it can also be implemented using arrays or linked lists. The conclusions regarding time and space efficiency for queues are similar to those for stacks.
    • A double-ended queue (deque) is a more flexible type of queue that allows adding and removing elements at both ends.
    "},{"location":"chapter_stack_and_queue/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is the browser's forward and backward functionality implemented with a doubly linked list?

    A browser's forward and backward navigation is essentially a manifestation of the \"stack\" concept. When a user visits a new page, the page is added to the top of the stack; when they click the back button, the page is popped from the top of the stack. A double-ended queue (deque) can conveniently implement some additional operations, as mentioned in the \"Double-Ended Queue\" section.

    Q: After popping from a stack, is it necessary to free the memory of the popped node?

    If the popped node will still be used later, it's not necessary to free its memory. In languages like Java and Python that have automatic garbage collection, manual memory release is not necessary; in C and C++, manual memory release is required.

    Q: A double-ended queue seems like two stacks joined together. What are its uses?

    A double-ended queue, which is a combination of a stack and a queue or two stacks joined together, exhibits both stack and queue logic. Thus, it can implement all applications of stacks and queues while offering more flexibility.

    Q: How exactly are undo and redo implemented?

    Undo and redo operations are implemented using two stacks: Stack A for undo and Stack B for redo.

    1. Each time a user performs an operation, it is pushed onto Stack A, and Stack B is cleared.
    2. When the user executes an \"undo\", the most recent operation is popped from Stack A and pushed onto Stack B.
    3. When the user executes a \"redo\", the most recent operation is popped from Stack B and pushed back onto Stack A.
    "},{"location":"chapter_tree/","title":"Chapter 7. \u00a0 Tree","text":"

    Abstract

    The towering tree, vibrant with it's deep roots and lush leaves, branches spreading wide.

    It vividly illustrates the concept of divide-and-conquer in data.

    "},{"location":"chapter_tree/#chapter-contents","title":"Chapter contents","text":"
    • 7.1 \u00a0 Binary tree
    • 7.2 \u00a0 Binary tree Traversal
    • 7.3 \u00a0 Array Representation of tree
    • 7.4 \u00a0 Binary Search tree
    • 7.5 \u00a0 AVL tree *
    • 7.6 \u00a0 Summary
    "},{"location":"chapter_tree/array_representation_of_tree/","title":"7.3 \u00a0 Array representation of binary trees","text":"

    Under the linked list representation, the storage unit of a binary tree is a node TreeNode, with nodes connected by pointers. The basic operations of binary trees under the linked list representation were introduced in the previous section.

    So, can we use an array to represent a binary tree? The answer is yes.

    "},{"location":"chapter_tree/array_representation_of_tree/#731-representing-perfect-binary-trees","title":"7.3.1 \u00a0 Representing perfect binary trees","text":"

    Let's analyze a simple case first. Given a perfect binary tree, we store all nodes in an array according to the order of level-order traversal, where each node corresponds to a unique array index.

    Based on the characteristics of level-order traversal, we can deduce a \"mapping formula\" between the index of a parent node and its children: If a node's index is \\(i\\), then the index of its left child is \\(2i + 1\\) and the right child is \\(2i + 2\\). The Figure 7-12 shows the mapping relationship between the indices of various nodes.

    Figure 7-12 \u00a0 Array representation of a perfect binary tree

    The mapping formula plays a role similar to the node references (pointers) in linked lists. Given any node in the array, we can access its left (right) child node using the mapping formula.

    "},{"location":"chapter_tree/array_representation_of_tree/#732-representing-any-binary-tree","title":"7.3.2 \u00a0 Representing any binary tree","text":"

    Perfect binary trees are a special case; there are often many None values in the middle levels of a binary tree. Since the sequence of level-order traversal does not include these None values, we cannot solely rely on this sequence to deduce the number and distribution of None values. This means that multiple binary tree structures can match the same level-order traversal sequence.

    As shown in the Figure 7-13 , given a non-perfect binary tree, the above method of array representation fails.

    Figure 7-13 \u00a0 Level-order traversal sequence corresponds to multiple binary tree possibilities

    To solve this problem, we can consider explicitly writing out all None values in the level-order traversal sequence. As shown in the following figure, after this treatment, the level-order traversal sequence can uniquely represent a binary tree. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # Array representation of a binary tree\n# Using None to represent empty slots\ntree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]\n
    /* Array representation of a binary tree */\n// Using the maximum integer value INT_MAX to mark empty slots\nvector<int> tree = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* Array representation of a binary tree */\n// Using the Integer wrapper class allows for using null to mark empty slots\nInteger[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };\n
    /* Array representation of a binary tree */\n// Using nullable int (int?) allows for using null to mark empty slots\nint?[] tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using an any type slice, allowing for nil to mark empty slots\ntree := []any{1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15}\n
    /* Array representation of a binary tree */\n// Using optional Int (Int?) allows for using nil to mark empty slots\nlet tree: [Int?] = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]\n
    /* Array representation of a binary tree */\n// Using null to represent empty slots\nlet tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using null to represent empty slots\nlet tree: (number | null)[] = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using nullable int (int?) allows for using null to mark empty slots\nList<int?> tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using None to mark empty slots\nlet tree = [Some(1), Some(2), Some(3), Some(4), None, Some(6), Some(7), Some(8), Some(9), None, None, Some(12), None, None, Some(15)];\n
    /* Array representation of a binary tree */\n// Using the maximum int value to mark empty slots, therefore, node values must not be INT_MAX\nint tree[] = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* Array representation of a binary tree */\n// Using null to represent empty slots\nval tree = mutableListOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )\n
    \n
    \n

    Figure 7-14 \u00a0 Array representation of any type of binary tree

    It's worth noting that complete binary trees are very suitable for array representation. Recalling the definition of a complete binary tree, None appears only at the bottom level and towards the right, meaning all None values definitely appear at the end of the level-order traversal sequence.

    This means that when using an array to represent a complete binary tree, it's possible to omit storing all None values, which is very convenient. The Figure 7-15 gives an example.

    Figure 7-15 \u00a0 Array representation of a complete binary tree

    The following code implements a binary tree based on array representation, including the following operations:

    • Given a node, obtain its value, left (right) child node, and parent node.
    • Obtain the preorder, inorder, postorder, and level-order traversal sequences.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_binary_tree.py
    class ArrayBinaryTree:\n    \"\"\"\u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b\"\"\"\n\n    def __init__(self, arr: list[int | None]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._tree = list(arr)\n\n    def size(self):\n        \"\"\"\u5217\u8868\u5bb9\u91cf\"\"\"\n        return len(self._tree)\n\n    def val(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c\"\"\"\n        # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 or i >= self.size():\n            return None\n        return self._tree[i]\n\n    def left(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 1\n\n    def right(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 2\n\n    def parent(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return (i - 1) // 2\n\n    def level_order(self) -> list[int]:\n        \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in range(self.size()):\n            if self.val(i) is not None:\n                self.res.append(self.val(i))\n        return self.res\n\n    def dfs(self, i: int, order: str):\n        \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n        if self.val(i) is None:\n            return\n        # \u524d\u5e8f\u904d\u5386\n        if order == \"pre\":\n            self.res.append(self.val(i))\n        self.dfs(self.left(i), order)\n        # \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\":\n            self.res.append(self.val(i))\n        self.dfs(self.right(i), order)\n        # \u540e\u5e8f\u904d\u5386\n        if order == \"post\":\n            self.res.append(self.val(i))\n\n    def pre_order(self) -> list[int]:\n        \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"pre\")\n        return self.res\n\n    def in_order(self) -> list[int]:\n        \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"in\")\n        return self.res\n\n    def post_order(self) -> list[int]:\n        \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"post\")\n        return self.res\n
    array_binary_tree.cpp
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayBinaryTree(vector<int> arr) {\n        tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    int val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return INT_MAX;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    int parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    vector<int> levelOrder() {\n        vector<int> res;\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != INT_MAX)\n                res.push_back(val(i));\n        }\n        return res;\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    vector<int> preOrder() {\n        vector<int> res;\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    vector<int> inOrder() {\n        vector<int> res;\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    vector<int> postOrder() {\n        vector<int> res;\n        dfs(0, \"post\", res);\n        return res;\n    }\n\n  private:\n    vector<int> tree;\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void dfs(int i, string order, vector<int> &res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == INT_MAX)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.push_back(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.push_back(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.push_back(val(i));\n    }\n};\n
    array_binary_tree.java
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private List<Integer> tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayBinaryTree(List<Integer> arr) {\n        tree = new ArrayList<>(arr);\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public Integer val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return null;\n        return tree.get(i);\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<Integer> levelOrder() {\n        List<Integer> res = new ArrayList<>();\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != null)\n                res.add(val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private void dfs(Integer i, String order, List<Integer> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == null)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\".equals(order))\n            res.add(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\".equals(order))\n            res.add(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\".equals(order))\n            res.add(val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<Integer> preOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<Integer> inOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<Integer> postOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.cs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(List<int?> arr) {\n    List<int?> tree = new(arr);\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int Size() {\n        return tree.Count;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public int? Val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= Size())\n            return null;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<int> LevelOrder() {\n        List<int> res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < Size(); i++) {\n            if (Val(i).HasValue)\n                res.Add(Val(i)!.Value);\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void DFS(int i, string order, List<int> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (!Val(i).HasValue)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.Add(Val(i)!.Value);\n        DFS(Left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.Add(Val(i)!.Value);\n        DFS(Right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.Add(Val(i)!.Value);\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<int> PreOrder() {\n        List<int> res = [];\n        DFS(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<int> InOrder() {\n        List<int> res = [];\n        DFS(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<int> PostOrder() {\n        List<int> res = [];\n        DFS(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.go
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\ntype arrayBinaryTree struct {\n    tree []any\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newArrayBinaryTree(arr []any) *arrayBinaryTree {\n    return &arrayBinaryTree{\n        tree: arr,\n    }\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nfunc (abt *arrayBinaryTree) size() int {\n    return len(abt.tree)\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nfunc (abt *arrayBinaryTree) val(i int) any {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if i < 0 || i >= abt.size() {\n        return nil\n    }\n    return abt.tree[i]\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) parent(i int) int {\n    return (i - 1) / 2\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) levelOrder() []any {\n    var res []any\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i := 0; i < abt.size(); i++ {\n        if abt.val(i) != nil {\n            res = append(res, abt.val(i))\n        }\n    }\n    return res\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nfunc (abt *arrayBinaryTree) dfs(i int, order string, res *[]any) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if abt.val(i) == nil {\n        return\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if order == \"pre\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.left(i), order, res)\n    // \u4e2d\u5e8f\u904d\u5386\n    if order == \"in\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.right(i), order, res)\n    // \u540e\u5e8f\u904d\u5386\n    if order == \"post\" {\n        *res = append(*res, abt.val(i))\n    }\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) preOrder() []any {\n    var res []any\n    abt.dfs(0, \"pre\", &res)\n    return res\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) inOrder() []any {\n    var res []any\n    abt.dfs(0, \"in\", &res)\n    return res\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) postOrder() []any {\n    var res []any\n    abt.dfs(0, \"post\", &res)\n    return res\n}\n
    array_binary_tree.swift
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private var tree: [Int?]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(arr: [Int?]) {\n        tree = arr\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    func size() -> Int {\n        tree.count\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    func val(i: Int) -> Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= size() {\n            return nil\n        }\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func left(i: Int) -> Int {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func right(i: Int) -> Int {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    func parent(i: Int) -> Int {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    func levelOrder() -> [Int] {\n        var res: [Int] = []\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0 ..< size() {\n            if let val = val(i: i) {\n                res.append(val)\n            }\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private func dfs(i: Int, order: String, res: inout [Int]) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        guard let val = val(i: i) else {\n            return\n        }\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.append(val)\n        }\n        dfs(i: left(i: i), order: order, res: &res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.append(val)\n        }\n        dfs(i: right(i: i), order: order, res: &res)\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.append(val)\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    func preOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"pre\", res: &res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    func inOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"in\", res: &res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    func postOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"post\", res: &res)\n        return res\n    }\n}\n
    array_binary_tree.js
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size() {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i) {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder() {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i, order, res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder() {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder() {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder() {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.ts
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree: (number | null)[];\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr: (number | null)[]) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size(): number {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i: number): number | null {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i: number): number {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i: number): number {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i: number): number {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder(): number[] {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i: number, order: Order, res: (number | null)[]): void {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.dart
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  late List<int?> _tree;\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayBinaryTree(this._tree);\n\n  /* \u5217\u8868\u5bb9\u91cf */\n  int size() {\n    return _tree.length;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n  int? val(int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size()) {\n      return null;\n    }\n    return _tree[i];\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? left(int i) {\n    return 2 * i + 1;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? right(int i) {\n    return 2 * i + 2;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? parent(int i) {\n    return (i - 1) ~/ 2;\n  }\n\n  /* \u5c42\u5e8f\u904d\u5386 */\n  List<int> levelOrder() {\n    List<int> res = [];\n    for (int i = 0; i < size(); i++) {\n      if (val(i) != null) {\n        res.add(val(i)!);\n      }\n    }\n    return res;\n  }\n\n  /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n  void dfs(int i, String order, List<int?> res) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(i) == null) {\n      return;\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if (order == 'pre') {\n      res.add(val(i));\n    }\n    dfs(left(i)!, order, res);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (order == 'in') {\n      res.add(val(i));\n    }\n    dfs(right(i)!, order, res);\n    // \u540e\u5e8f\u904d\u5386\n    if (order == 'post') {\n      res.add(val(i));\n    }\n  }\n\n  /* \u524d\u5e8f\u904d\u5386 */\n  List<int?> preOrder() {\n    List<int?> res = [];\n    dfs(0, 'pre', res);\n    return res;\n  }\n\n  /* \u4e2d\u5e8f\u904d\u5386 */\n  List<int?> inOrder() {\n    List<int?> res = [];\n    dfs(0, 'in', res);\n    return res;\n  }\n\n  /* \u540e\u5e8f\u904d\u5386 */\n  List<int?> postOrder() {\n    List<int?> res = [];\n    dfs(0, 'post', res);\n    return res;\n  }\n}\n
    array_binary_tree.rs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nstruct ArrayBinaryTree {\n    tree: Vec<Option<i32>>,\n}\n\nimpl ArrayBinaryTree {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(arr: Vec<Option<i32>>) -> Self {\n        Self { tree: arr }\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    fn size(&self) -> i32 {\n        self.tree.len() as i32\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fn val(&self, i: i32) -> Option<i32> {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= self.size() {\n            None\n        } else {\n            self.tree[i as usize]\n        }\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn left(&self, i: i32) -> i32 {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn right(&self, i: i32) -> i32 {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn parent(&self, i: i32) -> i32 {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fn level_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0..self.size() {\n            if let Some(val) = self.val(i) {\n                res.push(val)\n            }\n        }\n        res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fn dfs(&self, i: i32, order: &str, res: &mut Vec<i32>) {\n        if self.val(i).is_none() {\n            return;\n        }\n        let val = self.val(i).unwrap();\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.push(val);\n        }\n        self.dfs(self.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.push(val);\n        }\n        self.dfs(self.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.push(val);\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fn pre_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"pre\", &mut res);\n        res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fn in_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"in\", &mut res);\n        res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fn post_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"post\", &mut res);\n        res\n    }\n}\n
    array_binary_tree.c
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int *tree;\n    int size;\n} ArrayBinaryTree;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayBinaryTree *newArrayBinaryTree(int *arr, int arrSize) {\n    ArrayBinaryTree *abt = (ArrayBinaryTree *)malloc(sizeof(ArrayBinaryTree));\n    abt->tree = malloc(sizeof(int) * arrSize);\n    memcpy(abt->tree, arr, sizeof(int) * arrSize);\n    abt->size = arrSize;\n    return abt;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayBinaryTree(ArrayBinaryTree *abt) {\n    free(abt->tree);\n    free(abt);\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nint size(ArrayBinaryTree *abt) {\n    return abt->size;\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nint val(ArrayBinaryTree *abt, int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size(abt))\n        return INT_MAX;\n    return abt->tree[i];\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size(abt); i++) {\n        if (val(abt, i) != INT_MAX)\n            res[index++] = val(abt, i);\n    }\n    *returnSize = index;\n    return res;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nvoid dfs(ArrayBinaryTree *abt, int i, char *order, int *res, int *index) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(abt, i) == INT_MAX)\n        return;\n    // \u524d\u5e8f\u904d\u5386\n    if (strcmp(order, \"pre\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, left(i), order, res, index);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (strcmp(order, \"in\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, right(i), order, res, index);\n    // \u540e\u5e8f\u904d\u5386\n    if (strcmp(order, \"post\") == 0)\n        res[(*index)++] = val(abt, i);\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nint *preOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"pre\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nint *inOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"in\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nint *postOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"post\", res, &index);\n    *returnSize = index;\n    return res;\n}\n
    array_binary_tree.kt
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(val tree: MutableList<Int?>) {\n    /* \u5217\u8868\u5bb9\u91cf */\n    fun size(): Int {\n        return tree.size\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fun _val(i: Int): Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size()) return null\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun parent(i: Int): Int {\n        return (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fun levelOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (i in 0..<size()) {\n            if (_val(i) != null)\n                res.add(_val(i))\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fun dfs(i: Int, order: String, res: MutableList<Int?>) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (_val(i) == null)\n            return\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\" == order)\n            res.add(_val(i))\n        dfs(left(i), order, res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\" == order)\n            res.add(_val(i))\n        dfs(right(i), order, res)\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\" == order)\n            res.add(_val(i))\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fun preOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"pre\", res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fun inOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"in\", res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fun postOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"post\", res)\n        return res\n    }\n}\n
    array_binary_tree.rb
    ### \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b ###\nclass ArrayBinaryTree\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(arr)\n    @tree = arr.to_a\n  end\n\n  ### \u5217\u8868\u5bb9\u91cf ###\n  def size\n    @tree.length\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c ###\n  def val(i)\n    # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de nil \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    return if i < 0 || i >= size\n\n    @tree[i]\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def left(i)\n    2 * i + 1\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def right(i)\n    2 * i + 2\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def parent(i)\n    (i - 1) / 2\n  end\n\n  ### \u5c42\u5e8f\u904d\u5386 ###\n  def level_order\n    @res = []\n\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i in 0...size\n      @res << val(i) unless val(i).nil?\n    end\n\n    @res\n  end\n\n  ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\n  def dfs(i, order)\n    return if val(i).nil?\n    # \u524d\u5e8f\u904d\u5386\n    @res << val(i) if order == :pre\n    dfs(left(i), order)\n    # \u4e2d\u5e8f\u904d\u5386\n    @res << val(i) if order == :in\n    dfs(right(i), order)\n    # \u540e\u5e8f\u904d\u5386\n    @res << val(i) if order == :post\n  end\n\n  ### \u524d\u5e8f\u904d\u5386 ###\n  def pre_order\n    @res = []\n    dfs(0, :pre)\n    @res\n  end\n\n  ### \u4e2d\u5e8f\u904d\u5386 ###\n  def in_order\n    @res = []\n    dfs(0, :in)\n    @res\n  end\n\n  ### \u540e\u5e8f\u904d\u5386 ###\n  def post_order\n    @res = []\n    dfs(0, :post)\n    @res\n  end\nend\n
    array_binary_tree.zig
    [class]{ArrayBinaryTree}-[func]{}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/array_representation_of_tree/#733-advantages-and-limitations","title":"7.3.3 \u00a0 Advantages and limitations","text":"

    The array representation of binary trees has the following advantages:

    • Arrays are stored in contiguous memory spaces, which is cache-friendly and allows for faster access and traversal.
    • It does not require storing pointers, which saves space.
    • It allows random access to nodes.

    However, the array representation also has some limitations:

    • Array storage requires contiguous memory space, so it is not suitable for storing trees with a large amount of data.
    • Adding or deleting nodes requires array insertion and deletion operations, which are less efficient.
    • When there are many None values in the binary tree, the proportion of node data contained in the array is low, leading to lower space utilization.
    "},{"location":"chapter_tree/avl_tree/","title":"7.5 \u00a0 AVL tree *","text":"

    In the \"Binary Search Tree\" section, we mentioned that after multiple insertions and removals, a binary search tree might degrade to a linked list. In such cases, the time complexity of all operations degrades from \\(O(\\log n)\\) to \\(O(n)\\).

    As shown in the Figure 7-24 , after two node removal operations, this binary search tree will degrade into a linked list.

    Figure 7-24 \u00a0 Degradation of an AVL tree after removing nodes

    For example, in the perfect binary tree shown in the Figure 7-25 , after inserting two nodes, the tree will lean heavily to the left, and the time complexity of search operations will also degrade.

    Figure 7-25 \u00a0 Degradation of an AVL tree after inserting nodes

    In 1962, G. M. Adelson-Velsky and E. M. Landis proposed the \"AVL Tree\" in their paper \"An algorithm for the organization of information\". The paper detailed a series of operations to ensure that after continuously adding and removing nodes, the AVL tree would not degrade, thus maintaining the time complexity of various operations at \\(O(\\log n)\\) level. In other words, in scenarios where frequent additions, removals, searches, and modifications are needed, the AVL tree can always maintain efficient data operation performance, which has great application value.

    "},{"location":"chapter_tree/avl_tree/#751-common-terminology-in-avl-trees","title":"7.5.1 \u00a0 Common terminology in AVL trees","text":"

    An AVL tree is both a binary search tree and a balanced binary tree, satisfying all properties of these two types of binary trees, hence it is a \"balanced binary search tree\".

    "},{"location":"chapter_tree/avl_tree/#1-node-height","title":"1. \u00a0 Node height","text":"

    Since the operations related to AVL trees require obtaining node heights, we need to add a height variable to the node class:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"AVL tree node\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                 # Node value\n        self.height: int = 0                # Node height\n        self.left: TreeNode | None = None   # Left child reference\n        self.right: TreeNode | None = None  # Right child reference\n
    /* AVL tree node */\nstruct TreeNode {\n    int val{};          // Node value\n    int height = 0;     // Node height\n    TreeNode *left{};   // Left child\n    TreeNode *right{};  // Right child\n    TreeNode() = default;\n    explicit TreeNode(int x) : val(x){}\n};\n
    /* AVL tree node */\nclass TreeNode {\n    public int val;        // Node value\n    public int height;     // Node height\n    public TreeNode left;  // Left child\n    public TreeNode right; // Right child\n    public TreeNode(int x) { val = x; }\n}\n
    /* AVL tree node */\nclass TreeNode(int? x) {\n    public int? val = x;    // Node value\n    public int height;      // Node height\n    public TreeNode? left;  // Left child reference\n    public TreeNode? right; // Right child reference\n}\n
    /* AVL tree node */\ntype TreeNode struct {\n    Val    int       // Node value\n    Height int       // Node height\n    Left   *TreeNode // Left child reference\n    Right  *TreeNode // Right child reference\n}\n
    /* AVL tree node */\nclass TreeNode {\n    var val: Int // Node value\n    var height: Int // Node height\n    var left: TreeNode? // Left child\n    var right: TreeNode? // Right child\n\n    init(x: Int) {\n        val = x\n        height = 0\n    }\n}\n
    /* AVL tree node */\nclass TreeNode {\n    val; // Node value\n    height; // Node height\n    left; // Left child pointer\n    right; // Right child pointer\n    constructor(val, left, right, height) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* AVL tree node */\nclass TreeNode {\n    val: number;            // Node value\n    height: number;         // Node height\n    left: TreeNode | null;  // Left child pointer\n    right: TreeNode | null; // Right child pointer\n    constructor(val?: number, height?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height; \n        this.left = left === undefined ? null : left; \n        this.right = right === undefined ? null : right; \n    }\n}\n
    /* AVL tree node */\nclass TreeNode {\n  int val;         // Node value\n  int height;      // Node height\n  TreeNode? left;  // Left child\n  TreeNode? right; // Right child\n  TreeNode(this.val, [this.height = 0, this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* AVL tree node */\nstruct TreeNode {\n    val: i32,                               // Node value\n    height: i32,                            // Node height\n    left: Option<Rc<RefCell<TreeNode>>>,    // Left child\n    right: Option<Rc<RefCell<TreeNode>>>,   // Right child\n}\n\nimpl TreeNode {\n    /* Constructor */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            height: 0,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* AVL tree node */\nTreeNode struct TreeNode {\n    int val;\n    int height;\n    struct TreeNode *left;\n    struct TreeNode *right;\n} TreeNode;\n\n/* Constructor */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* AVL tree node */\nclass TreeNode(val _val: Int) {  // Node value\n    val height: Int = 0          // Node height\n    val left: TreeNode? = null   // Left child\n    val right: TreeNode? = null  // Right child\n}\n
    \n
    \n

    The \"node height\" refers to the distance from that node to its farthest leaf node, i.e., the number of \"edges\" passed. It is important to note that the height of a leaf node is \\(0\\), and the height of a null node is \\(-1\\). We will create two utility functions for getting and updating the height of a node:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def height(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node is not None:\n        return node.height\n    return -1\n\ndef update_height(self, node: TreeNode | None):\n    \"\"\"\u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = max([self.height(node.left), self.height(node.right)]) + 1\n
    avl_tree.cpp
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == nullptr ? -1 : node->height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node->height = max(height(node->left), height(node->right)) + 1;\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint Height(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid UpdateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.Max(Height(node.left), Height(node.right)) + 1;\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) height(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node != nil {\n        return node.Height\n    }\n    return -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) updateHeight(node *TreeNode) {\n    lh := t.height(node.Left)\n    rh := t.height(node.Right)\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if lh > rh {\n        node.Height = lh + 1\n    } else {\n        node.Height = rh + 1\n    }\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc height(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    node?.height ?? -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node: node?.left), height(node: node?.right)) + 1\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\n#updateHeight(node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nupdateHeight(node: TreeNode): void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode? node) {\n  // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node!.height = max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfn height(node: OptionTreeNodeRc) -> i32 {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    match node {\n        Some(node) => node.borrow().height,\n        None => -1,\n    }\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfn update_height(node: OptionTreeNodeRc) {\n    if let Some(node) = node {\n        let left = node.borrow().left.clone();\n        let right = node.borrow().right.clone();\n        // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n        node.borrow_mut().height = std::cmp::max(Self::height(left), Self::height(right)) + 1;\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if (node != NULL) {\n        return node->height;\n    }\n    return -1;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    int lh = height(node->left);\n    int rh = height(node->right);\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if (lh > rh) {\n        node->height = lh + 1;\n    } else {\n        node->height = rh + 1;\n    }\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfun height(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node?.height ?: -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfun updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node?.left), height(node?.right)) + 1\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 ###\ndef height(node)\n  # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node.height unless node.nil?\n\n  -1\nend\n\n### \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 ###\ndef update_height(node)\n  # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node.height = [height(node.left), height(node.right)].max + 1\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\nfn height(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    _ = self;\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return if (node == null) -1 else node.?.height;\n}\n\n// \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\nfn updateHeight(self: *Self, node: ?*inc.TreeNode(T)) void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.?.height = @max(self.height(node.?.left), self.height(node.?.right)) + 1;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2-node-balance-factor","title":"2. \u00a0 Node balance factor","text":"

    The \"balance factor\" of a node is defined as the height of the node's left subtree minus the height of its right subtree, with the balance factor of a null node defined as \\(0\\). We will also encapsulate the functionality of obtaining the node balance factor into a function for easy use later on:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def balance_factor(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u5e73\u8861\u56e0\u5b50\"\"\"\n    # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node is None:\n        return 0\n    # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.left) - self.height(node.right)\n
    avl_tree.cpp
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == nullptr)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right);\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint BalanceFactor(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return Height(node.left) - Height(node.right);\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc (t *aVLTree) balanceFactor(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node == nil {\n        return 0\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return t.height(node.Left) - t.height(node.Right)\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc balanceFactor(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    guard let node = node else { return 0 }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node: node.left) - height(node: node.right)\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  if (node == null) return 0;\n  // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  return height(node.left) - height(node.right);\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfn balance_factor(node: OptionTreeNodeRc) -> i32 {\n    match node {\n        // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n        None => 0,\n        // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n        Some(node) => {\n            Self::height(node.borrow().left.clone()) - Self::height(node.borrow().right.clone())\n        }\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == NULL) {\n        return 0;\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfun balanceFactor(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right)\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 ###\ndef balance_factor(node)\n  # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  return 0 if node.nil?\n\n  # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  height(node.left) - height(node.right)\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u5e73\u8861\u56e0\u5b50\nfn balanceFactor(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.?.left) - self.height(node.?.right);\n}\n

    Tip

    Let the balance factor be \\(f\\), then the balance factor of any node in an AVL tree satisfies \\(-1 \\le f \\le 1\\).

    "},{"location":"chapter_tree/avl_tree/#752-rotations-in-avl-trees","title":"7.5.2 \u00a0 Rotations in AVL trees","text":"

    The characteristic feature of an AVL tree is the \"rotation\" operation, which can restore balance to an unbalanced node without affecting the in-order traversal sequence of the binary tree. In other words, the rotation operation can maintain the property of a \"binary search tree\" while also turning the tree back into a \"balanced binary tree\".

    We call nodes with an absolute balance factor \\(> 1\\) \"unbalanced nodes\". Depending on the type of imbalance, there are four kinds of rotations: right rotation, left rotation, right-left rotation, and left-right rotation. Below, we detail these rotation operations.

    "},{"location":"chapter_tree/avl_tree/#1-right-rotation","title":"1. \u00a0 Right rotation","text":"

    As shown in the Figure 7-26 , the first unbalanced node from the bottom up in the binary tree is \"node 3\". Focusing on the subtree with this unbalanced node as the root, denoted as node, and its left child as child, perform a \"right rotation\". After the right rotation, the subtree is balanced again while still maintaining the properties of a binary search tree.

    <1><2><3><4>

    Figure 7-26 \u00a0 Steps of right rotation

    As shown in the Figure 7-27 , when the child node has a right child (denoted as grand_child), a step needs to be added in the right rotation: set grand_child as the left child of node.

    Figure 7-27 \u00a0 Right rotation with grand_child

    \"Right rotation\" is a figurative term; in practice, it is achieved by modifying node pointers, as shown in the following code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def right_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u53f3\u65cb\u64cd\u4f5c\"\"\"\n    child = node.left\n    grand_child = child.right\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child = node->left;\n    TreeNode *grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode rightRotate(TreeNode node) {\n    TreeNode child = node.left;\n    TreeNode grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? RightRotate(TreeNode? node) {\n    TreeNode? child = node?.left;\n    TreeNode? grandChild = child?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) rightRotate(node *TreeNode) *TreeNode {\n    child := node.Left\n    grandChild := child.Right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.Right = node\n    node.Left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc rightRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.left\n    let grandChild = child?.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child?.right = node\n    node?.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u53f3\u65cb\u64cd\u4f5c */\n#rightRotate(node) {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u53f3\u65cb\u64cd\u4f5c */\nrightRotate(node: TreeNode): TreeNode {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? rightRotate(TreeNode? node) {\n  TreeNode? child = node!.left;\n  TreeNode? grandChild = child!.right;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node;\n  node.left = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u53f3\u65cb\u64cd\u4f5c */\nfn right_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().left.clone().unwrap();\n            let grand_child = child.borrow().right.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n            child.borrow_mut().right = Some(node.clone());\n            node.borrow_mut().left = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->left;\n    grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u53f3\u65cb\u64cd\u4f5c */\nfun rightRotate(node: TreeNode?): TreeNode {\n    val child = node!!.left\n    val grandChild = child!!.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u53f3\u65cb\u64cd\u4f5c ###\ndef right_rotate(node)\n  child = node.left\n  grand_child = child.right\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node\n  node.left = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u53f3\u65cb\u64cd\u4f5c\nfn rightRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.left;\n    var grandChild = child.?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.?.right = node;\n    node.?.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2-left-rotation","title":"2. \u00a0 Left rotation","text":"

    Correspondingly, if considering the \"mirror\" of the above unbalanced binary tree, the \"left rotation\" operation shown in the Figure 7-28 needs to be performed.

    Figure 7-28 \u00a0 Left rotation operation

    Similarly, as shown in the Figure 7-29 , when the child node has a left child (denoted as grand_child), a step needs to be added in the left rotation: set grand_child as the right child of node.

    Figure 7-29 \u00a0 Left rotation with grand_child

    It can be observed that the right and left rotation operations are logically symmetrical, and they solve two symmetrical types of imbalance. Based on symmetry, by replacing all left with right, and all right with left in the implementation code of right rotation, we can get the implementation code for left rotation:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def left_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u5de6\u65cb\u64cd\u4f5c\"\"\"\n    child = node.right\n    grand_child = child.left\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child = node->right;\n    TreeNode *grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode leftRotate(TreeNode node) {\n    TreeNode child = node.right;\n    TreeNode grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? LeftRotate(TreeNode? node) {\n    TreeNode? child = node?.right;\n    TreeNode? grandChild = child?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) leftRotate(node *TreeNode) *TreeNode {\n    child := node.Right\n    grandChild := child.Left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.Left = node\n    node.Right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc leftRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.right\n    let grandChild = child?.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child?.left = node\n    node?.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u5de6\u65cb\u64cd\u4f5c */\n#leftRotate(node) {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u5de6\u65cb\u64cd\u4f5c */\nleftRotate(node: TreeNode): TreeNode {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? leftRotate(TreeNode? node) {\n  TreeNode? child = node!.right;\n  TreeNode? grandChild = child!.left;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node;\n  node.right = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u5de6\u65cb\u64cd\u4f5c */\nfn left_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().right.clone().unwrap();\n            let grand_child = child.borrow().left.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n            child.borrow_mut().left = Some(node.clone());\n            node.borrow_mut().right = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->right;\n    grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u5de6\u65cb\u64cd\u4f5c */\nfun leftRotate(node: TreeNode?): TreeNode {\n    val child = node!!.right\n    val grandChild = child!!.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u5de6\u65cb\u64cd\u4f5c ###\ndef left_rotate(node)\n  child = node.right\n  grand_child = child.left\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node\n  node.right = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u5de6\u65cb\u64cd\u4f5c\nfn leftRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.right;\n    var grandChild = child.?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.?.left = node;\n    node.?.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3-right-left-rotation","title":"3. \u00a0 Right-left rotation","text":"

    For the unbalanced node 3 shown in the Figure 7-30 , using either left or right rotation alone cannot restore balance to the subtree. In this case, a \"left rotation\" needs to be performed on child first, followed by a \"right rotation\" on node.

    Figure 7-30 \u00a0 Right-left rotation

    "},{"location":"chapter_tree/avl_tree/#4-left-right-rotation","title":"4. \u00a0 Left-right rotation","text":"

    As shown in the Figure 7-31 , for the mirror case of the above unbalanced binary tree, a \"right rotation\" needs to be performed on child first, followed by a \"left rotation\" on node.

    Figure 7-31 \u00a0 Left-right rotation

    "},{"location":"chapter_tree/avl_tree/#5-choice-of-rotation","title":"5. \u00a0 Choice of rotation","text":"

    The four kinds of imbalances shown in the Figure 7-32 correspond to the cases described above, respectively requiring right rotation, left-right rotation, right-left rotation, and left rotation.

    Figure 7-32 \u00a0 The four rotation cases of AVL tree

    As shown in the Table 7-3 , we determine which of the above cases an unbalanced node belongs to by judging the sign of the balance factor of the unbalanced node and its higher-side child's balance factor.

    Table 7-3 \u00a0 Conditions for Choosing Among the Four Rotation Cases

    Balance factor of unbalanced node Balance factor of child node Rotation method to use \\(> 1\\) (Left-leaning tree) \\(\\geq 0\\) Right rotation \\(> 1\\) (Left-leaning tree) \\(<0\\) Left rotation then right rotation \\(< -1\\) (Right-leaning tree) \\(\\leq 0\\) Left rotation \\(< -1\\) (Right-leaning tree) \\(>0\\) Right rotation then left rotation

    For convenience, we encapsulate the rotation operations into a function. With this function, we can perform rotations on various kinds of imbalances, restoring balance to unbalanced nodes. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\"\"\"\n    # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    balance_factor = self.balance_factor(node)\n    # \u5de6\u504f\u6811\n    if balance_factor > 1:\n        if self.balance_factor(node.left) >= 0:\n            # \u53f3\u65cb\n            return self.right_rotate(node)\n        else:\n            # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = self.left_rotate(node.left)\n            return self.right_rotate(node)\n    # \u53f3\u504f\u6811\n    elif balance_factor < -1:\n        if self.balance_factor(node.right) <= 0:\n            # \u5de6\u65cb\n            return self.left_rotate(node)\n        else:\n            # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = self.right_rotate(node.right)\n            return self.left_rotate(node)\n    # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n
    avl_tree.cpp
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int _balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (_balanceFactor > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (_balanceFactor < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.java
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode rotate(TreeNode node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.cs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? Rotate(TreeNode? node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactorInt = BalanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactorInt > 1) {\n        if (BalanceFactor(node?.left) >= 0) {\n            // \u53f3\u65cb\n            return RightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node!.left = LeftRotate(node!.left);\n            return RightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactorInt < -1) {\n        if (BalanceFactor(node?.right) <= 0) {\n            // \u5de6\u65cb\n            return LeftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node!.right = RightRotate(node!.right);\n            return LeftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.go
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc (t *aVLTree) rotate(node *TreeNode) *TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    // Go \u63a8\u8350\u77ed\u53d8\u91cf\uff0c\u8fd9\u91cc bf \u6307\u4ee3 t.balanceFactor\n    bf := t.balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if bf > 1 {\n        if t.balanceFactor(node.Left) >= 0 {\n            // \u53f3\u65cb\n            return t.rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.Left = t.leftRotate(node.Left)\n            return t.rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if bf < -1 {\n        if t.balanceFactor(node.Right) <= 0 {\n            // \u5de6\u65cb\n            return t.leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.Right = t.rightRotate(node.Right)\n            return t.leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.swift
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc rotate(node: TreeNode?) -> TreeNode? {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balanceFactor = balanceFactor(node: node)\n    // \u5de6\u504f\u6811\n    if balanceFactor > 1 {\n        if self.balanceFactor(node: node?.left) >= 0 {\n            // \u53f3\u65cb\n            return rightRotate(node: node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node?.left = leftRotate(node: node?.left)\n            return rightRotate(node: node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if balanceFactor < -1 {\n        if self.balanceFactor(node: node?.right) <= 0 {\n            // \u5de6\u65cb\n            return leftRotate(node: node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node?.right = rightRotate(node: node?.right)\n            return leftRotate(node: node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.js
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n#rotate(node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.#rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.#leftRotate(node.left);\n            return this.#rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.#leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.#rightRotate(node.right);\n            return this.#leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.ts
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nrotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.leftRotate(node.left);\n            return this.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.rightRotate(node.right);\n            return this.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.dart
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? rotate(TreeNode? node) {\n  // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  int factor = balanceFactor(node);\n  // \u5de6\u504f\u6811\n  if (factor > 1) {\n    if (balanceFactor(node!.left) >= 0) {\n      // \u53f3\u65cb\n      return rightRotate(node);\n    } else {\n      // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = leftRotate(node.left);\n      return rightRotate(node);\n    }\n  }\n  // \u53f3\u504f\u6811\n  if (factor < -1) {\n    if (balanceFactor(node!.right) <= 0) {\n      // \u5de6\u65cb\n      return leftRotate(node);\n    } else {\n      // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = rightRotate(node.right);\n      return leftRotate(node);\n    }\n  }\n  // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  return node;\n}\n
    avl_tree.rs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfn rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balance_factor = Self::balance_factor(node.clone());\n    // \u5de6\u504f\u6811\n    if balance_factor > 1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().left.clone()) >= 0 {\n            // \u53f3\u65cb\n            Self::right_rotate(Some(node))\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            let left = node.borrow().left.clone();\n            node.borrow_mut().left = Self::left_rotate(left);\n            Self::right_rotate(Some(node))\n        }\n    }\n    // \u53f3\u504f\u6811\n    else if balance_factor < -1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().right.clone()) <= 0 {\n            // \u5de6\u65cb\n            Self::left_rotate(Some(node))\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            let right = node.borrow().right.clone();\n            node.borrow_mut().right = Self::right_rotate(right);\n            Self::left_rotate(Some(node))\n        }\n    } else {\n        // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n        node\n    }\n}\n
    avl_tree.c
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int bf = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (bf > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (bf < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.kt
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfun rotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    val balanceFactor = balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left)\n            return rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right)\n            return leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.rb
    ### \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 ###\ndef rotate(node)\n  # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  balance_factor = balance_factor(node)\n  # \u5de6\u904d\u6811\n  if balance_factor > 1\n    if balance_factor(node.left) >= 0\n      # \u53f3\u65cb\n      return right_rotate(node)\n    else\n      # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = left_rotate(node.left)\n      return right_rotate(node)\n    end\n  # \u53f3\u904d\u6811\n  elsif balance_factor < -1\n    if balance_factor(node.right) <= 0\n      # \u5de6\u65cb\n      return left_rotate(node)\n    else\n      # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = right_rotate(node.right)\n      return left_rotate(node)\n    end\n  end\n  # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  node\nend\n
    avl_tree.zig
    // \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\nfn rotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    var balance_factor = self.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balance_factor > 1) {\n        if (self.balanceFactor(node.?.left) >= 0) {\n            // \u53f3\u65cb\n            return self.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.?.left = self.leftRotate(node.?.left);\n            return self.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balance_factor < -1) {\n        if (self.balanceFactor(node.?.right) <= 0) {\n            // \u5de6\u65cb\n            return self.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.?.right = self.rightRotate(node.?.right);\n            return self.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#753-common-operations-in-avl-trees","title":"7.5.3 \u00a0 Common operations in AVL trees","text":""},{"location":"chapter_tree/avl_tree/#1-node-insertion","title":"1. \u00a0 Node insertion","text":"

    The node insertion operation in AVL trees is similar to that in binary search trees. The only difference is that after inserting a node in an AVL tree, a series of unbalanced nodes may appear along the path from that node to the root node. Therefore, we need to start from this node and perform rotation operations upwards to restore balance to all unbalanced nodes. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def insert(self, val):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    self._root = self.insert_helper(self._root, val)\n\ndef insert_helper(self, node: TreeNode | None, val: int) -> TreeNode:\n    \"\"\"\u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return TreeNode(val)\n    # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if val < node.val:\n        node.left = self.insert_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.insert_helper(node.right, val)\n    else:\n        # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val)\n        node->left = insertHelper(node->left, val);\n    else if (val > node->val)\n        node->right = insertHelper(node->right, val);\n    else\n        return node;    // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode insertHelper(TreeNode node, int val) {\n    if (node == null)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = insertHelper(node.right, val);\n    else\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int val) {\n    root = InsertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? InsertHelper(TreeNode? node, int val) {\n    if (node == null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = InsertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = InsertHelper(node.right, val);\n    else\n        return node;     // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (t *aVLTree) insert(val int) {\n    t.root = t.insertHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return NewTreeNode(val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node.Val.(int) {\n        node.Left = t.insertHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.insertHelper(node.Right, val)\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(val: Int) {\n    root = insertHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc insertHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return TreeNode(x: val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node!.val {\n        node?.left = insertHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = insertHelper(node: node?.right, val: val)\n    } else {\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val) {\n    this.root = this.#insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#insertHelper(node, val) {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) node.left = this.#insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#insertHelper(node.right, val);\n    else return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val: number): void {\n    this.root = this.insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\ninsertHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) {\n        node.left = this.insertHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.insertHelper(node.right, val);\n    } else {\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n  root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? insertHelper(TreeNode? node, int val) {\n  if (node == null) return TreeNode(val);\n  /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n  if (val < node.val)\n    node.left = insertHelper(node.left, val);\n  else if (val > node.val)\n    node.right = insertHelper(node.right, val);\n  else\n    return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\nfn insert(&mut self, val: i32) {\n    self.root = Self::insert_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn insert_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n            match {\n                let node_val = node.borrow().val;\n                node_val\n            }\n            .cmp(&val)\n            {\n                Ordering::Greater => {\n                    let left = node.borrow().left.clone();\n                    node.borrow_mut().left = Self::insert_helper(left, val);\n                }\n                Ordering::Less => {\n                    let right = node.borrow().right.clone();\n                    node.borrow_mut().right = Self::insert_helper(right, val);\n                }\n                Ordering::Equal => {\n                    return Some(node); // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n                }\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => Some(TreeNode::new(val)),\n    }\n}\n
    avl_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(AVLTree *tree, int val) {\n    tree->root = insertHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == NULL) {\n        return newTreeNode(val);\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val) {\n        node->left = insertHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = insertHelper(node->right, val);\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node;\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(_val: Int) {\n    root = insertHelper(root, _val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun insertHelper(n: TreeNode?, _val: Int): TreeNode {\n    if (n == null)\n        return TreeNode(_val)\n    var node = n\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (_val < node._val)\n        node.left = insertHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = insertHelper(node.right, _val)\n    else\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(val)\n  @root = insert_helper(@root, val)\nend\n\n### \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef insert_helper(node, val)\n  return TreeNode.new(val) if node.nil?\n  # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n  if val < node.val\n    node.left = insert_helper(node.left, val)\n  elsif val > node.val\n    node.right = insert_helper(node.right, val)\n  else\n    # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, val: T) !void {\n    self.root = (try self.insertHelper(self.root, val)).?;\n}\n\n// \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn insertHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) !?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) {\n        var tmp_node = try self.mem_allocator.create(inc.TreeNode(T));\n        tmp_node.init(val);\n        return tmp_node;\n    }\n    // 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if (val < node.?.val) {\n        node.?.left = try self.insertHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = try self.insertHelper(node.?.right, val);\n    } else {\n        return node;            // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    self.updateHeight(node);    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2-node-removal","title":"2. \u00a0 Node removal","text":"

    Similarly, based on the method of removing nodes in binary search trees, rotation operations need to be performed from the bottom up to restore balance to all unbalanced nodes. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def remove(self, val: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    self._root = self.remove_helper(self._root, val)\n\ndef remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None:\n    \"\"\"\u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return None\n    # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if val < node.val:\n        node.left = self.remove_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.remove_helper(node.right, val)\n    else:\n        if node.left is None or node.right is None:\n            child = node.left or node.right\n            # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child is None:\n                return None\n            # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else:\n                node = child\n        else:\n            # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp = node.right\n            while temp.left is not None:\n                temp = temp.left\n            node.right = self.remove_helper(node.right, temp.val)\n            node.val = temp.val\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return nullptr;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val)\n        node->left = removeHelper(node->left, val);\n    else if (val > node->val)\n        node->right = removeHelper(node->right, val);\n    else {\n        if (node->left == nullptr || node->right == nullptr) {\n            TreeNode *child = node->left != nullptr ? node->left : node->right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == nullptr) {\n                delete node;\n                return nullptr;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                delete node;\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != nullptr) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode removeHelper(TreeNode node, int val) {\n    if (node == null)\n        return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = removeHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode child = node.left != null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int val) {\n    root = RemoveHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? RemoveHelper(TreeNode? node, int val) {\n    if (node == null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = RemoveHelper(node.left, val);\n    else if (val > node.val)\n        node.right = RemoveHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode? child = node.left ?? node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode? temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = RemoveHelper(node.right, temp.val!.Value);\n            node.val = temp.val;\n        }\n    }\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (t *aVLTree) remove(val int) {\n    t.root = t.removeHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node.Val.(int) {\n        node.Left = t.removeHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.removeHelper(node.Right, val)\n    } else {\n        if node.Left == nil || node.Right == nil {\n            child := node.Left\n            if node.Right != nil {\n                child = node.Right\n            }\n            if child == nil {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                return nil\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp := node.Right\n            for temp.Left != nil {\n                temp = temp.Left\n            }\n            node.Right = t.removeHelper(node.Right, temp.Val.(int))\n            node.Val = temp.Val\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(val: Int) {\n    root = removeHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc removeHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node!.val {\n        node?.left = removeHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = removeHelper(node: node?.right, val: val)\n    } else {\n        if node?.left == nil || node?.right == nil {\n            let child = node?.left ?? node?.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child == nil {\n                return nil\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node?.right\n            while temp?.left != nil {\n                temp = temp?.left\n            }\n            node?.right = removeHelper(node: node?.right, val: temp!.val)\n            node?.val = temp!.val\n        }\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(val) {\n    this.root = this.#removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#removeHelper(node, val) {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) node.left = this.#removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#removeHelper(node.right, val);\n    else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.#removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(val: number): void {\n    this.root = this.removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nremoveHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) {\n        node.left = this.removeHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.removeHelper(node.right, val);\n    } else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) {\n                return null;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n  root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? removeHelper(TreeNode? node, int val) {\n  if (node == null) return null;\n  /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n  if (val < node.val)\n    node.left = removeHelper(node.left, val);\n  else if (val > node.val)\n    node.right = removeHelper(node.right, val);\n  else {\n    if (node.left == null || node.right == null) {\n      TreeNode? child = node.left ?? node.right;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      if (child == null)\n        return null;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      else\n        node = child;\n    } else {\n      // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      TreeNode? temp = node.right;\n      while (temp!.left != null) {\n        temp = temp.left;\n      }\n      node.right = removeHelper(node.right, temp.val);\n      node.val = temp.val;\n    }\n  }\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\nfn remove(&self, val: i32) {\n    Self::remove_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn remove_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n            if val < node.borrow().val {\n                let left = node.borrow().left.clone();\n                node.borrow_mut().left = Self::remove_helper(left, val);\n            } else if val > node.borrow().val {\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, val);\n            } else if node.borrow().left.is_none() || node.borrow().right.is_none() {\n                let child = if node.borrow().left.is_some() {\n                    node.borrow().left.clone()\n                } else {\n                    node.borrow().right.clone()\n                };\n                match child {\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                    None => {\n                        return None;\n                    }\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                    Some(child) => node = child,\n                }\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n                let mut temp = node.borrow().right.clone().unwrap();\n                loop {\n                    let temp_left = temp.borrow().left.clone();\n                    if temp_left.is_none() {\n                        break;\n                    }\n                    temp = temp_left.unwrap();\n                }\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, temp.borrow().val);\n                node.borrow_mut().val = temp.borrow().val;\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(AVLTree *tree, int val) {\n    TreeNode *root = removeHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    TreeNode *child, *grandChild;\n    if (node == NULL) {\n        return NULL;\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val) {\n        node->left = removeHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = removeHelper(node->right, val);\n    } else {\n        if (node->left == NULL || node->right == NULL) {\n            child = node->left;\n            if (node->right != NULL) {\n                child = node->right;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == NULL) {\n                return NULL;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != NULL) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(_val: Int) {\n    root = removeHelper(root, _val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun removeHelper(n: TreeNode?, _val: Int): TreeNode? {\n    var node = n ?: return null\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (_val < node._val)\n        node.left = removeHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = removeHelper(node.right, _val)\n    else {\n        if (node.left == null || node.right == null) {\n            val child = if (node.left != null)\n                node.left\n            else\n                node.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.right\n            while (temp!!.left != null) {\n                temp = temp.left\n            }\n            node.right = removeHelper(node.right, temp._val)\n            node._val = temp._val\n        }\n    }\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(val)\n  @root = remove_helper(@root, val)\nend\n\n### \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef remove_helper(node, val)\n  return if node.nil?\n  # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n  if val < node.val\n    node.left = remove_helper(node.left, val)\n  elsif val > node.val\n    node.right = remove_helper(node.right, val)\n  else\n    if node.left.nil? || node.right.nil?\n      child = node.left || node.right\n      # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      return if child.nil?\n      # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      node = child\n    else\n      # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      temp = node.right\n      while !temp.left.nil?\n        temp = temp.left\n      end\n      node.right = remove_helper(node.right, temp.val)\n      node.val = temp.val\n    end\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, val: T) void {\n   self.root = self.removeHelper(self.root, val).?;\n}\n\n// \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn removeHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) ?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) return null;\n    // 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if (val < node.?.val) {\n        node.?.left = self.removeHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = self.removeHelper(node.?.right, val);\n    } else {\n        if (node.?.left == null or node.?.right == null) {\n            var child = if (node.?.left != null) node.?.left else node.?.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null) {\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            } else {\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.?.right;\n            while (temp.?.left != null) {\n                temp = temp.?.left;\n            }\n            node.?.right = self.removeHelper(node.?.right, temp.?.val);\n            node.?.val = temp.?.val;\n        }\n    }\n    self.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3-node-search","title":"3. \u00a0 Node search","text":"

    The node search operation in AVL trees is consistent with that in binary search trees and will not be detailed here.

    "},{"location":"chapter_tree/avl_tree/#754-typical-applications-of-avl-trees","title":"7.5.4 \u00a0 Typical applications of AVL trees","text":"
    • Organizing and storing large amounts of data, suitable for scenarios with high-frequency searches and low-frequency intertions and removals.
    • Used to build index systems in databases.
    • Red-black trees are also a common type of balanced binary search tree. Compared to AVL trees, red-black trees have more relaxed balancing conditions, require fewer rotations for node insertion and removal, and have a higher average efficiency for node addition and removal operations.
    "},{"location":"chapter_tree/binary_search_tree/","title":"7.4 \u00a0 Binary search tree","text":"

    As shown in the Figure 7-16 , a \"binary search tree\" satisfies the following conditions.

    1. For the root node, the value of all nodes in the left subtree < the value of the root node < the value of all nodes in the right subtree.
    2. The left and right subtrees of any node are also binary search trees, i.e., they satisfy condition 1. as well.

    Figure 7-16 \u00a0 Binary search tree

    "},{"location":"chapter_tree/binary_search_tree/#741-operations-on-a-binary-search-tree","title":"7.4.1 \u00a0 Operations on a binary search tree","text":"

    We encapsulate the binary search tree as a class BinarySearchTree and declare a member variable root, pointing to the tree's root node.

    "},{"location":"chapter_tree/binary_search_tree/#1-searching-for-a-node","title":"1. \u00a0 Searching for a node","text":"

    Given a target node value num, one can search according to the properties of the binary search tree. As shown in the Figure 7-17 , we declare a node cur and start from the binary tree's root node root, looping to compare the size relationship between the node value cur.val and num.

    • If cur.val < num, it means the target node is in cur's right subtree, thus execute cur = cur.right.
    • If cur.val > num, it means the target node is in cur's left subtree, thus execute cur = cur.left.
    • If cur.val = num, it means the target node is found, exit the loop and return the node.
    <1><2><3><4>

    Figure 7-17 \u00a0 Example of searching for a node in a binary search tree

    The search operation in a binary search tree works on the same principle as the binary search algorithm, eliminating half of the possibilities in each round. The number of loops is at most the height of the binary tree. When the binary tree is balanced, it uses \\(O(\\log n)\\) time. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def search(self, num: int) -> TreeNode | None:\n    \"\"\"\u67e5\u627e\u8282\u70b9\"\"\"\n    cur = self._root\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur is not None:\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        elif cur.val > num:\n            cur = cur.left\n        # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else:\n            break\n    return cur\n
    binary_search_tree.cpp
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(int num) {\n    TreeNode *cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur->val > num)\n            cur = cur->left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.java
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode search(int num) {\n    TreeNode cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.cs
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? Search(int num) {\n    TreeNode? cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur =\n            cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.go
    /* \u67e5\u627e\u8282\u70b9 */\nfunc (bst *binarySearchTree) search(num int) *TreeNode {\n    node := bst.root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for node != nil {\n        if node.Val.(int) < num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            node = node.Right\n        } else if node.Val.(int) > num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            node = node.Left\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return node\n}\n
    binary_search_tree.swift
    /* \u67e5\u627e\u8282\u70b9 */\nfunc search(num: Int) -> TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if cur!.val > num {\n            cur = cur?.left\n        }\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else {\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.js
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num) {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.ts
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num: number): TreeNode | null {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.dart
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? search(int _num) {\n  TreeNode? cur = _root;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else if (cur.val > _num)\n      cur = cur.left;\n    // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break;\n  }\n  // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n  return cur;\n}\n
    binary_search_tree.rs
    /* \u67e5\u627e\u8282\u70b9 */\npub fn search(&self, num: i32) -> OptionTreeNodeRc {\n    let mut cur = self.root.clone();\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => cur = node.borrow().right.clone(),\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => cur = node.borrow().left.clone(),\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n        }\n    }\n\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    cur\n}\n
    binary_search_tree.c
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(BinarySearchTree *bst, int num) {\n    TreeNode *cur = bst->root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        if (cur->val < num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else if (cur->val > num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.kt
    /* \u67e5\u627e\u8282\u70b9 */\nfun search(num: Int): TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur._val > num)\n            cur.left\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.rb
    ### \u67e5\u627e\u8282\u70b9 ###\ndef search(num)\n  cur = @root\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while !cur.nil?\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    elsif cur.val > num\n      cur = cur.left\n    # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break\n    end\n  end\n\n  cur\nend\n
    binary_search_tree.zig
    // \u67e5\u627e\u8282\u70b9\nfn search(self: *Self, num: T) ?*inc.TreeNode(T) {\n    var cur = self.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else if (cur.?.val > num) {\n            cur = cur.?.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        } else {\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/binary_search_tree/#2-inserting-a-node","title":"2. \u00a0 Inserting a node","text":"

    Given an element num to be inserted, to maintain the property of the binary search tree \"left subtree < root node < right subtree,\" the insertion operation proceeds as shown in the Figure 7-18 .

    1. Finding the insertion position: Similar to the search operation, start from the root node and loop downwards according to the size relationship between the current node value and num until passing through the leaf node (traversing to None) then exit the loop.
    2. Insert the node at that position: Initialize the node num and place it where None was.

    Figure 7-18 \u00a0 Inserting a node into a binary search tree

    In the code implementation, note the following two points.

    • The binary search tree does not allow duplicate nodes; otherwise, it will violate its definition. Therefore, if the node to be inserted already exists in the tree, the insertion is not performed, and it directly returns.
    • To perform the insertion operation, we need to use the node pre to save the node from the last loop. This way, when traversing to None, we can get its parent node, thus completing the node insertion operation.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def insert(self, num: int):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self._root is None:\n        self._root = TreeNode(num)\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur.val == num:\n            return\n        pre = cur\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u63d2\u5165\u8282\u70b9\n    node = TreeNode(num)\n    if pre.val < num:\n        pre.right = node\n    else:\n        pre.left = node\n
    binary_search_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == nullptr) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = new TreeNode(num);\n    if (pre->val < num)\n        pre->right = node;\n    else\n        pre->left = node;\n}\n
    binary_search_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new TreeNode(num);\n    if (pre.val < num)\n        pre.right = node;\n    else\n        pre.left = node;\n}\n
    binary_search_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new(num);\n    if (pre != null) {\n        if (pre.val < num)\n            pre.right = node;\n        else\n            pre.left = node;\n    }\n}\n
    binary_search_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (bst *binarySearchTree) insert(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if cur == nil {\n        bst.root = NewTreeNode(num)\n        return\n    }\n    // \u5f85\u63d2\u5165\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            return\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            cur = cur.Right\n        } else {\n            cur = cur.Left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    node := NewTreeNode(num)\n    if pre.Val.(int) < num {\n        pre.Right = node\n    } else {\n        pre.Left = node\n    }\n}\n
    binary_search_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if root == nil {\n        root = TreeNode(x: num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur!.val == num {\n            return\n        }\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let node = TreeNode(x: num)\n    if pre!.val < num {\n        pre?.right = node\n    } else {\n        pre?.left = node\n    }\n}\n
    binary_search_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre.val < num) pre.right = node;\n    else pre.left = node;\n}\n
    binary_search_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre!.val < num) pre!.right = node;\n    else pre!.left = node;\n}\n
    binary_search_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if (_root == null) {\n    _root = TreeNode(_num);\n    return;\n  }\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    if (cur.val == _num) return;\n    pre = cur;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u63d2\u5165\u8282\u70b9\n  TreeNode? node = TreeNode(_num);\n  if (pre!.val < _num)\n    pre.right = node;\n  else\n    pre.left = node;\n}\n
    binary_search_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\npub fn insert(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self.root.is_none() {\n        self.root = Some(TreeNode::new(num));\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n            Ordering::Equal => return,\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let pre = pre.unwrap();\n    let node = Some(TreeNode::new(num));\n    if num > pre.borrow().val {\n        pre.borrow_mut().right = node;\n    } else {\n        pre.borrow_mut().left = node;\n    }\n}\n
    binary_search_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (bst->root == NULL) {\n        bst->root = newTreeNode(num);\n        return;\n    }\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num) {\n            return;\n        }\n        pre = cur;\n        if (cur->val < num) {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = newTreeNode(num);\n    if (pre->val < num) {\n        pre->right = node;\n    } else {\n        pre->left = node;\n    }\n}\n
    binary_search_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = TreeNode(num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur._val == num)\n            return\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u63d2\u5165\u8282\u70b9\n    val node = TreeNode(num)\n    if (pre?._val!! < num)\n        pre.right = node\n    else\n        pre.left = node\n}\n
    binary_search_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if @root.nil?\n    @root = TreeNode.new(num)\n    return\n  end\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    return if cur.val == num\n\n    pre = cur\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n\n  # \u63d2\u5165\u8282\u70b9\n  node = TreeNode.new(num)\n  if pre.val < num\n    pre.right = node\n  else\n    pre.left = node\n  end\nend\n
    binary_search_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, num: T) !void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (self.root == null) {\n        self.root = try self.mem_allocator.create(inc.TreeNode(T));\n        return;\n    }\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.?.val == num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    var node = try self.mem_allocator.create(inc.TreeNode(T));\n    node.init(num);\n    if (pre.?.val < num) {\n        pre.?.right = node;\n    } else {\n        pre.?.left = node;\n    }\n}\n
    Code Visualization

    Full Screen >

    Similar to searching for a node, inserting a node uses \\(O(\\log n)\\) time.

    "},{"location":"chapter_tree/binary_search_tree/#3-removing-a-node","title":"3. \u00a0 Removing a node","text":"

    First, find the target node in the binary tree, then remove it. Similar to inserting a node, we need to ensure that after the removal operation is completed, the property of the binary search tree \"left subtree < root node < right subtree\" is still satisfied. Therefore, based on the number of child nodes of the target node, we divide it into 0, 1, and 2 cases, performing the corresponding node removal operations.

    As shown in the Figure 7-19 , when the degree of the node to be removed is \\(0\\), it means the node is a leaf node, and it can be directly removed.

    Figure 7-19 \u00a0 Removing a node in a binary search tree (degree 0)

    As shown in the Figure 7-20 , when the degree of the node to be removed is \\(1\\), replacing the node to be removed with its child node is sufficient.

    Figure 7-20 \u00a0 Removing a node in a binary search tree (degree 1)

    When the degree of the node to be removed is \\(2\\), we cannot remove it directly, but need to use a node to replace it. To maintain the property of the binary search tree \"left subtree < root node < right subtree,\" this node can be either the smallest node of the right subtree or the largest node of the left subtree.

    Assuming we choose the smallest node of the right subtree (the next node in in-order traversal), then the removal operation proceeds as shown in the Figure 7-21 .

    1. Find the next node in the \"in-order traversal sequence\" of the node to be removed, denoted as tmp.
    2. Replace the value of the node to be removed with tmp's value, and recursively remove the node tmp in the tree.
    <1><2><3><4>

    Figure 7-21 \u00a0 Removing a node in a binary search tree (degree 2)

    The operation of removing a node also uses \\(O(\\log n)\\) time, where finding the node to be removed requires \\(O(\\log n)\\) time, and obtaining the in-order traversal successor node requires \\(O(\\log n)\\) time. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def remove(self, num: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self._root is None:\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur.val == num:\n            break\n        pre = cur\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur is None:\n        return\n\n    # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur.left is None or cur.right is None:\n        # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        child = cur.left or cur.right\n        # \u5220\u9664\u8282\u70b9 cur\n        if cur != self._root:\n            if pre.left == cur:\n                pre.left = child\n            else:\n                pre.right = child\n        else:\n            # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            self._root = child\n    # \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else:\n        # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp: TreeNode = cur.right\n        while tmp.left is not None:\n            tmp = tmp.left\n        # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.val)\n        # \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val\n
    binary_search_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == nullptr)\n        return;\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == nullptr)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur->left == nullptr || cur->right == nullptr) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != nullptr ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre->left == cur)\n                pre->left = child;\n            else\n                pre->right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete cur;\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != nullptr) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode child = cur.left != null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode? child = cur.left ?? cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode? tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        Remove(tmp.val!.Value);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (bst *binarySearchTree) remove(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5f85\u5220\u9664\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            break\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u53f3\u5b50\u6811\u4e2d\n            cur = cur.Right\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u5de6\u5b50\u6811\u4e2d\n            cur = cur.Left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u4e3a 0 \u6216 1\n    if cur.Left == nil || cur.Right == nil {\n        var child *TreeNode = nil\n        // \u53d6\u51fa\u5f85\u5220\u9664\u8282\u70b9\u7684\u5b50\u8282\u70b9\n        if cur.Left != nil {\n            child = cur.Left\n        } else {\n            child = cur.Right\n        }\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur != bst.root {\n            if pre.Left == cur {\n                pre.Left = child\n            } else {\n                pre.Right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            bst.root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u4e3a 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d\u5f85\u5220\u9664\u8282\u70b9 cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp := cur.Right\n        for tmp.Left != nil {\n            tmp = tmp.Left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        bst.remove(tmp.Val.(int))\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.Val = tmp.Val\n    }\n}\n
    binary_search_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if root == nil {\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur!.val == num {\n            break\n        }\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur?.left == nil || cur?.right == nil {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        let child = cur?.left ?? cur?.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur !== root {\n            if pre?.left === cur {\n                pre?.left = child\n            } else {\n                pre?.right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur?.right\n        while tmp?.left != nil {\n            tmp = tmp?.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(num: tmp!.val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur?.val = tmp!.val\n    }\n}\n
    binary_search_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child = cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre.left === cur) pre.left = child;\n            else pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp = cur.right;\n        while (tmp.left !== null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child: TreeNode | null =\n            cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre!.left === cur) pre!.left = child;\n            else pre!.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp: TreeNode | null = cur.right;\n        while (tmp!.left !== null) {\n            tmp = tmp!.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp!.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp!.val;\n    }\n}\n
    binary_search_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  if (_root == null) return;\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    if (cur.val == _num) break;\n    pre = cur;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n  if (cur == null) return;\n  // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if (cur.left == null || cur.right == null) {\n    // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    TreeNode? child = cur.left ?? cur.right;\n    // \u5220\u9664\u8282\u70b9 cur\n    if (cur != _root) {\n      if (pre!.left == cur)\n        pre.left = child;\n      else\n        pre.right = child;\n    } else {\n      // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      _root = child;\n    }\n  } else {\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    TreeNode? tmp = cur.right;\n    while (tmp!.left != null) {\n      tmp = tmp.left;\n    }\n    // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val);\n    // \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val;\n  }\n}\n
    binary_search_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\npub fn remove(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self.root.is_none() {\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur.is_none() {\n        return;\n    }\n    let cur = cur.unwrap();\n    let (left_child, right_child) = (cur.borrow().left.clone(), cur.borrow().right.clone());\n    match (left_child.clone(), right_child.clone()) {\n        // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n        (None, None) | (Some(_), None) | (None, Some(_)) => {\n            // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n            let child = left_child.or(right_child);\n            let pre = pre.unwrap();\n            // \u5220\u9664\u8282\u70b9 cur\n            if !Rc::ptr_eq(&cur, self.root.as_ref().unwrap()) {\n                let left = pre.borrow().left.clone();\n                if left.is_some() && Rc::ptr_eq(&left.as_ref().unwrap(), &cur) {\n                    pre.borrow_mut().left = child;\n                } else {\n                    pre.borrow_mut().right = child;\n                }\n            } else {\n                // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n                self.root = child;\n            }\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n        (Some(_), Some(_)) => {\n            // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n            let mut tmp = cur.borrow().right.clone();\n            while let Some(node) = tmp.clone() {\n                if node.borrow().left.is_some() {\n                    tmp = node.borrow().left.clone();\n                } else {\n                    break;\n                }\n            }\n            let tmpval = tmp.unwrap().borrow().val;\n            // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n            self.remove(tmpval);\n            // \u7528 tmp \u8986\u76d6 cur\n            cur.borrow_mut().val = tmpval;\n        }\n    }\n}\n
    binary_search_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (bst->root == NULL)\n        return;\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        if (cur->val < num) {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == NULL)\n        return;\n    // \u5224\u65ad\u5f85\u5220\u9664\u8282\u70b9\u662f\u5426\u5b58\u5728\u5b50\u8282\u70b9\n    if (cur->left == NULL || cur->right == NULL) {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1 */\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != NULL ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre->left == cur) {\n            pre->left = child;\n        } else {\n            pre->right = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(cur);\n    } else {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 2 */\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != NULL) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        removeItem(bst, tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur._val == num)\n            break\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        val child = if (cur.left != null)\n            cur.left\n        else\n            cur.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!!.left == cur)\n                pre.left = child\n            else\n                pre.right = child\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.right\n        while (tmp!!.left != null) {\n            tmp = tmp.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp._val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur._val = tmp._val\n    }\n}\n
    binary_search_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  return if @root.nil?\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    break if cur.val == num\n\n    pre = cur\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n  # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  return if cur.nil?\n\n  # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if cur.left.nil? || cur.right.nil?\n    # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    child = cur.left || cur.right\n    # \u5220\u9664\u8282\u70b9 cur\n    if cur != @root\n      if pre.left == cur\n        pre.left = child\n      else\n        pre.right = child\n      end\n    else\n      # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      @root = child\n    end\n  # \u5b50\u8282\u70b9\u6570\u91cf = 2\n  else\n    # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    tmp = cur.right\n    while !tmp.left.nil?\n      tmp = tmp.left\n    end\n    # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val)\n    # \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val\n  end\nend\n
    binary_search_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, num: T) void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (self.root == null) return;\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.?.val == num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.?.left == null or cur.?.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        var child = if (cur.?.left != null) cur.?.left else cur.?.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre.?.left == cur) {\n            pre.?.left = child;\n        } else {\n            pre.?.right = child;\n        }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.?.right;\n        while (tmp.?.left != null) {\n            tmp = tmp.?.left;\n        }\n        var tmp_val = tmp.?.val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.?.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.?.val = tmp_val;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/binary_search_tree/#4-in-order-traversal-is-ordered","title":"4. \u00a0 In-order traversal is ordered","text":"

    As shown in the Figure 7-22 , the in-order traversal of a binary tree follows the \"left \\(\\rightarrow\\) root \\(\\rightarrow\\) right\" traversal order, and a binary search tree satisfies the size relationship \"left child node < root node < right child node\".

    This means that in-order traversal in a binary search tree always traverses the next smallest node first, thus deriving an important property: The in-order traversal sequence of a binary search tree is ascending.

    Using the ascending property of in-order traversal, obtaining ordered data in a binary search tree requires only \\(O(n)\\) time, without the need for additional sorting operations, which is very efficient.

    Figure 7-22 \u00a0 In-order traversal sequence of a binary search tree

    "},{"location":"chapter_tree/binary_search_tree/#742-efficiency-of-binary-search-trees","title":"7.4.2 \u00a0 Efficiency of binary search trees","text":"

    Given a set of data, we consider using an array or a binary search tree for storage. Observing the Table 7-2 , the operations on a binary search tree all have logarithmic time complexity, which is stable and efficient. Only in scenarios of high-frequency addition and low-frequency search and removal, arrays are more efficient than binary search trees.

    Table 7-2 \u00a0 Efficiency comparison between arrays and search trees

    Unsorted array Binary search tree Search element \\(O(n)\\) \\(O(\\log n)\\) Insert element \\(O(1)\\) \\(O(\\log n)\\) Remove element \\(O(n)\\) \\(O(\\log n)\\)

    In ideal conditions, the binary search tree is \"balanced,\" thus any node can be found within \\(\\log n\\) loops.

    However, continuously inserting and removing nodes in a binary search tree may lead to the binary tree degenerating into a chain list as shown in the Figure 7-23 , at which point the time complexity of various operations also degrades to \\(O(n)\\).

    Figure 7-23 \u00a0 Degradation of a binary search tree

    "},{"location":"chapter_tree/binary_search_tree/#743-common-applications-of-binary-search-trees","title":"7.4.3 \u00a0 Common applications of binary search trees","text":"
    • Used as multi-level indexes in systems to implement efficient search, insertion, and removal operations.
    • Serves as the underlying data structure for certain search algorithms.
    • Used to store data streams to maintain their ordered state.
    "},{"location":"chapter_tree/binary_tree/","title":"7.1 \u00a0 Binary tree","text":"

    A \"binary tree\" is a non-linear data structure that represents the ancestral and descendent relationships, embodying the \"divide and conquer\" logic. Similar to a linked list, the basic unit of a binary tree is a node, each containing a value, a reference to the left child node, and a reference to the right child node.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"Binary tree node\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # Node value\n        self.left: TreeNode | None = None  # Reference to left child node\n        self.right: TreeNode | None = None # Reference to right child node\n
    /* Binary tree node */\nstruct TreeNode {\n    int val;          // Node value\n    TreeNode *left;   // Pointer to left child node\n    TreeNode *right;  // Pointer to right child node\n    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n};\n
    /* Binary tree node */\nclass TreeNode {\n    int val;         // Node value\n    TreeNode left;   // Reference to left child node\n    TreeNode right;  // Reference to right child node\n    TreeNode(int x) { val = x; }\n}\n
    /* Binary tree node */\nclass TreeNode(int? x) {\n    public int? val = x;    // Node value\n    public TreeNode? left;  // Reference to left child node\n    public TreeNode? right; // Reference to right child node\n}\n
    /* Binary tree node */\ntype TreeNode struct {\n    Val   int\n    Left  *TreeNode\n    Right *TreeNode\n}\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc NewTreeNode(v int) *TreeNode {\n    return &TreeNode{\n        Left:  nil, // Pointer to left child node\n        Right: nil, // Pointer to right child node\n        Val:   v,   // Node value\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n    var val: Int // Node value\n    var left: TreeNode? // Reference to left child node\n    var right: TreeNode? // Reference to right child node\n\n    init(x: Int) {\n        val = x\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n    val; // Node value\n    left; // Pointer to left child node\n    right; // Pointer to right child node\n    constructor(val, left, right) {\n        this.val = val === undefined ? 0 : val;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n    val: number;\n    left: TreeNode | null;\n    right: TreeNode | null;\n\n    constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val; // Node value\n        this.left = left === undefined ? null : left; // Reference to left child node\n        this.right = right === undefined ? null : right; // Reference to right child node\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n  int val;         // Node value\n  TreeNode? left;  // Reference to left child node\n  TreeNode? right; // Reference to right child node\n  TreeNode(this.val, [this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* Binary tree node */\nstruct TreeNode {\n    val: i32,                               // Node value\n    left: Option<Rc<RefCell<TreeNode>>>,    // Reference to left child node\n    right: Option<Rc<RefCell<TreeNode>>>,   // Reference to right child node\n}\n\nimpl TreeNode {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* Binary tree node */\ntypedef struct TreeNode {\n    int val;                // Node value\n    int height;             // \u8282\u70b9\u9ad8\u5ea6\n    struct TreeNode *left;  // Pointer to left child node\n    struct TreeNode *right; // Pointer to right child node\n} TreeNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* Binary tree node */\nclass TreeNode(val _val: Int) {  // Node value\n    val left: TreeNode? = null   // Reference to left child node\n    val right: TreeNode? = null  // Reference to right child node\n}\n
    \n
    \n

    Each node has two references (pointers), pointing to the \"left-child node\" and \"right-child node,\" respectively. This node is called the \"parent node\" of these two child nodes. When given a node of a binary tree, we call the tree formed by this node's left child and all nodes under it the \"left subtree\" of this node. Similarly, the \"right subtree\" can be defined.

    In a binary tree, except for leaf nodes, all other nodes contain child nodes and non-empty subtrees. As shown in the Figure 7-1 , if \"Node 2\" is considered as the parent node, then its left and right child nodes are \"Node 4\" and \"Node 5,\" respectively. The left subtree is \"the tree formed by Node 4 and all nodes under it,\" and the right subtree is \"the tree formed by Node 5 and all nodes under it.\"

    Figure 7-1 \u00a0 Parent Node, child Node, subtree

    "},{"location":"chapter_tree/binary_tree/#711-common-terminology-of-binary-trees","title":"7.1.1 \u00a0 Common terminology of binary trees","text":"

    The commonly used terminology of binary trees is shown in the following figure.

    • \"Root node\": The node at the top level of the binary tree, which has no parent node.
    • \"Leaf node\": A node with no children, both of its pointers point to None.
    • \"Edge\": The line segment connecting two nodes, i.e., node reference (pointer).
    • The \"level\" of a node: Incrementing from top to bottom, with the root node's level being 1.
    • The \"degree\" of a node: The number of a node's children. In a binary tree, the degree can be 0, 1, or 2.
    • The \"height\" of a binary tree: The number of edges passed from the root node to the farthest leaf node.
    • The \"depth\" of a node: The number of edges passed from the root node to the node.
    • The \"height\" of a node: The number of edges from the farthest leaf node to the node.

    Figure 7-2 \u00a0 Common Terminology of Binary Trees

    Tip

    Please note that we usually define \"height\" and \"depth\" as \"the number of edges passed,\" but some problems or textbooks may define them as \"the number of nodes passed.\" In this case, both height and depth need to be incremented by 1.

    "},{"location":"chapter_tree/binary_tree/#712-basic-operations-of-binary-trees","title":"7.1.2 \u00a0 Basic operations of binary trees","text":""},{"location":"chapter_tree/binary_tree/#1-initializing-a-binary-tree","title":"1. \u00a0 Initializing a binary tree","text":"

    Similar to a linked list, initialize nodes first, then construct references (pointers).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # Initializing a binary tree\n# Initializing nodes\nn1 = TreeNode(val=1)\nn2 = TreeNode(val=2)\nn3 = TreeNode(val=3)\nn4 = TreeNode(val=4)\nn5 = TreeNode(val=5)\n# Linking references (pointers) between nodes\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.cpp
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode* n1 = new TreeNode(1);\nTreeNode* n2 = new TreeNode(2);\nTreeNode* n3 = new TreeNode(3);\nTreeNode* n4 = new TreeNode(4);\nTreeNode* n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.java
    // Initializing nodes\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.cs
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode n1 = new(1);\nTreeNode n2 = new(2);\nTreeNode n3 = new(3);\nTreeNode n4 = new(4);\nTreeNode n5 = new(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.go
    /* Initializing a binary tree */\n// Initializing nodes\nn1 := NewTreeNode(1)\nn2 := NewTreeNode(2)\nn3 := NewTreeNode(3)\nn4 := NewTreeNode(4)\nn5 := NewTreeNode(5)\n// Linking references (pointers) between nodes\nn1.Left = n2\nn1.Right = n3\nn2.Left = n4\nn2.Right = n5\n
    binary_tree.swift
    // Initializing nodes\nlet n1 = TreeNode(x: 1)\nlet n2 = TreeNode(x: 2)\nlet n3 = TreeNode(x: 3)\nlet n4 = TreeNode(x: 4)\nlet n5 = TreeNode(x: 5)\n// Linking references (pointers) between nodes\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.js
    /* Initializing a binary tree */\n// Initializing nodes\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.ts
    /* Initializing a binary tree */\n// Initializing nodes\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.dart
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.rs
    // Initializing nodes\nlet n1 = TreeNode::new(1);\nlet n2 = TreeNode::new(2);\nlet n3 = TreeNode::new(3);\nlet n4 = TreeNode::new(4);\nlet n5 = TreeNode::new(5);\n// Linking references (pointers) between nodes\nn1.borrow_mut().left = Some(n2.clone());\nn1.borrow_mut().right = Some(n3);\nn2.borrow_mut().left = Some(n4);\nn2.borrow_mut().right = Some(n5);\n
    binary_tree.c
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode *n1 = newTreeNode(1);\nTreeNode *n2 = newTreeNode(2);\nTreeNode *n3 = newTreeNode(3);\nTreeNode *n4 = newTreeNode(4);\nTreeNode *n5 = newTreeNode(5);\n// Linking references (pointers) between nodes\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.kt
    // Initializing nodes\nval n1 = TreeNode(1)\nval n2 = TreeNode(2)\nval n3 = TreeNode(3)\nval n4 = TreeNode(4)\nval n5 = TreeNode(5)\n// Linking references (pointers) between nodes\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.rb
    \n
    binary_tree.zig
    \n
    Code visualization

    https://pythontutor.com/render.html#code=class%20TreeNode%3A%0A%20%20%20%20%22%22%22%E4%BA%8C%E5%8F%89%E6%A0%91%E8%8A%82%E7%82%B9%E7%B1%BB%22%22%22%0A%20%20%20%20def%20__init__%28self,%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8A%82%E7%82%B9%E5%80%BC%0A%20%20%20%20%20%20%20%20self.left%3A%20TreeNode%20%7C%20None%20%3D%20None%20%20%23%20%E5%B7%A6%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%20%20%20%20%20%20%20%20self.right%3A%20TreeNode%20%7C%20None%20%3D%20None%20%23%20%E5%8F%B3%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BA%8C%E5%8F%89%E6%A0%91%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E8%8A%82%E7%82%B9%0A%20%20%20%20n1%20%3D%20TreeNode%28val%3D1%29%0A%20%20%20%20n2%20%3D%20TreeNode%28val%3D2%29%0A%20%20%20%20n3%20%3D%20TreeNode%28val%3D3%29%0A%20%20%20%20n4%20%3D%20TreeNode%28val%3D4%29%0A%20%20%20%20n5%20%3D%20TreeNode%28val%3D5%29%0A%20%20%20%20%23%20%E6%9E%84%E5%BB%BA%E8%8A%82%E7%82%B9%E4%B9%8B%E9%97%B4%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%88%E6%8C%87%E9%92%88%EF%BC%89%0A%20%20%20%20n1.left%20%3D%20n2%0A%20%20%20%20n1.right%20%3D%20n3%0A%20%20%20%20n2.left%20%3D%20n4%0A%20%20%20%20n2.right%20%3D%20n5&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    "},{"location":"chapter_tree/binary_tree/#2-inserting-and-removing-nodes","title":"2. \u00a0 Inserting and removing nodes","text":"

    Similar to a linked list, inserting and removing nodes in a binary tree can be achieved by modifying pointers. The Figure 7-3 provides an example.

    Figure 7-3 \u00a0 Inserting and removing nodes in a binary tree

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # Inserting and removing nodes\np = TreeNode(0)\n# Inserting node P between n1 -> n2\nn1.left = p\np.left = n2\n# Removing node P\nn1.left = n2\n
    binary_tree.cpp
    /* Inserting and removing nodes */\nTreeNode* P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1->left = P;\nP->left = n2;\n// Removing node P\nn1->left = n2;\n
    binary_tree.java
    TreeNode P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.cs
    /* Inserting and removing nodes */\nTreeNode P = new(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.go
    /* Inserting and removing nodes */\n// Inserting node P between n1 and n2\np := NewTreeNode(0)\nn1.Left = p\np.Left = n2\n// Removing node P\nn1.Left = n2\n
    binary_tree.swift
    let P = TreeNode(x: 0)\n// Inserting node P between n1 and n2\nn1.left = P\nP.left = n2\n// Removing node P\nn1.left = n2\n
    binary_tree.js
    /* Inserting and removing nodes */\nlet P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.ts
    /* Inserting and removing nodes */\nconst P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.dart
    /* Inserting and removing nodes */\nTreeNode P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.rs
    let p = TreeNode::new(0);\n// Inserting node P between n1 and n2\nn1.borrow_mut().left = Some(p.clone());\np.borrow_mut().left = Some(n2.clone());\n// Removing node P\nn1.borrow_mut().left = Some(n2);\n
    binary_tree.c
    /* Inserting and removing nodes */\nTreeNode *P = newTreeNode(0);\n// Inserting node P between n1 and n2\nn1->left = P;\nP->left = n2;\n// Removing node P\nn1->left = n2;\n
    binary_tree.kt
    val P = TreeNode(0)\n// Inserting node P between n1 and n2\nn1.left = P\nP.left = n2\n// Removing node P\nn1.left = n2\n
    binary_tree.rb
    \n
    binary_tree.zig
    \n
    Code visualization

    https://pythontutor.com/render.html#code=class%20TreeNode%3A%0A%20%20%20%20%22%22%22%E4%BA%8C%E5%8F%89%E6%A0%91%E8%8A%82%E7%82%B9%E7%B1%BB%22%22%22%0A%20%20%20%20def%20__init__%28self,%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8A%82%E7%82%B9%E5%80%BC%0A%20%20%20%20%20%20%20%20self.left%3A%20TreeNode%20%7C%20None%20%3D%20None%20%20%23%20%E5%B7%A6%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%20%20%20%20%20%20%20%20self.right%3A%20TreeNode%20%7C%20None%20%3D%20None%20%23%20%E5%8F%B3%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BA%8C%E5%8F%89%E6%A0%91%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E8%8A%82%E7%82%B9%0A%20%20%20%20n1%20%3D%20TreeNode%28val%3D1%29%0A%20%20%20%20n2%20%3D%20TreeNode%28val%3D2%29%0A%20%20%20%20n3%20%3D%20TreeNode%28val%3D3%29%0A%20%20%20%20n4%20%3D%20TreeNode%28val%3D4%29%0A%20%20%20%20n5%20%3D%20TreeNode%28val%3D5%29%0A%20%20%20%20%23%20%E6%9E%84%E5%BB%BA%E8%8A%82%E7%82%B9%E4%B9%8B%E9%97%B4%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%88%E6%8C%87%E9%92%88%EF%BC%89%0A%20%20%20%20n1.left%20%3D%20n2%0A%20%20%20%20n1.right%20%3D%20n3%0A%20%20%20%20n2.left%20%3D%20n4%0A%20%20%20%20n2.right%20%3D%20n5%0A%0A%20%20%20%20%23%20%E6%8F%92%E5%85%A5%E4%B8%8E%E5%88%A0%E9%99%A4%E8%8A%82%E7%82%B9%0A%20%20%20%20p%20%3D%20TreeNode%280%29%0A%20%20%20%20%23%20%E5%9C%A8%20n1%20-%3E%20n2%20%E4%B8%AD%E9%97%B4%E6%8F%92%E5%85%A5%E8%8A%82%E7%82%B9%20P%0A%20%20%20%20n1.left%20%3D%20p%0A%20%20%20%20p.left%20%3D%20n2%0A%20%20%20%20%23%20%E5%88%A0%E9%99%A4%E8%8A%82%E7%82%B9%20P%0A%20%20%20%20n1.left%20%3D%20n2&cumulative=false&curInstr=37&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    Tip

    It's important to note that inserting nodes may change the original logical structure of the binary tree, while removing nodes usually means removing the node and all its subtrees. Therefore, in a binary tree, insertion and removal are usually performed through a set of operations to achieve meaningful actions.

    "},{"location":"chapter_tree/binary_tree/#713-common-types-of-binary-trees","title":"7.1.3 \u00a0 Common types of binary trees","text":""},{"location":"chapter_tree/binary_tree/#1-perfect-binary-tree","title":"1. \u00a0 Perfect binary tree","text":"

    As shown in the Figure 7-4 , in a \"perfect binary tree,\" all levels of nodes are fully filled. In a perfect binary tree, the degree of leaf nodes is \\(0\\), and the degree of all other nodes is \\(2\\); if the tree's height is \\(h\\), then the total number of nodes is \\(2^{h+1} - 1\\), showing a standard exponential relationship, reflecting the common phenomenon of cell division in nature.

    Tip

    Please note that in the Chinese community, a perfect binary tree is often referred to as a \"full binary tree.\"

    Figure 7-4 \u00a0 Perfect binary tree

    "},{"location":"chapter_tree/binary_tree/#2-complete-binary-tree","title":"2. \u00a0 Complete binary tree","text":"

    As shown in the Figure 7-5 , a \"complete binary tree\" has only the bottom level nodes not fully filled, and the bottom level nodes are filled as far left as possible.

    Figure 7-5 \u00a0 Complete binary tree

    "},{"location":"chapter_tree/binary_tree/#3-full-binary-tree","title":"3. \u00a0 Full binary tree","text":"

    As shown in the Figure 7-6 , a \"full binary tree\" has all nodes except leaf nodes having two children.

    Figure 7-6 \u00a0 Full binary tree

    "},{"location":"chapter_tree/binary_tree/#4-balanced-binary-tree","title":"4. \u00a0 Balanced binary tree","text":"

    As shown in the Figure 7-7 , in a \"balanced binary tree,\" the absolute difference in height between the left and right subtrees of any node does not exceed 1.

    Figure 7-7 \u00a0 Balanced binary tree

    "},{"location":"chapter_tree/binary_tree/#714-degeneration-of-binary-trees","title":"7.1.4 \u00a0 Degeneration of binary trees","text":"

    The Figure 7-8 shows the ideal and degenerate structures of binary trees. When every level of a binary tree is filled, it reaches the \"perfect binary tree\"; when all nodes are biased towards one side, the binary tree degenerates into a \"linked list\".

    • The perfect binary tree is the ideal situation, fully leveraging the \"divide and conquer\" advantage of binary trees.
    • A linked list is another extreme, where operations become linear, degrading the time complexity to \\(O(n)\\).

    Figure 7-8 \u00a0 The Best and Worst Structures of Binary Trees

    As shown in the Table 7-1 , in the best and worst structures, the number of leaf nodes, total number of nodes, and height of the binary tree reach their maximum or minimum values.

    Table 7-1 \u00a0 The Best and Worst Structures of Binary Trees

    Perfect binary tree Linked list Number of nodes at level \\(i\\) \\(2^{i-1}\\) \\(1\\) Number of leaf nodes in a tree with height \\(h\\) \\(2^h\\) \\(1\\) Total number of nodes in a tree with height \\(h\\) \\(2^{h+1} - 1\\) \\(h + 1\\) Height of a tree with \\(n\\) total nodes \\(\\log_2 (n+1) - 1\\) \\(n - 1\\)"},{"location":"chapter_tree/binary_tree_traversal/","title":"7.2 \u00a0 Binary tree traversal","text":"

    From the perspective of physical structure, a tree is a data structure based on linked lists, hence its traversal method involves accessing nodes one by one through pointers. However, a tree is a non-linear data structure, which makes traversing a tree more complex than traversing a linked list, requiring the assistance of search algorithms to achieve.

    Common traversal methods for binary trees include level-order traversal, preorder traversal, inorder traversal, and postorder traversal, among others.

    "},{"location":"chapter_tree/binary_tree_traversal/#721-level-order-traversal","title":"7.2.1 \u00a0 Level-order traversal","text":"

    As shown in the Figure 7-9 , \"level-order traversal\" traverses the binary tree from top to bottom, layer by layer, and accesses nodes in each layer in a left-to-right order.

    Level-order traversal essentially belongs to \"breadth-first traversal\", also known as \"breadth-first search (BFS)\", which embodies a \"circumferentially outward expanding\" layer-by-layer traversal method.

    Figure 7-9 \u00a0 Level-order traversal of a binary tree

    "},{"location":"chapter_tree/binary_tree_traversal/#1-code-implementation","title":"1. \u00a0 Code implementation","text":"

    Breadth-first traversal is usually implemented with the help of a \"queue\". The queue follows the \"first in, first out\" rule, while breadth-first traversal follows the \"layer-by-layer progression\" rule, the underlying ideas of the two are consistent. The implementation code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_bfs.py
    def level_order(root: TreeNode | None) -> list[int]:\n    \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n    # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue: deque[TreeNode] = deque()\n    queue.append(root)\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    res = []\n    while queue:\n        node: TreeNode = queue.popleft()  # \u961f\u5217\u51fa\u961f\n        res.append(node.val)  # \u4fdd\u5b58\u8282\u70b9\u503c\n        if node.left is not None:\n            queue.append(node.left)  # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if node.right is not None:\n            queue.append(node.right)  # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    return res\n
    binary_tree_bfs.cpp
    /* \u5c42\u5e8f\u904d\u5386 */\nvector<int> levelOrder(TreeNode *root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue<TreeNode *> queue;\n    queue.push(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    vector<int> vec;\n    while (!queue.empty()) {\n        TreeNode *node = queue.front();\n        queue.pop();              // \u961f\u5217\u51fa\u961f\n        vec.push_back(node->val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node->left != nullptr)\n            queue.push(node->left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node->right != nullptr)\n            queue.push(node->right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return vec;\n}\n
    binary_tree_bfs.java
    /* \u5c42\u5e8f\u904d\u5386 */\nList<Integer> levelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new LinkedList<>();\n    queue.add(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<Integer> list = new ArrayList<>();\n    while (!queue.isEmpty()) {\n        TreeNode node = queue.poll(); // \u961f\u5217\u51fa\u961f\n        list.add(node.val);           // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left);   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right);  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.cs
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> LevelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new();\n    queue.Enqueue(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<int> list = [];\n    while (queue.Count != 0) {\n        TreeNode node = queue.Dequeue(); // \u961f\u5217\u51fa\u961f\n        list.Add(node.val!.Value);       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.Enqueue(node.left);    // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.Enqueue(node.right);   // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.go
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root *TreeNode) []any {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue := list.New()\n    queue.PushBack(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5207\u7247\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    nums := make([]any, 0)\n    for queue.Len() > 0 {\n        // \u961f\u5217\u51fa\u961f\n        node := queue.Remove(queue.Front()).(*TreeNode)\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        nums = append(nums, node.Val)\n        if node.Left != nil {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Left)\n        }\n        if node.Right != nil {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Right)\n        }\n    }\n    return nums\n}\n
    binary_tree_bfs.swift
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root: TreeNode) -> [Int] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    var queue: [TreeNode] = [root]\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list: [Int] = []\n    while !queue.isEmpty {\n        let node = queue.removeFirst() // \u961f\u5217\u51fa\u961f\n        list.append(node.val) // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let left = node.left {\n            queue.append(left) // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let right = node.right {\n            queue.append(right) // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list\n}\n
    binary_tree_bfs.js
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list = [];\n    while (queue.length) {\n        let node = queue.shift(); // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right) queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.ts
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root: TreeNode | null): number[] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list: number[] = [];\n    while (queue.length) {\n        let node = queue.shift() as TreeNode; // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) {\n            queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right) {\n            queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list;\n}\n
    binary_tree_bfs.dart
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> levelOrder(TreeNode? root) {\n  // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  Queue<TreeNode?> queue = Queue();\n  queue.add(root);\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  List<int> res = [];\n  while (queue.isNotEmpty) {\n    TreeNode? node = queue.removeFirst(); // \u961f\u5217\u51fa\u961f\n    res.add(node!.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n    if (node.left != null) queue.add(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    if (node.right != null) queue.add(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  }\n  return res;\n}\n
    binary_tree_bfs.rs
    /* \u5c42\u5e8f\u904d\u5386 */\nfn level_order(root: &Rc<RefCell<TreeNode>>) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    let mut que = VecDeque::new();\n    que.push_back(root.clone());\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    let mut vec = Vec::new();\n\n    while let Some(node) = que.pop_front() {\n        // \u961f\u5217\u51fa\u961f\n        vec.push(node.borrow().val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let Some(left) = node.borrow().left.as_ref() {\n            que.push_back(left.clone()); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let Some(right) = node.borrow().right.as_ref() {\n            que.push_back(right.clone()); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        };\n    }\n    vec\n}\n
    binary_tree_bfs.c
    /* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(TreeNode *root, int *size) {\n    /* \u8f85\u52a9\u961f\u5217 */\n    int front, rear;\n    int index, *arr;\n    TreeNode *node;\n    TreeNode **queue;\n\n    /* \u8f85\u52a9\u961f\u5217 */\n    queue = (TreeNode **)malloc(sizeof(TreeNode *) * MAX_SIZE);\n    // \u961f\u5217\u6307\u9488\n    front = 0, rear = 0;\n    // \u52a0\u5165\u6839\u8282\u70b9\n    queue[rear++] = root;\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    /* \u8f85\u52a9\u6570\u7ec4 */\n    arr = (int *)malloc(sizeof(int) * MAX_SIZE);\n    // \u6570\u7ec4\u6307\u9488\n    index = 0;\n    while (front < rear) {\n        // \u961f\u5217\u51fa\u961f\n        node = queue[front++];\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        arr[index++] = node->val;\n        if (node->left != NULL) {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->left;\n        }\n        if (node->right != NULL) {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->right;\n        }\n    }\n    // \u66f4\u65b0\u6570\u7ec4\u957f\u5ea6\u7684\u503c\n    *size = index;\n    arr = realloc(arr, sizeof(int) * (*size));\n\n    // \u91ca\u653e\u8f85\u52a9\u6570\u7ec4\u7a7a\u95f4\n    free(queue);\n    return arr;\n}\n
    binary_tree_bfs.kt
    /* \u5c42\u5e8f\u904d\u5386 */\nfun levelOrder(root: TreeNode?): MutableList<Int> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    val queue = LinkedList<TreeNode?>()\n    queue.add(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    val list = mutableListOf<Int>()\n    while (queue.isNotEmpty()) {\n        val node = queue.poll()      // \u961f\u5217\u51fa\u961f\n        list.add(node?._val!!)       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left)   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right)  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list\n}\n
    binary_tree_bfs.rb
    ### \u5c42\u5e8f\u904d\u5386 ###\ndef level_order(root)\n  # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  queue = [root]\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  res = []\n  while !queue.empty?\n    node = queue.shift # \u961f\u5217\u51fa\u961f\n    res << node.val # \u4fdd\u5b58\u8282\u70b9\u503c\n    queue << node.left unless node.left.nil? # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    queue << node.right unless node.right.nil? # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  end\n  res\nend\n
    binary_tree_bfs.zig
    // \u5c42\u5e8f\u904d\u5386\nfn levelOrder(comptime T: type, mem_allocator: std.mem.Allocator, root: *inc.TreeNode(T)) !std.ArrayList(T) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const L = std.TailQueue(*inc.TreeNode(T));\n    var queue = L{};\n    var root_node = try mem_allocator.create(L.Node);\n    root_node.data = root;\n    queue.append(root_node); \n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list = std.ArrayList(T).init(std.heap.page_allocator);\n    while (queue.len > 0) {\n        var queue_node = queue.popFirst().?;    // \u961f\u5217\u51fa\u961f\n        var node = queue_node.data;\n        try list.append(node.val);              // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.left.?;\n            queue.append(tmp_node);             // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.right.?;\n            queue.append(tmp_node);             // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }        \n    }\n    return list;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/binary_tree_traversal/#2-complexity-analysis","title":"2. \u00a0 Complexity analysis","text":"
    • Time complexity is \\(O(n)\\): All nodes are visited once, using \\(O(n)\\) time, where \\(n\\) is the number of nodes.
    • Space complexity is \\(O(n)\\): In the worst case, i.e., a full binary tree, before traversing to the lowest level, the queue can contain at most \\((n + 1) / 2\\) nodes at the same time, occupying \\(O(n)\\) space.
    "},{"location":"chapter_tree/binary_tree_traversal/#722-preorder-inorder-and-postorder-traversal","title":"7.2.2 \u00a0 Preorder, inorder, and postorder traversal","text":"

    Correspondingly, preorder, inorder, and postorder traversal all belong to \"depth-first traversal\", also known as \"depth-first search (DFS)\", which embodies a \"proceed to the end first, then backtrack and continue\" traversal method.

    The Figure 7-10 shows the working principle of performing a depth-first traversal on a binary tree. Depth-first traversal is like walking around the perimeter of the entire binary tree, encountering three positions at each node, corresponding to preorder traversal, inorder traversal, and postorder traversal.

    Figure 7-10 \u00a0 Preorder, inorder, and postorder traversal of a binary search tree

    "},{"location":"chapter_tree/binary_tree_traversal/#1-code-implementation_1","title":"1. \u00a0 Code implementation","text":"

    Depth-first search is usually implemented based on recursion:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_dfs.py
    def pre_order(root: TreeNode | None):\n    \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    res.append(root.val)\n    pre_order(root=root.left)\n    pre_order(root=root.right)\n\ndef in_order(root: TreeNode | None):\n    \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    in_order(root=root.left)\n    res.append(root.val)\n    in_order(root=root.right)\n\ndef post_order(root: TreeNode | None):\n    \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    post_order(root=root.left)\n    post_order(root=root.right)\n    res.append(root.val)\n
    binary_tree_dfs.cpp
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    vec.push_back(root->val);\n    preOrder(root->left);\n    preOrder(root->right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left);\n    vec.push_back(root->val);\n    inOrder(root->right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left);\n    postOrder(root->right);\n    vec.push_back(root->val);\n}\n
    binary_tree_dfs.java
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.add(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.add(root.val);\n}\n
    binary_tree_dfs.cs
    /* \u524d\u5e8f\u904d\u5386 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.Add(root.val!.Value);\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid InOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    InOrder(root.left);\n    list.Add(root.val!.Value);\n    InOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid PostOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    PostOrder(root.left);\n    PostOrder(root.right);\n    list.Add(root.val!.Value);\n}\n
    binary_tree_dfs.go
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    nums = append(nums, node.Val)\n    preOrder(node.Left)\n    preOrder(node.Right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(node.Left)\n    nums = append(nums, node.Val)\n    inOrder(node.Right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(node.Left)\n    postOrder(node.Right)\n    nums = append(nums, node.Val)\n}\n
    binary_tree_dfs.swift
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.append(root.val)\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root: root.left)\n    list.append(root.val)\n    inOrder(root: root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root: root.left)\n    postOrder(root: root.right)\n    list.append(root.val)\n}\n
    binary_tree_dfs.js
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.ts
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.dart
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  list.add(node.val);\n  preOrder(node.left);\n  preOrder(node.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  inOrder(node.left);\n  list.add(node.val);\n  inOrder(node.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  postOrder(node.left);\n  postOrder(node.right);\n  list.add(node.val);\n}\n
    binary_tree_dfs.rs
    /* \u524d\u5e8f\u904d\u5386 */\nfn pre_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n        result.push(node.borrow().val);\n        result.extend(pre_order(node.borrow().left.as_ref()));\n        result.extend(pre_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfn in_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n        result.extend(in_order(node.borrow().left.as_ref()));\n        result.push(node.borrow().val);\n        result.extend(in_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfn post_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n        result.extend(post_order(node.borrow().left.as_ref()));\n        result.extend(post_order(node.borrow().right.as_ref()));\n        result.push(node.borrow().val);\n    }\n    result\n}\n
    binary_tree_dfs.c
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    arr[(*size)++] = root->val;\n    preOrder(root->left, size);\n    preOrder(root->right, size);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left, size);\n    arr[(*size)++] = root->val;\n    inOrder(root->right, size);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left, size);\n    postOrder(root->right, size);\n    arr[(*size)++] = root->val;\n}\n
    binary_tree_dfs.kt
    /* \u524d\u5e8f\u904d\u5386 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root._val)\n    preOrder(root.left)\n    preOrder(root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfun inOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left)\n    list.add(root._val)\n    inOrder(root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfun postOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left)\n    postOrder(root.right)\n    list.add(root._val)\n}\n
    binary_tree_dfs.rb
    ### \u524d\u5e8f\u904d\u5386 ###\ndef pre_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  $res << root.val\n  pre_order(root.left)\n  pre_order(root.right)\nend\n\n### \u4e2d\u5e8f\u904d\u5386 ###\ndef in_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  in_order(root.left)\n  $res << root.val\n  in_order(root.right)\nend\n\n### \u540e\u5e8f\u904d\u5386 ###\ndef post_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  post_order(root.left)\n  post_order(root.right)\n  $res << root.val\nend\n
    binary_tree_dfs.zig
    // \u524d\u5e8f\u904d\u5386\nfn preOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    try list.append(root.?.val);\n    try preOrder(T, root.?.left);\n    try preOrder(T, root.?.right);\n}\n\n// \u4e2d\u5e8f\u904d\u5386\nfn inOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    try inOrder(T, root.?.left);\n    try list.append(root.?.val);\n    try inOrder(T, root.?.right);\n}\n\n// \u540e\u5e8f\u904d\u5386\nfn postOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    try postOrder(T, root.?.left);\n    try postOrder(T, root.?.right);\n    try list.append(root.?.val);\n}\n
    Code Visualization

    Full Screen >

    Tip

    Depth-first search can also be implemented based on iteration, interested readers can study this on their own.

    The Figure 7-11 shows the recursive process of preorder traversal of a binary tree, which can be divided into two opposite parts: \"recursion\" and \"return\".

    1. \"Recursion\" means starting a new method, the program accesses the next node in this process.
    2. \"Return\" means the function returns, indicating the current node has been fully accessed.
    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 7-11 \u00a0 The recursive process of preorder traversal

    "},{"location":"chapter_tree/binary_tree_traversal/#2-complexity-analysis_1","title":"2. \u00a0 Complexity analysis","text":"
    • Time complexity is \\(O(n)\\): All nodes are visited once, using \\(O(n)\\) time.
    • Space complexity is \\(O(n)\\): In the worst case, i.e., the tree degrades into a linked list, the recursion depth reaches \\(n\\), the system occupies \\(O(n)\\) stack frame space.
    "},{"location":"chapter_tree/summary/","title":"7.6 \u00a0 Summary","text":""},{"location":"chapter_tree/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • A binary tree is a non-linear data structure that reflects the \"divide and conquer\" logic of splitting one into two. Each binary tree node contains a value and two pointers, which point to its left and right child nodes, respectively.
    • For a node in a binary tree, the tree formed by its left (right) child node and all nodes under it is called the node's left (right) subtree.
    • Related terminology of binary trees includes root node, leaf node, level, degree, edge, height, and depth, among others.
    • The operations of initializing a binary tree, inserting nodes, and removing nodes are similar to those of linked list operations.
    • Common types of binary trees include perfect binary trees, complete binary trees, full binary trees, and balanced binary trees. The perfect binary tree represents the ideal state, while the linked list is the worst state after degradation.
    • A binary tree can be represented using an array by arranging the node values and empty slots in a level-order traversal sequence and implementing pointers based on the index mapping relationship between parent nodes and child nodes.
    • The level-order traversal of a binary tree is a breadth-first search method, which reflects a layer-by-layer traversal manner of \"expanding circle by circle.\" It is usually implemented using a queue.
    • Pre-order, in-order, and post-order traversals are all depth-first search methods, reflecting the traversal manner of \"going to the end first, then backtracking to continue.\" They are usually implemented using recursion.
    • A binary search tree is an efficient data structure for element searching, with the time complexity of search, insert, and remove operations all being \\(O(\\log n)\\). When a binary search tree degrades into a linked list, these time complexities deteriorate to \\(O(n)\\).
    • An AVL tree, also known as a balanced binary search tree, ensures that the tree remains balanced after continuous node insertions and removals through rotation operations.
    • Rotation operations in an AVL tree include right rotation, left rotation, right-then-left rotation, and left-then-right rotation. After inserting or removing nodes, an AVL tree performs rotation operations from bottom to top to rebalance the tree.
    "},{"location":"chapter_tree/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: For a binary tree with only one node, are both the height of the tree and the depth of the root node \\(0\\)?

    Yes, because height and depth are typically defined as \"the number of edges passed.\"

    Q: The insertion and removal in a binary tree are generally completed by a set of operations. What does \"a set of operations\" refer to here? Can it be understood as the release of resources of the child nodes?

    Taking the binary search tree as an example, the operation of removing a node needs to be handled in three different scenarios, each requiring multiple steps of node operations.

    Q: Why are there three sequences: pre-order, in-order, and post-order for DFS traversal of a binary tree, and what are their uses?

    Similar to sequential and reverse traversal of arrays, pre-order, in-order, and post-order traversals are three methods of traversing a binary tree, allowing us to obtain a traversal result in a specific order. For example, in a binary search tree, since the node sizes satisfy left child node value < root node value < right child node value, we can obtain an ordered node sequence by traversing the tree in the \"left \u2192 root \u2192 right\" priority.

    Q: In a right rotation operation that deals with the relationship between the imbalance nodes node, child, grand_child, isn't the connection between node and its parent node and the original link of node lost after the right rotation?

    We need to view this problem from a recursive perspective. The right_rotate(root) operation passes the root node of the subtree and eventually returns the root node of the rotated subtree with return child. The connection between the subtree's root node and its parent node is established after this function returns, which is outside the scope of the right rotation operation's maintenance.

    Q: In C++, functions are divided into private and public sections. What considerations are there for this? Why are the height() function and the updateHeight() function placed in public and private, respectively?

    It depends on the scope of the method's use. If a method is only used within the class, then it is designed to be private. For example, it makes no sense for users to call updateHeight() on their own, as it is just a step in the insertion or removal operations. However, height() is for accessing node height, similar to vector.size(), thus it is set to public for use.

    Q: How do you build a binary search tree from a set of input data? Is the choice of root node very important?

    Yes, the method for building the tree is provided in the build_tree() method in the binary search tree code. As for the choice of the root node, we usually sort the input data and then select the middle element as the root node, recursively building the left and right subtrees. This approach maximizes the balance of the tree.

    Q: In Java, do you always have to use the equals() method for string comparison?

    In Java, for primitive data types, == is used to compare whether the values of two variables are equal. For reference types, the working principles of the two symbols are different.

    • ==: Used to compare whether two variables point to the same object, i.e., whether their positions in memory are the same.
    • equals(): Used to compare whether the values of two objects are equal.

    Therefore, to compare values, we should use equals(). However, strings initialized with String a = \"hi\"; String b = \"hi\"; are stored in the string constant pool and point to the same object, so a == b can also be used to compare the contents of two strings.

    Q: Before reaching the bottom level, is the number of nodes in the queue \\(2^h\\) in breadth-first traversal?

    Yes, for example, a full binary tree with height \\(h = 2\\) has a total of \\(n = 7\\) nodes, then the bottom level has \\(4 = 2^h = (n + 1) / 2\\) nodes.

    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"chapter_appendix/","title":"Chapter 16. \u00a0 Appendix","text":""},{"location":"chapter_appendix/#chapter-contents","title":"Chapter contents","text":"
    • 16.1 \u00a0 Installation
    • 16.2 \u00a0 Contributing
    • 16.3 \u00a0 Terminology
    "},{"location":"chapter_appendix/contribution/","title":"16.2 \u00a0 Contributing","text":"

    Due to the limited abilities of the author, some omissions and errors are inevitable in this book. Please understand. If you discover any typos, broken links, missing content, textual ambiguities, unclear explanations, or unreasonable text structures, please assist us in making corrections to provide readers with better quality learning resources.

    The GitHub IDs of all contributors will be displayed on the repository, web, and PDF versions of the homepage of this book to thank them for their selfless contributions to the open-source community.

    The charm of open source

    The interval between two printings of a paper book is often long, making content updates very inconvenient.

    In this open-source book, however, the content update cycle is shortened to just a few days or even hours.

    "},{"location":"chapter_appendix/contribution/#1-content-fine-tuning","title":"1. \u00a0 Content fine-tuning","text":"

    As shown in the Figure 16-3 , there is an \"edit icon\" in the upper right corner of each page. You can follow these steps to modify text or code.

    1. Click the \"edit icon\". If prompted to \"fork this repository\", please agree to do so.
    2. Modify the Markdown source file content, check the accuracy of the content, and try to keep the formatting consistent.
    3. Fill in the modification description at the bottom of the page, then click the \"Propose file change\" button. After the page redirects, click the \"Create pull request\" button to initiate the pull request.

    Figure 16-3 \u00a0 Edit page button

    Images cannot be directly modified and require the creation of a new Issue or a comment to describe the problem. We will redraw and replace the images as soon as possible.

    "},{"location":"chapter_appendix/contribution/#2-content-creation","title":"2. \u00a0 Content creation","text":"

    If you are interested in participating in this open-source project, including translating code into other programming languages or expanding article content, then the following Pull Request workflow needs to be implemented.

    1. Log in to GitHub and Fork the code repository of this book to your personal account.
    2. Go to your Forked repository web page and use the git clone command to clone the repository to your local machine.
    3. Create content locally and perform complete tests to verify the correctness of the code.
    4. Commit the changes made locally, then push them to the remote repository.
    5. Refresh the repository webpage and click the \"Create pull request\" button to initiate the pull request.
    "},{"location":"chapter_appendix/contribution/#3-docker-deployment","title":"3. \u00a0 Docker deployment","text":"

    In the hello-algo root directory, execute the following Docker script to access the project at http://localhost:8000:

    docker-compose up -d\n

    Use the following command to remove the deployment:

    docker-compose down\n
    "},{"location":"chapter_appendix/installation/","title":"16.1 \u00a0 Installation","text":""},{"location":"chapter_appendix/installation/#1611-install-ide","title":"16.1.1 \u00a0 Install IDE","text":"

    We recommend using the open-source, lightweight VS Code as your local Integrated Development Environment (IDE). Visit the VS Code official website and choose the version of VS Code appropriate for your operating system to download and install.

    Figure 16-1 \u00a0 Download VS Code from the official website

    VS Code has a powerful extension ecosystem, supporting the execution and debugging of most programming languages. For example, after installing the \"Python Extension Pack,\" you can debug Python code. The installation steps are shown in the following figure.

    Figure 16-2 \u00a0 Install VS Code Extension Pack

    "},{"location":"chapter_appendix/installation/#1612-install-language-environments","title":"16.1.2 \u00a0 Install language environments","text":""},{"location":"chapter_appendix/installation/#1-python-environment","title":"1. \u00a0 Python environment","text":"
    1. Download and install Miniconda3, requiring Python 3.10 or newer.
    2. In the VS Code extension marketplace, search for python and install the Python Extension Pack.
    3. (Optional) Enter pip install black in the command line to install the code formatting tool.
    "},{"location":"chapter_appendix/installation/#2-cc-environment","title":"2. \u00a0 C/C++ environment","text":"
    1. Windows systems need to install MinGW (Configuration tutorial); MacOS comes with Clang, so no installation is necessary.
    2. In the VS Code extension marketplace, search for c++ and install the C/C++ Extension Pack.
    3. (Optional) Open the Settings page, search for the Clang_format_fallback Style code formatting option, and set it to { BasedOnStyle: Microsoft, BreakBeforeBraces: Attach }.
    "},{"location":"chapter_appendix/installation/#3-java-environment","title":"3. \u00a0 Java environment","text":"
    1. Download and install OpenJDK (version must be > JDK 9).
    2. In the VS Code extension marketplace, search for java and install the Extension Pack for Java.
    "},{"location":"chapter_appendix/installation/#4-c-environment","title":"4. \u00a0 C# environment","text":"
    1. Download and install .Net 8.0.
    2. In the VS Code extension marketplace, search for C# Dev Kit and install the C# Dev Kit (Configuration tutorial).
    3. You can also use Visual Studio (Installation tutorial).
    "},{"location":"chapter_appendix/installation/#5-go-environment","title":"5. \u00a0 Go environment","text":"
    1. Download and install go.
    2. In the VS Code extension marketplace, search for go and install Go.
    3. Press Ctrl + Shift + P to call up the command bar, enter go, choose Go: Install/Update Tools, select all and install.
    "},{"location":"chapter_appendix/installation/#6-swift-environment","title":"6. \u00a0 Swift environment","text":"
    1. Download and install Swift.
    2. In the VS Code extension marketplace, search for swift and install Swift for Visual Studio Code.
    "},{"location":"chapter_appendix/installation/#7-javascript-environment","title":"7. \u00a0 JavaScript environment","text":"
    1. Download and install Node.js.
    2. (Optional) In the VS Code extension marketplace, search for Prettier and install the code formatting tool.
    "},{"location":"chapter_appendix/installation/#8-typescript-environment","title":"8. \u00a0 TypeScript environment","text":"
    1. Follow the same installation steps as the JavaScript environment.
    2. Install TypeScript Execute (tsx).
    3. In the VS Code extension marketplace, search for typescript and install Pretty TypeScript Errors.
    "},{"location":"chapter_appendix/installation/#9-dart-environment","title":"9. \u00a0 Dart environment","text":"
    1. Download and install Dart.
    2. In the VS Code extension marketplace, search for dart and install Dart.
    "},{"location":"chapter_appendix/installation/#10-rust-environment","title":"10. \u00a0 Rust environment","text":"
    1. Download and install Rust.
    2. In the VS Code extension marketplace, search for rust and install rust-analyzer.
    "},{"location":"chapter_appendix/terminology/","title":"16.3 \u00a0 Glossary","text":"

    The Table 16-1 lists the important terms that appear in the book, and it is worth noting the following points.

    • It is recommended to remember the English names of the terms to facilitate reading English literature.
    • Some terms have different names in Simplified and Traditional Chinese.

    Table 16-1 \u00a0 Important Terms in Data Structures and Algorithms

    English \u7b80\u4f53\u4e2d\u6587 \u7e41\u4f53\u4e2d\u6587 algorithm \u7b97\u6cd5 \u6f14\u7b97\u6cd5 data structure \u6570\u636e\u7ed3\u6784 \u8cc7\u6599\u7d50\u69cb code \u4ee3\u7801 \u7a0b\u5f0f\u78bc file \u6587\u4ef6 \u6a94\u6848 function \u51fd\u6570 \u51fd\u5f0f method \u65b9\u6cd5 \u65b9\u6cd5 variable \u53d8\u91cf \u8b8a\u6578 asymptotic complexity analysis \u6e10\u8fd1\u590d\u6742\u5ea6\u5206\u6790 \u6f38\u8fd1\u8907\u96dc\u5ea6\u5206\u6790 time complexity \u65f6\u95f4\u590d\u6742\u5ea6 \u6642\u9593\u8907\u96dc\u5ea6 space complexity \u7a7a\u95f4\u590d\u6742\u5ea6 \u7a7a\u9593\u8907\u96dc\u5ea6 loop \u5faa\u73af \u8ff4\u5708 iteration \u8fed\u4ee3 \u8fed\u4ee3 recursion \u9012\u5f52 \u905e\u8ff4 tail recursion \u5c3e\u9012\u5f52 \u5c3e\u905e\u8ff4 recursion tree \u9012\u5f52\u6811 \u905e\u8ff4\u6a39 big-\\(O\\) notation \u5927 \\(O\\) \u8bb0\u53f7 \u5927 \\(O\\) \u8a18\u865f asymptotic upper bound \u6e10\u8fd1\u4e0a\u754c \u6f38\u8fd1\u4e0a\u754c sign-magnitude \u539f\u7801 \u539f\u78bc 1\u2019s complement \u53cd\u7801 \u4e00\u88dc\u6578 2\u2019s complement \u8865\u7801 \u4e8c\u88dc\u6578 array \u6570\u7ec4 \u9663\u5217 index \u7d22\u5f15 \u7d22\u5f15 linked list \u94fe\u8868 \u93c8\u7d50\u4e32\u5217 linked list node, list node \u94fe\u8868\u8282\u70b9 \u93c8\u7d50\u4e32\u5217\u7bc0\u9ede head node \u5934\u8282\u70b9 \u982d\u7bc0\u9ede tail node \u5c3e\u8282\u70b9 \u5c3e\u7bc0\u9ede list \u5217\u8868 \u4e32\u5217 dynamic array \u52a8\u6001\u6570\u7ec4 \u52d5\u614b\u9663\u5217 hard disk \u786c\u76d8 \u786c\u789f random-access memory (RAM) \u5185\u5b58 \u8a18\u61b6\u9ad4 cache memory \u7f13\u5b58 \u5feb\u53d6 cache miss \u7f13\u5b58\u672a\u547d\u4e2d \u5feb\u53d6\u672a\u547d\u4e2d cache hit rate \u7f13\u5b58\u547d\u4e2d\u7387 \u5feb\u53d6\u547d\u4e2d\u7387 stack \u6808 \u5806\u758a top of the stack \u6808\u9876 \u5806\u758a\u9802 bottom of the stack \u6808\u5e95 \u5806\u758a\u5e95 queue \u961f\u5217 \u4f47\u5217 double-ended queue \u53cc\u5411\u961f\u5217 \u96d9\u5411\u4f47\u5217 front of the queue \u961f\u9996 \u4f47\u5217\u9996 rear of the queue \u961f\u5c3e \u4f47\u5217\u5c3e hash table \u54c8\u5e0c\u8868 \u96dc\u6e4a\u8868 hash set \u54c8\u5e0c\u96c6\u5408 \u96dc\u6e4a\u96c6\u5408 bucket \u6876 \u6876 hash function \u54c8\u5e0c\u51fd\u6570 \u96dc\u6e4a\u51fd\u5f0f hash collision \u54c8\u5e0c\u51b2\u7a81 \u96dc\u6e4a\u885d\u7a81 load factor \u8d1f\u8f7d\u56e0\u5b50 \u8ca0\u8f09\u56e0\u5b50 separate chaining \u94fe\u5f0f\u5730\u5740 \u93c8\u7d50\u4f4d\u5740 open addressing \u5f00\u653e\u5bfb\u5740 \u958b\u653e\u5b9a\u5740 linear probing \u7ebf\u6027\u63a2\u6d4b \u7dda\u6027\u63a2\u67e5 lazy deletion \u61d2\u5220\u9664 \u61f6\u522a\u9664 binary tree \u4e8c\u53c9\u6811 \u4e8c\u5143\u6a39 tree node \u6811\u8282\u70b9 \u6a39\u7bc0\u9ede left-child node \u5de6\u5b50\u8282\u70b9 \u5de6\u5b50\u7bc0\u9ede right-child node \u53f3\u5b50\u8282\u70b9 \u53f3\u5b50\u7bc0\u9ede parent node \u7236\u8282\u70b9 \u7236\u7bc0\u9ede left subtree \u5de6\u5b50\u6811 \u5de6\u5b50\u6a39 right subtree \u53f3\u5b50\u6811 \u53f3\u5b50\u6a39 root node \u6839\u8282\u70b9 \u6839\u7bc0\u9ede leaf node \u53f6\u8282\u70b9 \u8449\u7bc0\u9ede edge \u8fb9 \u908a level \u5c42 \u5c64 degree \u5ea6 \u5ea6 height \u9ad8\u5ea6 \u9ad8\u5ea6 depth \u6df1\u5ea6 \u6df1\u5ea6 perfect binary tree \u5b8c\u7f8e\u4e8c\u53c9\u6811 \u5b8c\u7f8e\u4e8c\u5143\u6a39 complete binary tree \u5b8c\u5168\u4e8c\u53c9\u6811 \u5b8c\u5168\u4e8c\u5143\u6a39 full binary tree \u5b8c\u6ee1\u4e8c\u53c9\u6811 \u5b8c\u6eff\u4e8c\u5143\u6a39 balanced binary tree \u5e73\u8861\u4e8c\u53c9\u6811 \u5e73\u8861\u4e8c\u5143\u6a39 binary search tree \u4e8c\u53c9\u641c\u7d22\u6811 \u4e8c\u5143\u641c\u5c0b\u6a39 AVL tree AVL \u6811 AVL \u6a39 red-black tree \u7ea2\u9ed1\u6811 \u7d05\u9ed1\u6a39 level-order traversal \u5c42\u5e8f\u904d\u5386 \u5c64\u5e8f\u8d70\u8a2a breadth-first traversal \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 \u5ee3\u5ea6\u512a\u5148\u8d70\u8a2a depth-first traversal \u6df1\u5ea6\u4f18\u5148\u904d\u5386 \u6df1\u5ea6\u512a\u5148\u8d70\u8a2a binary search tree \u4e8c\u53c9\u641c\u7d22\u6811 \u4e8c\u5143\u641c\u5c0b\u6a39 balanced binary search tree \u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811 \u5e73\u8861\u4e8c\u5143\u641c\u5c0b\u6a39 balance factor \u5e73\u8861\u56e0\u5b50 \u5e73\u8861\u56e0\u5b50 heap \u5806 \u5806\u7a4d max heap \u5927\u9876\u5806 \u5927\u9802\u5806\u7a4d min heap \u5c0f\u9876\u5806 \u5c0f\u9802\u5806\u7a4d priority queue \u4f18\u5148\u961f\u5217 \u512a\u5148\u4f47\u5217 heapify \u5806\u5316 \u5806\u7a4d\u5316 top-\\(k\\) problem Top-\\(k\\) \u95ee\u9898 Top-\\(k\\) \u554f\u984c graph \u56fe \u5716 vertex \u9876\u70b9 \u9802\u9ede undirected graph \u65e0\u5411\u56fe \u7121\u5411\u5716 directed graph \u6709\u5411\u56fe \u6709\u5411\u5716 connected graph \u8fde\u901a\u56fe \u9023\u901a\u5716 disconnected graph \u975e\u8fde\u901a\u56fe \u975e\u9023\u901a\u5716 weighted graph \u6709\u6743\u56fe \u6709\u6b0a\u5716 adjacency \u90bb\u63a5 \u9130\u63a5 path \u8def\u5f84 \u8def\u5f91 in-degree \u5165\u5ea6 \u5165\u5ea6 out-degree \u51fa\u5ea6 \u51fa\u5ea6 adjacency matrix \u90bb\u63a5\u77e9\u9635 \u9130\u63a5\u77e9\u9663 adjacency list \u90bb\u63a5\u8868 \u9130\u63a5\u8868 breadth-first search \u5e7f\u5ea6\u4f18\u5148\u641c\u7d22 \u5ee3\u5ea6\u512a\u5148\u641c\u5c0b depth-first search \u6df1\u5ea6\u4f18\u5148\u641c\u7d22 \u6df1\u5ea6\u512a\u5148\u641c\u5c0b binary search \u4e8c\u5206\u67e5\u627e \u4e8c\u5206\u641c\u5c0b searching algorithm \u641c\u7d22\u7b97\u6cd5 \u641c\u5c0b\u6f14\u7b97\u6cd5 sorting algorithm \u6392\u5e8f\u7b97\u6cd5 \u6392\u5e8f\u6f14\u7b97\u6cd5 selection sort \u9009\u62e9\u6392\u5e8f \u9078\u64c7\u6392\u5e8f bubble sort \u5192\u6ce1\u6392\u5e8f \u6ce1\u6cab\u6392\u5e8f insertion sort \u63d2\u5165\u6392\u5e8f \u63d2\u5165\u6392\u5e8f quick sort \u5feb\u901f\u6392\u5e8f \u5feb\u901f\u6392\u5e8f merge sort \u5f52\u5e76\u6392\u5e8f \u5408\u4f75\u6392\u5e8f heap sort \u5806\u6392\u5e8f \u5806\u7a4d\u6392\u5e8f bucket sort \u6876\u6392\u5e8f \u6876\u6392\u5e8f counting sort \u8ba1\u6570\u6392\u5e8f \u8a08\u6578\u6392\u5e8f radix sort \u57fa\u6570\u6392\u5e8f \u57fa\u6578\u6392\u5e8f divide and conquer \u5206\u6cbb \u5206\u6cbb hanota problem \u6c49\u8bfa\u5854\u95ee\u9898 \u6cb3\u5167\u5854\u554f\u984c backtracking algorithm \u56de\u6eaf\u7b97\u6cd5 \u56de\u6eaf\u6f14\u7b97\u6cd5 constraint \u7ea6\u675f \u7d04\u675f solution \u89e3 \u89e3 state \u72b6\u6001 \u72c0\u614b pruning \u526a\u679d \u526a\u679d permutations problem \u5168\u6392\u5217\u95ee\u9898 \u5168\u6392\u5217\u554f\u984c subset-sum problem \u5b50\u96c6\u548c\u95ee\u9898 \u5b50\u96c6\u5408\u554f\u984c \\(n\\)-queens problem \\(n\\) \u7687\u540e\u95ee\u9898 \\(n\\) \u7687\u540e\u554f\u984c dynamic programming \u52a8\u6001\u89c4\u5212 \u52d5\u614b\u898f\u5283 initial state \u521d\u59cb\u72b6\u6001 \u521d\u59cb\u72c0\u614b state-transition equation \u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b \u72c0\u614b\u8f49\u79fb\u65b9\u7a0b knapsack problem \u80cc\u5305\u95ee\u9898 \u80cc\u5305\u554f\u984c edit distance problem \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898 \u7de8\u8f2f\u8ddd\u96e2\u554f\u984c greedy algorithm \u8d2a\u5fc3\u7b97\u6cd5 \u8caa\u5a6a\u6f14\u7b97\u6cd5"},{"location":"chapter_array_and_linkedlist/","title":"Chapter 4. \u00a0 Arrays and linked lists","text":"

    Abstract

    The world of data structures resembles a sturdy brick wall.

    In arrays, envision bricks snugly aligned, each resting seamlessly beside the next, creating a unified formation. Meanwhile, in linked lists, these bricks disperse freely, embraced by vines gracefully knitting connections between them.

    "},{"location":"chapter_array_and_linkedlist/#chapter-contents","title":"Chapter contents","text":"
    • 4.1 \u00a0 Array
    • 4.2 \u00a0 Linked list
    • 4.3 \u00a0 List
    • 4.4 \u00a0 Memory and cache *
    • 4.5 \u00a0 Summary
    "},{"location":"chapter_array_and_linkedlist/array/","title":"4.1 \u00a0 Array","text":"

    An \"array\" is a linear data structure that operates as a lineup of similar items, stored together in a computer's memory in contiguous spaces. It's like a sequence that maintains organized storage. Each item in this lineup has its unique 'spot' known as an \"index\". Please refer to the Figure 4-1 to observe how arrays work and grasp these key terms.

    Figure 4-1 \u00a0 Array definition and storage method

    "},{"location":"chapter_array_and_linkedlist/array/#411-common-operations-on-arrays","title":"4.1.1 \u00a0 Common operations on arrays","text":""},{"location":"chapter_array_and_linkedlist/array/#1-initializing-arrays","title":"1. \u00a0 Initializing arrays","text":"

    Arrays can be initialized in two ways depending on the needs: either without initial values or with specified initial values. When initial values are not specified, most programming languages will set the array elements to \\(0\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig array.py
    # Initialize array\narr: list[int] = [0] * 5  # [ 0, 0, 0, 0, 0 ]\nnums: list[int] = [1, 3, 2, 5, 4]\n
    array.cpp
    /* Initialize array */\n// Stored on stack\nint arr[5];\nint nums[5] = { 1, 3, 2, 5, 4 };\n// Stored on heap (manual memory release needed)\nint* arr1 = new int[5];\nint* nums1 = new int[5] { 1, 3, 2, 5, 4 };\n
    array.java
    /* Initialize array */\nint[] arr = new int[5]; // { 0, 0, 0, 0, 0 }\nint[] nums = { 1, 3, 2, 5, 4 };\n
    array.cs
    /* Initialize array */\nint[] arr = new int[5]; // [ 0, 0, 0, 0, 0 ]\nint[] nums = [1, 3, 2, 5, 4];\n
    array.go
    /* Initialize array */\nvar arr [5]int\n// In Go, specifying the length ([5]int) denotes an array, while not specifying it ([]int) denotes a slice.\n// Since Go's arrays are designed to have compile-time fixed length, only constants can be used to specify the length.\n// For convenience in implementing the extend() method, the Slice will be considered as an Array here.\nnums := []int{1, 3, 2, 5, 4}\n
    array.swift
    /* Initialize array */\nlet arr = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]\nlet nums = [1, 3, 2, 5, 4]\n
    array.js
    /* Initialize array */\nvar arr = new Array(5).fill(0);\nvar nums = [1, 3, 2, 5, 4];\n
    array.ts
    /* Initialize array */\nlet arr: number[] = new Array(5).fill(0);\nlet nums: number[] = [1, 3, 2, 5, 4];\n
    array.dart
    /* Initialize array */\nList<int> arr = List.filled(5, 0); // [0, 0, 0, 0, 0]\nList<int> nums = [1, 3, 2, 5, 4];\n
    array.rs
    /* Initialize array */\nlet arr: Vec<i32> = vec![0; 5]; // [0, 0, 0, 0, 0]\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    array.c
    /* Initialize array */\nint arr[5] = { 0 }; // { 0, 0, 0, 0, 0 }\nint nums[5] = { 1, 3, 2, 5, 4 };\n
    array.kt
    \n
    array.zig
    // Initialize array\nvar arr = [_]i32{0} ** 5; // { 0, 0, 0, 0, 0 }\nvar nums = [_]i32{ 1, 3, 2, 5, 4 };\n
    "},{"location":"chapter_array_and_linkedlist/array/#2-accessing-elements","title":"2. \u00a0 Accessing elements","text":"

    Elements in an array are stored in contiguous memory spaces, making it simpler to compute each element's memory address. The formula shown in the Figure below aids in determining an element's memory address, utilizing the array's memory address (specifically, the first element's address) and the element's index. This computation streamlines direct access to the desired element.

    Figure 4-2 \u00a0 Memory address calculation for array elements

    As observed in the above illustration, array indexing conventionally begins at \\(0\\). While this might appear counterintuitive, considering counting usually starts at \\(1\\), within the address calculation formula, an index is essentially an offset from the memory address. For the first element's address, this offset is \\(0\\), validating its index as \\(0\\).

    Accessing elements in an array is highly efficient, allowing us to randomly access any element in \\(O(1)\\) time.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def random_access(nums: list[int]) -> int:\n    \"\"\"\u968f\u673a\u8bbf\u95ee\u5143\u7d20\"\"\"\n    # \u5728\u533a\u95f4 [0, len(nums)-1] \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    random_index = random.randint(0, len(nums) - 1)\n    # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    random_num = nums[random_index]\n    return random_num\n
    array.cpp
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.java
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int[] nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = ThreadLocalRandom.current().nextInt(0, nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.cs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint RandomAccess(int[] nums) {\n    Random random = new();\n    // \u5728\u533a\u95f4 [0, nums.Length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = random.Next(nums.Length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.go
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums []int) (randomNum int) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    randomIndex := rand.Intn(len(nums))\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    randomNum = nums[randomIndex]\n    return\n}\n
    array.swift
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums: [Int]) -> Int {\n    // \u5728\u533a\u95f4 [0, nums.count) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let randomIndex = nums.indices.randomElement()!\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.js
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.ts
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums: number[]): number {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.dart
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(List<int> nums) {\n  // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  int randomIndex = Random().nextInt(nums.length);\n  // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  int randomNum = nums[randomIndex];\n  return randomNum;\n}\n
    array.rs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfn random_access(nums: &[i32]) -> i32 {\n    // \u5728\u533a\u95f4 [0, nums.len()) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let random_index = rand::thread_rng().gen_range(0..nums.len());\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let random_num = nums[random_index];\n    random_num\n}\n
    array.c
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.kt
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfun randomAccess(nums: IntArray): Int {\n    // \u5728\u533a\u95f4 [0, nums.size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    val randomIndex = ThreadLocalRandom.current().nextInt(0, nums.size)\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    val randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.rb
    ### \u968f\u673a\u8bbf\u95ee\u5143\u7d20 ###\ndef random_access(nums)\n  # \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  random_index = Random.rand(0...nums.length)\n\n  # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  nums[random_index]\nend\n
    array.zig
    // \u968f\u673a\u8bbf\u95ee\u5143\u7d20\nfn randomAccess(nums: []i32) i32 {\n    // \u5728\u533a\u95f4 [0, nums.len) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6574\u6570\n    var randomIndex = std.crypto.random.intRangeLessThan(usize, 0, nums.len);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    var randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#3-inserting-elements","title":"3. \u00a0 Inserting elements","text":"

    Array elements are tightly packed in memory, with no space available to accommodate additional data between them. Illustrated in Figure below, inserting an element in the middle of an array requires shifting all subsequent elements back by one position to create room for the new element.

    Figure 4-3 \u00a0 Array element insertion example

    It's important to note that due to the fixed length of an array, inserting an element will unavoidably result in the loss of the last element in the array. Solutions to address this issue will be explored in the \"List\" chapter.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def insert(nums: list[int], num: int, index: int):\n    \"\"\"\u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\"\"\"\n    # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in range(len(nums) - 1, index, -1):\n        nums[i] = nums[i - 1]\n    # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n
    array.cpp
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid Insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.Length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums []int, num int, index int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i := len(nums) - 1; i > index; i-- {\n        nums[i] = nums[i-1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums: inout [Int], num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).reversed() {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums, num, index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums: number[], num: number, index: number): void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 _num */\nvoid insert(List<int> nums, int _num, int index) {\n  // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for (var i = nums.length - 1; i > index; i--) {\n    nums[i] = nums[i - 1];\n  }\n  // \u5c06 _num \u8d4b\u7ed9 index \u5904\u5143\u7d20\n  nums[index] = _num;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfn insert(nums: &mut Vec<i32>, num: i32, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in (index + 1..nums.len()).rev() {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfun insert(nums: IntArray, num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (i in nums.size - 1 downTo index + 1) {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num ###\ndef insert(nums, num, index)\n  # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for i in (nums.length - 1).downto(index + 1)\n    nums[i] = nums[i - 1]\n  end\n\n  # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n  nums[index] = num\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\nfn insert(nums: []i32, num: i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    var i = nums.len - 1;\n    while (i > index) : (i -= 1) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#4-deleting-elements","title":"4. \u00a0 Deleting elements","text":"

    Similarly, as depicted in the Figure 4-4 , to delete an element at index \\(i\\), all elements following index \\(i\\) must be moved forward by one position.

    Figure 4-4 \u00a0 Array element deletion example

    Please note that after deletion, the former last element becomes \"meaningless,\" hence requiring no specific modification.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def remove(nums: list[int], index: int):\n    \"\"\"\u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\"\"\"\n    # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in range(index, len(nums) - 1):\n        nums[i] = nums[i + 1]\n
    array.cpp
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.java
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.cs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid Remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.Length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.go
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums []int, index int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i := index; i < len(nums)-1; i++ {\n        nums[i] = nums[i+1]\n    }\n}\n
    array.swift
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums: inout [Int], index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).dropLast() {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.js
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums, index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.ts
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums: number[], index: number): void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.dart
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(List<int> nums, int index) {\n  // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for (var i = index; i < nums.length - 1; i++) {\n    nums[i] = nums[i + 1];\n  }\n}\n
    array.rs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfn remove(nums: &mut Vec<i32>, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in index..nums.len() - 1 {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.c
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.kt
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfun remove(nums: IntArray, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (i in index..<nums.size - 1) {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.rb
    ### \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 ###\ndef remove(nums, index)\n  # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for i in index...(nums.length - 1)\n    nums[i] = nums[i + 1]\n  end\nend\n
    array.zig
    // \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\nfn remove(nums: []i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    var i = index;\n    while (i < nums.len - 1) : (i += 1) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    Code Visualization

    Full Screen >

    In summary, the insertion and deletion operations in arrays present the following disadvantages:

    • High time complexity: Both insertion and deletion in an array have an average time complexity of \\(O(n)\\), where \\(n\\) is the length of the array.
    • Loss of elements: Due to the fixed length of arrays, elements that exceed the array's capacity are lost during insertion.
    • Waste of memory: Initializing a longer array and utilizing only the front part results in \"meaningless\" end elements during insertion, leading to some wasted memory space.
    "},{"location":"chapter_array_and_linkedlist/array/#5-traversing-arrays","title":"5. \u00a0 Traversing arrays","text":"

    In most programming languages, we can traverse an array either by using indices or by directly iterating over each element:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def traverse(nums: list[int]):\n    \"\"\"\u904d\u5386\u6570\u7ec4\"\"\"\n    count = 0\n    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in range(len(nums)):\n        count += nums[i]\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums:\n        count += num\n    # \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num in enumerate(nums):\n        count += nums[i]\n        count += num\n
    array.cpp
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.java
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (int num : nums) {\n        count += num;\n    }\n}\n
    array.cs
    /* \u904d\u5386\u6570\u7ec4 */\nvoid Traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    foreach (int num in nums) {\n        count += num;\n    }\n}\n
    array.go
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums []int) {\n    count := 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i := 0; i < len(nums); i++ {\n        count += nums[i]\n    }\n    count = 0\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for _, num := range nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num := range nums {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.swift
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums: [Int]) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in nums.indices {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for (i, num) in nums.enumerated() {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.js
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums) {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.ts
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums: number[]): void {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.dart
    /* \u904d\u5386\u6570\u7ec4\u5143\u7d20 */\nvoid traverse(List<int> nums) {\n  int count = 0;\n  // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n  }\n  // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for (int _num in nums) {\n    count += _num;\n  }\n  // \u901a\u8fc7 forEach \u65b9\u6cd5\u904d\u5386\u6570\u7ec4\n  nums.forEach((_num) {\n    count += _num;\n  });\n}\n
    array.rs
    /* \u904d\u5386\u6570\u7ec4 */\nfn traverse(nums: &[i32]) {\n    let mut _count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in 0..nums.len() {\n        _count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        _count += num;\n    }\n}\n
    array.c
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.kt
    /* \u904d\u5386\u6570\u7ec4 */\nfun traverse(nums: IntArray) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (i in nums.indices) {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (j in nums) {\n        count += j\n    }\n}\n
    array.rb
    ### \u904d\u5386\u6570\u7ec4 ###\ndef traverse(nums)\n  count = 0\n\n  # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for i in 0...nums.length\n    count += nums[i]\n  end\n\n  # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for num in nums\n    count += num\n  end\nend\n
    array.zig
    // \u904d\u5386\u6570\u7ec4\nfn traverse(nums: []i32) void {\n    var count: i32 = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    var i: i32 = 0;\n    while (i < nums.len) : (i += 1) {\n        count += nums[i];\n    }\n    count = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (nums) |num| {\n        count += num;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#6-finding-elements","title":"6. \u00a0 Finding elements","text":"

    Locating a specific element within an array involves iterating through the array, checking each element to determine if it matches the desired value.

    Because arrays are linear data structures, this operation is commonly referred to as \"linear search.\"

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def find(nums: list[int], target: int) -> int:\n    \"\"\"\u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\"\"\"\n    for i in range(len(nums)):\n        if nums[i] == target:\n            return i\n    return -1\n
    array.cpp
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int[] nums, int target) {\n    for (int i = 0; i < nums.length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint Find(int[] nums, int target) {\n    for (int i = 0; i < nums.Length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums []int, target int) (index int) {\n    index = -1\n    for i := 0; i < len(nums); i++ {\n        if nums[i] == target {\n            index = i\n            break\n        }\n    }\n    return\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums: [Int], target: Int) -> Int {\n    for i in nums.indices {\n        if nums[i] == target {\n            return i\n        }\n    }\n    return -1\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums, target) {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) return i;\n    }\n    return -1;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums: number[], target: number): number {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(List<int> nums, int target) {\n  for (var i = 0; i < nums.length; i++) {\n    if (nums[i] == target) return i;\n  }\n  return -1;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfn find(nums: &[i32], target: i32) -> Option<usize> {\n    for i in 0..nums.len() {\n        if nums[i] == target {\n            return Some(i);\n        }\n    }\n    None\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfun find(nums: IntArray, target: Int): Int {\n    for (i in nums.indices) {\n        if (nums[i] == target)\n            return i\n    }\n    return -1\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 ###\ndef find(nums, target)\n  for i in 0...nums.length\n    return i if nums[i] == target\n  end\n\n  -1\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\nfn find(nums: []i32, target: i32) i32 {\n    for (nums, 0..) |num, i| {\n        if (num == target) return @intCast(i);\n    }\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#7-expanding-arrays","title":"7. \u00a0 Expanding arrays","text":"

    In complex system environments, ensuring the availability of memory space after an array for safe capacity extension becomes challenging. Consequently, in most programming languages, the length of an array is immutable.

    To expand an array, it's necessary to create a larger array and then copy the elements from the original array. This operation has a time complexity of \\(O(n)\\) and can be time-consuming for large arrays. The code are as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def extend(nums: list[int], enlarge: int) -> list[int]:\n    \"\"\"\u6269\u5c55\u6570\u7ec4\u957f\u5ea6\"\"\"\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res = [0] * (len(nums) + enlarge)\n    # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in range(len(nums)):\n        res[i] = nums[i]\n    # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n
    array.cpp
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = new int[size + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    delete[] nums;\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.java
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.cs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] Extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.Length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.go
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums []int, enlarge int) []int {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res := make([]int, len(nums)+enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i, num := range nums {\n        res[i] = num\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.swift
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums: [Int], enlarge: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = Array(repeating: 0, count: nums.count + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in nums.indices {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.js
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cJavaScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums, enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.ts
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cTypeScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums: number[], enlarge: number): number[] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.dart
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nList<int> extend(List<int> nums, int enlarge) {\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  List<int> res = List.filled(nums.length + enlarge, 0);\n  // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    res[i] = nums[i];\n  }\n  // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  return res;\n}\n
    array.rs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfn extend(nums: Vec<i32>, enlarge: usize) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    let mut res: Vec<i32> = vec![0; nums.len() + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\n    for i in 0..nums.len() {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    res\n}\n
    array.c
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = (int *)malloc(sizeof(int) * (size + enlarge));\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u521d\u59cb\u5316\u6269\u5c55\u540e\u7684\u7a7a\u95f4\n    for (int i = size; i < size + enlarge; i++) {\n        res[i] = 0;\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.kt
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfun extend(nums: IntArray, enlarge: Int): IntArray {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    val res = IntArray(nums.size + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (i in nums.indices) {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.rb
    ### \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 ###\n# \u8bf7\u6ce8\u610f\uff0cRuby \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n# \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\ndef extend(nums, enlarge)\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  res = Array.new(nums.length + enlarge, 0)\n\n  # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for i in 0...nums.length\n    res[i] = nums[i]\n  end\n\n  # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  res\nend\n
    array.zig
    // \u6269\u5c55\u6570\u7ec4\u957f\u5ea6\nfn extend(mem_allocator: std.mem.Allocator, nums: []i32, enlarge: usize) ![]i32 {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = try mem_allocator.alloc(i32, nums.len + enlarge);\n    @memset(res, 0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    std.mem.copy(i32, res, nums);\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/array/#412-advantages-and-limitations-of-arrays","title":"4.1.2 \u00a0 Advantages and limitations of arrays","text":"

    Arrays are stored in contiguous memory spaces and consist of elements of the same type. This approach provides substantial prior information that systems can leverage to optimize the efficiency of data structure operations.

    • High space efficiency: Arrays allocate a contiguous block of memory for data, eliminating the need for additional structural overhead.
    • Support for random access: Arrays allow \\(O(1)\\) time access to any element.
    • Cache locality: When accessing array elements, the computer not only loads them but also caches the surrounding data, utilizing high-speed cache to enchance subsequent operation speeds.

    However, continuous space storage is a double-edged sword, with the following limitations:

    • Low efficiency in insertion and deletion: As arrays accumulate many elements, inserting or deleting elements requires shifting a large number of elements.
    • Fixed length: The length of an array is fixed after initialization. Expanding an array requires copying all data to a new array, incurring significant costs.
    • Space wastage: If the allocated array size exceeds the what is necessary, the extra space is wasted.
    "},{"location":"chapter_array_and_linkedlist/array/#413-typical-applications-of-arrays","title":"4.1.3 \u00a0 Typical applications of arrays","text":"

    Arrays are fundamental and widely used data structures. They find frequent application in various algorithms and serve in the implementation of complex data structures.

    • Random access: Arrays are ideal for storing data when random sampling is required. By generating a random sequence based on indices, we can achieve random sampling efficiently.
    • Sorting and searching: Arrays are the most commonly used data structure for sorting and searching algorithms. Techniques like quick sort, merge sort, binary search, etc., are primarily operate on arrays.
    • Lookup tables: Arrays serve as efficient lookup tables for quick element or relationship retrieval. For instance, mapping characters to ASCII codes becomes seamless by using the ASCII code values as indices and storing corresponding elements in the array.
    • Machine learning: Within the domain of neural networks, arrays play a pivotal role in executing crucial linear algebra operations involving vectors, matrices, and tensors. Arrays serve as the primary and most extensively used data structure in neural network programming.
    • Data structure implementation: Arrays serve as the building blocks for implementing various data structures like stacks, queues, hash tables, heaps, graphs, etc. For instance, the adjacency matrix representation of a graph is essentially a two-dimensional array.
    "},{"location":"chapter_array_and_linkedlist/linked_list/","title":"4.2 \u00a0 Linked list","text":"

    Memory space is a shared resource among all programs. In a complex system environment, available memory can be dispersed throughout the memory space. We understand that the memory allocated for an array must be continuous. However, for very large arrays, finding a sufficiently large contiguous memory space might be challenging. This is where the flexible advantage of linked lists becomes evident.

    A \"linked list\" is a linear data structure in which each element is a node object, and the nodes are interconnected through \"references\". These references hold the memory addresses of subsequent nodes, enabling navigation from one node to the next.

    The design of linked lists allows for their nodes to be distributed across memory locations without requiring contiguous memory addresses.

    Figure 4-5 \u00a0 Linked list definition and storage method

    As shown in the figure, we see that the basic building block of a linked list is the \"node\" object. Each node comprises two key components: the node's \"value\" and a \"reference\" to the next node.

    • The first node in a linked list is the \"head node\", and the final one is the \"tail node\".
    • The tail node points to \"null\", designated as null in Java, nullptr in C++, and None in Python.
    • In languages that support pointers, like C, C++, Go, and Rust, this \"reference\" is typically implemented as a \"pointer\".

    As the code below illustrates, a ListNode in a linked list, besides holding a value, must also maintain an additional reference (or pointer). Therefore, a linked list occupies more memory space than an array when storing the same quantity of data..

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    class ListNode:\n    \"\"\"Linked list node class\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val               # Node value\n        self.next: ListNode | None = None # Reference to the next node\n
    /* Linked list node structure */\nstruct ListNode {\n    int val;         // Node value\n    ListNode *next;  // Pointer to the next node\n    ListNode(int x) : val(x), next(nullptr) {}  // Constructor\n};\n
    /* Linked list node class */\nclass ListNode {\n    int val;        // Node value\n    ListNode next;  // Reference to the next node\n    ListNode(int x) { val = x; }  // Constructor\n}\n
    /* Linked list node class */\nclass ListNode(int x) {  // Constructor\n    int val = x;         // Node value\n    ListNode? next;      // Reference to the next node\n}\n
    /* Linked list node structure */\ntype ListNode struct {\n    Val  int       // Node value\n    Next *ListNode // Pointer to the next node\n}\n\n// NewListNode Constructor, creates a new linked list\nfunc NewListNode(val int) *ListNode {\n    return &ListNode{\n        Val:  val,\n        Next: nil,\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n    var val: Int // Node value\n    var next: ListNode? // Reference to the next node\n\n    init(x: Int) { // Constructor\n        val = x\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n    constructor(val, next) {\n        this.val = (val === undefined ? 0 : val);       // Node value\n        this.next = (next === undefined ? null : next); // Reference to the next node\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    constructor(val?: number, next?: ListNode | null) {\n        this.val = val === undefined ? 0 : val;        // Node value\n        this.next = next === undefined ? null : next;  // Reference to the next node\n    }\n}\n
    /* Linked list node class */\nclass ListNode {\n  int val; // Node value\n  ListNode? next; // Reference to the next node\n  ListNode(this.val, [this.next]); // Constructor\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n/* Linked list node class */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // Node value\n    next: Option<Rc<RefCell<ListNode>>>, // Pointer to the next node\n}\n
    /* Linked list node structure */\ntypedef struct ListNode {\n    int val;               // Node value\n    struct ListNode *next; // Pointer to the next node\n} ListNode;\n\n/* Constructor */\nListNode *newListNode(int val) {\n    ListNode *node;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    return node;\n}\n
    \n
    // Linked list node class\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // Node value\n        next: ?*Self = null, // Pointer to the next node\n\n        // Constructor\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n        }\n    };\n}\n
    "},{"location":"chapter_array_and_linkedlist/linked_list/#421-common-operations-on-linked-lists","title":"4.2.1 \u00a0 Common operations on linked lists","text":""},{"location":"chapter_array_and_linkedlist/linked_list/#1-initializing-a-linked-list","title":"1. \u00a0 Initializing a linked list","text":"

    Constructing a linked list is a two-step process: first, initializing each node object, and second, forming the reference links between the nodes. After initialization, we can traverse all nodes sequentially from the head node by following the next reference.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig linked_list.py
    # Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4\n# Initialize each node\nn0 = ListNode(1)\nn1 = ListNode(3)\nn2 = ListNode(2)\nn3 = ListNode(5)\nn4 = ListNode(4)\n# Build references between nodes\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.cpp
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode* n0 = new ListNode(1);\nListNode* n1 = new ListNode(3);\nListNode* n2 = new ListNode(2);\nListNode* n3 = new ListNode(5);\nListNode* n4 = new ListNode(4);\n// Build references between nodes\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.java
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode n0 = new ListNode(1);\nListNode n1 = new ListNode(3);\nListNode n2 = new ListNode(2);\nListNode n3 = new ListNode(5);\nListNode n4 = new ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.cs
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode n0 = new(1);\nListNode n1 = new(3);\nListNode n2 = new(2);\nListNode n3 = new(5);\nListNode n4 = new(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.go
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nn0 := NewListNode(1)\nn1 := NewListNode(3)\nn2 := NewListNode(2)\nn3 := NewListNode(5)\nn4 := NewListNode(4)\n// Build references between nodes\nn0.Next = n1\nn1.Next = n2\nn2.Next = n3\nn3.Next = n4\n
    linked_list.swift
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nlet n0 = ListNode(x: 1)\nlet n1 = ListNode(x: 3)\nlet n2 = ListNode(x: 2)\nlet n3 = ListNode(x: 5)\nlet n4 = ListNode(x: 4)\n// Build references between nodes\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.js
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.ts
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.dart
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode n0 = ListNode(1);\nListNode n1 = ListNode(3);\nListNode n2 = ListNode(2);\nListNode n3 = ListNode(5);\nListNode n4 = ListNode(4);\n// Build references between nodes\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.rs
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nlet n0 = Rc::new(RefCell::new(ListNode { val: 1, next: None }));\nlet n1 = Rc::new(RefCell::new(ListNode { val: 3, next: None }));\nlet n2 = Rc::new(RefCell::new(ListNode { val: 2, next: None }));\nlet n3 = Rc::new(RefCell::new(ListNode { val: 5, next: None }));\nlet n4 = Rc::new(RefCell::new(ListNode { val: 4, next: None }));\n\n// Build references between nodes\nn0.borrow_mut().next = Some(n1.clone());\nn1.borrow_mut().next = Some(n2.clone());\nn2.borrow_mut().next = Some(n3.clone());\nn3.borrow_mut().next = Some(n4.clone());\n
    linked_list.c
    /* Initialize linked list: 1 -> 3 -> 2 -> 5 -> 4 */\n// Initialize each node\nListNode* n0 = newListNode(1);\nListNode* n1 = newListNode(3);\nListNode* n2 = newListNode(2);\nListNode* n3 = newListNode(5);\nListNode* n4 = newListNode(4);\n// Build references between nodes\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.kt
    \n
    linked_list.zig
    // Initialize linked list\n// Initialize each node\nvar n0 = inc.ListNode(i32){.val = 1};\nvar n1 = inc.ListNode(i32){.val = 3};\nvar n2 = inc.ListNode(i32){.val = 2};\nvar n3 = inc.ListNode(i32){.val = 5};\nvar n4 = inc.ListNode(i32){.val = 4};\n// Build references between nodes\nn0.next = &n1;\nn1.next = &n2;\nn2.next = &n3;\nn3.next = &n4;\n

    The array as a whole is a variable, for instance, the array nums includes elements like nums[0], nums[1], and so on, whereas a linked list is made up of several distinct node objects. We typically refer to a linked list by its head node, for example, the linked list in the previous code snippet is referred to as n0.

    "},{"location":"chapter_array_and_linkedlist/linked_list/#2-inserting-nodes","title":"2. \u00a0 Inserting nodes","text":"

    Inserting a node into a linked list is very easy. As shown in the figure, let's assume we aim to insert a new node P between two adjacent nodes n0 and n1. This can be achieved by simply modifying two node references (pointers), with a time complexity of \\(O(1)\\).

    By comparison, inserting an element into an array has a time complexity of \\(O(n)\\), which becomes less efficient when dealing with large data volumes.

    Figure 4-6 \u00a0 Linked list node insertion example

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def insert(n0: ListNode, P: ListNode):\n    \"\"\"\u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\"\"\"\n    n1 = n0.next\n    P.next = n1\n    n0.next = P\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n    ListNode n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid Insert(ListNode n0, ListNode P) {\n    ListNode? n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insertNode(n0 *ListNode, P *ListNode) {\n    n1 := n0.Next\n    P.Next = n1\n    n0.Next = P\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insert(n0: ListNode, P: ListNode) {\n    let n1 = n0.next\n    P.next = n1\n    n0.next = P\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0, P) {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0: ListNode, P: ListNode): void {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n  ListNode? n1 = n0.next;\n  P.next = n1;\n  n0.next = P;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\n#[allow(non_snake_case)]\npub fn insert<T>(n0: &Rc<RefCell<ListNode<T>>>, P: Rc<RefCell<ListNode<T>>>) {\n    let n1 = n0.borrow_mut().next.take();\n    P.borrow_mut().next = n1;\n    n0.borrow_mut().next = Some(P);\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfun insert(n0: ListNode?, p: ListNode?) {\n    val n1 = n0?.next\n    p?.next = n1\n    n0?.next = p\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 _p ###\n# Ruby \u7684 `p` \u662f\u4e00\u4e2a\u5185\u7f6e\u51fd\u6570\uff0c `P` \u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u4f7f\u7528 `_p` \u4ee3\u66ff\ndef insert(n0, _p)\n  n1 = n0.next\n  _p.next = n1\n  n0.next = _p\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\nfn insert(n0: ?*inc.ListNode(i32), P: ?*inc.ListNode(i32)) void {\n    var n1 = n0.?.next;\n    P.?.next = n1;\n    n0.?.next = P;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#3-deleting-nodes","title":"3. \u00a0 Deleting nodes","text":"

    As shown in the figure, deleting a node from a linked list is also very easy, involving only the modification of a single node's reference (pointer).

    It's important to note that even though node P continues to point to n1 after being deleted, it becomes inaccessible during linked list traversal. This effectively means that P is no longer a part of the linked list.

    Figure 4-7 \u00a0 Linked list node deletion

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def remove(n0: ListNode):\n    \"\"\"\u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    if not n0.next:\n        return\n    # n0 -> P -> n1\n    P = n0.next\n    n1 = P.next\n    n0.next = n1\n
    linked_list.cpp
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode *n0) {\n    if (n0->next == nullptr)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    delete P;\n}\n
    linked_list.java
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.cs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid Remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode? n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.go
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc removeItem(n0 *ListNode) {\n    if n0.Next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    P := n0.Next\n    n1 := P.Next\n    n0.Next = n1\n}\n
    linked_list.swift
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc remove(n0: ListNode) {\n    if n0.next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    let P = n0.next\n    let n1 = P?.next\n    n0.next = n1\n}\n
    linked_list.js
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0) {\n    if (!n0.next) return;\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.ts
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0: ListNode): void {\n    if (!n0.next) {\n        return;\n    }\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.dart
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n  if (n0.next == null) return;\n  // n0 -> P -> n1\n  ListNode P = n0.next!;\n  ListNode? n1 = P.next;\n  n0.next = n1;\n}\n
    linked_list.rs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n#[allow(non_snake_case)]\npub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {\n    if n0.borrow().next.is_none() {\n        return;\n    };\n    // n0 -> P -> n1\n    let P = n0.borrow_mut().next.take();\n    if let Some(node) = P {\n        let n1 = node.borrow_mut().next.take();\n        n0.borrow_mut().next = n1;\n    }\n}\n
    linked_list.c
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(ListNode *n0) {\n    if (!n0->next)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    free(P);\n}\n
    linked_list.kt
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfun remove(n0: ListNode?) {\n    if (n0?.next == null)\n        return\n    // n0 -> P -> n1\n    val p = n0.next\n    val n1 = p?.next\n    n0.next = n1\n}\n
    linked_list.rb
    ### \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 ###\ndef remove(n0)\n  return if n0.next.nil?\n\n  # n0 -> remove_node -> n1\n  remove_node = n0.next\n  n1 = remove_node.next\n  n0.next = n1\nend\n
    linked_list.zig
    // \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\nfn remove(n0: ?*inc.ListNode(i32)) void {\n    if (n0.?.next == null) return;\n    // n0 -> P -> n1\n    var P = n0.?.next;\n    var n1 = P.?.next;\n    n0.?.next = n1;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#4-accessing-nodes","title":"4. \u00a0 Accessing nodes","text":"

    Accessing nodes in a linked list is less efficient. As previously mentioned, any element in an array can be accessed in \\(O(1)\\) time. In contrast, with a linked list, the program involves starting from the head node and sequentially traversing through the nodes until the desired node is found. In other words, to access the \\(i\\)-th node in a linked list, the program must iterate through \\(i - 1\\) nodes, resulting in a time complexity of \\(O(n)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def access(head: ListNode, index: int) -> ListNode | None:\n    \"\"\"\u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\"\"\"\n    for _ in range(index):\n        if not head:\n            return None\n        head = head.next\n    return head\n
    linked_list.cpp
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == nullptr)\n            return nullptr;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.java
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode access(ListNode head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.cs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? Access(ListNode? head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.go
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head *ListNode, index int) *ListNode {\n    for i := 0; i < index; i++ {\n        if head == nil {\n            return nil\n        }\n        head = head.Next\n    }\n    return head\n}\n
    linked_list.swift
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head: ListNode, index: Int) -> ListNode? {\n    var head: ListNode? = head\n    for _ in 0 ..< index {\n        if head == nil {\n            return nil\n        }\n        head = head?.next\n    }\n    return head\n}\n
    linked_list.js
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head, index) {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.ts
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head: ListNode | null, index: number): ListNode | null {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.dart
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? access(ListNode? head, int index) {\n  for (var i = 0; i < index; i++) {\n    if (head == null) return null;\n    head = head.next;\n  }\n  return head;\n}\n
    linked_list.rs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\npub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Rc<RefCell<ListNode<T>>> {\n    if index <= 0 {\n        return head;\n    };\n    if let Some(node) = &head.borrow().next {\n        return access(node.clone(), index - 1);\n    }\n\n    return head;\n}\n
    linked_list.c
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == NULL)\n            return NULL;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.kt
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfun access(head: ListNode?, index: Int): ListNode? {\n    var h = head\n    for (i in 0..<index) {\n        if (h == null)\n            return null\n        h = h.next\n    }\n    return h\n}\n
    linked_list.rb
    ### \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 ###\ndef access(head, index)\n  for i in 0...index\n    return nil if head.nil?\n    head = head.next\n  end\n\n  head\nend\n
    linked_list.zig
    // \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\nfn access(node: ?*inc.ListNode(i32), index: i32) ?*inc.ListNode(i32) {\n    var head = node;\n    var i: i32 = 0;\n    while (i < index) : (i += 1) {\n        head = head.?.next;\n        if (head == null) return null;\n    }\n    return head;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#5-finding-nodes","title":"5. \u00a0 Finding nodes","text":"

    Traverse the linked list to locate a node whose value matches target, and then output the index of that node within the linked list. This procedure is also an example of linear search. The corresponding code is provided below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def find(head: ListNode, target: int) -> int:\n    \"\"\"\u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    index = 0\n    while head:\n        if head.val == target:\n            return index\n        head = head.next\n        index += 1\n    return -1\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head != nullptr) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint Find(ListNode? head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc findNode(head *ListNode, target int) int {\n    index := 0\n    for head != nil {\n        if head.Val == target {\n            return index\n        }\n        head = head.Next\n        index++\n    }\n    return -1\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc find(head: ListNode, target: Int) -> Int {\n    var head: ListNode? = head\n    var index = 0\n    while head != nil {\n        if head?.val == target {\n            return index\n        }\n        head = head?.next\n        index += 1\n    }\n    return -1\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head, target) {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head: ListNode | null, target: number): number {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode? head, int target) {\n  int index = 0;\n  while (head != null) {\n    if (head.val == target) {\n      return index;\n    }\n    head = head.next;\n    index++;\n  }\n  return -1;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\npub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T, index: i32) -> i32 {\n    if head.borrow().val == target {\n        return index;\n    };\n    if let Some(node) = &head.borrow_mut().next {\n        return find(node.clone(), target, index + 1);\n    }\n    return -1;\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfun find(head: ListNode?, target: Int): Int {\n    var index = 0\n    var h = head\n    while (h != null) {\n        if (h._val == target)\n            return index\n        h = h.next\n        index++\n    }\n    return -1\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 ###\ndef find(head, target)\n  index = 0\n  while head\n    return index if head.val == target\n    head = head.next\n    index += 1\n  end\n\n  -1\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\nfn find(node: ?*inc.ListNode(i32), target: i32) i32 {\n    var head = node;\n    var index: i32 = 0;\n    while (head != null) {\n        if (head.?.val == target) return index;\n        head = head.?.next;\n        index += 1;\n    }\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#422-arrays-vs-linked-lists","title":"4.2.2 \u00a0 Arrays vs. linked lists","text":"

    The Table 4-1 summarizes the characteristics of arrays and linked lists, and it also compares their efficiencies in various operations. Because they utilize opposing storage strategies, their respective properties and operational efficiencies exhibit distinct contrasts.

    Table 4-1 \u00a0 Efficiency comparison of arrays and linked lists

    Arrays Linked Lists Storage Contiguous Memory Space Dispersed Memory Space Capacity Expansion Fixed Length Flexible Expansion Memory Efficiency Less Memory per Element, Potential Space Wastage More Memory per Element Accessing Elements \\(O(1)\\) \\(O(n)\\) Adding Elements \\(O(n)\\) \\(O(1)\\) Deleting Elements \\(O(n)\\) \\(O(1)\\)"},{"location":"chapter_array_and_linkedlist/linked_list/#423-common-types-of-linked-lists","title":"4.2.3 \u00a0 Common types of linked lists","text":"

    As shown in the figure, there are three common types of linked lists.

    • Singly linked list: This is the standard linked list described earlier. Nodes in a singly linked list include a value and a reference to the next node. The first node is known as the head node, and the last node, which points to null (None), is the tail node.
    • Circular linked list: This is formed when the tail node of a singly linked list points back to the head node, creating a loop. In a circular linked list, any node can function as the head node.
    • Doubly linked list: In contrast to a singly linked list, a doubly linked list maintains references in two directions. Each node contains references (pointer) to both its successor (the next node) and predecessor (the previous node). Although doubly linked lists offer more flexibility for traversing in either direction, they also consume more memory space.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    class ListNode:\n    \"\"\"Bidirectional linked list node class\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # Node value\n        self.next: ListNode | None = None  # Reference to the successor node\n        self.prev: ListNode | None = None  # Reference to a predecessor node\n
    /* Bidirectional linked list node structure */\nstruct ListNode {\n    int val;         // Node value\n    ListNode *next;  // Pointer to the successor node\n    ListNode *prev;  // Pointer to the predecessor node\n    ListNode(int x) : val(x), next(nullptr), prev(nullptr) {}  // Constructor\n};\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    int val;        // Node value\n    ListNode next;  // Reference to the next node\n    ListNode prev;  // Reference to the predecessor node\n    ListNode(int x) { val = x; }  // Constructor\n}\n
    /* Bidirectional linked list node class */\nclass ListNode(int x) {  // Constructor\n    int val = x;    // Node value\n    ListNode next;  // Reference to the next node\n    ListNode prev;  // Reference to the predecessor node\n}\n
    /* Bidirectional linked list node structure */\ntype DoublyListNode struct {\n    Val  int             // Node value\n    Next *DoublyListNode // Pointer to the successor node\n    Prev *DoublyListNode // Pointer to the predecessor node\n}\n\n// NewDoublyListNode initialization\nfunc NewDoublyListNode(val int) *DoublyListNode {\n    return &DoublyListNode{\n        Val:  val,\n        Next: nil,\n        Prev: nil,\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    var val: Int // Node value\n    var next: ListNode? // Reference to the next node\n    var prev: ListNode? // Reference to the predecessor node\n\n    init(x: Int) { // Constructor\n        val = x\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    constructor(val, next, prev) {\n        this.val = val  ===  undefined ? 0 : val;        // Node value\n        this.next = next  ===  undefined ? null : next;  // Reference to the successor node\n        this.prev = prev  ===  undefined ? null : prev;  // Reference to the predecessor node\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    prev: ListNode | null;\n    constructor(val?: number, next?: ListNode | null, prev?: ListNode | null) {\n        this.val = val  ===  undefined ? 0 : val;        // Node value\n        this.next = next  ===  undefined ? null : next;  // Reference to the successor node\n        this.prev = prev  ===  undefined ? null : prev;  // Reference to the predecessor node\n    }\n}\n
    /* Bidirectional linked list node class */\nclass ListNode {\n    int val;        // Node value\n    ListNode next;  // Reference to the next node\n    ListNode prev;  // Reference to the predecessor node\n    ListNode(this.val, [this.next, this.prev]);  // Constructor\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* Bidirectional linked list node type */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // Node value\n    next: Option<Rc<RefCell<ListNode>>>, // Pointer to successor node\n    prev: Option<Rc<RefCell<ListNode>>>, // Pointer to predecessor node\n}\n\n/* Constructors */\nimpl ListNode {\n    fn new(val: i32) -> Self {\n        ListNode {\n            val,\n            next: None,\n            prev: None,\n        }\n    }\n}\n
    /* Bidirectional linked list node structure */\ntypedef struct ListNode {\n    int val;               // Node value\n    struct ListNode *next; // Pointer to the successor node\n    struct ListNode *prev; // Pointer to the predecessor node\n} ListNode;\n\n/* Constructors */\nListNode *newListNode(int val) {\n    ListNode *node, *next;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    node->prev = NULL;\n    return node;\n}\n
    \n
    // Bidirectional linked list node class\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // Node value\n        next: ?*Self = null, // Pointer to the successor node\n        prev: ?*Self = null, // Pointer to the predecessor node\n\n        // Constructor\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n

    Figure 4-8 \u00a0 Common types of linked lists

    "},{"location":"chapter_array_and_linkedlist/linked_list/#424-typical-applications-of-linked-lists","title":"4.2.4 \u00a0 Typical applications of linked lists","text":"

    Singly linked lists are frequently utilized in implementing stacks, queues, hash tables, and graphs.

    • Stacks and queues: In singly linked lists, if insertions and deletions occur at the same end, it behaves like a stack (last-in-first-out). Conversely, if insertions are at one end and deletions at the other, it functions like a queue (first-in-first-out).
    • Hash tables: Linked lists are used in chaining, a popular method for resolving hash collisions. Here, all collided elements are grouped into a linked list.
    • Graphs: Adjacency lists, a standard method for graph representation, associate each graph vertex with a linked list. This list contains elements that represent vertices connected to the corresponding vertex.

    Doubly linked lists are ideal for scenarios requiring rapid access to preceding and succeeding elements.

    • Advanced data structures: In structures like red-black trees and B-trees, accessing a node's parent is essential. This is achieved by incorporating a reference to the parent node in each node, akin to a doubly linked list.
    • Browser history: In web browsers, doubly linked lists facilitate navigating the history of visited pages when users click forward or back.
    • LRU algorithm: Doubly linked lists are apt for Least Recently Used (LRU) cache eviction algorithms, enabling swift identification of the least recently used data and facilitating fast node addition and removal.

    Circular linked lists are ideal for applications that require periodic operations, such as resource scheduling in operating systems.

    • Round-robin scheduling algorithm: In operating systems, the round-robin scheduling algorithm is a common CPU scheduling method, requiring cycling through a group of processes. Each process is assigned a time slice, and upon expiration, the CPU rotates to the next process. This cyclical operation can be efficiently realized using a circular linked list, allowing for a fair and time-shared system among all processes.
    • Data buffers: Circular linked lists are also used in data buffers, like in audio and video players, where the data stream is divided into multiple buffer blocks arranged in a circular fashion for seamless playback.
    "},{"location":"chapter_array_and_linkedlist/list/","title":"4.3 \u00a0 List","text":"

    A \"list\" is an abstract data structure concept that represents an ordered collection of elements, supporting operations such as element access, modification, addition, deletion, and traversal, without requiring users to consider capacity limitations. Lists can be implemented based on linked lists or arrays.

    • A linked list inherently serves as a list, supporting operations for adding, deleting, searching, and modifying elements, with the flexibility to dynamically adjust its size.
    • Arrays also support these operations, but due to their immutable length, they can be considered as a list with a length limit.

    When implementing lists using arrays, the immutability of length reduces the practicality of the list. This is because predicting the amount of data to be stored in advance is often challenging, making it difficult to choose an appropriate list length. If the length is too small, it may not meet the requirements; if too large, it may waste memory space.

    To solve this problem, we can implement lists using a \"dynamic array.\" It inherits the advantages of arrays and can dynamically expand during program execution.

    In fact, many programming languages' standard libraries implement lists using dynamic arrays, such as Python's list, Java's ArrayList, C++'s vector, and C#'s List. In the following discussion, we will consider \"list\" and \"dynamic array\" as synonymous concepts.

    "},{"location":"chapter_array_and_linkedlist/list/#431-common-list-operations","title":"4.3.1 \u00a0 Common list operations","text":""},{"location":"chapter_array_and_linkedlist/list/#1-initializing-a-list","title":"1. \u00a0 Initializing a list","text":"

    We typically use two initialization methods: \"without initial values\" and \"with initial values\".

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Initialize list\n# Without initial values\nnums1: list[int] = []\n# With initial values\nnums: list[int] = [1, 3, 2, 5, 4]\n
    list.cpp
    /* Initialize list */\n// Note, in C++ the vector is the equivalent of nums described here\n// Without initial values\nvector<int> nums1;\n// With initial values\nvector<int> nums = { 1, 3, 2, 5, 4 };\n
    list.java
    /* Initialize list */\n// Without initial values\nList<Integer> nums1 = new ArrayList<>();\n// With initial values (note the element type should be the wrapper class Integer[] for int[])\nInteger[] numbers = new Integer[] { 1, 3, 2, 5, 4 };\nList<Integer> nums = new ArrayList<>(Arrays.asList(numbers));\n
    list.cs
    /* Initialize list */\n// Without initial values\nList<int> nums1 = [];\n// With initial values\nint[] numbers = [1, 3, 2, 5, 4];\nList<int> nums = [.. numbers];\n
    list_test.go
    /* Initialize list */\n// Without initial values\nnums1 := []int{}\n// With initial values\nnums := []int{1, 3, 2, 5, 4}\n
    list.swift
    /* Initialize list */\n// Without initial values\nlet nums1: [Int] = []\n// With initial values\nvar nums = [1, 3, 2, 5, 4]\n
    list.js
    /* Initialize list */\n// Without initial values\nconst nums1 = [];\n// With initial values\nconst nums = [1, 3, 2, 5, 4];\n
    list.ts
    /* Initialize list */\n// Without initial values\nconst nums1: number[] = [];\n// With initial values\nconst nums: number[] = [1, 3, 2, 5, 4];\n
    list.dart
    /* Initialize list */\n// Without initial values\nList<int> nums1 = [];\n// With initial values\nList<int> nums = [1, 3, 2, 5, 4];\n
    list.rs
    /* Initialize list */\n// Without initial values\nlet nums1: Vec<i32> = Vec::new();\n// With initial values\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Initialize list\nvar nums = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums.deinit();\ntry nums.appendSlice(&[_]i32{ 1, 3, 2, 5, 4 });\n
    "},{"location":"chapter_array_and_linkedlist/list/#2-accessing-elements","title":"2. \u00a0 Accessing elements","text":"

    Lists are essentially arrays, thus they can access and update elements in \\(O(1)\\) time, which is very efficient.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Access elements\nnum: int = nums[1]  # Access the element at index 1\n\n# Update elements\nnums[1] = 0    # Update the element at index 1 to 0\n
    list.cpp
    /* Access elements */\nint num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.java
    /* Access elements */\nint num = nums.get(1);  // Access the element at index 1\n\n/* Update elements */\nnums.set(1, 0);  // Update the element at index 1 to 0\n
    list.cs
    /* Access elements */\nint num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list_test.go
    /* Access elements */\nnum := nums[1]  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0     // Update the element at index 1 to 0\n
    list.swift
    /* Access elements */\nlet num = nums[1] // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0 // Update the element at index 1 to 0\n
    list.js
    /* Access elements */\nconst num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.ts
    /* Access elements */\nconst num: number = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.dart
    /* Access elements */\nint num = nums[1];  // Access the element at index 1\n\n/* Update elements */\nnums[1] = 0;  // Update the element at index 1 to 0\n
    list.rs
    /* Access elements */\nlet num: i32 = nums[1];  // Access the element at index 1\n/* Update elements */\nnums[1] = 0;             // Update the element at index 1 to 0\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Access elements\nvar num = nums.items[1]; // Access the element at index 1\n\n// Update elements\nnums.items[1] = 0; // Update the element at index 1 to 0  \n
    "},{"location":"chapter_array_and_linkedlist/list/#3-inserting-and-removing-elements","title":"3. \u00a0 Inserting and removing elements","text":"

    Compared to arrays, lists offer more flexibility in adding and removing elements. While adding elements to the end of a list is an \\(O(1)\\) operation, the efficiency of inserting and removing elements elsewhere in the list remains the same as in arrays, with a time complexity of \\(O(n)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Clear list\nnums.clear()\n\n# Append elements at the end\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n# Insert element in the middle\nnums.insert(3, 6)  # Insert number 6 at index 3\n\n# Remove elements\nnums.pop(3)        # Remove the element at index 3\n
    list.cpp
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.push_back(1);\nnums.push_back(3);\nnums.push_back(2);\nnums.push_back(5);\nnums.push_back(4);\n\n/* Insert element in the middle */\nnums.insert(nums.begin() + 3, 6);  // Insert number 6 at index 3\n\n/* Remove elements */\nnums.erase(nums.begin() + 3);      // Remove the element at index 3\n
    list.java
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* Insert element in the middle */\nnums.add(3, 6);  // Insert number 6 at index 3\n\n/* Remove elements */\nnums.remove(3);  // Remove the element at index 3\n
    list.cs
    /* Clear list */\nnums.Clear();\n\n/* Append elements at the end */\nnums.Add(1);\nnums.Add(3);\nnums.Add(2);\nnums.Add(5);\nnums.Add(4);\n\n/* Insert element in the middle */\nnums.Insert(3, 6);\n\n/* Remove elements */\nnums.RemoveAt(3);\n
    list_test.go
    /* Clear list */\nnums = nil\n\n/* Append elements at the end */\nnums = append(nums, 1)\nnums = append(nums, 3)\nnums = append(nums, 2)\nnums = append(nums, 5)\nnums = append(nums, 4)\n\n/* Insert element in the middle */\nnums = append(nums[:3], append([]int{6}, nums[3:]...)...) // Insert number 6 at index 3\n\n/* Remove elements */\nnums = append(nums[:3], nums[4:]...) // Remove the element at index 3\n
    list.swift
    /* Clear list */\nnums.removeAll()\n\n/* Append elements at the end */\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n/* Insert element in the middle */\nnums.insert(6, at: 3) // Insert number 6 at index 3\n\n/* Remove elements */\nnums.remove(at: 3) // Remove the element at index 3\n
    list.js
    /* Clear list */\nnums.length = 0;\n\n/* Append elements at the end */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* Insert element in the middle */\nnums.splice(3, 0, 6);\n\n/* Remove elements */\nnums.splice(3, 1);\n
    list.ts
    /* Clear list */\nnums.length = 0;\n\n/* Append elements at the end */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* Insert element in the middle */\nnums.splice(3, 0, 6);\n\n/* Remove elements */\nnums.splice(3, 1);\n
    list.dart
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* Insert element in the middle */\nnums.insert(3, 6); // Insert number 6 at index 3\n\n/* Remove elements */\nnums.removeAt(3); // Remove the element at index 3\n
    list.rs
    /* Clear list */\nnums.clear();\n\n/* Append elements at the end */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* Insert element in the middle */\nnums.insert(3, 6);  // Insert number 6 at index 3\n\n/* Remove elements */\nnums.remove(3);    // Remove the element at index 3\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Clear list\nnums.clearRetainingCapacity();\n\n// Append elements at the end\ntry nums.append(1);\ntry nums.append(3);\ntry nums.append(2);\ntry nums.append(5);\ntry nums.append(4);\n\n// Insert element in the middle\ntry nums.insert(3, 6); // Insert number 6 at index 3\n\n// Remove elements\n_ = nums.orderedRemove(3); // Remove the element at index 3\n
    "},{"location":"chapter_array_and_linkedlist/list/#4-iterating-the-list","title":"4. \u00a0 Iterating the list","text":"

    Similar to arrays, lists can be iterated either by using indices or by directly iterating through each element.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Iterate through the list by index\ncount = 0\nfor i in range(len(nums)):\n    count += nums[i]\n\n# Iterate directly through list elements\nfor num in nums:\n    count += num\n
    list.cpp
    /* Iterate through the list by index */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (int num : nums) {\n    count += num;\n}\n
    list.java
    /* Iterate through the list by index */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums.get(i);\n}\n\n/* Iterate directly through list elements */\nfor (int num : nums) {\n    count += num;\n}\n
    list.cs
    /* Iterate through the list by index */\nint count = 0;\nfor (int i = 0; i < nums.Count; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nforeach (int num in nums) {\n    count += num;\n}\n
    list_test.go
    /* Iterate through the list by index */\ncount := 0\nfor i := 0; i < len(nums); i++ {\n    count += nums[i]\n}\n\n/* Iterate directly through list elements */\ncount = 0\nfor _, num := range nums {\n    count += num\n}\n
    list.swift
    /* Iterate through the list by index */\nvar count = 0\nfor i in nums.indices {\n    count += nums[i]\n}\n\n/* Iterate directly through list elements */\ncount = 0\nfor num in nums {\n    count += num\n}\n
    list.js
    /* Iterate through the list by index */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.ts
    /* Iterate through the list by index */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.dart
    /* Iterate through the list by index */\nint count = 0;\nfor (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* Iterate directly through list elements */\ncount = 0;\nfor (var num in nums) {\n    count += num;\n}\n
    list.rs
    // Iterate through the list by index\nlet mut _count = 0;\nfor i in 0..nums.len() {\n    _count += nums[i];\n}\n\n// Iterate directly through list elements\n_count = 0;\nfor num in &nums {\n    _count += num;\n}\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Iterate through the list by index\nvar count: i32 = 0;\nvar i: i32 = 0;\nwhile (i < nums.items.len) : (i += 1) {\n    count += nums[i];\n}\n\n// Iterate directly through list elements\ncount = 0;\nfor (nums.items) |num| {\n    count += num;\n}\n
    "},{"location":"chapter_array_and_linkedlist/list/#5-concatenating-lists","title":"5. \u00a0 Concatenating lists","text":"

    Given a new list nums1, we can append it to the end of the original list.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Concatenate two lists\nnums1: list[int] = [6, 8, 7, 10, 9]\nnums += nums1  # Concatenate nums1 to the end of nums\n
    list.cpp
    /* Concatenate two lists */\nvector<int> nums1 = { 6, 8, 7, 10, 9 };\n// Concatenate nums1 to the end of nums\nnums.insert(nums.end(), nums1.begin(), nums1.end());\n
    list.java
    /* Concatenate two lists */\nList<Integer> nums1 = new ArrayList<>(Arrays.asList(new Integer[] { 6, 8, 7, 10, 9 }));\nnums.addAll(nums1);  // Concatenate nums1 to the end of nums\n
    list.cs
    /* Concatenate two lists */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.AddRange(nums1);  // Concatenate nums1 to the end of nums\n
    list_test.go
    /* Concatenate two lists */\nnums1 := []int{6, 8, 7, 10, 9}\nnums = append(nums, nums1...)  // Concatenate nums1 to the end of nums\n
    list.swift
    /* Concatenate two lists */\nlet nums1 = [6, 8, 7, 10, 9]\nnums.append(contentsOf: nums1) // Concatenate nums1 to the end of nums\n
    list.js
    /* Concatenate two lists */\nconst nums1 = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // Concatenate nums1 to the end of nums\n
    list.ts
    /* Concatenate two lists */\nconst nums1: number[] = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // Concatenate nums1 to the end of nums\n
    list.dart
    /* Concatenate two lists */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.addAll(nums1);  // Concatenate nums1 to the end of nums\n
    list.rs
    /* Concatenate two lists */\nlet nums1: Vec<i32> = vec![6, 8, 7, 10, 9];\nnums.extend(nums1);\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Concatenate two lists\nvar nums1 = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums1.deinit();\ntry nums1.appendSlice(&[_]i32{ 6, 8, 7, 10, 9 });\ntry nums.insertSlice(nums.items.len, nums1.items); // Concatenate nums1 to the end of nums\n
    "},{"location":"chapter_array_and_linkedlist/list/#6-sorting-the-list","title":"6. \u00a0 Sorting the list","text":"

    Once the list is sorted, we can employ algorithms commonly used in array-related algorithm problems, such as \"binary search\" and \"two-pointer\" algorithms.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig list.py
    # Sort the list\nnums.sort()  # After sorting, the list elements are in ascending order\n
    list.cpp
    /* Sort the list */\nsort(nums.begin(), nums.end());  // After sorting, the list elements are in ascending order\n
    list.java
    /* Sort the list */\nCollections.sort(nums);  // After sorting, the list elements are in ascending order\n
    list.cs
    /* Sort the list */\nnums.Sort(); // After sorting, the list elements are in ascending order\n
    list_test.go
    /* Sort the list */\nsort.Ints(nums)  // After sorting, the list elements are in ascending order\n
    list.swift
    /* Sort the list */\nnums.sort() // After sorting, the list elements are in ascending order\n
    list.js
    /* Sort the list */  \nnums.sort((a, b) => a - b);  // After sorting, the list elements are in ascending order\n
    list.ts
    /* Sort the list */\nnums.sort((a, b) => a - b);  // After sorting, the list elements are in ascending order\n
    list.dart
    /* Sort the list */\nnums.sort(); // After sorting, the list elements are in ascending order\n
    list.rs
    /* Sort the list */\nnums.sort(); // After sorting, the list elements are in ascending order\n
    list.c
    // C does not provide built-in dynamic arrays\n
    list.kt
    \n
    list.zig
    // Sort the list\nstd.sort.sort(i32, nums.items, {}, comptime std.sort.asc(i32));\n
    "},{"location":"chapter_array_and_linkedlist/list/#432-list-implementation","title":"4.3.2 \u00a0 List implementation","text":"

    Many programming languages come with built-in lists, including Java, C++, Python, etc. Their implementations tend to be intricate, featuring carefully considered settings for various parameters, like initial capacity and expansion factors. Readers who are curious can delve into the source code for further learning.

    To enhance our understanding of how lists work, we will attempt to implement a simplified version of a list, focusing on three crucial design aspects:

    • Initial capacity: Choose a reasonable initial capacity for the array. In this example, we choose 10 as the initial capacity.
    • Size recording: Declare a variable size to record the current number of elements in the list, updating in real-time with element insertion and deletion. With this variable, we can locate the end of the list and determine whether expansion is needed.
    • Expansion mechanism: If the list reaches full capacity upon an element insertion, an expansion process is required. This involves creating a larger array based on the expansion factor, and then transferring all elements from the current array to the new one. In this example, we stipulate that the array size should double with each expansion.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_list.py
    class MyList:\n    \"\"\"\u5217\u8868\u7c7b\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._capacity: int = 10  # \u5217\u8868\u5bb9\u91cf\n        self._arr: list[int] = [0] * self._capacity  # \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        self._size: int = 0  # \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        self._extend_ratio: int = 2  # \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\"\"\"\n        return self._size\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u5bb9\u91cf\"\"\"\n        return self._capacity\n\n    def get(self, index: int) -> int:\n        \"\"\"\u8bbf\u95ee\u5143\u7d20\"\"\"\n        # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        return self._arr[index]\n\n    def set(self, num: int, index: int):\n        \"\"\"\u66f4\u65b0\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        self._arr[index] = num\n\n    def add(self, num: int):\n        \"\"\"\u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\"\"\"\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size() == self.capacity():\n            self.extend_capacity()\n        self._arr[self._size] = num\n        self._size += 1\n\n    def insert(self, num: int, index: int):\n        \"\"\"\u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self._size == self.capacity():\n            self.extend_capacity()\n        # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in range(self._size - 1, index - 1, -1):\n            self._arr[j + 1] = self._arr[j]\n        self._arr[index] = num\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size += 1\n\n    def remove(self, index: int) -> int:\n        \"\"\"\u5220\u9664\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        num = self._arr[index]\n        # \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in range(index, self._size - 1):\n            self._arr[j] = self._arr[j + 1]\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size -= 1\n        # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n\n    def extend_capacity(self):\n        \"\"\"\u5217\u8868\u6269\u5bb9\"\"\"\n        # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1)\n        # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self._capacity = len(self._arr)\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868\"\"\"\n        return self._arr[: self._size]\n
    my_list.cpp
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  private:\n    int *arr;             // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int arrCapacity = 10; // \u5217\u8868\u5bb9\u91cf\n    int arrSize = 0;      // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    int extendRatio = 2;   // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~MyList() {\n        delete[] arr;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    int size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    int capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    void set(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        arr[size()] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    void insert(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size() - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    int remove(int index) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size() - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n        int newCapacity = capacity() * extendRatio;\n        int *tmp = arr;\n        arr = new int[newCapacity];\n        // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            arr[i] = tmp[i];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete[] tmp;\n        arrCapacity = newCapacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Vector \u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> vec(size());\n        for (int i = 0; i < size(); i++) {\n            vec[i] = arr[i];\n        }\n        return vec;\n    }\n};\n
    my_list.java
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    private int size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private int extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[capacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    public int size() {\n        return size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int capacity() {\n        return capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void set(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        arr[size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void insert(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int remove(int index) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = Arrays.copyOf(arr, capacity() * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] toArray() {\n        int size = size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[size];\n        for (int i = 0; i < size; i++) {\n            arr[i] = get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.cs
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr;           // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int arrCapacity = 10;    // \u5217\u8868\u5bb9\u91cf\n    private int arrSize = 0;         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private readonly int extendRatio = 2;  // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public int Size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int Capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int Get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void Set(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void Add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        arr[arrSize] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void Insert(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = arrSize - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int Remove(int index) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < arrSize - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void ExtendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a arrCapacity * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        Array.Resize(ref arr, arrCapacity * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        arrCapacity = arr.Length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[arrSize];\n        for (int i = 0; i < arrSize; i++) {\n            arr[i] = Get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.go
    /* \u5217\u8868\u7c7b */\ntype myList struct {\n    arrCapacity int\n    arr         []int\n    arrSize     int\n    extendRatio int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newMyList() *myList {\n    return &myList{\n        arrCapacity: 10,              // \u5217\u8868\u5bb9\u91cf\n        arr:         make([]int, 10), // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrSize:     0,               // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: 2,               // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n    }\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\nfunc (l *myList) size() int {\n    return l.arrSize\n}\n\n/*  \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nfunc (l *myList) capacity() int {\n    return l.arrCapacity\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nfunc (l *myList) get(index int) int {\n    // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    return l.arr[index]\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nfunc (l *myList) set(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    l.arr[index] = num\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nfunc (l *myList) add(num int) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    l.arr[l.arrSize] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nfunc (l *myList) insert(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j := l.arrSize - 1; j >= index; j-- {\n        l.arr[j+1] = l.arr[j]\n    }\n    l.arr[index] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5220\u9664\u5143\u7d20 */\nfunc (l *myList) remove(index int) int {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    num := l.arr[index]\n    // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j := index; j < l.arrSize-1; j++ {\n        l.arr[j] = l.arr[j+1]\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize--\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return num\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nfunc (l *myList) extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    l.arr = append(l.arr, make([]int, l.arrCapacity*(l.extendRatio-1))...)\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    l.arrCapacity = len(l.arr)\n}\n\n/* \u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868 */\nfunc (l *myList) toArray() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    return l.arr[:l.arrSize]\n}\n
    my_list.swift
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: [Int] // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var _capacity: Int // \u5217\u8868\u5bb9\u91cf\n    private var _size: Int // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private let extendRatio: Int // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        _capacity = 10\n        _size = 0\n        extendRatio = 2\n        arr = Array(repeating: 0, count: _capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    func size() -> Int {\n        _size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    func capacity() -> Int {\n        _capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    func get(index: Int) -> Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\u5219\u629b\u51fa\u9519\u8bef\uff0c\u4e0b\u540c\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    func set(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    func add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        arr[size()] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    func insert(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index ..< size()).reversed() {\n            arr[j + 1] = arr[j]\n        }\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    @discardableResult\n    func remove(index: Int) -> Int {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        let num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in index ..< (size() - 1) {\n            arr[j] = arr[j + 1]\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size -= 1\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    func extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr + Array(repeating: 0, count: capacity() * (extendRatio - 1))\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        _capacity = arr.count\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        Array(arr.prefix(size()))\n    }\n}\n
    my_list.js
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    #arr = new Array(); // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    #capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    #size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    #extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#arr = new Array(this.#capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    size() {\n        return this.#size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    capacity() {\n        return this.#capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    get(index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.#arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    set(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.#arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    add(num) {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.#arr[this.#size] = num;\n        this.#size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    insert(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this.#size - 1; j >= index; j--) {\n            this.#arr[j + 1] = this.#arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#arr[index] = num;\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    remove(index) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.#arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this.#size - 1; j++) {\n            this.#arr[j] = this.#arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.#arr = this.#arr.concat(\n            new Array(this.capacity() * (this.#extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this.#capacity = this.#arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    toArray() {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.ts
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private arr: Array<number>; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private _capacity: number = 10; // \u5217\u8868\u5bb9\u91cf\n    private _size: number = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private extendRatio: number = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.arr = new Array(this._capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public size(): number {\n        return this._size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public capacity(): number {\n        return this._capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public get(index: number): number {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public set(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public add(num: number): void {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this._size === this._capacity) this.extendCapacity();\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.arr[this._size] = num;\n        this._size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public insert(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this._size === this._capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this._size - 1; j >= index; j--) {\n            this.arr[j + 1] = this.arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.arr[index] = num;\n        this._size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public remove(index: number): number {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this._size - 1; j++) {\n            this.arr[j] = this.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this._size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public extendCapacity(): void {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.arr = this.arr.concat(\n            new Array(this.capacity() * (this.extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this._capacity = this.arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public toArray(): number[] {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.dart
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  late List<int> _arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n  int _capacity = 10; // \u5217\u8868\u5bb9\u91cf\n  int _size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  int _extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  MyList() {\n    _arr = List.filled(_capacity, 0);\n  }\n\n  /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n  int size() => _size;\n\n  /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n  int capacity() => _capacity;\n\n  /* \u8bbf\u95ee\u5143\u7d20 */\n  int get(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    return _arr[index];\n  }\n\n  /* \u66f4\u65b0\u5143\u7d20 */\n  void set(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    _arr[index] = _num;\n  }\n\n  /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n  void add(int _num) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    _arr[_size] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n  void insert(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (var j = _size - 1; j >= index; j--) {\n      _arr[j + 1] = _arr[j];\n    }\n    _arr[index] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5220\u9664\u5143\u7d20 */\n  int remove(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    int _num = _arr[index];\n    // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (var j = index; j < _size - 1; j++) {\n      _arr[j] = _arr[j + 1];\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size--;\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return _num;\n  }\n\n  /* \u5217\u8868\u6269\u5bb9 */\n  void extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n    final _newNums = List.filled(_capacity * _extendRatio, 0);\n    // \u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    List.copyRange(_newNums, 0, _arr);\n    // \u66f4\u65b0 _arr \u7684\u5f15\u7528\n    _arr = _newNums;\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    _capacity = _arr.length;\n  }\n\n  /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n  List<int> toArray() {\n    List<int> arr = [];\n    for (var i = 0; i < _size; i++) {\n      arr.add(get(i));\n    }\n    return arr;\n  }\n}\n
    my_list.rs
    /* \u5217\u8868\u7c7b */\n#[allow(dead_code)]\nstruct MyList {\n    arr: Vec<i32>,       // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    capacity: usize,     // \u5217\u8868\u5bb9\u91cf\n    size: usize,         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    extend_ratio: usize, // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n}\n\n#[allow(unused, unused_comparisons)]\nimpl MyList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        let mut vec = Vec::new();\n        vec.resize(capacity, 0);\n        Self {\n            arr: vec,\n            capacity,\n            size: 0,\n            extend_ratio: 2,\n        }\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    pub fn size(&self) -> usize {\n        return self.size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        return self.capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    pub fn get(&self, index: usize) -> i32 {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        return self.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    pub fn set(&mut self, index: usize, num: i32) {\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        self.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    pub fn add(&mut self, num: i32) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        self.arr[self.size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    pub fn insert(&mut self, index: usize, num: i32) {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size).rev() {\n            self.arr[j + 1] = self.arr[j];\n        }\n        self.arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    pub fn remove(&mut self, index: usize) -> i32 {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        let num = self.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size - 1) {\n            self.arr[j] = self.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size -= 1;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    pub fn extend_capacity(&mut self) {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        let new_capacity = self.capacity * self.extend_ratio;\n        self.arr.resize(new_capacity, 0);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self.capacity = new_capacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    pub fn to_array(&mut self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut arr = Vec::new();\n        for i in 0..self.size {\n            arr.push(self.get(i));\n        }\n        arr\n    }\n}\n
    my_list.c
    /* \u5217\u8868\u7c7b */\ntypedef struct {\n    int *arr;        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int capacity;    // \u5217\u8868\u5bb9\u91cf\n    int size;        // \u5217\u8868\u5927\u5c0f\n    int extendRatio; // \u5217\u8868\u6bcf\u6b21\u6269\u5bb9\u7684\u500d\u6570\n} MyList;\n\n/* \u6784\u9020\u51fd\u6570 */\nMyList *newMyList() {\n    MyList *nums = malloc(sizeof(MyList));\n    nums->capacity = 10;\n    nums->arr = malloc(sizeof(int) * nums->capacity);\n    nums->size = 0;\n    nums->extendRatio = 2;\n    return nums;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delMyList(MyList *nums) {\n    free(nums->arr);\n    free(nums);\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6 */\nint size(MyList *nums) {\n    return nums->size;\n}\n\n/* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nint capacity(MyList *nums) {\n    return nums->capacity;\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint get(MyList *nums, int index) {\n    assert(index >= 0 && index < nums->size);\n    return nums->arr[index];\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nvoid set(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < nums->size);\n    nums->arr[index] = num;\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nvoid add(MyList *nums, int num) {\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    nums->arr[size(nums)] = num;\n    nums->size++;\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nvoid insert(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < size(nums));\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    for (int i = size(nums); i > index; --i) {\n        nums->arr[i] = nums->arr[i - 1];\n    }\n    nums->arr[index] = num;\n    nums->size++;\n}\n\n/* \u5220\u9664\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nint removeItem(MyList *nums, int index) {\n    assert(index >= 0 && index < size(nums));\n    int num = nums->arr[index];\n    for (int i = index; i < size(nums) - 1; i++) {\n        nums->arr[i] = nums->arr[i + 1];\n    }\n    nums->size--;\n    return num;\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nvoid extendCapacity(MyList *nums) {\n    // \u5148\u5206\u914d\u7a7a\u95f4\n    int newCapacity = capacity(nums) * nums->extendRatio;\n    int *extend = (int *)malloc(sizeof(int) * newCapacity);\n    int *temp = nums->arr;\n\n    // \u62f7\u8d1d\u65e7\u6570\u636e\u5230\u65b0\u6570\u636e\n    for (int i = 0; i < size(nums); i++)\n        extend[i] = nums->arr[i];\n\n    // \u91ca\u653e\u65e7\u6570\u636e\n    free(temp);\n\n    // \u66f4\u65b0\u65b0\u6570\u636e\n    nums->arr = extend;\n    nums->capacity = newCapacity;\n}\n\n/* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Array \u7528\u4e8e\u6253\u5370 */\nint *toArray(MyList *nums) {\n    return nums->arr;\n}\n
    my_list.kt
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: IntArray = intArrayOf() // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var capacity: Int = 10 // \u5217\u8868\u5bb9\u91cf\n    private var size: Int = 0 // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private var extendRatio: Int = 2 // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        arr = IntArray(capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    fun size(): Int {\n        return size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    fun capacity(): Int {\n        return capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    fun get(index: Int): Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    fun set(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    fun add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        arr[size] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    fun insert(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (j in size - 1 downTo index)\n            arr[j + 1] = arr[j]\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    fun remove(index: Int): Int {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        val num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (j in index..<size - 1)\n            arr[j] = arr[j + 1]\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    fun extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr.copyOf(capacity() * extendRatio)\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.size\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        val size = size()\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val arr = IntArray(size)\n        for (i in 0..<size) {\n            arr[i] = get(i)\n        }\n        return arr\n    }\n}\n
    my_list.rb
    ### \u5217\u8868\u7c7b ###\nclass MyList\n  attr_reader :size       # \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  attr_reader :capacity   # \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @capacity = 10\n    @size = 0\n    @extend_ratio = 2\n    @arr = Array.new(capacity)\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def get(index)\n    # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index]\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def set(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index] = num\n  end\n\n  ### \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 ###\n  def add(num)\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n    @arr[size] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 ###\n  def insert(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n\n    # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j in (size - 1).downto(index)\n      @arr[j + 1] = @arr[j]\n    end\n    @arr[index] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5220\u9664\u5143\u7d20 ###\n  def remove(index)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    num = @arr[index]\n\n    # \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j in index...size\n      @arr[j] = @arr[j + 1]\n    end\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size -= 1\n\n    # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    num\n  end\n\n  ### \u5217\u8868\u6269\u5bb9 ###\n  def extend_capacity\n    # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1))\n    # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    @capacity = arr.length\n  end\n\n  ### \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 ###\n  def to_array\n    sz = size\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    arr = Array.new(sz)\n    for i in 0...sz\n      arr[i] = get(i)\n    end\n    arr\n  end\nend\n
    my_list.zig
    // \u5217\u8868\u7c7b\nfn MyList(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        arr: []T = undefined,                        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrCapacity: usize = 10,                     // \u5217\u8868\u5bb9\u91cf\n        numSize: usize = 0,                           // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: usize = 2,                       // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined, // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u5217\u8868\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.arr = try self.mem_allocator.alloc(T, self.arrCapacity);\n            @memset(self.arr, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        pub fn size(self: *Self) usize {\n            return self.numSize;\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.arrCapacity;\n        }\n\n        // \u8bbf\u95ee\u5143\u7d20\n        pub fn get(self: *Self, index: usize) T {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            return self.arr[index];\n        }  \n\n        // \u66f4\u65b0\u5143\u7d20\n        pub fn set(self: *Self, index: usize, num: T) void {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            self.arr[index] = num;\n        }  \n\n        // \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\n        pub fn add(self: *Self, num: T) !void {\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            self.arr[self.size()] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }  \n\n        // \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\n        pub fn insert(self: *Self, index: usize, num: T) !void {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n            var j = self.size() - 1;\n            while (j >= index) : (j -= 1) {\n                self.arr[j + 1] = self.arr[j];\n            }\n            self.arr[index] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }\n\n        // \u5220\u9664\u5143\u7d20\n        pub fn remove(self: *Self, index: usize) T {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            var num = self.arr[index];\n            // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n            var j = index;\n            while (j < self.size() - 1) : (j += 1) {\n                self.arr[j] = self.arr[j + 1];\n            }\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize -= 1;\n            // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n            return num;\n        }\n\n        // \u5217\u8868\u6269\u5bb9\n        pub fn extendCapacity(self: *Self) !void {\n            // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            var newCapacity = self.capacity() * self.extendRatio;\n            var extend = try self.mem_allocator.alloc(T, newCapacity);\n            @memset(extend, @as(T, 0));\n            // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            std.mem.copy(T, extend, self.arr);\n            self.arr = extend;\n            // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n            self.arrCapacity = newCapacity;\n        }\n\n        // \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var arr = try self.mem_allocator.alloc(T, self.size());\n           @memset(arr, @as(T, 0));\n            for (arr, 0..) |*num, i| {\n                num.* = self.get(i);\n            }\n            return arr;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/","title":"4.4 \u00a0 Memory and cache *","text":"

    In the first two sections of this chapter, we explored arrays and linked lists, two fundamental and important data structures, representing \"continuous storage\" and \"dispersed storage\" respectively.

    In fact, the physical structure largely determines the efficiency of a program's use of memory and cache, which in turn affects the overall performance of the algorithm.

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#441-computer-storage-devices","title":"4.4.1 \u00a0 Computer storage devices","text":"

    There are three types of storage devices in computers: \"hard disk,\" \"random-access memory (RAM),\" and \"cache memory.\" The following table shows their different roles and performance characteristics in computer systems.

    Table 4-2 \u00a0 Computer storage devices

    Hard Disk Memory Cache Usage Long-term storage of data, including OS, programs, files, etc. Temporary storage of currently running programs and data being processed Stores frequently accessed data and instructions, reducing the number of CPU accesses to memory Volatility Data is not lost after power off Data is lost after power off Data is lost after power off Capacity Larger, TB level Smaller, GB level Very small, MB level Speed Slower, several hundred to thousands MB/s Faster, several tens of GB/s Very fast, several tens to hundreds of GB/s Price Cheaper, several cents to yuan / GB More expensive, tens to hundreds of yuan / GB Very expensive, priced with CPU

    We can imagine the computer storage system as a pyramid structure shown in the Figure 4-9 . The storage devices closer to the top of the pyramid are faster, have smaller capacity, and are more costly. This multi-level design is not accidental, but the result of careful consideration by computer scientists and engineers.

    • Hard disks are difficult to replace with memory. Firstly, data in memory is lost after power off, making it unsuitable for long-term data storage; secondly, the cost of memory is dozens of times that of hard disks, making it difficult to popularize in the consumer market.
    • It is difficult for caches to have both large capacity and high speed. As the capacity of L1, L2, L3 caches gradually increases, their physical size becomes larger, increasing the physical distance from the CPU core, leading to increased data transfer time and higher element access latency. Under current technology, a multi-level cache structure is the best balance between capacity, speed, and cost.

    Figure 4-9 \u00a0 Computer storage system

    Tip

    The storage hierarchy of computers reflects a delicate balance between speed, capacity, and cost. In fact, this kind of trade-off is common in all industrial fields, requiring us to find the best balance between different advantages and limitations.

    Overall, hard disks are used for long-term storage of large amounts of data, memory is used for temporary storage of data being processed during program execution, and cache is used to store frequently accessed data and instructions to improve program execution efficiency. Together, they ensure the efficient operation of computer systems.

    As shown in the Figure 4-10 , during program execution, data is read from the hard disk into memory for CPU computation. The cache can be considered a part of the CPU, smartly loading data from memory to provide fast data access to the CPU, significantly enhancing program execution efficiency and reducing reliance on slower memory.

    Figure 4-10 \u00a0 Data flow between hard disk, memory, and cache

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#442-memory-efficiency-of-data-structures","title":"4.4.2 \u00a0 Memory efficiency of data structures","text":"

    In terms of memory space utilization, arrays and linked lists have their advantages and limitations.

    On one hand, memory is limited and cannot be shared by multiple programs, so we hope that data structures can use space as efficiently as possible. The elements of an array are tightly packed without extra space for storing references (pointers) between linked list nodes, making them more space-efficient. However, arrays require allocating sufficient continuous memory space at once, which may lead to memory waste, and array expansion also requires additional time and space costs. In contrast, linked lists allocate and reclaim memory dynamically on a per-node basis, providing greater flexibility.

    On the other hand, during program execution, as memory is repeatedly allocated and released, the degree of fragmentation of free memory becomes higher, leading to reduced memory utilization efficiency. Arrays, due to their continuous storage method, are relatively less likely to cause memory fragmentation. In contrast, the elements of a linked list are dispersedly stored, and frequent insertion and deletion operations make memory fragmentation more likely.

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#443-cache-efficiency-of-data-structures","title":"4.4.3 \u00a0 Cache efficiency of data structures","text":"

    Although caches are much smaller in space capacity than memory, they are much faster and play a crucial role in program execution speed. Since the cache's capacity is limited and can only store a small part of frequently accessed data, when the CPU tries to access data not in the cache, a \"cache miss\" occurs, forcing the CPU to load the needed data from slower memory.

    Clearly, the fewer the cache misses, the higher the CPU's data read-write efficiency, and the better the program performance. The proportion of successful data retrieval from the cache by the CPU is called the \"cache hit rate,\" a metric often used to measure cache efficiency.

    To achieve higher efficiency, caches adopt the following data loading mechanisms.

    • Cache lines: Caches don't store and load data byte by byte but in units of cache lines. Compared to byte-by-byte transfer, the transmission of cache lines is more efficient.
    • Prefetch mechanism: Processors try to predict data access patterns (such as sequential access, fixed stride jumping access, etc.) and load data into the cache according to specific patterns to improve the hit rate.
    • Spatial locality: If data is accessed, data nearby is likely to be accessed in the near future. Therefore, when loading certain data, the cache also loads nearby data to improve the hit rate.
    • Temporal locality: If data is accessed, it's likely to be accessed again in the near future. Caches use this principle to retain recently accessed data to improve the hit rate.

    In fact, arrays and linked lists have different cache utilization efficiencies, mainly reflected in the following aspects.

    • Occupied space: Linked list elements occupy more space than array elements, resulting in less effective data volume in the cache.
    • Cache lines: Linked list data is scattered throughout memory, and since caches load \"by line,\" the proportion of loading invalid data is higher.
    • Prefetch mechanism: The data access pattern of arrays is more \"predictable\" than that of linked lists, meaning the system is more likely to guess which data will be loaded next.
    • Spatial locality: Arrays are stored in concentrated memory spaces, so the data near the loaded data is more likely to be accessed next.

    Overall, arrays have a higher cache hit rate and are generally more efficient in operation than linked lists. This makes data structures based on arrays more popular in solving algorithmic problems.

    It should be noted that high cache efficiency does not mean that arrays are always better than linked lists. Which data structure to choose in actual applications should be based on specific requirements. For example, both arrays and linked lists can implement the \"stack\" data structure (which will be detailed in the next chapter), but they are suitable for different scenarios.

    • In algorithm problems, we tend to choose stacks based on arrays because they provide higher operational efficiency and random access capabilities, with the only cost being the need to pre-allocate a certain amount of memory space for the array.
    • If the data volume is very large, highly dynamic, and the expected size of the stack is difficult to estimate, then a stack based on a linked list is more appropriate. Linked lists can disperse a large amount of data in different parts of the memory and avoid the additional overhead of array expansion.
    "},{"location":"chapter_array_and_linkedlist/summary/","title":"4.5 \u00a0 Summary","text":""},{"location":"chapter_array_and_linkedlist/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Arrays and linked lists are two basic data structures, representing two storage methods in computer memory: contiguous space storage and non-contiguous space storage. Their characteristics complement each other.
    • Arrays support random access and use less memory; however, they are inefficient in inserting and deleting elements and have a fixed length after initialization.
    • Linked lists implement efficient node insertion and deletion through changing references (pointers) and can flexibly adjust their length; however, they have lower node access efficiency and consume more memory.
    • Common types of linked lists include singly linked lists, circular linked lists, and doubly linked lists, each with its own application scenarios.
    • Lists are ordered collections of elements that support addition, deletion, and modification, typically implemented based on dynamic arrays, retaining the advantages of arrays while allowing flexible length adjustment.
    • The advent of lists significantly enhanced the practicality of arrays but may lead to some memory space wastage.
    • During program execution, data is mainly stored in memory. Arrays provide higher memory space efficiency, while linked lists are more flexible in memory usage.
    • Caches provide fast data access to CPUs through mechanisms like cache lines, prefetching, spatial locality, and temporal locality, significantly enhancing program execution efficiency.
    • Due to higher cache hit rates, arrays are generally more efficient than linked lists. When choosing a data structure, the appropriate choice should be made based on specific needs and scenarios.
    "},{"location":"chapter_array_and_linkedlist/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Does storing arrays on the stack versus the heap affect time and space efficiency?

    Arrays stored on both the stack and heap are stored in contiguous memory spaces, and data operation efficiency is essentially the same. However, stacks and heaps have their own characteristics, leading to the following differences.

    1. Allocation and release efficiency: The stack is a smaller memory block, allocated automatically by the compiler; the heap memory is relatively larger and can be dynamically allocated in the code, more prone to fragmentation. Therefore, allocation and release operations on the heap are generally slower than on the stack.
    2. Size limitation: Stack memory is relatively small, while the heap size is generally limited by available memory. Therefore, the heap is more suitable for storing large arrays.
    3. Flexibility: The size of arrays on the stack needs to be determined at compile-time, while the size of arrays on the heap can be dynamically determined at runtime.

    Q: Why do arrays require elements of the same type, while linked lists do not emphasize same-type elements?

    Linked lists consist of nodes connected by references (pointers), and each node can store data of different types, such as int, double, string, object, etc.

    In contrast, array elements must be of the same type, allowing the calculation of offsets to access the corresponding element positions. For example, an array containing both int and long types, with single elements occupying 4 bytes and 8 bytes respectively, cannot use the following formula to calculate offsets, as the array contains elements of two different lengths.

    # Element memory address = array memory address + element length * element index\n

    Q: After deleting a node, is it necessary to set P.next to None?

    Not modifying P.next is also acceptable. From the perspective of the linked list, traversing from the head node to the tail node will no longer encounter P. This means that node P has been effectively removed from the list, and where P points no longer affects the list.

    From a garbage collection perspective, for languages with automatic garbage collection mechanisms like Java, Python, and Go, whether node P is collected depends on whether there are still references pointing to it, not on the value of P.next. In languages like C and C++, we need to manually free the node's memory.

    Q: In linked lists, the time complexity for insertion and deletion operations is O(1). But searching for the element before insertion or deletion takes O(n) time, so why isn't the time complexity O(n)?

    If an element is searched first and then deleted, the time complexity is indeed O(n). However, the O(1) advantage of linked lists in insertion and deletion can be realized in other applications. For example, in the implementation of double-ended queues using linked lists, we maintain pointers always pointing to the head and tail nodes, making each insertion and deletion operation O(1).

    Q: In the image \"Linked List Definition and Storage Method\", do the light blue storage nodes occupy a single memory address, or do they share half with the node value?

    The diagram is just a qualitative representation; quantitative analysis depends on specific situations.

    • Different types of node values occupy different amounts of space, such as int, long, double, and object instances.
    • The memory space occupied by pointer variables depends on the operating system and compilation environment used, usually 8 bytes or 4 bytes.

    Q: Is adding elements to the end of a list always O(1)?

    If adding an element exceeds the list length, the list needs to be expanded first. The system will request a new memory block and move all elements of the original list over, in which case the time complexity becomes O(n).

    Q: The statement \"The emergence of lists greatly improves the practicality of arrays, but may lead to some memory space wastage\" - does this refer to the memory occupied by additional variables like capacity, length, and expansion multiplier?

    The space wastage here mainly refers to two aspects: on the one hand, lists are set with an initial length, which we may not always need; on the other hand, to prevent frequent expansion, expansion usually multiplies by a coefficient, such as \\(\\times 1.5\\). This results in many empty slots, which we typically cannot fully fill.

    Q: In Python, after initializing n = [1, 2, 3], the addresses of these 3 elements are contiguous, but initializing m = [2, 1, 3] shows that each element's id is not consecutive but identical to those in n. If the addresses of these elements are not contiguous, is m still an array?

    If we replace list elements with linked list nodes n = [n1, n2, n3, n4, n5], these 5 node objects are also typically dispersed throughout memory. However, given a list index, we can still access the node's memory address in O(1) time, thereby accessing the corresponding node. This is because the array stores references to the nodes, not the nodes themselves.

    Unlike many languages, in Python, numbers are also wrapped as objects, and lists store references to these numbers, not the numbers themselves. Therefore, we find that the same number in two arrays has the same id, and these numbers' memory addresses need not be contiguous.

    Q: The std::list in C++ STL has already implemented a doubly linked list, but it seems that some algorithm books don't directly use it. Is there any limitation?

    On the one hand, we often prefer to use arrays to implement algorithms, only using linked lists when necessary, mainly for two reasons.

    • Space overhead: Since each element requires two additional pointers (one for the previous element and one for the next), std::list usually occupies more space than std::vector.
    • Cache unfriendly: As the data is not stored continuously, std::list has a lower cache utilization rate. Generally, std::vector performs better.

    On the other hand, linked lists are primarily necessary for binary trees and graphs. Stacks and queues are often implemented using the programming language's stack and queue classes, rather than linked lists.

    Q: Does initializing a list res = [0] * self.size() result in each element of res referencing the same address?

    No. However, this issue arises with two-dimensional arrays, for example, initializing a two-dimensional list res = [[0] * self.size()] would reference the same list [0] multiple times.

    Q: In deleting a node, is it necessary to break the reference to its successor node?

    From the perspective of data structures and algorithms (problem-solving), it's okay not to break the link, as long as the program's logic is correct. From the perspective of standard libraries, breaking the link is safer and more logically clear. If the link is not broken, and the deleted node is not properly recycled, it could affect the recycling of the successor node's memory.

    "},{"location":"chapter_backtracking/","title":"Chapter 13. \u00a0 Backtracking","text":"

    Abstract

    Like explorers in a maze, we may encounter difficulties on our path forward.

    The power of backtracking allows us to start over, keep trying, and eventually find the exit to the light.

    "},{"location":"chapter_backtracking/#chapter-contents","title":"Chapter contents","text":"
    • 13.1 \u00a0 Backtracking algorithms
    • 13.2 \u00a0 Permutation problem
    • 13.3 \u00a0 Subset sum problem
    • 13.4 \u00a0 n queens problem
    • 13.5 \u00a0 Summary
    "},{"location":"chapter_backtracking/backtracking_algorithm/","title":"13.1 \u00a0 Backtracking algorithms","text":"

    Backtracking algorithm is a method to solve problems by exhaustive search, where the core idea is to start from an initial state and brute force all possible solutions, recording the correct ones until a solution is found or all possible choices are exhausted without finding a solution.

    Backtracking typically employs \"depth-first search\" to traverse the solution space. In the \"Binary Tree\" chapter, we mentioned that preorder, inorder, and postorder traversals are all depth-first searches. Next, we use preorder traversal to construct a backtracking problem to gradually understand the workings of the backtracking algorithm.

    Example One

    Given a binary tree, search and record all nodes with a value of \\(7\\), please return a list of nodes.

    For this problem, we traverse this tree in preorder and check if the current node's value is \\(7\\). If it is, we add the node's value to the result list res. The relevant process is shown in the following diagram and code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_i_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00\"\"\"\n    if root is None:\n        return\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(root)\n    pre_order(root.left)\n    pre_order(root.right)\n
    preorder_traversal_i_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr) {\n        return;\n    }\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(root);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n}\n
    preorder_traversal_i_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode root) {\n    if (root == null) {\n        return;\n    }\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(root);\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n}\n
    preorder_traversal_i_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) {\n        return;\n    }\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(root);\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n
    preorder_traversal_i_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunc preOrderI(root *TreeNode, res *[]*TreeNode) {\n    if root == nil {\n        return\n    }\n    if (root.Val).(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, root)\n    }\n    preOrderI(root.Left, res)\n    preOrderI(root.Right, res)\n}\n
    preorder_traversal_i_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(root)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n
    preorder_traversal_i_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunction preOrder(root, res) {\n    if (root === null) {\n        return;\n    }\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push(root);\n    }\n    preOrder(root.left, res);\n    preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunction preOrder(root: TreeNode | null, res: TreeNode[]): void {\n    if (root === null) {\n        return;\n    }\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push(root);\n    }\n    preOrder(root.left, res);\n    preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode? root, List<TreeNode> res) {\n  if (root == null) {\n    return;\n  }\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(root);\n  }\n  preOrder(root.left, res);\n  preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfn pre_order(res: &mut Vec<Rc<RefCell<TreeNode>>>, root: Option<Rc<RefCell<TreeNode>>>) {\n    if root.is_none() {\n        return;\n    }\n    if let Some(node) = root {\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(node.clone());\n        }\n        pre_order(res, node.borrow().left.clone());\n        pre_order(res, node.borrow().right.clone());\n    }\n}\n
    preorder_traversal_i_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode *root) {\n    if (root == NULL) {\n        return;\n    }\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res[resSize++] = root;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n}\n
    preorder_traversal_i_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) {\n        return\n    }\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(root)\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n}\n
    preorder_traversal_i_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_i_compact.zig
    [class]{}-[func]{preOrder}\n
    Code Visualization

    Full Screen >

    Figure 13-1 \u00a0 Searching nodes in preorder traversal

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1311-trying-and-retreating","title":"13.1.1 \u00a0 Trying and retreating","text":"

    The reason it is called backtracking is that the algorithm uses a \"try\" and \"retreat\" strategy when searching the solution space. When the algorithm encounters a state where it can no longer progress or fails to achieve a satisfying solution, it undoes the previous choice, reverts to the previous state, and tries other possible choices.

    For Example One, visiting each node represents a \"try\", and passing a leaf node or returning to the parent node's return represents \"retreat\".

    It's worth noting that retreat is not merely about function returns. We expand slightly on Example One for clarification.

    Example Two

    In a binary tree, search for all nodes with a value of \\(7\\) and please return the paths from the root node to these nodes.

    Based on the code from Example One, we need to use a list path to record the visited node paths. When a node with a value of \\(7\\) is reached, we copy path and add it to the result list res. After the traversal, res holds all the solutions. The code is as shown:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_ii_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c\"\"\"\n    if root is None:\n        return\n    # \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(list(path))\n    pre_order(root.left)\n    pre_order(root.right)\n    # \u56de\u9000\n    path.pop()\n
    preorder_traversal_ii_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push_back(root);\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(path);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    path.pop_back();\n}\n
    preorder_traversal_ii_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode root) {\n    if (root == null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(new ArrayList<>(path));\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n    // \u56de\u9000\n    path.remove(path.size() - 1);\n}\n
    preorder_traversal_ii_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.Add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(new List<TreeNode>(path));\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n    // \u56de\u9000\n    path.RemoveAt(path.Count - 1);\n}\n
    preorder_traversal_ii_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunc preOrderII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {\n    if root == nil {\n        return\n    }\n    // \u5c1d\u8bd5\n    *path = append(*path, root)\n    if root.Val.(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, append([]*TreeNode{}, *path...))\n    }\n    preOrderII(root.Left, res, path)\n    preOrderII(root.Right, res, path)\n    // \u56de\u9000\n    *path = (*path)[:len(*path)-1]\n}\n
    preorder_traversal_ii_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(path)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n    // \u56de\u9000\n    path.removeLast()\n}\n
    preorder_traversal_ii_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunction preOrder(root, path, res) {\n    if (root === null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_ii_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunction preOrder(\n    root: TreeNode | null,\n    path: TreeNode[],\n    res: TreeNode[][]\n): void {\n    if (root === null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_ii_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(\n  TreeNode? root,\n  List<TreeNode> path,\n  List<List<TreeNode>> res,\n) {\n  if (root == null) {\n    return;\n  }\n\n  // \u5c1d\u8bd5\n  path.add(root);\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(List.from(path));\n  }\n  preOrder(root.left, path, res);\n  preOrder(root.right, path, res);\n  // \u56de\u9000\n  path.removeLast();\n}\n
    preorder_traversal_ii_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfn pre_order(\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n    path: &mut Vec<Rc<RefCell<TreeNode>>>,\n    root: Option<Rc<RefCell<TreeNode>>>,\n) {\n    if root.is_none() {\n        return;\n    }\n    if let Some(node) = root {\n        // \u5c1d\u8bd5\n        path.push(node.clone());\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(path.clone());\n        }\n        pre_order(res, path, node.borrow().left.clone());\n        pre_order(res, path, node.borrow().right.clone());\n        // \u56de\u9000\n        path.remove(path.len() - 1);\n    }\n}\n
    preorder_traversal_ii_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode *root) {\n    if (root == NULL) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path[pathSize++] = root;\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        for (int i = 0; i < pathSize; ++i) {\n            res[resSize][i] = path[i];\n        }\n        resSize++;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    pathSize--;\n}\n
    preorder_traversal_ii_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfun preOrder(root: TreeNode?) {\n    if (root == null) {\n        return\n    }\n    // \u5c1d\u8bd5\n    path!!.add(root)\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(path!!.toMutableList())\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n    // \u56de\u9000\n    path!!.removeAt(path!!.size - 1)\n}\n
    preorder_traversal_ii_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_ii_compact.zig
    [class]{}-[func]{preOrder}\n
    Code Visualization

    Full Screen >

    In each \"try\", we record the path by adding the current node to path; before \"retreating\", we need to pop the node from path to restore the state before this attempt.

    Observe the process shown below, we can understand trying and retreating as \"advancing\" and \"undoing\", two operations that are reverse to each other.

    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 13-2 \u00a0 Trying and retreating

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1312-pruning","title":"13.1.2 \u00a0 Pruning","text":"

    Complex backtracking problems usually involve one or more constraints, which are often used for \"pruning\".

    Example Three

    In a binary tree, search for all nodes with a value of \\(7\\) and return the paths from the root to these nodes, requiring that the paths do not contain nodes with a value of \\(3\\).

    To meet the above constraints, we need to add a pruning operation: during the search process, if a node with a value of \\(3\\) is encountered, it returns early, discontinuing further search. The code is as shown:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_iii_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09\"\"\"\n    # \u526a\u679d\n    if root is None or root.val == 3:\n        return\n    # \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(list(path))\n    pre_order(root.left)\n    pre_order(root.right)\n    # \u56de\u9000\n    path.pop()\n
    preorder_traversal_iii_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode *root) {\n    // \u526a\u679d\n    if (root == nullptr || root->val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push_back(root);\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(path);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    path.pop_back();\n}\n
    preorder_traversal_iii_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode root) {\n    // \u526a\u679d\n    if (root == null || root.val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(new ArrayList<>(path));\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n    // \u56de\u9000\n    path.remove(path.size() - 1);\n}\n
    preorder_traversal_iii_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid PreOrder(TreeNode? root) {\n    // \u526a\u679d\n    if (root == null || root.val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.Add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(new List<TreeNode>(path));\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n    // \u56de\u9000\n    path.RemoveAt(path.Count - 1);\n}\n
    preorder_traversal_iii_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunc preOrderIII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {\n    // \u526a\u679d\n    if root == nil || root.Val == 3 {\n        return\n    }\n    // \u5c1d\u8bd5\n    *path = append(*path, root)\n    if root.Val.(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, append([]*TreeNode{}, *path...))\n    }\n    preOrderIII(root.Left, res, path)\n    preOrderIII(root.Right, res, path)\n    // \u56de\u9000\n    *path = (*path)[:len(*path)-1]\n}\n
    preorder_traversal_iii_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunc preOrder(root: TreeNode?) {\n    // \u526a\u679d\n    guard let root = root, root.val != 3 else {\n        return\n    }\n    // \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(path)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n    // \u56de\u9000\n    path.removeLast()\n}\n
    preorder_traversal_iii_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunction preOrder(root, path, res) {\n    // \u526a\u679d\n    if (root === null || root.val === 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_iii_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunction preOrder(\n    root: TreeNode | null,\n    path: TreeNode[],\n    res: TreeNode[][]\n): void {\n    // \u526a\u679d\n    if (root === null || root.val === 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_iii_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(\n  TreeNode? root,\n  List<TreeNode> path,\n  List<List<TreeNode>> res,\n) {\n  if (root == null || root.val == 3) {\n    return;\n  }\n\n  // \u5c1d\u8bd5\n  path.add(root);\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(List.from(path));\n  }\n  preOrder(root.left, path, res);\n  preOrder(root.right, path, res);\n  // \u56de\u9000\n  path.removeLast();\n}\n
    preorder_traversal_iii_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfn pre_order(\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n    path: &mut Vec<Rc<RefCell<TreeNode>>>,\n    root: Option<Rc<RefCell<TreeNode>>>,\n) {\n    // \u526a\u679d\n    if root.is_none() || root.as_ref().unwrap().borrow().val == 3 {\n        return;\n    }\n    if let Some(node) = root {\n        // \u5c1d\u8bd5\n        path.push(node.clone());\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(path.clone());\n        }\n        pre_order(res, path, node.borrow().left.clone());\n        pre_order(res, path, node.borrow().right.clone());\n        // \u56de\u9000\n        path.remove(path.len() - 1);\n    }\n}\n
    preorder_traversal_iii_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode *root) {\n    // \u526a\u679d\n    if (root == NULL || root->val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path[pathSize++] = root;\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        for (int i = 0; i < pathSize; i++) {\n            res[resSize][i] = path[i];\n        }\n        resSize++;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    pathSize--;\n}\n
    preorder_traversal_iii_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfun preOrder(root: TreeNode?) {\n    // \u526a\u679d\n    if (root == null || root._val == 3) {\n        return\n    }\n    // \u5c1d\u8bd5\n    path!!.add(root)\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(path!!.toMutableList())\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n    // \u56de\u9000\n    path!!.removeAt(path!!.size - 1)\n}\n
    preorder_traversal_iii_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_iii_compact.zig
    [class]{}-[func]{preOrder}\n
    Code Visualization

    Full Screen >

    \"Pruning\" is a very vivid noun. As shown in the diagram below, in the search process, we \"cut off\" the search branches that do not meet the constraints, avoiding many meaningless attempts, thus enhancing the search efficiency.

    Figure 13-3 \u00a0 Pruning based on constraints

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1313-framework-code","title":"13.1.3 \u00a0 Framework code","text":"

    Next, we attempt to distill the main framework of \"trying, retreating, and pruning\" from backtracking to enhance the code's universality.

    In the following framework code, state represents the current state of the problem, choices represents the choices available under the current state:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def backtrack(state: State, choices: list[choice], res: list[state]):\n    \"\"\"Backtracking algorithm framework\"\"\"\n    # Check if it's a solution\n    if is_solution(state):\n        # Record the solution\n        record_solution(state, res)\n        # Stop searching\n        return\n    # Iterate through all choices\n    for choice in choices:\n        # Pruning: check if the choice is valid\n        if is_valid(state, choice):\n            # Try: make a choice, update the state\n            make_choice(state, choice)\n            backtrack(state, choices, res)\n            # Retreat: undo the choice, revert to the previous state\n            undo_choice(state, choice)\n
    /* Backtracking algorithm framework */\nvoid backtrack(State *state, vector<Choice *> &choices, vector<State *> &res) {\n    // Check if it's a solution\n    if (isSolution(state)) {\n        // Record the solution\n        recordSolution(state, res);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    for (Choice choice : choices) {\n        // Pruning: check if the choice is valid\n        if (isValid(state, choice)) {\n            // Try: make a choice, update the state\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nvoid backtrack(State state, List<Choice> choices, List<State> res) {\n    // Check if it's a solution\n    if (isSolution(state)) {\n        // Record the solution\n        recordSolution(state, res);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    for (Choice choice : choices) {\n        // Pruning: check if the choice is valid\n        if (isValid(state, choice)) {\n            // Try: make a choice, update the state\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nvoid Backtrack(State state, List<Choice> choices, List<State> res) {\n    // Check if it's a solution\n    if (IsSolution(state)) {\n        // Record the solution\n        RecordSolution(state, res);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    foreach (Choice choice in choices) {\n        // Pruning: check if the choice is valid\n        if (IsValid(state, choice)) {\n            // Try: make a choice, update the state\n            MakeChoice(state, choice);\n            Backtrack(state, choices, res);\n            // Retreat: undo the choice, revert to the previous state\n            UndoChoice(state, choice);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nfunc backtrack(state *State, choices []Choice, res *[]State) {\n    // Check if it's a solution\n    if isSolution(state) {\n        // Record the solution\n        recordSolution(state, res)\n        // Stop searching\n        return\n    }\n    // Iterate through all choices\n    for _, choice := range choices {\n        // Pruning: check if the choice is valid\n        if isValid(state, choice) {\n            // Try: make a choice, update the state\n            makeChoice(state, choice)\n            backtrack(state, choices, res)\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, choice)\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nfunc backtrack(state: inout State, choices: [Choice], res: inout [State]) {\n    // Check if it's a solution\n    if isSolution(state: state) {\n        // Record the solution\n        recordSolution(state: state, res: &res)\n        // Stop searching\n        return\n    }\n    // Iterate through all choices\n    for choice in choices {\n        // Pruning: check if the choice is valid\n        if isValid(state: state, choice: choice) {\n            // Try: make a choice, update the state\n            makeChoice(state: &state, choice: choice)\n            backtrack(state: &state, choices: choices, res: &res)\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state: &state, choice: choice)\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nfunction backtrack(state, choices, res) {\n    // Check if it's a solution\n    if (isSolution(state)) {\n        // Record the solution\n        recordSolution(state, res);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    for (let choice of choices) {\n        // Pruning: check if the choice is valid\n        if (isValid(state, choice)) {\n            // Try: make a choice, update the state\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nfunction backtrack(state: State, choices: Choice[], res: State[]): void {\n    // Check if it's a solution\n    if (isSolution(state)) {\n        // Record the solution\n        recordSolution(state, res);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    for (let choice of choices) {\n        // Pruning: check if the choice is valid\n        if (isValid(state, choice)) {\n            // Try: make a choice, update the state\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nvoid backtrack(State state, List<Choice>, List<State> res) {\n  // Check if it's a solution\n  if (isSolution(state)) {\n    // Record the solution\n    recordSolution(state, res);\n    // Stop searching\n    return;\n  }\n  // Iterate through all choices\n  for (Choice choice in choices) {\n    // Pruning: check if the choice is valid\n    if (isValid(state, choice)) {\n      // Try: make a choice, update the state\n      makeChoice(state, choice);\n      backtrack(state, choices, res);\n      // Retreat: undo the choice, revert to the previous state\n      undoChoice(state, choice);\n    }\n  }\n}\n
    /* Backtracking algorithm framework */\nfn backtrack(state: &mut State, choices: &Vec<Choice>, res: &mut Vec<State>) {\n    // Check if it's a solution\n    if is_solution(state) {\n        // Record the solution\n        record_solution(state, res);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    for choice in choices {\n        // Pruning: check if the choice is valid\n        if is_valid(state, choice) {\n            // Try: make a choice, update the state\n            make_choice(state, choice);\n            backtrack(state, choices, res);\n            // Retreat: undo the choice, revert to the previous state\n            undo_choice(state, choice);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nvoid backtrack(State *state, Choice *choices, int numChoices, State *res, int numRes) {\n    // Check if it's a solution\n    if (isSolution(state)) {\n        // Record the solution\n        recordSolution(state, res, numRes);\n        // Stop searching\n        return;\n    }\n    // Iterate through all choices\n    for (int i = 0; i < numChoices; i++) {\n        // Pruning: check if the choice is valid\n        if (isValid(state, &choices[i])) {\n            // Try: make a choice, update the state\n            makeChoice(state, &choices[i]);\n            backtrack(state, choices, numChoices, res, numRes);\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, &choices[i]);\n        }\n    }\n}\n
    /* Backtracking algorithm framework */\nfun backtrack(state: State?, choices: List<Choice?>, res: List<State?>?) {\n    // Check if it's a solution\n    if (isSolution(state)) {\n        // Record the solution\n        recordSolution(state, res)\n        // Stop searching\n        return\n    }\n    // Iterate through all choices\n    for (choice in choices) {\n        // Pruning: check if the choice is valid\n        if (isValid(state, choice)) {\n            // Try: make a choice, update the state\n            makeChoice(state, choice)\n            backtrack(state, choices, res)\n            // Retreat: undo the choice, revert to the previous state\n            undoChoice(state, choice)\n        }\n    }\n}\n
    \n
    \n

    Next, we solve Example Three based on the framework code. The state is the node traversal path, choices are the current node's left and right children, and the result res is the list of paths:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_iii_template.py
    def is_solution(state: list[TreeNode]) -> bool:\n    \"\"\"\u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3\"\"\"\n    return state and state[-1].val == 7\n\ndef record_solution(state: list[TreeNode], res: list[list[TreeNode]]):\n    \"\"\"\u8bb0\u5f55\u89e3\"\"\"\n    res.append(list(state))\n\ndef is_valid(state: list[TreeNode], choice: TreeNode) -> bool:\n    \"\"\"\u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5\"\"\"\n    return choice is not None and choice.val != 3\n\ndef make_choice(state: list[TreeNode], choice: TreeNode):\n    \"\"\"\u66f4\u65b0\u72b6\u6001\"\"\"\n    state.append(choice)\n\ndef undo_choice(state: list[TreeNode], choice: TreeNode):\n    \"\"\"\u6062\u590d\u72b6\u6001\"\"\"\n    state.pop()\n\ndef backtrack(\n    state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09\"\"\"\n    # \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if is_solution(state):\n        # \u8bb0\u5f55\u89e3\n        record_solution(state, res)\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice):\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice)\n
    preorder_traversal_iii_template.cpp
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(vector<TreeNode *> &state) {\n    return !state.empty() && state.back()->val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(vector<TreeNode *> &state, vector<vector<TreeNode *>> &res) {\n    res.push_back(state);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(vector<TreeNode *> &state, TreeNode *choice) {\n    return choice != nullptr && choice->val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(vector<TreeNode *> &state, TreeNode *choice) {\n    state.push_back(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(vector<TreeNode *> &state, TreeNode *choice) {\n    state.pop_back();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(vector<TreeNode *> &state, vector<TreeNode *> &choices, vector<vector<TreeNode *>> &res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (TreeNode *choice : choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            vector<TreeNode *> nextChoices{choice->left, choice->right};\n            backtrack(state, nextChoices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.java
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nboolean isSolution(List<TreeNode> state) {\n    return !state.isEmpty() && state.get(state.size() - 1).val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n    res.add(new ArrayList<>(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nboolean isValid(List<TreeNode> state, TreeNode choice) {\n    return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(List<TreeNode> state, TreeNode choice) {\n    state.add(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(List<TreeNode> state, TreeNode choice) {\n    state.remove(state.size() - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(List<TreeNode> state, List<TreeNode> choices, List<List<TreeNode>> res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (TreeNode choice : choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, Arrays.asList(choice.left, choice.right), res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.cs
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool IsSolution(List<TreeNode> state) {\n    return state.Count != 0 && state[^1].val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid RecordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n    res.Add(new List<TreeNode>(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool IsValid(List<TreeNode> state, TreeNode choice) {\n    return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid MakeChoice(List<TreeNode> state, TreeNode choice) {\n    state.Add(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid UndoChoice(List<TreeNode> state, TreeNode choice) {\n    state.RemoveAt(state.Count - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid Backtrack(List<TreeNode> state, List<TreeNode> choices, List<List<TreeNode>> res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (IsSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        RecordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (TreeNode choice in choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (IsValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            MakeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, [choice.left!, choice.right!], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            UndoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.go
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunc isSolution(state *[]*TreeNode) bool {\n    return len(*state) != 0 && (*state)[len(*state)-1].Val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunc recordSolution(state *[]*TreeNode, res *[][]*TreeNode) {\n    *res = append(*res, append([]*TreeNode{}, *state...))\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunc isValid(state *[]*TreeNode, choice *TreeNode) bool {\n    return choice != nil && choice.Val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunc makeChoice(state *[]*TreeNode, choice *TreeNode) {\n    *state = append(*state, choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunc undoChoice(state *[]*TreeNode, choice *TreeNode) {\n    *state = (*state)[:len(*state)-1]\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunc backtrackIII(state *[]*TreeNode, choices *[]*TreeNode, res *[][]*TreeNode) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if isSolution(state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range *choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            temp := make([]*TreeNode, 0)\n            temp = append(temp, choice.Left, choice.Right)\n            backtrackIII(state, &temp, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.swift
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunc isSolution(state: [TreeNode]) -> Bool {\n    !state.isEmpty && state.last!.val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunc recordSolution(state: [TreeNode], res: inout [[TreeNode]]) {\n    res.append(state)\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunc isValid(state: [TreeNode], choice: TreeNode?) -> Bool {\n    choice != nil && choice!.val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunc makeChoice(state: inout [TreeNode], choice: TreeNode) {\n    state.append(choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunc undoChoice(state: inout [TreeNode], choice: TreeNode) {\n    state.removeLast()\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunc backtrack(state: inout [TreeNode], choices: [TreeNode], res: inout [[TreeNode]]) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if isSolution(state: state) {\n        recordSolution(state: state, res: &res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state: state, choice: choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state: &state, choice: choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: [choice.left, choice.right].compactMap { $0 }, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state: &state, choice: choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.js
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunction isSolution(state) {\n    return state && state[state.length - 1]?.val === 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunction recordSolution(state, res) {\n    res.push([...state]);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunction isValid(state, choice) {\n    return choice !== null && choice.val !== 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunction makeChoice(state, choice) {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunction undoChoice(state) {\n    state.pop();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunction backtrack(state, choices, res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state);\n        }\n    }\n}\n
    preorder_traversal_iii_template.ts
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunction isSolution(state: TreeNode[]): boolean {\n    return state && state[state.length - 1]?.val === 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunction recordSolution(state: TreeNode[], res: TreeNode[][]): void {\n    res.push([...state]);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunction isValid(state: TreeNode[], choice: TreeNode): boolean {\n    return choice !== null && choice.val !== 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunction makeChoice(state: TreeNode[], choice: TreeNode): void {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunction undoChoice(state: TreeNode[]): void {\n    state.pop();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunction backtrack(\n    state: TreeNode[],\n    choices: TreeNode[],\n    res: TreeNode[][]\n): void {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state);\n        }\n    }\n}\n
    preorder_traversal_iii_template.dart
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(List<TreeNode> state) {\n  return state.isNotEmpty && state.last.val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n  res.add(List.from(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(List<TreeNode> state, TreeNode? choice) {\n  return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(List<TreeNode> state, TreeNode? choice) {\n  state.add(choice!);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(List<TreeNode> state, TreeNode? choice) {\n  state.removeLast();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(\n  List<TreeNode> state,\n  List<TreeNode?> choices,\n  List<List<TreeNode>> res,\n) {\n  // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n  if (isSolution(state)) {\n    // \u8bb0\u5f55\u89e3\n    recordSolution(state, res);\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (TreeNode? choice in choices) {\n    // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n    if (isValid(state, choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      makeChoice(state, choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, [choice!.left, choice.right], res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      undoChoice(state, choice);\n    }\n  }\n}\n
    preorder_traversal_iii_template.rs
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfn is_solution(state: &mut Vec<Rc<RefCell<TreeNode>>>) -> bool {\n    return !state.is_empty() && state.get(state.len() - 1).unwrap().borrow().val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfn record_solution(\n    state: &mut Vec<Rc<RefCell<TreeNode>>>,\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n) {\n    res.push(state.clone());\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfn is_valid(_: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) -> bool {\n    return choice.borrow().val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfn make_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfn undo_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, _: Rc<RefCell<TreeNode>>) {\n    state.remove(state.len() - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfn backtrack(\n    state: &mut Vec<Rc<RefCell<TreeNode>>>,\n    choices: &mut Vec<Rc<RefCell<TreeNode>>>,\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if is_solution(state) {\n        // \u8bb0\u5f55\u89e3\n        record_solution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice.clone()) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice.clone());\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(\n                state,\n                &mut vec![\n                    choice.borrow().left.clone().unwrap(),\n                    choice.borrow().right.clone().unwrap(),\n                ],\n                res,\n            );\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice.clone());\n        }\n    }\n}\n
    preorder_traversal_iii_template.c
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(void) {\n    return pathSize > 0 && path[pathSize - 1]->val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(void) {\n    for (int i = 0; i < pathSize; i++) {\n        res[resSize][i] = path[i];\n    }\n    resSize++;\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(TreeNode *choice) {\n    return choice != NULL && choice->val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(TreeNode *choice) {\n    path[pathSize++] = choice;\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(void) {\n    pathSize--;\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(TreeNode *choices[2]) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution()) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution();\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < 2; i++) {\n        TreeNode *choice = choices[i];\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            TreeNode *nextChoices[2] = {choice->left, choice->right};\n            backtrack(nextChoices);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice();\n        }\n    }\n}\n
    preorder_traversal_iii_template.kt
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfun isSolution(state: MutableList<TreeNode?>): Boolean {\n    return state.isNotEmpty() && state[state.size - 1]?._val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfun recordSolution(state: MutableList<TreeNode?>?, res: MutableList<MutableList<TreeNode?>?>) {\n    res.add(state!!.toMutableList())\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfun isValid(state: MutableList<TreeNode?>?, choice: TreeNode?): Boolean {\n    return choice != null && choice._val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfun makeChoice(state: MutableList<TreeNode?>, choice: TreeNode?) {\n    state.add(choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfun undoChoice(state: MutableList<TreeNode?>, choice: TreeNode?) {\n    state.removeLast()\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfun backtrack(\n    state: MutableList<TreeNode?>,\n    choices: MutableList<TreeNode?>,\n    res: MutableList<MutableList<TreeNode?>?>\n) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, mutableListOf(choice!!.left, choice.right), res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.rb
    [class]{}-[func]{is_solution}\n\n[class]{}-[func]{record_solution}\n\n[class]{}-[func]{is_valid}\n\n[class]{}-[func]{make_choice}\n\n[class]{}-[func]{undo_choice}\n\n[class]{}-[func]{backtrack}\n
    preorder_traversal_iii_template.zig
    [class]{}-[func]{isSolution}\n\n[class]{}-[func]{recordSolution}\n\n[class]{}-[func]{isValid}\n\n[class]{}-[func]{makeChoice}\n\n[class]{}-[func]{undoChoice}\n\n[class]{}-[func]{backtrack}\n
    Code Visualization

    Full Screen >

    As per the requirements, after finding a node with a value of \\(7\\), the search should continue, thus the return statement after recording the solution should be removed. The following diagram compares the search processes with and without retaining the return statement.

    Figure 13-4 \u00a0 Comparison of retaining and removing the return in the search process

    Compared to the implementation based on preorder traversal, the code implementation based on the backtracking algorithm framework seems verbose, but it has better universality. In fact, many backtracking problems can be solved within this framework. We just need to define state and choices according to the specific problem and implement the methods in the framework.

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1314-common-terminology","title":"13.1.4 \u00a0 Common terminology","text":"

    To analyze algorithmic problems more clearly, we summarize the meanings of commonly used terminology in backtracking algorithms and provide corresponding examples from Example Three as shown in the Table 13-1 .

    Table 13-1 \u00a0 Common backtracking algorithm terminology

    Term Definition Example Three Solution (solution) A solution is an answer that satisfies specific conditions of the problem, which may have one or more All paths from the root node to node \\(7\\) that meet the constraint Constraint (constraint) Constraints are conditions in the problem that limit the feasibility of solutions, often used for pruning Paths do not contain node \\(3\\) State (state) State represents the situation of the problem at a certain moment, including choices made Current visited node path, i.e., path node list Attempt (attempt) An attempt is the process of exploring the solution space based on available choices, including making choices, updating the state, and checking if it's a solution Recursively visiting left (right) child nodes, adding nodes to path, checking if the node's value is \\(7\\) Backtracking (backtracking) Backtracking refers to the action of undoing previous choices and returning to the previous state when encountering states that do not meet the constraints When passing leaf nodes, ending node visits, encountering nodes with a value of \\(3\\), terminating the search, and function return Pruning (pruning) Pruning is a method to avoid meaningless search paths based on the characteristics and constraints of the problem, which can enhance search efficiency When encountering a node with a value of \\(3\\), no further search is continued

    Tip

    Concepts like problems, solutions, states, etc., are universal, and are involved in divide and conquer, backtracking, dynamic programming, and greedy algorithms, among others.

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1315-advantages-and-limitations","title":"13.1.5 \u00a0 Advantages and limitations","text":"

    The backtracking algorithm is essentially a depth-first search algorithm that attempts all possible solutions until a satisfying solution is found. The advantage of this method is that it can find all possible solutions, and with reasonable pruning operations, it can be highly efficient.

    However, when dealing with large-scale or complex problems, the operational efficiency of backtracking may be difficult to accept.

    • Time: Backtracking algorithms usually need to traverse all possible states in the state space, which can reach exponential or factorial time complexity.
    • Space: In recursive calls, it is necessary to save the current state (such as paths, auxiliary variables for pruning, etc.). When the depth is very large, the space requirement may become significant.

    Even so, backtracking remains the best solution for certain search problems and constraint satisfaction problems. For these problems, since it is unpredictable which choices can generate valid solutions, we must traverse all possible choices. In this case, the key is how to optimize efficiency, with common efficiency optimization methods being two types.

    • Pruning: Avoid searching paths that definitely will not produce a solution, thus saving time and space.
    • Heuristic search: Introduce some strategies or estimates during the search process to prioritize the paths that are most likely to produce valid solutions.
    "},{"location":"chapter_backtracking/backtracking_algorithm/#1316-typical-backtracking-problems","title":"13.1.6 \u00a0 Typical backtracking problems","text":"

    Backtracking algorithms can be used to solve many search problems, constraint satisfaction problems, and combinatorial optimization problems.

    Search problems: The goal of these problems is to find solutions that meet specific conditions.

    • Full permutation problem: Given a set, find all possible permutations and combinations of it.
    • Subset sum problem: Given a set and a target sum, find all subsets of the set that sum to the target.
    • Tower of Hanoi problem: Given three rods and a series of different-sized discs, the goal is to move all the discs from one rod to another, moving only one disc at a time, and never placing a larger disc on a smaller one.

    Constraint satisfaction problems: The goal of these problems is to find solutions that satisfy all the constraints.

    • \\(n\\) queens: Place \\(n\\) queens on an \\(n \\times n\\) chessboard so that they do not attack each other.
    • Sudoku: Fill a \\(9 \\times 9\\) grid with the numbers \\(1\\) to \\(9\\), ensuring that the numbers do not repeat in each row, each column, and each \\(3 \\times 3\\) subgrid.
    • Graph coloring problem: Given an undirected graph, color each vertex with the fewest possible colors so that adjacent vertices have different colors.

    Combinatorial optimization problems: The goal of these problems is to find the optimal solution within a combination space that meets certain conditions.

    • 0-1 knapsack problem: Given a set of items and a backpack, each item has a certain value and weight. The goal is to choose items to maximize the total value within the backpack's capacity limit.
    • Traveling salesman problem: In a graph, starting from one point, visit all other points exactly once and then return to the starting point, seeking the shortest path.
    • Maximum clique problem: Given an undirected graph, find the largest complete subgraph, i.e., a subgraph where any two vertices are connected by an edge.

    Please note that for many combinatorial optimization problems, backtracking is not the optimal solution.

    • The 0-1 knapsack problem is usually solved using dynamic programming to achieve higher time efficiency.
    • The traveling salesman is a well-known NP-Hard problem, commonly solved using genetic algorithms and ant colony algorithms, among others.
    • The maximum clique problem is a classic problem in graph theory, which can be solved using greedy algorithms and other heuristic methods.
    "},{"location":"chapter_backtracking/n_queens_problem/","title":"13.4 \u00a0 n queens problem","text":"

    Question

    According to the rules of chess, a queen can attack pieces in the same row, column, or on a diagonal line. Given \\(n\\) queens and an \\(n \\times n\\) chessboard, find arrangements where no two queens can attack each other.

    As shown in the Figure 13-15 , when \\(n = 4\\), there are two solutions. From the perspective of the backtracking algorithm, an \\(n \\times n\\) chessboard has \\(n^2\\) squares, presenting all possible choices choices. The state of the chessboard state changes continuously as each queen is placed.

    Figure 13-15 \u00a0 Solution to the 4 queens problem

    The following image shows the three constraints of this problem: multiple queens cannot be on the same row, column, or diagonal. It is important to note that diagonals are divided into the main diagonal \\ and the secondary diagonal /.

    Figure 13-16 \u00a0 Constraints of the n queens problem

    "},{"location":"chapter_backtracking/n_queens_problem/#1-row-by-row-placing-strategy","title":"1. \u00a0 Row-by-row placing strategy","text":"

    As the number of queens equals the number of rows on the chessboard, both being \\(n\\), it is easy to conclude: each row on the chessboard allows and only allows one queen to be placed.

    This means that we can adopt a row-by-row placing strategy: starting from the first row, place one queen per row until the last row is reached.

    The image below shows the row-by-row placing process for the 4 queens problem. Due to space limitations, the image only expands one search branch of the first row, and prunes any placements that do not meet the column and diagonal constraints.

    Figure 13-17 \u00a0 Row-by-row placing strategy

    Essentially, the row-by-row placing strategy serves as a pruning function, avoiding all search branches that would place multiple queens in the same row.

    "},{"location":"chapter_backtracking/n_queens_problem/#2-column-and-diagonal-pruning","title":"2. \u00a0 Column and diagonal pruning","text":"

    To satisfy column constraints, we can use a boolean array cols of length \\(n\\) to track whether a queen occupies each column. Before each placement decision, cols is used to prune the columns that already have queens, and it is dynamically updated during backtracking.

    How about the diagonal constraints? Let the row and column indices of a cell on the chessboard be \\((row, col)\\). By selecting a specific main diagonal, we notice that the difference \\(row - col\\) is the same for all cells on that diagonal, meaning that \\(row - col\\) is a constant value on that diagonal.

    Thus, if two cells satisfy \\(row_1 - col_1 = row_2 - col_2\\), they are definitely on the same main diagonal. Using this pattern, we can utilize the array diags1 shown below to track whether a queen is on any main diagonal.

    Similarly, the sum \\(row + col\\) is a constant value for all cells on a secondary diagonal. We can also use the array diags2 to handle secondary diagonal constraints.

    Figure 13-18 \u00a0 Handling column and diagonal constraints

    "},{"location":"chapter_backtracking/n_queens_problem/#3-code-implementation","title":"3. \u00a0 Code implementation","text":"

    Please note, in an \\(n\\)-dimensional matrix, the range of \\(row - col\\) is \\([-n + 1, n - 1]\\), and the range of \\(row + col\\) is \\([0, 2n - 2]\\), thus the number of both main and secondary diagonals is \\(2n - 1\\), meaning the length of both arrays diags1 and diags2 is \\(2n - 1\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig n_queens.py
    def backtrack(\n    row: int,\n    n: int,\n    state: list[list[str]],\n    res: list[list[list[str]]],\n    cols: list[bool],\n    diags1: list[bool],\n    diags2: list[bool],\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e\"\"\"\n    # \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n:\n        res.append([list(row) for row in state])\n        return\n    # \u904d\u5386\u6240\u6709\u5217\n    for col in range(n):\n        # \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        diag1 = row - col + n - 1\n        diag2 = row + col\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if not cols[col] and not diags1[diag1] and not diags2[diag2]:\n            # \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            cols[col] = diags1[diag1] = diags2[diag2] = True\n            # \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2)\n            # \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            cols[col] = diags1[diag1] = diags2[diag2] = False\n\ndef n_queens(n: int) -> list[list[list[str]]]:\n    \"\"\"\u6c42\u89e3 n \u7687\u540e\"\"\"\n    # \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    state = [[\"#\" for _ in range(n)] for _ in range(n)]\n    cols = [False] * n  # \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    diags1 = [False] * (2 * n - 1)  # \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    diags2 = [False] * (2 * n - 1)  # \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    res = []\n    backtrack(0, n, state, res, cols, diags1, diags2)\n\n    return res\n
    n_queens.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, vector<vector<string>> &state, vector<vector<vector<string>>> &res, vector<bool> &cols,\n               vector<bool> &diags1, vector<bool> &diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\";\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\";\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nvector<vector<vector<string>>> nQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    vector<vector<string>> state(n, vector<string>(n, \"#\"));\n    vector<bool> cols(n, false);           // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    vector<bool> diags1(2 * n - 1, false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    vector<bool> diags2(2 * n - 1, false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    vector<vector<vector<string>>> res;\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, List<List<String>> state, List<List<List<String>>> res,\n        boolean[] cols, boolean[] diags1, boolean[] diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        List<List<String>> copyState = new ArrayList<>();\n        for (List<String> sRow : state) {\n            copyState.add(new ArrayList<>(sRow));\n        }\n        res.add(copyState);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state.get(row).set(col, \"Q\");\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state.get(row).set(col, \"#\");\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<String>>> nQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    List<List<String>> state = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<String> row = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            row.add(\"#\");\n        }\n        state.add(row);\n    }\n    boolean[] cols = new boolean[n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    boolean[] diags1 = new boolean[2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    boolean[] diags2 = new boolean[2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    List<List<List<String>>> res = new ArrayList<>();\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid Backtrack(int row, int n, List<List<string>> state, List<List<List<string>>> res,\n        bool[] cols, bool[] diags1, bool[] diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        List<List<string>> copyState = [];\n        foreach (List<string> sRow in state) {\n            copyState.Add(new List<string>(sRow));\n        }\n        res.Add(copyState);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\";\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            Backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\";\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<string>>> NQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    List<List<string>> state = [];\n    for (int i = 0; i < n; i++) {\n        List<string> row = [];\n        for (int j = 0; j < n; j++) {\n            row.Add(\"#\");\n        }\n        state.Add(row);\n    }\n    bool[] cols = new bool[n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    bool[] diags1 = new bool[2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    bool[] diags2 = new bool[2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    List<List<List<string>>> res = [];\n\n    Backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunc backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        newState := make([][]string, len(*state))\n        for i, _ := range newState {\n            newState[i] = make([]string, len((*state)[0]))\n            copy(newState[i], (*state)[i])\n\n        }\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col := 0; col < n; col++ {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        diag1 := row - col + n - 1\n        diag2 := row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !(*cols)[col] && !(*diags1)[diag1] && !(*diags2)[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            (*state)[row][col] = \"Q\"\n            (*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = true, true, true\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row+1, n, state, res, cols, diags1, diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            (*state)[row][col] = \"#\"\n            (*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = false, false, false\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunc nQueens(n int) [][][]string {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    state := make([][]string, n)\n    for i := 0; i < n; i++ {\n        row := make([]string, n)\n        for i := 0; i < n; i++ {\n            row[i] = \"#\"\n        }\n        state[i] = row\n    }\n    // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    cols := make([]bool, n)\n    diags1 := make([]bool, 2*n-1)\n    diags2 := make([]bool, 2*n-1)\n    res := make([][][]string, 0)\n    backtrack(0, n, &state, &res, &cols, &diags1, &diags2)\n    return res\n}\n
    n_queens.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunc backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]], cols: inout [Bool], diags1: inout [Bool], diags2: inout [Bool]) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col in 0 ..< n {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        let diag1 = row - col + n - 1\n        let diag2 = row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !cols[col] && !diags1[diag1] && !diags2[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            cols[col] = true\n            diags1[diag1] = true\n            diags2[diag2] = true\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row: row + 1, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            cols[col] = false\n            diags1[diag1] = false\n            diags2[diag2] = false\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunc nQueens(n: Int) -> [[[String]]] {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    var state = Array(repeating: Array(repeating: \"#\", count: n), count: n)\n    var cols = Array(repeating: false, count: n) // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    var diags1 = Array(repeating: false, count: 2 * n - 1) // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    var diags2 = Array(repeating: false, count: 2 * n - 1) // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    var res: [[[String]]] = []\n\n    backtrack(row: 0, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)\n\n    return res\n}\n
    n_queens.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunction backtrack(row, n, state, res, cols, diags1, diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row === n) {\n        res.push(state.map((row) => row.slice()));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (let col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        const diag1 = row - col + n - 1;\n        const diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunction nQueens(n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    const state = Array.from({ length: n }, () => Array(n).fill('#'));\n    const cols = Array(n).fill(false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    const diags1 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const diags2 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const res = [];\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunction backtrack(\n    row: number,\n    n: number,\n    state: string[][],\n    res: string[][][],\n    cols: boolean[],\n    diags1: boolean[],\n    diags2: boolean[]\n): void {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row === n) {\n        res.push(state.map((row) => row.slice()));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (let col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        const diag1 = row - col + n - 1;\n        const diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunction nQueens(n: number): string[][][] {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    const state = Array.from({ length: n }, () => Array(n).fill('#'));\n    const cols = Array(n).fill(false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    const diags1 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const diags2 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const res: string[][][] = [];\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(\n  int row,\n  int n,\n  List<List<String>> state,\n  List<List<List<String>>> res,\n  List<bool> cols,\n  List<bool> diags1,\n  List<bool> diags2,\n) {\n  // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (row == n) {\n    List<List<String>> copyState = [];\n    for (List<String> sRow in state) {\n      copyState.add(List.from(sRow));\n    }\n    res.add(copyState);\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u5217\n  for (int col = 0; col < n; col++) {\n    // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n    int diag1 = row - col + n - 1;\n    int diag2 = row + col;\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n    if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n      // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n      state[row][col] = \"Q\";\n      cols[col] = true;\n      diags1[diag1] = true;\n      diags2[diag2] = true;\n      // \u653e\u7f6e\u4e0b\u4e00\u884c\n      backtrack(row + 1, n, state, res, cols, diags1, diags2);\n      // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n      state[row][col] = \"#\";\n      cols[col] = false;\n      diags1[diag1] = false;\n      diags2[diag2] = false;\n    }\n  }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<String>>> nQueens(int n) {\n  // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n  List<List<String>> state = List.generate(n, (index) => List.filled(n, \"#\"));\n  List<bool> cols = List.filled(n, false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n  List<bool> diags1 = List.filled(2 * n - 1, false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n  List<bool> diags2 = List.filled(2 * n - 1, false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n  List<List<List<String>>> res = [];\n\n  backtrack(0, n, state, res, cols, diags1, diags2);\n\n  return res;\n}\n
    n_queens.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfn backtrack(\n    row: usize,\n    n: usize,\n    state: &mut Vec<Vec<String>>,\n    res: &mut Vec<Vec<Vec<String>>>,\n    cols: &mut [bool],\n    diags1: &mut [bool],\n    diags2: &mut [bool],\n) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        let mut copy_state: Vec<Vec<String>> = Vec::new();\n        for s_row in state.clone() {\n            copy_state.push(s_row);\n        }\n        res.push(copy_state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col in 0..n {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        let diag1 = row + n - 1 - col;\n        let diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !cols[col] && !diags1[diag1] && !diags2[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state.get_mut(row).unwrap()[col] = \"Q\".into();\n            (cols[col], diags1[diag1], diags2[diag2]) = (true, true, true);\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state.get_mut(row).unwrap()[col] = \"#\".into();\n            (cols[col], diags1[diag1], diags2[diag2]) = (false, false, false);\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    let mut state: Vec<Vec<String>> = Vec::new();\n    for _ in 0..n {\n        let mut row: Vec<String> = Vec::new();\n        for _ in 0..n {\n            row.push(\"#\".into());\n        }\n        state.push(row);\n    }\n    let mut cols = vec![false; n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    let mut diags1 = vec![false; 2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    let mut diags2 = vec![false; 2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    let mut res: Vec<Vec<Vec<String>>> = Vec::new();\n\n    backtrack(\n        0,\n        n,\n        &mut state,\n        &mut res,\n        &mut cols,\n        &mut diags1,\n        &mut diags2,\n    );\n\n    res\n}\n
    n_queens.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, char state[MAX_SIZE][MAX_SIZE], char ***res, int *resSize, bool cols[MAX_SIZE],\n               bool diags1[2 * MAX_SIZE - 1], bool diags2[2 * MAX_SIZE - 1]) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        res[*resSize] = (char **)malloc(sizeof(char *) * n);\n        for (int i = 0; i < n; ++i) {\n            res[*resSize][i] = (char *)malloc(sizeof(char) * (n + 1));\n            strcpy(res[*resSize][i], state[i]);\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, resSize, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nchar ***nQueens(int n, int *returnSize) {\n    char state[MAX_SIZE][MAX_SIZE];\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            state[i][j] = '#';\n        }\n        state[i][n] = '\\0';\n    }\n    bool cols[MAX_SIZE] = {false};           // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    bool diags1[2 * MAX_SIZE - 1] = {false}; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    bool diags2[2 * MAX_SIZE - 1] = {false}; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n\n    char ***res = (char ***)malloc(sizeof(char **) * MAX_SIZE);\n    *returnSize = 0;\n    backtrack(0, n, state, res, returnSize, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfun backtrack(\n    row: Int,\n    n: Int,\n    state: MutableList<MutableList<String>>,\n    res: MutableList<MutableList<MutableList<String>>?>,\n    cols: BooleanArray,\n    diags1: BooleanArray,\n    diags2: BooleanArray\n) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        val copyState = mutableListOf<MutableList<String>>()\n        for (sRow in state) {\n            copyState.add(sRow.toMutableList())\n        }\n        res.add(copyState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (col in 0..<n) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        val diag1 = row - col + n - 1\n        val diag2 = row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            diags2[diag2] = true\n            diags1[diag1] = diags2[diag2]\n            cols[col] = diags1[diag1]\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            diags2[diag2] = false\n            diags1[diag1] = diags2[diag2]\n            cols[col] = diags1[diag1]\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfun nQueens(n: Int): MutableList<MutableList<MutableList<String>>?> {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    val state = mutableListOf<MutableList<String>>()\n    for (i in 0..<n) {\n        val row = mutableListOf<String>()\n        for (j in 0..<n) {\n            row.add(\"#\")\n        }\n        state.add(row)\n    }\n    val cols = BooleanArray(n) // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    val diags1 = BooleanArray(2 * n - 1) // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    val diags2 = BooleanArray(2 * n - 1) // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    val res = mutableListOf<MutableList<MutableList<String>>?>()\n\n    backtrack(0, n, state, res, cols, diags1, diags2)\n\n    return res\n}\n
    n_queens.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{n_queens}\n
    n_queens.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{nQueens}\n
    Code Visualization

    Full Screen >

    Placing \\(n\\) queens row-by-row, considering column constraints, from the first row to the last row there are \\(n\\), \\(n-1\\), \\(\\dots\\), \\(2\\), \\(1\\) choices, using \\(O(n!)\\) time. When recording a solution, it is necessary to copy the matrix state and add it to res, with the copying operation using \\(O(n^2)\\) time. Therefore, the overall time complexity is \\(O(n! \\cdot n^2)\\). In practice, pruning based on diagonal constraints can significantly reduce the search space, thus often the search efficiency is better than the above time complexity.

    Array state uses \\(O(n^2)\\) space, and arrays cols, diags1, and diags2 each use \\(O(n)\\) space. The maximum recursion depth is \\(n\\), using \\(O(n)\\) stack space. Therefore, the space complexity is \\(O(n^2)\\).

    "},{"location":"chapter_backtracking/permutations_problem/","title":"13.2 \u00a0 Permutation problem","text":"

    The permutation problem is a typical application of the backtracking algorithm. It is defined as finding all possible arrangements of elements from a given set (such as an array or string).

    The Table 13-2 lists several example data, including the input arrays and their corresponding permutations.

    Table 13-2 \u00a0 Permutation examples

    Input array Permutations \\([1]\\) \\([1]\\) \\([1, 2]\\) \\([1, 2], [2, 1]\\) \\([1, 2, 3]\\) \\([1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]\\)"},{"location":"chapter_backtracking/permutations_problem/#1321-cases-without-equal-elements","title":"13.2.1 \u00a0 Cases without equal elements","text":"

    Question

    Enter an integer array without duplicate elements and return all possible permutations.

    From the perspective of the backtracking algorithm, we can imagine the process of generating permutations as a series of choices. Suppose the input array is \\([1, 2, 3]\\), if we first choose \\(1\\), then \\(3\\), and finally \\(2\\), we obtain the permutation \\([1, 3, 2]\\). Backtracking means undoing a choice and then continuing to try other choices.

    From the code perspective, the candidate set choices contains all elements of the input array, and the state state contains elements that have been selected so far. Please note that each element can only be chosen once, thus all elements in state must be unique.

    As shown in the following figure, we can unfold the search process into a recursive tree, where each node represents the current state state. Starting from the root node, after three rounds of choices, we reach the leaf nodes, each corresponding to a permutation.

    Figure 13-5 \u00a0 Permutation recursive tree

    "},{"location":"chapter_backtracking/permutations_problem/#1-pruning-of-repeated-choices","title":"1. \u00a0 Pruning of repeated choices","text":"

    To ensure that each element is selected only once, we consider introducing a boolean array selected, where selected[i] indicates whether choices[i] has been selected. We base our pruning operations on this array:

    • After making the choice choice[i], we set selected[i] to \\(\\text{True}\\), indicating it has been chosen.
    • When iterating through the choice list choices, skip all nodes that have already been selected, i.e., prune.

    As shown in the following figure, suppose we choose 1 in the first round, 3 in the second round, and 2 in the third round, we need to prune the branch of element 1 in the second round and elements 1 and 3 in the third round.

    Figure 13-6 \u00a0 Permutation pruning example

    Observing the above figure, this pruning operation reduces the search space size from \\(O(n^n)\\) to \\(O(n!)\\).

    "},{"location":"chapter_backtracking/permutations_problem/#2-code-implementation","title":"2. \u00a0 Code implementation","text":"

    After understanding the above information, we can \"fill in the blanks\" in the framework code. To shorten the overall code, we do not implement individual functions within the framework code separately, but expand them in the backtrack() function:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig permutations_i.py
    def backtrack(\n    state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I\"\"\"\n    # \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(state) == len(choices):\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i, choice in enumerate(choices):\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if not selected[i]:\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = True\n            state.append(choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = False\n            state.pop()\n\ndef permutations_i(nums: list[int]) -> list[list[int]]:\n    \"\"\"\u5168\u6392\u5217 I\"\"\"\n    res = []\n    backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res)\n    return res\n
    permutations_i.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(vector<int> &state, const vector<int> &choices, vector<bool> &selected, vector<vector<int>> &res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.size()) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.size(); i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push_back(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop_back();\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nvector<vector<int>> permutationsI(vector<int> nums) {\n    vector<int> state;\n    vector<bool> selected(nums.size(), false);\n    vector<vector<int>> res;\n    backtrack(state, nums, selected, res);\n    return res;\n}\n
    permutations_i.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(List<Integer> state, int[] choices, boolean[] selected, List<List<Integer>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.length) {\n        res.add(new ArrayList<Integer>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.size() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<Integer>> permutationsI(int[] nums) {\n    List<List<Integer>> res = new ArrayList<List<Integer>>();\n    backtrack(new ArrayList<Integer>(), nums, new boolean[nums.length], res);\n    return res;\n}\n
    permutations_i.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid Backtrack(List<int> state, int[] choices, bool[] selected, List<List<int>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.Count == choices.Length) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.Length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.Add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.RemoveAt(state.Count - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<int>> PermutationsI(int[] nums) {\n    List<List<int>> res = [];\n    Backtrack([], nums, new bool[nums.Length], res);\n    return res;\n}\n
    permutations_i.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunc backtrackI(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(*state) == len(*choices) {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i := 0; i < len(*choices); i++ {\n        choice := (*choices)[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !(*selected)[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            (*selected)[i] = true\n            *state = append(*state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrackI(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            (*selected)[i] = false\n            *state = (*state)[:len(*state)-1]\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfunc permutationsI(nums []int) [][]int {\n    res := make([][]int, 0)\n    state := make([]int, 0)\n    selected := make([]bool, len(nums))\n    backtrackI(&state, &nums, &selected, &res)\n    return res\n}\n
    permutations_i.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunc backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.count == choices.count {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i, choice) in choices.enumerated() {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !selected[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true\n            state.append(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: choices, selected: &selected, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeLast()\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfunc permutationsI(nums: [Int]) -> [[Int]] {\n    var state: [Int] = []\n    var selected = Array(repeating: false, count: nums.count)\n    var res: [[Int]] = []\n    backtrack(state: &state, choices: nums, selected: &selected, res: &res)\n    return res\n}\n
    permutations_i.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunction backtrack(state, choices, selected, res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 I */\nfunction permutationsI(nums) {\n    const res = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_i.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunction backtrack(\n    state: number[],\n    choices: number[],\n    selected: boolean[],\n    res: number[][]\n): void {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 I */\nfunction permutationsI(nums: number[]): number[][] {\n    const res: number[][] = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_i.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(\n  List<int> state,\n  List<int> choices,\n  List<bool> selected,\n  List<List<int>> res,\n) {\n  // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (state.length == choices.length) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int i = 0; i < choices.length; i++) {\n    int choice = choices[i];\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n    if (!selected[i]) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      selected[i] = true;\n      state.add(choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, choices, selected, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      selected[i] = false;\n      state.removeLast();\n    }\n  }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<int>> permutationsI(List<int> nums) {\n  List<List<int>> res = [];\n  backtrack([], nums, List.filled(nums.length, false), res);\n  return res;\n}\n
    permutations_i.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfn backtrack(mut state: Vec<i32>, choices: &[i32], selected: &mut [bool], res: &mut Vec<Vec<i32>>) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.len() == choices.len() {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in 0..choices.len() {\n        let choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !selected[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state.clone(), choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.len() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfn permutations_i(nums: &mut [i32]) -> Vec<Vec<i32>> {\n    let mut res = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    backtrack(Vec::new(), nums, &mut vec![false; nums.len()], &mut res);\n    res\n}\n
    permutations_i.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (stateSize == choicesSize) {\n        res[*resSize] = (int *)malloc(choicesSize * sizeof(int));\n        for (int i = 0; i < choicesSize; i++) {\n            res[*resSize][i] = state[i];\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choicesSize; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state[stateSize] = choice;\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nint **permutationsI(int *nums, int numsSize, int *returnSize) {\n    int *state = (int *)malloc(numsSize * sizeof(int));\n    bool *selected = (bool *)malloc(numsSize * sizeof(bool));\n    for (int i = 0; i < numsSize; i++) {\n        selected[i] = false;\n    }\n    int **res = (int **)malloc(MAX_SIZE * sizeof(int *));\n    *returnSize = 0;\n\n    backtrack(state, 0, nums, numsSize, selected, res, returnSize);\n\n    free(state);\n    free(selected);\n\n    return res;\n}\n
    permutations_i.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfun backtrack(\n    state: MutableList<Int>,\n    choices: IntArray,\n    selected: BooleanArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size == choices.size) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i in choices.indices) {\n        val choice = choices[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true\n            state.add(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeAt(state.size - 1)\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfun permutationsI(nums: IntArray): MutableList<MutableList<Int>?> {\n    val res = mutableListOf<MutableList<Int>?>()\n    backtrack(mutableListOf(), nums, BooleanArray(nums.size), res)\n    return res\n}\n
    permutations_i.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutations_i}\n
    permutations_i.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutationsI}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_backtracking/permutations_problem/#1322-considering-cases-with-equal-elements","title":"13.2.2 \u00a0 Considering cases with equal elements","text":"

    Question

    Enter an integer array, which may contain duplicate elements, and return all unique permutations.

    Suppose the input array is \\([1, 1, 2]\\). To differentiate the two duplicate elements \\(1\\), we mark the second \\(1\\) as \\(\\hat{1}\\).

    As shown in the following figure, half of the permutations generated by the above method are duplicates.

    Figure 13-7 \u00a0 Duplicate permutations

    So, how do we eliminate duplicate permutations? Most directly, consider using a hash set to deduplicate permutation results. However, this is not elegant, as branches generating duplicate permutations are unnecessary and should be identified and pruned in advance, which can further improve algorithm efficiency.

    "},{"location":"chapter_backtracking/permutations_problem/#1-pruning-of-equal-elements","title":"1. \u00a0 Pruning of equal elements","text":"

    Observing the following figure, in the first round, choosing \\(1\\) or \\(\\hat{1}\\) results in identical permutations under both choices, thus we should prune \\(\\hat{1}\\).

    Similarly, after choosing \\(2\\) in the first round, choosing \\(1\\) and \\(\\hat{1}\\) in the second round also produces duplicate branches, so we should also prune \\(\\hat{1}\\) in the second round.

    Essentially, our goal is to ensure that multiple equal elements are only selected once in each round of choices.

    Figure 13-8 \u00a0 Duplicate permutations pruning

    "},{"location":"chapter_backtracking/permutations_problem/#2-code-implementation_1","title":"2. \u00a0 Code implementation","text":"

    Based on the code from the previous problem, we consider initiating a hash set duplicated in each round of choices, used to record elements that have been tried in that round, and prune duplicate elements:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig permutations_ii.py
    def backtrack(\n    state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II\"\"\"\n    # \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(state) == len(choices):\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    duplicated = set[int]()\n    for i, choice in enumerate(choices):\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if not selected[i] and choice not in duplicated:\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice)  # \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = True\n            state.append(choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = False\n            state.pop()\n\ndef permutations_ii(nums: list[int]) -> list[list[int]]:\n    \"\"\"\u5168\u6392\u5217 II\"\"\"\n    res = []\n    backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res)\n    return res\n
    permutations_ii.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(vector<int> &state, const vector<int> &choices, vector<bool> &selected, vector<vector<int>> &res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.size()) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    unordered_set<int> duplicated;\n    for (int i = 0; i < choices.size(); i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && duplicated.find(choice) == duplicated.end()) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.emplace(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push_back(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop_back();\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nvector<vector<int>> permutationsII(vector<int> nums) {\n    vector<int> state;\n    vector<bool> selected(nums.size(), false);\n    vector<vector<int>> res;\n    backtrack(state, nums, selected, res);\n    return res;\n}\n
    permutations_ii.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(List<Integer> state, int[] choices, boolean[] selected, List<List<Integer>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.length) {\n        res.add(new ArrayList<Integer>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    Set<Integer> duplicated = new HashSet<Integer>();\n    for (int i = 0; i < choices.length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.size() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<Integer>> permutationsII(int[] nums) {\n    List<List<Integer>> res = new ArrayList<List<Integer>>();\n    backtrack(new ArrayList<Integer>(), nums, new boolean[nums.length], res);\n    return res;\n}\n
    permutations_ii.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid Backtrack(List<int> state, int[] choices, bool[] selected, List<List<int>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.Count == choices.Length) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    HashSet<int> duplicated = [];\n    for (int i = 0; i < choices.Length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.Contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.Add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.Add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.RemoveAt(state.Count - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<int>> PermutationsII(int[] nums) {\n    List<List<int>> res = [];\n    Backtrack([], nums, new bool[nums.Length], res);\n    return res;\n}\n
    permutations_ii.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunc backtrackII(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(*state) == len(*choices) {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    duplicated := make(map[int]struct{}, 0)\n    for i := 0; i < len(*choices); i++ {\n        choice := (*choices)[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if _, ok := duplicated[choice]; !ok && !(*selected)[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            duplicated[choice] = struct{}{}\n            (*selected)[i] = true\n            *state = append(*state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrackII(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            (*selected)[i] = false\n            *state = (*state)[:len(*state)-1]\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfunc permutationsII(nums []int) [][]int {\n    res := make([][]int, 0)\n    state := make([]int, 0)\n    selected := make([]bool, len(nums))\n    backtrackII(&state, &nums, &selected, &res)\n    return res\n}\n
    permutations_ii.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunc backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.count == choices.count {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    var duplicated: Set<Int> = []\n    for (i, choice) in choices.enumerated() {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if !selected[i], !duplicated.contains(choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.insert(choice) // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true\n            state.append(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: choices, selected: &selected, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeLast()\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfunc permutationsII(nums: [Int]) -> [[Int]] {\n    var state: [Int] = []\n    var selected = Array(repeating: false, count: nums.count)\n    var res: [[Int]] = []\n    backtrack(state: &state, choices: nums, selected: &selected, res: &res)\n    return res\n}\n
    permutations_ii.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunction backtrack(state, choices, selected, res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    const duplicated = new Set();\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.has(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 II */\nfunction permutationsII(nums) {\n    const res = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_ii.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunction backtrack(\n    state: number[],\n    choices: number[],\n    selected: boolean[],\n    res: number[][]\n): void {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    const duplicated = new Set();\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.has(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 II */\nfunction permutationsII(nums: number[]): number[][] {\n    const res: number[][] = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_ii.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(\n  List<int> state,\n  List<int> choices,\n  List<bool> selected,\n  List<List<int>> res,\n) {\n  // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (state.length == choices.length) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  Set<int> duplicated = {};\n  for (int i = 0; i < choices.length; i++) {\n    int choice = choices[i];\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n    if (!selected[i] && !duplicated.contains(choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n      selected[i] = true;\n      state.add(choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, choices, selected, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      selected[i] = false;\n      state.removeLast();\n    }\n  }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<int>> permutationsII(List<int> nums) {\n  List<List<int>> res = [];\n  backtrack([], nums, List.filled(nums.length, false), res);\n  return res;\n}\n
    permutations_ii.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfn backtrack(mut state: Vec<i32>, choices: &[i32], selected: &mut [bool], res: &mut Vec<Vec<i32>>) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.len() == choices.len() {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    let mut duplicated = HashSet::<i32>::new();\n    for i in 0..choices.len() {\n        let choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if !selected[i] && !duplicated.contains(&choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.insert(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state.clone(), choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.len() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfn permutations_ii(nums: &mut [i32]) -> Vec<Vec<i32>> {\n    let mut res = Vec::new();\n    backtrack(Vec::new(), nums, &mut vec![false; nums.len()], &mut res);\n    res\n}\n
    permutations_ii.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (stateSize == choicesSize) {\n        res[*resSize] = (int *)malloc(choicesSize * sizeof(int));\n        for (int i = 0; i < choicesSize; i++) {\n            res[*resSize][i] = state[i];\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    bool duplicated[MAX_SIZE] = {false};\n    for (int i = 0; i < choicesSize; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated[choice]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated[choice] = true; // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state[stateSize] = choice;\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nint **permutationsII(int *nums, int numsSize, int *returnSize) {\n    int *state = (int *)malloc(numsSize * sizeof(int));\n    bool *selected = (bool *)malloc(numsSize * sizeof(bool));\n    for (int i = 0; i < numsSize; i++) {\n        selected[i] = false;\n    }\n    int **res = (int **)malloc(MAX_SIZE * sizeof(int *));\n    *returnSize = 0;\n\n    backtrack(state, 0, nums, numsSize, selected, res, returnSize);\n\n    free(state);\n    free(selected);\n\n    return res;\n}\n
    permutations_ii.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfun backtrack(\n    state: MutableList<Int>,\n    choices: IntArray,\n    selected: BooleanArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size == choices.size) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    val duplicated = HashSet<Int>()\n    for (i in choices.indices) {\n        val choice = choices[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice) // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true\n            state.add(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeAt(state.size - 1)\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfun permutationsII(nums: IntArray): MutableList<MutableList<Int>?> {\n    val res = mutableListOf<MutableList<Int>?>()\n    backtrack(mutableListOf(), nums, BooleanArray(nums.size), res)\n    return res\n}\n
    permutations_ii.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutations_ii}\n
    permutations_ii.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutationsII}\n
    Code Visualization

    Full Screen >

    Assuming all elements are distinct from each other, there are \\(n!\\) (factorial) permutations of \\(n\\) elements; when recording results, it is necessary to copy a list of length \\(n\\), using \\(O(n)\\) time. Thus, the time complexity is \\(O(n!n)\\).

    The maximum recursion depth is \\(n\\), using \\(O(n)\\) frame space. Selected uses \\(O(n)\\) space. At any one time, there can be up to \\(n\\) duplicated, using \\(O(n^2)\\) space. Therefore, the space complexity is \\(O(n^2)\\).

    "},{"location":"chapter_backtracking/permutations_problem/#3-comparison-of-the-two-pruning-methods","title":"3. \u00a0 Comparison of the two pruning methods","text":"

    Please note, although both selected and duplicated are used for pruning, their targets are different.

    • Repeated choice pruning: There is only one selected throughout the search process. It records which elements are currently in the state, aiming to prevent an element from appearing repeatedly in state.
    • Equal element pruning: Each round of choices (each call to the backtrack function) contains a duplicated. It records which elements have been chosen in the current traversal (for loop), aiming to ensure equal elements are selected only once.

    The following figure shows the scope of the two pruning conditions. Note, each node in the tree represents a choice, and the nodes from the root to the leaf form a permutation.

    Figure 13-9 \u00a0 Scope of the two pruning conditions

    "},{"location":"chapter_backtracking/subset_sum_problem/","title":"13.3 \u00a0 Subset sum problem","text":""},{"location":"chapter_backtracking/subset_sum_problem/#1331-case-without-duplicate-elements","title":"13.3.1 \u00a0 Case without duplicate elements","text":"

    Question

    Given an array of positive integers nums and a target positive integer target, find all possible combinations such that the sum of the elements in the combination equals target. The given array has no duplicate elements, and each element can be chosen multiple times. Please return these combinations as a list, which should not contain duplicate combinations.

    For example, for the input set \\(\\{3, 4, 5\\}\\) and target integer \\(9\\), the solutions are \\(\\{3, 3, 3\\}, \\{4, 5\\}\\). Note the following two points.

    • Elements in the input set can be chosen an unlimited number of times.
    • Subsets do not distinguish the order of elements, for example \\(\\{4, 5\\}\\) and \\(\\{5, 4\\}\\) are the same subset.
    "},{"location":"chapter_backtracking/subset_sum_problem/#1-reference-permutation-solution","title":"1. \u00a0 Reference permutation solution","text":"

    Similar to the permutation problem, we can imagine the generation of subsets as a series of choices, updating the \"element sum\" in real-time during the choice process. When the element sum equals target, the subset is recorded in the result list.

    Unlike the permutation problem, elements in this problem can be chosen an unlimited number of times, thus there is no need to use a selected boolean list to record whether an element has been chosen. We can make minor modifications to the permutation code to initially solve the problem:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_i_naive.py
    def backtrack(\n    state: list[int],\n    target: int,\n    total: int,\n    choices: list[int],\n    res: list[list[int]],\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in range(len(choices)):\n        # \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_i_naive(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    total = 0  # \u5b50\u96c6\u548c\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res)\n    return res\n
    subset_sum_i_naive.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(vector<int> &state, int target, int total, vector<int> &choices, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (size_t i = 0; i < choices.size(); i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nvector<vector<int>> subsetSumINaive(vector<int> &nums, int target) {\n    vector<int> state;       // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0;           // \u5b50\u96c6\u548c\n    vector<vector<int>> res; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(List<Integer> state, int target, int total, int[] choices, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<Integer>> subsetSumINaive(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0; // \u5b50\u96c6\u548c\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid Backtrack(List<int> state, int target, int total, int[] choices, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.Length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<int>> SubsetSumINaive(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0; // \u5b50\u96c6\u548c\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrackSubsetSumINaive(total, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == total {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i := 0; i < len(*choices); i++ {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total+(*choices)[i] > target {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumINaive(total+(*choices)[i], target, state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunc subsetSumINaive(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    total := 0              // \u5b50\u96c6\u548c\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumINaive(total, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_i_naive.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrack(state: inout [Int], target: Int, total: Int, choices: [Int], res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in choices.indices {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target, total: total + choices[i], choices: choices, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunc subsetSumINaive(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let total = 0 // \u5b50\u96c6\u548c\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, total: total, choices: nums, res: &res)\n    return res\n}\n
    subset_sum_i_naive.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(state, target, total, choices, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total === target) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunction subsetSumINaive(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    const total = 0; // \u5b50\u96c6\u548c\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(\n    state: number[],\n    target: number,\n    total: number,\n    choices: number[],\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total === target) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunction subsetSumINaive(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    const total = 0; // \u5b50\u96c6\u548c\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(\n  List<int> state,\n  int target,\n  int total,\n  List<int> choices,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (total == target) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int i = 0; i < choices.length; i++) {\n    // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n    if (total + choices[i] > target) {\n      continue;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target, total + choices[i], choices, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<int>> subsetSumINaive(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  int total = 0; // \u5143\u7d20\u548c\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, total, nums, res);\n  return res;\n}\n
    subset_sum_i_naive.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    total: i32,\n    choices: &[i32],\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in 0..choices.len() {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfn subset_sum_i_naive(nums: &[i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let total = 0; // \u5b50\u96c6\u548c\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, &mut res);\n    res\n}\n
    subset_sum_i_naive.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(int target, int total, int *choices, int choicesSize) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        for (int i = 0; i < stateSize; i++) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choicesSize; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state[stateSize++] = choices[i];\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target, total + choices[i], choices, choicesSize);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nvoid subsetSumINaive(int *nums, int numsSize, int target) {\n    resSize = 0; // \u521d\u59cb\u5316\u89e3\u7684\u6570\u91cf\u4e3a0\n    backtrack(target, 0, nums, numsSize);\n}\n
    subset_sum_i_naive.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    total: Int,\n    choices: IntArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i in choices.indices) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfun subsetSumINaive(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    val total = 0 // \u5b50\u96c6\u548c\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res)\n    return res\n}\n
    subset_sum_i_naive.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_i_naive}\n
    subset_sum_i_naive.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumINaive}\n
    Code Visualization

    Full Screen >

    Inputting the array \\([3, 4, 5]\\) and target element \\(9\\) into the above code yields the results \\([3, 3, 3], [4, 5], [5, 4]\\). Although it successfully finds all subsets with a sum of \\(9\\), it includes the duplicate subset \\([4, 5]\\) and \\([5, 4]\\).

    This is because the search process distinguishes the order of choices, however, subsets do not distinguish the choice order. As shown in the following figure, choosing \\(4\\) before \\(5\\) and choosing \\(5\\) before \\(4\\) are different branches, but correspond to the same subset.

    Figure 13-10 \u00a0 Subset search and pruning out of bounds

    To eliminate duplicate subsets, a straightforward idea is to deduplicate the result list. However, this method is very inefficient for two reasons.

    • When there are many array elements, especially when target is large, the search process produces a large number of duplicate subsets.
    • Comparing subsets (arrays) for differences is very time-consuming, requiring arrays to be sorted first, then comparing the differences of each element in the arrays.
    "},{"location":"chapter_backtracking/subset_sum_problem/#2-duplicate-subset-pruning","title":"2. \u00a0 Duplicate subset pruning","text":"

    We consider deduplication during the search process through pruning. Observing the following figure, duplicate subsets are generated when choosing array elements in different orders, for example in the following situations.

    1. When choosing \\(3\\) in the first round and \\(4\\) in the second round, all subsets containing these two elements are generated, denoted as \\([3, 4, \\dots]\\).
    2. Later, when \\(4\\) is chosen in the first round, the second round should skip \\(3\\) because the subset \\([4, 3, \\dots]\\) generated by this choice completely duplicates the subset from step 1..

    In the search process, each layer's choices are tried one by one from left to right, so the more to the right a branch is, the more it is pruned.

    1. First two rounds choose \\(3\\) and \\(5\\), generating subset \\([3, 5, \\dots]\\).
    2. First two rounds choose \\(4\\) and \\(5\\), generating subset \\([4, 5, \\dots]\\).
    3. If \\(5\\) is chosen in the first round, then the second round should skip \\(3\\) and \\(4\\) as the subsets \\([5, 3, \\dots]\\) and \\([5, 4, \\dots]\\) completely duplicate the subsets described in steps 1. and 2..

    Figure 13-11 \u00a0 Different choice orders leading to duplicate subsets

    In summary, given the input array \\([x_1, x_2, \\dots, x_n]\\), the choice sequence in the search process should be \\([x_{i_1}, x_{i_2}, \\dots, x_{i_m}]\\), which needs to satisfy \\(i_1 \\leq i_2 \\leq \\dots \\leq i_m\\). Any choice sequence that does not meet this condition will cause duplicates and should be pruned.

    "},{"location":"chapter_backtracking/subset_sum_problem/#3-code-implementation","title":"3. \u00a0 Code implementation","text":"

    To implement this pruning, we initialize the variable start, which indicates the starting point for traversal. After making the choice \\(x_{i}\\), set the next round to start from index \\(i\\). This will ensure the choice sequence satisfies \\(i_1 \\leq i_2 \\leq \\dots \\leq i_m\\), thereby ensuring the uniqueness of the subsets.

    Besides, we have made the following two optimizations to the code.

    • Before starting the search, sort the array nums. In the traversal of all choices, end the loop directly when the subset sum exceeds target as subsequent elements are larger and their subset sum will definitely exceed target.
    • Eliminate the element sum variable total, by performing subtraction on target to count the element sum. When target equals \\(0\\), record the solution.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_i.py
    def backtrack(\n    state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    # \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in range(start, len(choices)):\n        # \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        # \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0:\n            break\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_i(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c I\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort()  # \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start = 0  # \u904d\u5386\u8d77\u59cb\u70b9\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n
    subset_sum_i.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(vector<int> &state, int target, vector<int> &choices, int start, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.size(); i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nvector<vector<int>> subsetSumI(vector<int> &nums, int target) {\n    vector<int> state;              // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort(nums.begin(), nums.end()); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                  // \u904d\u5386\u8d77\u59cb\u70b9\n    vector<vector<int>> res;        // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(List<Integer> state, int target, int[] choices, int start, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<Integer>> subsetSumI(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Arrays.sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid Backtrack(List<int> state, int target, int[] choices, int start, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.Length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<int>> SubsetSumI(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Array.Sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrackSubsetSumI(start, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i := start; i < len(*choices); i++ {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target-(*choices)[i] < 0 {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumI(i, target-(*choices)[i], state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunc subsetSumI(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort.Ints(nums)         // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start := 0              // \u904d\u5386\u8d77\u59cb\u70b9\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumI(start, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_i.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in choices.indices.dropFirst(start) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target - choices[i], choices: choices, start: i, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunc subsetSumI(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let nums = nums.sorted() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, choices: nums, start: start, res: &res)\n    return res\n}\n
    subset_sum_i.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(state, target, choices, start, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunction subsetSumI(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(\n    state: number[],\n    target: number,\n    choices: number[],\n    start: number,\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunction subsetSumI(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(\n  List<int> state,\n  int target,\n  List<int> choices,\n  int start,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (target == 0) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n  for (int i = start; i < choices.length; i++) {\n    // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n    // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n    if (target - choices[i] < 0) {\n      break;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target - choices[i], choices, i, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<int>> subsetSumI(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n  int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, nums, start, res);\n  return res;\n}\n
    subset_sum_i.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    choices: &[i32],\n    start: usize,\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in start..choices.len() {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfn subset_sum_i(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, &mut res);\n    res\n}\n
    subset_sum_i.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(int target, int *choices, int choicesSize, int start) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        for (int i = 0; i < stateSize; ++i) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choicesSize; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state[stateSize] = choices[i];\n        stateSize++;\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target - choices[i], choices, choicesSize, i);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nvoid subsetSumI(int *nums, int numsSize, int target) {\n    qsort(nums, numsSize, sizeof(int), cmp); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                           // \u904d\u5386\u8d77\u59cb\u70b9\n    backtrack(target, nums, numsSize, start);\n}\n
    subset_sum_i.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    choices: IntArray,\n    start: Int,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (i in start..<choices.size) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfun subsetSumI(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    val start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n}\n
    subset_sum_i.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_i}\n
    subset_sum_i.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumI}\n
    Code Visualization

    Full Screen >

    The following figure shows the overall backtracking process after inputting the array \\([3, 4, 5]\\) and target element \\(9\\) into the above code.

    Figure 13-12 \u00a0 Subset sum I backtracking process

    "},{"location":"chapter_backtracking/subset_sum_problem/#1332-considering-cases-with-duplicate-elements","title":"13.3.2 \u00a0 Considering cases with duplicate elements","text":"

    Question

    Given an array of positive integers nums and a target positive integer target, find all possible combinations such that the sum of the elements in the combination equals target. The given array may contain duplicate elements, and each element can only be chosen once. Please return these combinations as a list, which should not contain duplicate combinations.

    Compared to the previous question, this question's input array may contain duplicate elements, introducing new problems. For example, given the array \\([4, \\hat{4}, 5]\\) and target element \\(9\\), the existing code's output results in \\([4, 5], [\\hat{4}, 5]\\), resulting in duplicate subsets.

    The reason for this duplication is that equal elements are chosen multiple times in a certain round. In the following figure, the first round has three choices, two of which are \\(4\\), generating two duplicate search branches, thus outputting duplicate subsets; similarly, the two \\(4\\)s in the second round also produce duplicate subsets.

    Figure 13-13 \u00a0 Duplicate subsets caused by equal elements

    "},{"location":"chapter_backtracking/subset_sum_problem/#1-equal-element-pruning","title":"1. \u00a0 Equal element pruning","text":"

    To solve this issue, we need to limit equal elements to being chosen only once per round. The implementation is quite clever: since the array is sorted, equal elements are adjacent. This means that in a certain round of choices, if the current element is equal to its left-hand element, it means it has already been chosen, so skip the current element directly.

    At the same time, this question stipulates that each array element can only be chosen once. Fortunately, we can also use the variable start to meet this constraint: after making the choice \\(x_{i}\\), set the next round to start from index \\(i + 1\\) going forward. This not only eliminates duplicate subsets but also avoids repeated selection of elements.

    "},{"location":"chapter_backtracking/subset_sum_problem/#2-code-implementation","title":"2. \u00a0 Code implementation","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_ii.py
    def backtrack(\n    state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    # \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    # \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in range(start, len(choices)):\n        # \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        # \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0:\n            break\n        # \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start and choices[i] == choices[i - 1]:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_ii(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c II\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort()  # \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start = 0  # \u904d\u5386\u8d77\u59cb\u70b9\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n
    subset_sum_ii.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(vector<int> &state, int target, vector<int> &choices, int start, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.size(); i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nvector<vector<int>> subsetSumII(vector<int> &nums, int target) {\n    vector<int> state;              // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort(nums.begin(), nums.end()); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                  // \u904d\u5386\u8d77\u59cb\u70b9\n    vector<vector<int>> res;        // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(List<Integer> state, int target, int[] choices, int start, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<Integer>> subsetSumII(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Arrays.sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid Backtrack(List<int> state, int target, int[] choices, int start, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.Length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<int>> SubsetSumII(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Array.Sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunc backtrackSubsetSumII(start, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i := start; i < len(*choices); i++ {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target-(*choices)[i] < 0 {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start && (*choices)[i] == (*choices)[i-1] {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumII(i+1, target-(*choices)[i], state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunc subsetSumII(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort.Ints(nums)         // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start := 0              // \u904d\u5386\u8d77\u59cb\u70b9\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumII(start, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_ii.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunc backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in choices.indices.dropFirst(start) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start, choices[i] == choices[i - 1] {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target - choices[i], choices: choices, start: i + 1, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunc subsetSumII(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let nums = nums.sorted() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, choices: nums, start: start, res: &res)\n    return res\n}\n
    subset_sum_ii.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunction backtrack(state, target, choices, start, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] === choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunction subsetSumII(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunction backtrack(\n    state: number[],\n    target: number,\n    choices: number[],\n    start: number,\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] === choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunction subsetSumII(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(\n  List<int> state,\n  int target,\n  List<int> choices,\n  int start,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (target == 0) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n  // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n  for (int i = start; i < choices.length; i++) {\n    // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n    // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n    if (target - choices[i] < 0) {\n      break;\n    }\n    // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n    if (i > start && choices[i] == choices[i - 1]) {\n      continue;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target - choices[i], choices, i + 1, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<int>> subsetSumII(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n  int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, nums, start, res);\n  return res;\n}\n
    subset_sum_ii.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    choices: &[i32],\n    start: usize,\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in start..choices.len() {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start && choices[i] == choices[i - 1] {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfn subset_sum_ii(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, &mut res);\n    res\n}\n
    subset_sum_ii.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(int target, int *choices, int choicesSize, int start) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        for (int i = 0; i < stateSize; i++) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choicesSize; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\n        if (target - choices[i] < 0) {\n            continue;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state[stateSize] = choices[i];\n        stateSize++;\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target - choices[i], choices, choicesSize, i + 1);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nvoid subsetSumII(int *nums, int numsSize, int target) {\n    // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    qsort(nums, numsSize, sizeof(int), cmp);\n    // \u5f00\u59cb\u56de\u6eaf\n    backtrack(target, nums, numsSize, 0);\n}\n
    subset_sum_ii.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    choices: IntArray,\n    start: Int,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (i in start..<choices.size) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfun subsetSumII(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    val start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n}\n
    subset_sum_ii.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_ii}\n
    subset_sum_ii.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumII}\n
    Code Visualization

    Full Screen >

    The following figure shows the backtracking process for the array \\([4, 4, 5]\\) and target element \\(9\\), including four types of pruning operations. Please combine the illustration with the code comments to understand the entire search process and how each type of pruning operation works.

    Figure 13-14 \u00a0 Subset sum II backtracking process

    "},{"location":"chapter_backtracking/summary/","title":"13.5 \u00a0 Summary","text":""},{"location":"chapter_backtracking/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • The essence of the backtracking algorithm is an exhaustive search method, where the solution space is traversed deeply first to find solutions that meet the criteria. During the search, if a satisfying solution is found, it is recorded, until all solutions are found or the search is completed.
    • The search process of the backtracking algorithm includes trying and retreating. It uses depth-first search to explore various choices, and when a choice does not meet the constraint conditions, the previous choice is undone, reverting to the previous state, and other options are then continued to be tried. Trying and retreating are operations in opposite directions.
    • Backtracking problems usually contain multiple constraints, which can be used to perform pruning operations. Pruning can terminate unnecessary search branches early, greatly enhancing search efficiency.
    • Backtracking algorithms are mainly used to solve search problems and constraint satisfaction problems. Although combinatorial optimization problems can be solved using backtracking, there are often more efficient or effective solutions available.
    • The permutation problem aims to search for all possible permutations of a given set of elements. We use an array to record whether each element has been chosen, cutting off branches that repeatedly select the same element, ensuring each element is selected only once.
    • In permutation problems, if the set contains duplicate elements, the final result will include duplicate permutations. We need to restrict that identical elements can only be selected once in each round, which is usually implemented using a hash set.
    • The subset-sum problem aims to find all subsets in a given set that sum to a target value. The set does not distinguish the order of elements, but the search process outputs all ordered results, producing duplicate subsets. Before backtracking, we sort the data and set a variable to indicate the starting point of each round of traversal, thereby pruning the search branches that generate duplicate subsets.
    • For the subset-sum problem, equal elements in the array can produce duplicate sets. Using the precondition that the array is already sorted, we prune by determining if adjacent elements are equal, thus ensuring equal elements are only selected once per round.
    • The \\(n\\) queens problem aims to find schemes to place \\(n\\) queens on an \\(n \\times n\\) size chessboard in such a way that no two queens can attack each other. The constraints of the problem include row constraints, column constraints, main diagonal constraints, and secondary diagonal constraints. To meet the row constraint, we adopt a strategy of placing one queen per row, ensuring each row has one queen placed.
    • The handling of column constraints and diagonal constraints is similar. For column constraints, we use an array to record whether there is a queen in each column, thereby indicating whether the selected cell is legal. For diagonal constraints, we use two arrays to respectively record the presence of queens on the main and secondary diagonals; the challenge is in identifying the row and column index patterns that satisfy the same primary (secondary) diagonal.
    "},{"location":"chapter_backtracking/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: How can we understand the relationship between backtracking and recursion?

    Overall, backtracking is a \"strategic algorithm,\" while recursion is more of a \"tool.\"

    • Backtracking algorithms are typically based on recursion. However, backtracking is one of the application scenarios of recursion, specifically in search problems.
    • The structure of recursion reflects the \"sub-problem decomposition\" problem-solving paradigm, commonly used in solving problems involving divide and conquer, backtracking, and dynamic programming (memoized recursion).
    "},{"location":"chapter_computational_complexity/","title":"Chapter 2. \u00a0 Complexity analysis","text":"

    Abstract

    Complexity analysis is like a space-time navigator in the vast universe of algorithms.

    It guides us in exploring deeper within the the dimensions of time and space, seeking more elegant solutions.

    "},{"location":"chapter_computational_complexity/#chapter-contents","title":"Chapter contents","text":"
    • 2.1 \u00a0 Algorithm efficiency assessment
    • 2.2 \u00a0 Iteration and recursion
    • 2.3 \u00a0 Time complexity
    • 2.4 \u00a0 Space complexity
    • 2.5 \u00a0 Summary
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/","title":"2.2 \u00a0 Iteration and recursion","text":"

    In algorithms, the repeated execution of a task is quite common and is closely related to the analysis of complexity. Therefore, before delving into the concepts of time complexity and space complexity, let's first explore how to implement repetitive tasks in programming. This involves understanding two fundamental programming control structures: iteration and recursion.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#221-iteration","title":"2.2.1 \u00a0 Iteration","text":"

    \"Iteration\" is a control structure for repeatedly performing a task. In iteration, a program repeats a block of code as long as a certain condition is met until this condition is no longer satisfied.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1-for-loops","title":"1. \u00a0 For loops","text":"

    The for loop is one of the most common forms of iteration, and it's particularly suitable when the number of iterations is known in advance.

    The following function uses a for loop to perform a summation of \\(1 + 2 + \\dots + n\\), with the sum being stored in the variable res. It's important to note that in Python, range(a, b) creates an interval that is inclusive of a but exclusive of b, meaning it iterates over the range from \\(a\\) up to \\(b\u22121\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def for_loop(n: int) -> int:\n    \"\"\"for \u5faa\u73af\"\"\"\n    res = 0\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        res += i\n    return res\n
    iteration.cpp
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.java
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.cs
    /* for \u5faa\u73af */\nint ForLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.go
    /* for \u5faa\u73af */\nfunc forLoop(n int) int {\n    res := 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        res += i\n    }\n    return res\n}\n
    iteration.swift
    /* for \u5faa\u73af */\nfunc forLoop(n: Int) -> Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        res += i\n    }\n    return res\n}\n
    iteration.js
    /* for \u5faa\u73af */\nfunction forLoop(n) {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.ts
    /* for \u5faa\u73af */\nfunction forLoop(n: number): number {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.dart
    /* for \u5faa\u73af */\nint forLoop(int n) {\n  int res = 0;\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    res += i;\n  }\n  return res;\n}\n
    iteration.rs
    /* for \u5faa\u73af */\nfn for_loop(n: i32) -> i32 {\n    let mut res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1..=n {\n        res += i;\n    }\n    res\n}\n
    iteration.c
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.kt
    /* for \u5faa\u73af */\nfun forLoop(n: Int): Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        res += i\n    }\n    return res\n}\n
    iteration.rb
    ### for \u5faa\u73af ###\ndef for_loop(n)\n  res = 0\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for i in 1..n\n    res += i\n  end\n\n  res\nend\n
    iteration.zig
    // for \u5faa\u73af\nfn forLoop(n: usize) i32 {\n    var res: i32 = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        res = res + @as(i32, @intCast(i));\n    }\n    return res;\n} \n
    Code Visualization

    Full Screen >

    The flowchart below represents this sum function.

    Figure 2-1 \u00a0 Flowchart of the sum function

    The number of operations in this summation function is proportional to the size of the input data \\(n\\), or in other words, it has a \"linear relationship.\" This \"linear relationship\" is what time complexity describes. This topic will be discussed in more detail in the next section.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2-while-loops","title":"2. \u00a0 While loops","text":"

    Similar to for loops, while loops are another approach for implementing iteration. In a while loop, the program checks a condition at the beginning of each iteration; if the condition is true, the execution continues, otherwise, the loop ends.

    Below we use a while loop to implement the sum \\(1 + 2 + \\dots + n\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop(n: int) -> int:\n    \"\"\"while \u5faa\u73af\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n:\n        res += i\n        i += 1  # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af */\nint WhileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af */\nfunc whileLoop(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af */\nfunc whileLoop(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i\n        i += 1 // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af */\nfunction whileLoop(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af */\nfunction whileLoop(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while (i <= n) {\n    res += i;\n    i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af */\nfn while_loop(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af */\nfun whileLoop(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i\n        i++ // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af ###\ndef while_loop(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while i <= n\n    res += i\n    i += 1 # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  end\n\n  res\nend\n
    iteration.zig
    // while \u5faa\u73af\nfn whileLoop(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += @intCast(i);\n        i += 1;\n    }\n    return res;\n}\n
    Code Visualization

    Full Screen >

    While loops provide more flexibility than for loops, especially since they allow for custom initialization and modification of the condition variable at each step.

    For example, in the following code, the condition variable \\(i\\) is updated twice each round, which would be inconvenient to implement with a for loop.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop_ii(n: int) -> int:\n    \"\"\"while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n:\n        res += i\n        # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint WhileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1; \n        i *= 2;\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while (i <= n) {\n    res += i;\n    // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i++;\n    i *= 2;\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfn while_loop_ii(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfun whileLoopII(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09###\ndef while_loop_ii(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while i <= n\n    res += i\n    # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i += 1\n    i *= 2\n  end\n\n  res\nend\n
    iteration.zig
    //  while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\nfn whileLoopII(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += @intCast(i);\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    return res;\n}\n
    Code Visualization

    Full Screen >

    Overall, for loops are more concise, while while loops are more flexible. Both can implement iterative structures. Which one to use should be determined based on the specific requirements of the problem.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3-nested-loops","title":"3. \u00a0 Nested loops","text":"

    We can nest one loop structure within another. Below is an example using for loops:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def nested_for_loop(n: int) -> str:\n    \"\"\"\u53cc\u5c42 for \u5faa\u73af\"\"\"\n    res = \"\"\n    # \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        # \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in range(1, n + 1):\n            res += f\"({i}, {j}), \"\n    return res\n
    iteration.cpp
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring nestedForLoop(int n) {\n    ostringstream res;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; ++j) {\n            res << \"(\" << i << \", \" << j << \"), \";\n        }\n    }\n    return res.str();\n}\n
    iteration.java
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n    StringBuilder res = new StringBuilder();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.append(\"(\" + i + \", \" + j + \"), \");\n        }\n    }\n    return res.toString();\n}\n
    iteration.cs
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring NestedForLoop(int n) {\n    StringBuilder res = new();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.Append($\"({i}, {j}), \");\n        }\n    }\n    return res.ToString();\n}\n
    iteration.go
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n int) string {\n    res := \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= n; j++ {\n            // \u5faa\u73af j = 1, 2, ..., n-1, n\n            res += fmt.Sprintf(\"(%d, %d), \", i, j)\n        }\n    }\n    return res\n}\n
    iteration.swift
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n: Int) -> String {\n    var res = \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1 ... n {\n            res.append(\"(\\(i), \\(j)), \")\n        }\n    }\n    return res\n}\n
    iteration.js
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n) {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.ts
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n: number): string {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.dart
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n  String res = \"\";\n  // \u5faa\u73af i = 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    // \u5faa\u73af j = 1, 2, ..., n-1, n\n    for (int j = 1; j <= n; j++) {\n      res += \"($i, $j), \";\n    }\n  }\n  return res;\n}\n
    iteration.rs
    /* \u53cc\u5c42 for \u5faa\u73af */\nfn nested_for_loop(n: i32) -> String {\n    let mut res = vec![];\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1..=n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1..=n {\n            res.push(format!(\"({}, {}), \", i, j));\n        }\n    }\n    res.join(\"\")\n}\n
    iteration.c
    /* \u53cc\u5c42 for \u5faa\u73af */\nchar *nestedForLoop(int n) {\n    // n * n \u4e3a\u5bf9\u5e94\u70b9\u6570\u91cf\uff0c\"(i, j), \" \u5bf9\u5e94\u5b57\u7b26\u4e32\u957f\u6700\u5927\u4e3a 6+10*2\uff0c\u52a0\u4e0a\u6700\u540e\u4e00\u4e2a\u7a7a\u5b57\u7b26 \\0 \u7684\u989d\u5916\u7a7a\u95f4\n    int size = n * n * 26 + 1;\n    char *res = malloc(size * sizeof(char));\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            char tmp[26];\n            snprintf(tmp, sizeof(tmp), \"(%d, %d), \", i, j);\n            strncat(res, tmp, size - strlen(res) - 1);\n        }\n    }\n    return res;\n}\n
    iteration.kt
    /* \u53cc\u5c42 for \u5faa\u73af */\nfun nestedForLoop(n: Int): String {\n    val res = StringBuilder()\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (j in 1..n) {\n            res.append(\" ($i, $j), \")\n        }\n    }\n    return res.toString()\n}\n
    iteration.rb
    ### \u53cc\u5c42 for \u5faa\u73af ###\ndef nested_for_loop(n)\n  res = \"\"\n\n  # \u5faa\u73af i = 1, 2, ..., n-1, n\n  for i in 1..n\n    # \u5faa\u73af j = 1, 2, ..., n-1, n\n    for j in 1..n\n      res += \"(#{i}, #{j}), \"\n    end\n  end\n\n  res\nend\n
    iteration.zig
    // \u53cc\u5c42 for \u5faa\u73af\nfn nestedForLoop(allocator: Allocator, n: usize) ![]const u8 {\n    var res = std.ArrayList(u8).init(allocator);\n    defer res.deinit();\n    var buffer: [20]u8 = undefined;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (1..n+1) |j| {\n            var _str = try std.fmt.bufPrint(&buffer, \"({d}, {d}), \", .{i, j});\n            try res.appendSlice(_str);\n        }\n    }\n    return res.toOwnedSlice();\n}\n
    Code Visualization

    Full Screen >

    The flowchart below represents this nested loop.

    Figure 2-2 \u00a0 Flowchart of the nested loop

    In such cases, the number of operations of the function is proportional to \\(n^2\\), meaning the algorithm's runtime and the size of the input data \\(n\\) has a 'quadratic relationship.'

    We can further increase the complexity by adding more nested loops, each level of nesting effectively \"increasing the dimension,\" which raises the time complexity to \"cubic,\" \"quartic,\" and so on.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#222-recursion","title":"2.2.2 \u00a0 Recursion","text":"

    \"Recursion\" is an algorithmic strategy where a function solves a problem by calling itself. It primarily involves two phases:

    1. Calling: This is where the program repeatedly calls itself, often with progressively smaller or simpler arguments, moving towards the \"termination condition.\"
    2. Returning: Upon triggering the \"termination condition,\" the program begins to return from the deepest recursive function, aggregating the results of each layer.

    From an implementation perspective, recursive code mainly includes three elements.

    1. Termination Condition: Determines when to switch from \"calling\" to \"returning.\"
    2. Recursive Call: Corresponds to \"calling,\" where the function calls itself, usually with smaller or more simplified parameters.
    3. Return Result: Corresponds to \"returning,\" where the result of the current recursion level is returned to the previous layer.

    Observe the following code, where simply calling the function recur(n) can compute the sum of \\(1 + 2 + \\dots + n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def recur(n: int) -> int:\n    \"\"\"\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 1:\n        return 1\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res = recur(n - 1)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n
    recursion.cpp
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.java
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.cs
    /* \u9012\u5f52 */\nint Recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = Recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.go
    /* \u9012\u5f52 */\nfunc recur(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res := recur(n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.swift
    /* \u9012\u5f52 */\nfunc recur(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n: n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.js
    /* \u9012\u5f52 */\nfunction recur(n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.ts
    /* \u9012\u5f52 */\nfunction recur(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.dart
    /* \u9012\u5f52 */\nint recur(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 1) return 1;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  int res = recur(n - 1);\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  return n + res;\n}\n
    recursion.rs
    /* \u9012\u5f52 */\nfn recur(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    n + res\n}\n
    recursion.c
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.kt
    /* \u9012\u5f52 */\nfun recur(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    val res = recur(n - 1)\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.rb
    ### \u9012\u5f52 ###\ndef recur(n)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return 1 if n == 1\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  res = recur(n - 1)\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  n + res\nend\n
    recursion.zig
    // \u9012\u5f52\u51fd\u6570\nfn recur(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1) {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var res: i32 = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    Code Visualization

    Full Screen >

    The Figure 2-3 shows the recursive process of this function.

    Figure 2-3 \u00a0 Recursive process of the sum function

    Although iteration and recursion can achieve the same results from a computational standpoint, they represent two entirely different paradigms of thinking and problem-solving.

    • Iteration: Solves problems \"from the bottom up.\" It starts with the most basic steps, and then repeatedly adds or accumulates these steps until the task is complete.
    • Recursion: Solves problems \"from the top down.\" It breaks down the original problem into smaller sub-problems, each of which has the same form as the original problem. These sub-problems are then further decomposed into even smaller sub-problems, stopping at the base case whose solution is known.

    Let's take the earlier example of the summation function, defined as \\(f(n) = 1 + 2 + \\dots + n\\).

    • Iteration: In this approach, we simulate the summation process within a loop. Starting from \\(1\\) and traversing to \\(n\\), we perform the summation operation in each iteration to eventually compute \\(f(n)\\).
    • Recursion: Here, the problem is broken down into a sub-problem: \\(f(n) = n + f(n-1)\\). This decomposition continues recursively until reaching the base case, \\(f(1) = 1\\), at which point the recursion terminates.
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1-call-stack","title":"1. \u00a0 Call stack","text":"

    Every time a recursive function calls itself, the system allocates memory for the newly initiated function to store local variables, the return address, and other relevant information. This leads to two primary outcomes.

    • The function's context data is stored in a memory area called \"stack frame space\" and is only released after the function returns. Therefore, recursion generally consumes more memory space than iteration.
    • Recursive calls introduce additional overhead. Hence, recursion is usually less time-efficient than loops.

    As shown in the Figure 2-4 , there are \\(n\\) unreturned recursive functions before triggering the termination condition, indicating a recursion depth of \\(n\\).

    Figure 2-4 \u00a0 Recursion call depth

    In practice, the depth of recursion allowed by programming languages is usually limited, and excessively deep recursion can lead to stack overflow errors.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2-tail-recursion","title":"2. \u00a0 Tail recursion","text":"

    Interestingly, if a function performs its recursive call as the very last step before returning, it can be optimized by the compiler or interpreter to be as space-efficient as iteration. This scenario is known as \"tail recursion.\"

    • Regular recursion: In standard recursion, when the function returns to the previous level, it continues to execute more code, requiring the system to save the context of the previous call.
    • Tail recursion: Here, the recursive call is the final operation before the function returns. This means that upon returning to the previous level, no further actions are needed, so the system does not need to save the context of the previous level.

    For example, in calculating \\(1 + 2 + \\dots + n\\), we can make the result variable res a parameter of the function, thereby achieving tail recursion:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def tail_recur(n, res):\n    \"\"\"\u5c3e\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 0:\n        return res\n    # \u5c3e\u9012\u5f52\u8c03\u7528\n    return tail_recur(n - 1, res + n)\n
    recursion.cpp
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.java
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.cs
    /* \u5c3e\u9012\u5f52 */\nint TailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return TailRecur(n - 1, res + n);\n}\n
    recursion.go
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n int, res int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n-1, res+n)\n}\n
    recursion.swift
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n: Int, res: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n: n - 1, res: res + n)\n}\n
    recursion.js
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n, res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.ts
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n: number, res: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.dart
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 0) return res;\n  // \u5c3e\u9012\u5f52\u8c03\u7528\n  return tailRecur(n - 1, res + n);\n}\n
    recursion.rs
    /* \u5c3e\u9012\u5f52 */\nfn tail_recur(n: i32, res: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    tail_recur(n - 1, res + n)\n}\n
    recursion.c
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.kt
    /* \u5c3e\u9012\u5f52 */\ntailrec fun tailRecur(n: Int, res: Int): Int {\n    // \u6dfb\u52a0 tailrec \u5173\u952e\u8bcd\uff0c\u4ee5\u5f00\u542f\u5c3e\u9012\u5f52\u4f18\u5316\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n)\n}\n
    recursion.rb
    ### \u5c3e\u9012\u5f52 ###\ndef tail_recur(n, res)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return res if n == 0\n  # \u5c3e\u9012\u5f52\u8c03\u7528\n  tail_recur(n - 1, res + n)\nend\n
    recursion.zig
    // \u5c3e\u9012\u5f52\u51fd\u6570\nfn tailRecur(n: i32, res: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0) {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    Code Visualization

    Full Screen >

    The execution process of tail recursion is shown in the following figure. Comparing regular recursion and tail recursion, the point of the summation operation is different.

    • Regular recursion: The summation operation occurs during the \"returning\" phase, requiring another summation after each layer returns.
    • Tail recursion: The summation operation occurs during the \"calling\" phase, and the \"returning\" phase only involves returning through each layer.

    Figure 2-5 \u00a0 Tail recursion process

    Tip

    Note that many compilers or interpreters do not support tail recursion optimization. For example, Python does not support tail recursion optimization by default, so even if the function is in the form of tail recursion, it may still encounter stack overflow issues.

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3-recursion-tree","title":"3. \u00a0 Recursion tree","text":"

    When dealing with algorithms related to \"divide and conquer\", recursion often offers a more intuitive approach and more readable code than iteration. Take the \"Fibonacci sequence\" as an example.

    Question

    Given a Fibonacci sequence \\(0, 1, 1, 2, 3, 5, 8, 13, \\dots\\), find the \\(n\\)th number in the sequence.

    Let the \\(n\\)th number of the Fibonacci sequence be \\(f(n)\\), it's easy to deduce two conclusions:

    • The first two numbers of the sequence are \\(f(1) = 0\\) and \\(f(2) = 1\\).
    • Each number in the sequence is the sum of the two preceding ones, that is, \\(f(n) = f(n - 1) + f(n - 2)\\).

    Using the recursive relation, and considering the first two numbers as termination conditions, we can write the recursive code. Calling fib(n) will yield the \\(n\\)th number of the Fibonacci sequence:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def fib(n: int) -> int:\n    \"\"\"\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 or n == 2:\n        return n - 1\n    # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res = fib(n - 1) + fib(n - 2)\n    # \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n
    recursion.cpp
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.java
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.cs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint Fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = Fib(n - 1) + Fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.go
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res := fib(n-1) + fib(n-2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.swift
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n: n - 1) + fib(n: n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.js
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.ts
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.dart
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  if (n == 1 || n == 2) return n - 1;\n  // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  int res = fib(n - 1) + fib(n - 2);\n  // \u8fd4\u56de\u7ed3\u679c f(n)\n  return res;\n}\n
    recursion.rs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfn fib(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c\n    res\n}\n
    recursion.c
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.kt
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfun fib(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    val res = fib(n - 1) + fib(n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.rb
    ### \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 ###\ndef fib(n)\n  # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  return n - 1 if n == 1 || n == 2\n  # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  res = fib(n - 1) + fib(n - 2)\n  # \u8fd4\u56de\u7ed3\u679c f(n)\n  res\nend\n
    recursion.zig
    // \u6590\u6ce2\u90a3\u5951\u6570\u5217\nfn fib(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 or n == 2) {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    var res: i32 = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    Code Visualization

    Full Screen >

    Observing the above code, we see that it recursively calls two functions within itself, meaning that one call generates two branching calls. As illustrated below, this continuous recursive calling eventually creates a \"recursion tree\" with a depth of \\(n\\).

    Figure 2-6 \u00a0 Fibonacci sequence recursion tree

    Fundamentally, recursion embodies the paradigm of \"breaking down a problem into smaller sub-problems.\" This divide-and-conquer strategy is crucial.

    • From an algorithmic perspective, many important strategies like searching, sorting, backtracking, divide-and-conquer, and dynamic programming directly or indirectly use this way of thinking.
    • From a data structure perspective, recursion is naturally suited for dealing with linked lists, trees, and graphs, as they are well suited for analysis using the divide-and-conquer approach.
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#223-comparison","title":"2.2.3 \u00a0 Comparison","text":"

    Summarizing the above content, the following table shows the differences between iteration and recursion in terms of implementation, performance, and applicability.

    Table: Comparison of iteration and recursion characteristics

    Iteration Recursion Approach Loop structure Function calls itself Time Efficiency Generally higher efficiency, no function call overhead Each function call generates overhead Memory Usage Typically uses a fixed size of memory space Accumulative function calls can use a substantial amount of stack frame space Suitable Problems Suitable for simple loop tasks, intuitive and readable code Suitable for problem decomposition, like trees, graphs, divide-and-conquer, backtracking, etc., concise and clear code structure

    Tip

    If you find the following content difficult to understand, consider revisiting it after reading the \"Stack\" chapter.

    So, what is the intrinsic connection between iteration and recursion? Taking the above recursive function as an example, the summation operation occurs during the recursion's \"return\" phase. This means that the initially called function is the last to complete its summation operation, mirroring the \"last in, first out\" principle of a stack.

    Recursive terms like \"call stack\" and \"stack frame space\" hint at the close relationship between recursion and stacks.

    1. Calling: When a function is called, the system allocates a new stack frame on the \"call stack\" for that function, storing local variables, parameters, return addresses, and other data.
    2. Returning: When a function completes execution and returns, the corresponding stack frame is removed from the \"call stack,\" restoring the execution environment of the previous function.

    Therefore, we can use an explicit stack to simulate the behavior of the call stack, thus transforming recursion into an iterative form:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def for_loop_recur(n: int) -> int:\n    \"\"\"\u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\"\"\"\n    # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack = []\n    res = 0\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in range(n, 0, -1):\n        # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while stack:\n        # \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    # res = 1+2+3+...+n\n    return res\n
    recursion.cpp
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack<int> stack;\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.empty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.top();\n        stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.java
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<Integer> stack = new Stack<>();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.isEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.cs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint ForLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<int> stack = new();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.Push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.Count > 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.go
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n int) int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack := list.New()\n    res := 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i := n; i > 0; i-- {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.PushBack(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    for stack.Len() != 0 {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Back().Value.(int)\n        stack.Remove(stack.Back())\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.swift
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n: Int) -> Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [Int] = []\n    var res = 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1 ... n).reversed() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.isEmpty {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.removeLast()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.js
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    const stack = [];\n    let res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.ts
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n: number): number {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808 \n    const stack: number[] = [];\n    let res: number = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.dart
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n  // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  List<int> stack = [];\n  int res = 0;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for (int i = n; i > 0; i--) {\n    // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack.add(i);\n  }\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while (!stack.isEmpty) {\n    // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n    res += stack.removeLast();\n  }\n  // res = 1+2+3+...+n\n  return res;\n}\n
    recursion.rs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfn for_loop_recur(n: i32) -> i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    let mut stack = Vec::new();\n    let mut res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1..=n).rev() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.is_empty() {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop().unwrap();\n    }\n    // res = 1+2+3+...+n\n    res\n}\n
    recursion.c
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    int stack[1000]; // \u501f\u52a9\u4e00\u4e2a\u5927\u6570\u7ec4\u6765\u6a21\u62df\u6808\n    int top = -1;    // \u6808\u9876\u7d22\u5f15\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack[1 + top++] = i;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (top >= 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack[top--];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.kt
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfun forLoopRecur(n: Int): Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    val stack = Stack<Int>()\n    var res = 0\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    for (i in n downTo 0) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i)\n    }\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    while (stack.isNotEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.rb
    ### \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 ###\ndef for_loop_recur(n)\n  # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  stack = []\n  res = 0\n\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for i in n.downto(0)\n    # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack << i\n  end\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while !stack.empty?\n    res += stack.pop\n  end\n\n  # res = 1+2+3+...+n\n  res\nend\n
    recursion.zig
    // \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\nfn forLoopRecur(comptime n: i32) i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [n]i32 = undefined;\n    var res: i32 = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var i: usize = n;\n    while (i > 0) {\n        stack[i - 1] = @intCast(i);\n        i -= 1;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    var index: usize = n;\n    while (index > 0) {\n        index -= 1;\n        res += stack[index];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    Code Visualization

    Full Screen >

    Observing the above code, when recursion is transformed into iteration, the code becomes more complex. Although iteration and recursion can often be transformed into each other, it's not always advisable to do so for two reasons:

    • The transformed code may become more challenging to understand and less readable.
    • For some complex problems, simulating the behavior of the system's call stack can be quite challenging.

    In conclusion, whether to choose iteration or recursion depends on the specific nature of the problem. In programming practice, it's crucial to weigh the pros and cons of both and choose the most suitable approach for the situation at hand.

    "},{"location":"chapter_computational_complexity/performance_evaluation/","title":"2.1 \u00a0 Algorithm efficiency assessment","text":"

    In algorithm design, we pursue the following two objectives in sequence.

    1. Finding a Solution to the Problem: The algorithm should reliably find the correct solution within the stipulated range of inputs.
    2. Seeking the Optimal Solution: For the same problem, multiple solutions might exist, and we aim to find the most efficient algorithm possible.

    In other words, under the premise of being able to solve the problem, algorithm efficiency has become the main criterion for evaluating the merits of an algorithm, which includes the following two dimensions.

    • Time efficiency: The speed at which an algorithm runs.
    • Space efficiency: The size of the memory space occupied by an algorithm.

    In short, our goal is to design data structures and algorithms that are both fast and memory-efficient. Effectively assessing algorithm efficiency is crucial because only then can we compare various algorithms and guide the process of algorithm design and optimization.

    There are mainly two methods of efficiency assessment: actual testing and theoretical estimation.

    "},{"location":"chapter_computational_complexity/performance_evaluation/#211-actual-testing","title":"2.1.1 \u00a0 Actual testing","text":"

    Suppose we have algorithms A and B, both capable of solving the same problem, and we need to compare their efficiencies. The most direct method is to use a computer to run these two algorithms and monitor and record their runtime and memory usage. This assessment method reflects the actual situation but has significant limitations.

    On one hand, it's difficult to eliminate interference from the testing environment. Hardware configurations can affect algorithm performance. For example, algorithm A might run faster than B on one computer, but the opposite result may occur on another computer with different configurations. This means we would need to test on a variety of machines to calculate average efficiency, which is impractical.

    On the other hand, conducting a full test is very resource-intensive. As the volume of input data changes, the efficiency of the algorithms may vary. For example, with smaller data volumes, algorithm A might run faster than B, but the opposite might be true with larger data volumes. Therefore, to draw convincing conclusions, we need to test a wide range of input data sizes, which requires significant computational resources.

    "},{"location":"chapter_computational_complexity/performance_evaluation/#212-theoretical-estimation","title":"2.1.2 \u00a0 Theoretical estimation","text":"

    Due to the significant limitations of actual testing, we can consider evaluating algorithm efficiency solely through calculations. This estimation method is known as \"asymptotic complexity analysis,\" or simply \"complexity analysis.\"

    Complexity analysis reflects the relationship between the time and space resources required for algorithm execution and the size of the input data. It describes the trend of growth in the time and space required by the algorithm as the size of the input data increases. This definition might sound complex, but we can break it down into three key points to understand it better.

    • \"Time and space resources\" correspond to \"time complexity\" and \"space complexity,\" respectively.
    • \"As the size of input data increases\" means that complexity reflects the relationship between algorithm efficiency and the volume of input data.
    • \"The trend of growth in time and space\" indicates that complexity analysis focuses not on the specific values of runtime or space occupied but on the \"rate\" at which time or space grows.

    Complexity analysis overcomes the disadvantages of actual testing methods, reflected in the following aspects:

    • It is independent of the testing environment and applicable to all operating platforms.
    • It can reflect algorithm efficiency under different data volumes, especially in the performance of algorithms with large data volumes.

    Tip

    If you're still confused about the concept of complexity, don't worry. We will introduce it in detail in subsequent chapters.

    Complexity analysis provides us with a \"ruler\" to measure the time and space resources needed to execute an algorithm and compare the efficiency between different algorithms.

    Complexity is a mathematical concept and may be abstract and challenging for beginners. From this perspective, complexity analysis might not be the best content to introduce first. However, when discussing the characteristics of a particular data structure or algorithm, it's hard to avoid analyzing its speed and space usage.

    In summary, it's recommended that you establish a preliminary understanding of complexity analysis before diving deep into data structures and algorithms, so that you can carry out simple complexity analyses of algorithms.

    "},{"location":"chapter_computational_complexity/space_complexity/","title":"2.4 \u00a0 Space complexity","text":"

    \"Space complexity\" is used to measure the growth trend of the memory space occupied by an algorithm as the amount of data increases. This concept is very similar to time complexity, except that \"running time\" is replaced with \"occupied memory space\".

    "},{"location":"chapter_computational_complexity/space_complexity/#241-space-related-to-algorithms","title":"2.4.1 \u00a0 Space related to algorithms","text":"

    The memory space used by an algorithm during its execution mainly includes the following types.

    • Input space: Used to store the input data of the algorithm.
    • Temporary space: Used to store variables, objects, function contexts, and other data during the algorithm's execution.
    • Output space: Used to store the output data of the algorithm.

    Generally, the scope of space complexity statistics includes both \"Temporary Space\" and \"Output Space\".

    Temporary space can be further divided into three parts.

    • Temporary data: Used to save various constants, variables, objects, etc., during the algorithm's execution.
    • Stack frame space: Used to save the context data of the called function. The system creates a stack frame at the top of the stack each time a function is called, and the stack frame space is released after the function returns.
    • Instruction space: Used to store compiled program instructions, which are usually negligible in actual statistics.

    When analyzing the space complexity of a program, we typically count the Temporary Data, Stack Frame Space, and Output Data, as shown in the Figure 2-15 .

    Figure 2-15 \u00a0 Space types used in algorithms

    The relevant code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    class Node:\n    \"\"\"Classes\"\"\"\n    def __init__(self, x: int):\n        self.val: int = x               # node value\n        self.next: Node | None = None   # reference to the next node\n\ndef function() -> int:\n    \"\"\"Functions\"\"\"\n    # Perform certain operations...\n    return 0\n\ndef algorithm(n) -> int:    # input data\n    A = 0                   # temporary data (constant, usually in uppercase)\n    b = 0                   # temporary data (variable)\n    node = Node(0)          # temporary data (object)\n    c = function()          # Stack frame space (call function)\n    return A + b + c        # output data\n
    /* Structures */\nstruct Node {\n    int val;\n    Node *next;\n    Node(int x) : val(x), next(nullptr) {}\n};\n\n/* Functions */\nint func() {\n    // Perform certain operations...\n    return 0;\n}\n\nint algorithm(int n) {          // input data\n    const int a = 0;            // temporary data (constant)\n    int b = 0;                  // temporary data (variable)\n    Node* node = new Node(0);   // temporary data (object)\n    int c = func();             // stack frame space (call function)\n    return a + b + c;           // output data\n}\n
    /* Classes */\nclass Node {\n    int val;\n    Node next;\n    Node(int x) { val = x; }\n}\n\n/* Functions */\nint function() {\n    // Perform certain operations...\n    return 0;\n}\n\nint algorithm(int n) {          // input data\n    final int a = 0;            // temporary data (constant)\n    int b = 0;                  // temporary data (variable)\n    Node node = new Node(0);    // temporary data (object)\n    int c = function();         // stack frame space (call function)\n    return a + b + c;           // output data\n}\n
    /* Classes */\nclass Node {\n    int val;\n    Node next;\n    Node(int x) { val = x; }\n}\n\n/* Functions */\nint Function() {\n    // Perform certain operations...\n    return 0;\n}\n\nint Algorithm(int n) {  // input data\n    const int a = 0;    // temporary data (constant)\n    int b = 0;          // temporary data (variable)\n    Node node = new(0); // temporary data (object)\n    int c = Function(); // stack frame space (call function)\n    return a + b + c;   // output data\n}\n
    /* Structures */\ntype node struct {\n    val  int\n    next *node\n}\n\n/* Create node structure */\nfunc newNode(val int) *node {\n    return &node{val: val}\n}\n\n/* Functions */\nfunc function() int {\n    // Perform certain operations...\n    return 0\n}\n\nfunc algorithm(n int) int { // input data\n    const a = 0             // temporary data (constant)\n    b := 0                  // temporary storage of data (variable)\n    newNode(0)              // temporary data (object)\n    c := function()         // stack frame space (call function)\n    return a + b + c        // output data\n}\n
    /* Classes */\nclass Node {\n    var val: Int\n    var next: Node?\n\n    init(x: Int) {\n        val = x\n    }\n}\n\n/* Functions */\nfunc function() -> Int {\n    // Perform certain operations...\n    return 0\n}\n\nfunc algorithm(n: Int) -> Int { // input data\n    let a = 0                   // temporary data (constant)\n    var b = 0                   // temporary data (variable)\n    let node = Node(x: 0)       // temporary data (object)\n    let c = function()          // stack frame space (call function)\n    return a + b + c            // output data\n}\n
    /* Classes */\nclass Node {\n    val;\n    next;\n    constructor(val) {\n        this.val = val === undefined ? 0 : val; // node value\n        this.next = null;                       // reference to the next node\n    }\n}\n\n/* Functions */\nfunction constFunc() {\n    // Perform certain operations\n    return 0;\n}\n\nfunction algorithm(n) {         // input data\n    const a = 0;                // temporary data (constant)\n    let b = 0;                  // temporary data (variable)\n    const node = new Node(0);   // temporary data (object)\n    const c = constFunc();      // Stack frame space (calling function)\n    return a + b + c;           // output data\n}\n
    /* Classes */\nclass Node {\n    val: number;\n    next: Node | null;\n    constructor(val?: number) {\n        this.val = val === undefined ? 0 : val; // node value\n        this.next = null;                       // reference to the next node\n    }\n}\n\n/* Functions */\nfunction constFunc(): number {\n    // Perform certain operations\n    return 0;\n}\n\nfunction algorithm(n: number): number { // input data\n    const a = 0;                        // temporary data (constant)\n    let b = 0;                          // temporary data (variable)\n    const node = new Node(0);           // temporary data (object)\n    const c = constFunc();              // Stack frame space (calling function)\n    return a + b + c;                   // output data\n}\n
    /* Classes */\nclass Node {\n  int val;\n  Node next;\n  Node(this.val, [this.next]);\n}\n\n/* Functions */\nint function() {\n  // Perform certain operations...\n  return 0;\n}\n\nint algorithm(int n) {  // input data\n  const int a = 0;      // temporary data (constant)\n  int b = 0;            // temporary data (variable)\n  Node node = Node(0);  // temporary data (object)\n  int c = function();   // stack frame space (call function)\n  return a + b + c;     // output data\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* Structures */\nstruct Node {\n    val: i32,\n    next: Option<Rc<RefCell<Node>>>,\n}\n\n/* Constructor */\nimpl Node {\n    fn new(val: i32) -> Self {\n        Self { val: val, next: None }\n    }\n}\n\n/* Functions */\nfn function() -> i32 {     \n    // Perform certain operations...\n    return 0;\n}\n\nfn algorithm(n: i32) -> i32 {   // input data\n    const a: i32 = 0;           // temporary data (constant)\n    let mut b = 0;              // temporary data (variable)\n    let node = Node::new(0);    // temporary data (object)\n    let c = function();         // stack frame space (call function)\n    return a + b + c;           // output data\n}\n
    /* Functions */\nint func() {\n    // Perform certain operations...\n    return 0;\n}\n\nint algorithm(int n) {  // input data\n    const int a = 0;    // temporary data (constant)\n    int b = 0;          // temporary data (variable)\n    int c = func();     // stack frame space (call function)\n    return a + b + c;   // output data\n}\n
    \n
    \n
    "},{"location":"chapter_computational_complexity/space_complexity/#242-calculation-method","title":"2.4.2 \u00a0 Calculation method","text":"

    The method for calculating space complexity is roughly similar to that of time complexity, with the only change being the shift of the statistical object from \"number of operations\" to \"size of used space\".

    However, unlike time complexity, we usually only focus on the worst-case space complexity. This is because memory space is a hard requirement, and we must ensure that there is enough memory space reserved under all input data.

    Consider the following code, the term \"worst-case\" in worst-case space complexity has two meanings.

    1. Based on the worst input data: When \\(n < 10\\), the space complexity is \\(O(1)\\); but when \\(n > 10\\), the initialized array nums occupies \\(O(n)\\) space, thus the worst-case space complexity is \\(O(n)\\).
    2. Based on the peak memory used during the algorithm's execution: For example, before executing the last line, the program occupies \\(O(1)\\) space; when initializing the array nums, the program occupies \\(O(n)\\) space, hence the worst-case space complexity is \\(O(n)\\).
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def algorithm(n: int):\n    a = 0               # O(1)\n    b = [0] * 10000     # O(1)\n    if n > 10:\n        nums = [0] * n  # O(n)\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    vector<int> b(10000);    // O(1)\n    if (n > 10)\n        vector<int> nums(n); // O(n)\n}\n
    void algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10)\n        int[] nums = new int[n]; // O(n)\n}\n
    void Algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10) {\n        int[] nums = new int[n]; // O(n)\n    }\n}\n
    func algorithm(n int) {\n    a := 0                      // O(1)\n    b := make([]int, 10000)     // O(1)\n    var nums []int\n    if n > 10 {\n        nums := make([]int, n)  // O(n)\n    }\n    fmt.Println(a, b, nums)\n}\n
    func algorithm(n: Int) {\n    let a = 0 // O(1)\n    let b = Array(repeating: 0, count: 10000) // O(1)\n    if n > 10 {\n        let nums = Array(repeating: 0, count: n) // O(n)\n    }\n}\n
    function algorithm(n) {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    function algorithm(n: number): void {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    void algorithm(int n) {\n  int a = 0;                            // O(1)\n  List<int> b = List.filled(10000, 0);  // O(1)\n  if (n > 10) {\n    List<int> nums = List.filled(n, 0); // O(n)\n  }\n}\n
    fn algorithm(n: i32) {\n    let a = 0;                           // O(1)\n    let b = [0; 10000];                  // O(1)\n    if n > 10 {\n        let nums = vec![0; n as usize];  // O(n)\n    }\n}\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    int b[10000];            // O(1)\n    if (n > 10)\n        int nums[n] = {0};   // O(n)\n}\n
    \n
    \n

    In recursive functions, stack frame space must be taken into count. Consider the following code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def function() -> int:\n    # Perform certain operations\n    return 0\n\ndef loop(n: int):\n    \"\"\"Loop O(1)\"\"\"\n    for _ in range(n):\n        function()\n\ndef recur(n: int):\n    \"\"\"Recursion O(n)\"\"\"\n    if n == 1:\n        return\n    return recur(n - 1)\n
    int func() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int Function() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid Loop(int n) {\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n/* Recursion O(n) */\nint Recur(int n) {\n    if (n == 1) return 1;\n    return Recur(n - 1);\n}\n
    func function() int {\n    // Perform certain operations\n    return 0\n}\n\n/* Cycle O(1) */\nfunc loop(n int) {\n    for i := 0; i < n; i++ {\n        function()\n    }\n}\n\n/* Recursion O(n) */\nfunc recur(n int) {\n    if n == 1 {\n        return\n    }\n    recur(n - 1)\n}\n
    @discardableResult\nfunc function() -> Int {\n    // Perform certain operations\n    return 0\n}\n\n/* Cycle O(1) */\nfunc loop(n: Int) {\n    for _ in 0 ..< n {\n        function()\n    }\n}\n\n/* Recursion O(n) */\nfunc recur(n: Int) {\n    if n == 1 {\n        return\n    }\n    recur(n: n - 1)\n}\n
    function constFunc() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nfunction loop(n) {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* Recursion O(n) */\nfunction recur(n) {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    function constFunc(): number {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nfunction loop(n: number): void {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* Recursion O(n) */\nfunction recur(n: number): void {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n  // Perform certain operations\n  return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n  for (int i = 0; i < n; i++) {\n    function();\n  }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n  if (n == 1) return;\n  return recur(n - 1);\n}\n
    fn function() -> i32 {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nfn loop(n: i32) {\n    for i in 0..n {\n        function();\n    }\n}\n/* Recursion O(n) */\nvoid recur(n: i32) {\n    if n == 1 {\n        return;\n    }\n    recur(n - 1);\n}\n
    int func() {\n    // Perform certain operations\n    return 0;\n}\n/* Cycle O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* Recursion O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    \n
    \n

    The time complexity of both loop() and recur() functions is \\(O(n)\\), but their space complexities differ.

    • The loop() function calls function() \\(n\\) times in a loop, where each iteration's function() returns and releases its stack frame space, so the space complexity remains \\(O(1)\\).
    • The recursive function recur() will have \\(n\\) instances of unreturned recur() existing simultaneously during its execution, thus occupying \\(O(n)\\) stack frame space.
    "},{"location":"chapter_computational_complexity/space_complexity/#243-common-types","title":"2.4.3 \u00a0 Common types","text":"

    Let the size of the input data be \\(n\\), the following chart displays common types of space complexities (arranged from low to high).

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n^2) < O(2^n) \\newline \\text{Constant Order} < \\text{Logarithmic Order} < \\text{Linear Order} < \\text{Quadratic Order} < \\text{Exponential Order} \\end{aligned} \\]

    Figure 2-16 \u00a0 Common types of space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#1-constant-order-o1","title":"1. \u00a0 Constant order \\(O(1)\\)","text":"

    Constant order is common in constants, variables, objects that are independent of the size of input data \\(n\\).

    Note that memory occupied by initializing variables or calling functions in a loop, which is released upon entering the next cycle, does not accumulate over space, thus the space complexity remains \\(O(1)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def function() -> int:\n    \"\"\"\u51fd\u6570\"\"\"\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n\ndef constant(n: int):\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    a = 0\n    nums = [0] * 10000\n    node = ListNode(0)\n    # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        c = 0\n    # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        function()\n
    space_complexity.cpp
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    vector<int> nums(10000);\n    ListNode node(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.java
    /* \u51fd\u6570 */\nint function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    final int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n
    space_complexity.cs
    /* \u51fd\u6570 */\nint Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid Constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n
    space_complexity.go
    /* \u51fd\u6570 */\nfunc function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc spaceConstant(n int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0\n    b := 0\n    nums := make([]int, 10000)\n    node := newNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    var c int\n    for i := 0; i < n; i++ {\n        c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i := 0; i < n; i++ {\n        function()\n    }\n    b += 0\n    c += 0\n    nums[0] = 0\n    node.val = 0\n}\n
    space_complexity.swift
    /* \u51fd\u6570 */\n@discardableResult\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    let a = 0\n    var b = 0\n    let nums = Array(repeating: 0, count: 10000)\n    let node = ListNode(x: 0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        let c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        function()\n    }\n}\n
    space_complexity.js
    /* \u51fd\u6570 */\nfunction constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.ts
    /* \u51fd\u6570 */\nfunction constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n: number): void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.dart
    /* \u51fd\u6570 */\nint function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n  // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  final int a = 0;\n  int b = 0;\n  List<int> nums = List.filled(10000, 0);\n  ListNode node = ListNode(0);\n  // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    int c = 0;\n  }\n  // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    function();\n  }\n}\n
    space_complexity.rs
    /* \u51fd\u6570 */\nfn function() -> i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\n#[allow(unused)]\nfn constant(n: i32) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const A: i32 = 0;\n    let b = 0;\n    let nums = vec![0; 10000];\n    let node = ListNode::new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        let c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        function();\n    }\n}\n
    space_complexity.c
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    int nums[1000];\n    ListNode *node = newListNode(0);\n    free(node);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.kt
    /* \u51fd\u6570 */\nfun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfun constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    val a = 0\n    var b = 0\n    val nums = Array(10000) { 0 }\n    val node = ListNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        val c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        function()\n    }\n}\n
    space_complexity.rb
    ### \u51fd\u6570 ###\ndef function\n  # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  0\nend\n\n### \u5e38\u6570\u9636 ###\ndef constant(n)\n  # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  a = 0\n  nums = [0] * 10000\n  node = ListNode.new\n\n  # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { c = 0 }\n  # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { function }\nend\n
    space_complexity.zig
    // \u51fd\u6570\nfn function() i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n// \u5e38\u6570\u9636\nfn constant(n: i32) void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a: i32 = 0;\n    var b: i32 = 0;\n    var nums = [_]i32{0}**10000;\n    var node = inc.ListNode(i32){.val = 0};\n    var i: i32 = 0;\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    while (i < n) : (i += 1) {\n        var c: i32 = 0;\n        _ = c;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    i = 0;\n    while (i < n) : (i += 1) {\n        _ = function();\n    }\n    _ = a;\n    _ = b;\n    _ = nums;\n    _ = node;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_computational_complexity/space_complexity/#2-linear-order-on","title":"2. \u00a0 Linear order \\(O(n)\\)","text":"

    Linear order is common in arrays, linked lists, stacks, queues, etc., where the number of elements is proportional to \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear(n: int):\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    nums = [0] * n\n    # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    hmap = dict[int, str]()\n    for i in range(n):\n        hmap[i] = str(i)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<int> nums(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<ListNode> nodes;\n    for (int i = 0; i < n; i++) {\n        nodes.push_back(ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    unordered_map<int, string> map;\n    for (int i = 0; i < n; i++) {\n        map[i] = to_string(i);\n    }\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        nodes.add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Map<Integer, String> map = new HashMap<>();\n    for (int i = 0; i < n; i++) {\n        map.put(i, String.valueOf(i));\n    }\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636 */\nvoid Linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = [];\n    for (int i = 0; i < n; i++) {\n        nodes.Add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Dictionary<int, string> map = [];\n    for (int i = 0; i < n; i++) {\n        map.Add(i, i.ToString());\n    }\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc spaceLinear(n int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    _ = make([]int, n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes []*node\n    for i := 0; i < n; i++ {\n        nodes = append(nodes, newNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    m := make(map[int]string, n)\n    for i := 0; i < n; i++ {\n        m[i] = strconv.Itoa(i)\n    }\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let nums = Array(repeating: 0, count: n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let nodes = (0 ..< n).map { ListNode(x: $0) }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let map = Dictionary(uniqueKeysWithValues: (0 ..< n).map { ($0, \"\\($0)\") })\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes: ListNode[] = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n  // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n  List<int> nums = List.filled(n, 0);\n  // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  List<ListNode> nodes = [];\n  for (var i = 0; i < n; i++) {\n    nodes.add(ListNode(i));\n  }\n  // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  Map<int, String> map = HashMap();\n  for (var i = 0; i < n; i++) {\n    map.putIfAbsent(i, () => i.toString());\n  }\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636 */\n#[allow(unused)]\nfn linear(n: i32) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nums = vec![0; n as usize];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nodes = Vec::new();\n    for i in 0..n {\n        nodes.push(ListNode::new(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut map = HashMap::new();\n    for i in 0..n {\n        map.insert(i, i.to_string());\n    }\n}\n
    space_complexity.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int *nums = malloc(sizeof(int) * n);\n    free(nums);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    ListNode **nodes = malloc(sizeof(ListNode *) * n);\n    for (int i = 0; i < n; i++) {\n        nodes[i] = newListNode(i);\n    }\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(nodes[i]);\n    }\n    free(nodes);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    HashTable *h = NULL;\n    for (int i = 0; i < n; i++) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = i;\n        tmp->val = i;\n        HASH_ADD_INT(h, key, tmp);\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    HashTable *curr, *tmp;\n    HASH_ITER(hh, h, curr, tmp) {\n        HASH_DEL(h, curr);\n        free(curr);\n    }\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    val nums = Array(n) { 0 }\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val nodes = mutableListOf<ListNode>()\n    for (i in 0..<n) {\n        nodes.add(ListNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val map = mutableMapOf<Int, String>()\n    for (i in 0..<n) {\n        map[i] = i.toString()\n    }\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  nums = Array.new(n, 0)\n\n  # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  hmap = {}\n  for i in 0...n\n    hmap[i] = i.to_s\n  end\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(comptime n: i32) !void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    var nums = [_]i32{0}**n;\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        try nodes.append(i);\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var map = std.AutoArrayHashMap(i32, []const u8).init(std.heap.page_allocator);\n    defer map.deinit();\n    var j: i32 = 0;\n    while (j < n) : (j += 1) {\n        const string = try std.fmt.allocPrint(std.heap.page_allocator, \"{d}\", .{j});\n        defer std.heap.page_allocator.free(string);\n        try map.put(i, string);\n    }\n    _ = nums;\n}\n
    Code Visualization

    Full Screen >

    As shown below, this function's recursive depth is \\(n\\), meaning there are \\(n\\) instances of unreturned linear_recur() function, using \\(O(n)\\) size of stack frame space:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear_recur(n: int):\n    \"\"\"\u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    print(\"\u9012\u5f52 n =\", n)\n    if n == 1:\n        return\n    linear_recur(n - 1)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    cout << \"\u9012\u5f52 n = \" << n << endl;\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    System.out.println(\"\u9012\u5f52 n = \" + n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid LinearRecur(int n) {\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n);\n    if (n == 1) return;\n    LinearRecur(n - 1);\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceLinearRecur(n int) {\n    fmt.Println(\"\u9012\u5f52 n =\", n)\n    if n == 1 {\n        return\n    }\n    spaceLinearRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc linearRecur(n: Int) {\n    print(\"\u9012\u5f52 n = \\(n)\")\n    if n == 1 {\n        return\n    }\n    linearRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n) {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n: number): void {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n  print('\u9012\u5f52 n = $n');\n  if (n == 1) return;\n  linearRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn linear_recur(n: i32) {\n    println!(\"\u9012\u5f52 n = {}\", n);\n    if n == 1 {\n        return;\n    };\n    linear_recur(n - 1);\n}\n
    space_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    printf(\"\u9012\u5f52 n = %d\\r\\n\", n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun linearRecur(n: Int) {\n    println(\"\u9012\u5f52 n = $n\")\n    if (n == 1)\n        return\n    linearRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef linear_recur(n)\n  puts \"\u9012\u5f52 n = #{n}\"\n  return if n == 1\n  linear_recur(n - 1)\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn linearRecur(comptime n: i32) void {\n    std.debug.print(\"\u9012\u5f52 n = {}\\n\", .{n});\n    if (n == 1) return;\n    linearRecur(n - 1);\n}\n
    Code Visualization

    Full Screen >

    Figure 2-17 \u00a0 Recursive function generating linear order space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#3-quadratic-order-on2","title":"3. \u00a0 Quadratic order \\(O(n^2)\\)","text":"

    Quadratic order is common in matrices and graphs, where the number of elements is quadratic to \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic(n: int):\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    num_matrix = [[0] * n for _ in range(n)]\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    vector<vector<int>> numMatrix;\n    for (int i = 0; i < n; i++) {\n        vector<int> tmp;\n        for (int j = 0; j < n; j++) {\n            tmp.push_back(0);\n        }\n        numMatrix.push_back(tmp);\n    }\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[][] numMatrix = new int[n][n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<Integer>> numList = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<Integer> tmp = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            tmp.add(0);\n        }\n        numList.add(tmp);\n    }\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636 */\nvoid Quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[,] numMatrix = new int[n, n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<int>> numList = [];\n    for (int i = 0; i < n; i++) {\n        List<int> tmp = [];\n        for (int j = 0; j < n; j++) {\n            tmp.Add(0);\n        }\n        numList.Add(tmp);\n    }\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc spaceQuadratic(n int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    numMatrix := make([][]int, n)\n    for i := 0; i < n; i++ {\n        numMatrix[i] = make([]int, n)\n    }\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let numList = Array(repeating: Array(repeating: 0, count: n), count: n)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): void {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n  // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numMatrix = List.generate(n, (_) => List.filled(n, 0));\n  // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numList = [];\n  for (var i = 0; i < n; i++) {\n    List<int> tmp = [];\n    for (int j = 0; j < n; j++) {\n      tmp.add(0);\n    }\n    numList.add(tmp);\n  }\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636 */\n#[allow(unused)]\nfn quadratic(n: i32) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let num_matrix = vec![vec![0; n as usize]; n as usize];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let mut num_list = Vec::new();\n    for i in 0..n {\n        let mut tmp = Vec::new();\n        for j in 0..n {\n            tmp.push(0);\n        }\n        num_list.push(tmp);\n    }\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int **numMatrix = malloc(sizeof(int *) * n);\n    for (int i = 0; i < n; i++) {\n        int *tmp = malloc(sizeof(int) * n);\n        for (int j = 0; j < n; j++) {\n            tmp[j] = 0;\n        }\n        numMatrix[i] = tmp;\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(numMatrix[i]);\n    }\n    free(numMatrix);\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numMatrix = arrayOfNulls<Array<Int>?>(n)\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numList = mutableListOf<MutableList<Int>>()\n    for (i in 0..<n) {\n        val tmp = mutableListOf<Int>()\n        for (j in 0..<n) {\n            tmp.add(0)\n        }\n        numList.add(tmp)\n    }\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  Array.new(n) { Array.new(n, 0) }\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) !void {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    var nodes = std.ArrayList(std.ArrayList(i32)).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        var tmp = std.ArrayList(i32).init(std.heap.page_allocator);\n        defer tmp.deinit();\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            try tmp.append(0);\n        }\n        try nodes.append(tmp);\n    }\n}\n
    Code Visualization

    Full Screen >

    As shown below, the recursive depth of this function is \\(n\\), and in each recursive call, an array is initialized with lengths \\(n\\), \\(n-1\\), \\(\\dots\\), \\(2\\), \\(1\\), averaging \\(n/2\\), thus overall occupying \\(O(n^2)\\) space:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic_recur(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 0:\n        return 0\n    # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    nums = [0] * n\n    return quadratic_recur(n - 1)\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    vector<int> nums(n);\n    cout << \"\u9012\u5f52 n = \" << n << \" \u4e2d\u7684 nums \u957f\u5ea6 = \" << nums.size() << endl;\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    int[] nums = new int[n];\n    System.out.println(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.length);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint QuadraticRecur(int n) {\n    if (n <= 0) return 0;\n    int[] nums = new int[n];\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.Length);\n    return QuadraticRecur(n - 1);\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceQuadraticRecur(n int) int {\n    if n <= 0 {\n        return 0\n    }\n    nums := make([]int, n)\n    fmt.Printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d \\n\", n, len(nums))\n    return spaceQuadraticRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\n@discardableResult\nfunc quadraticRecur(n: Int) -> Int {\n    if n <= 0 {\n        return 0\n    }\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = Array(repeating: 0, count: n)\n    print(\"\u9012\u5f52 n = \\(n) \u4e2d\u7684 nums \u957f\u5ea6 = \\(nums.count)\")\n    return quadraticRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n) {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n: number): number {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n  if (n <= 0) return 0;\n  List<int> nums = List.filled(n, 0);\n  print('\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}');\n  return quadraticRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn quadratic_recur(n: i32) -> i32 {\n    if n <= 0 {\n        return 0;\n    };\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = vec![0; n as usize];\n    println!(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\", n, nums.len());\n    return quadratic_recur(n - 1);\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    int *nums = malloc(sizeof(int) * n);\n    printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d\\r\\n\", n, n);\n    int res = quadraticRecur(n - 1);\n    free(nums);\n    return res;\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\ntailrec fun quadraticRecur(n: Int): Int {\n    if (n <= 0)\n        return 0\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    val nums = Array(n) { 0 }\n    println(\"\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.size}\")\n    return quadraticRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef quadratic_recur(n)\n  return 0 unless n > 0\n\n  # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n  nums = Array.new(n, 0)\n  quadratic_recur(n - 1)\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn quadraticRecur(comptime n: i32) i32 {\n    if (n <= 0) return 0;\n    var nums = [_]i32{0}**n;\n    std.debug.print(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\\n\", .{n, nums.len});\n    return quadraticRecur(n - 1);\n}\n
    Code Visualization

    Full Screen >

    Figure 2-18 \u00a0 Recursive function generating quadratic order space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#4-exponential-order-o2n","title":"4. \u00a0 Exponential order \\(O(2^n)\\)","text":"

    Exponential order is common in binary trees. Observe the below image, a \"full binary tree\" with \\(n\\) levels has \\(2^n - 1\\) nodes, occupying \\(O(2^n)\\) space:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def build_tree(n: int) -> TreeNode | None:\n    \"\"\"\u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\"\"\"\n    if n == 0:\n        return None\n    root = TreeNode(0)\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n    return root\n
    space_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return nullptr;\n    TreeNode *root = new TreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.java
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode buildTree(int n) {\n    if (n == 0)\n        return null;\n    TreeNode root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? BuildTree(int n) {\n    if (n == 0) return null;\n    TreeNode root = new(0) {\n        left = BuildTree(n - 1),\n        right = BuildTree(n - 1)\n    };\n    return root;\n}\n
    space_complexity.go
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n int) *TreeNode {\n    if n == 0 {\n        return nil\n    }\n    root := NewTreeNode(0)\n    root.Left = buildTree(n - 1)\n    root.Right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n: Int) -> TreeNode? {\n    if n == 0 {\n        return nil\n    }\n    let root = TreeNode(x: 0)\n    root.left = buildTree(n: n - 1)\n    root.right = buildTree(n: n - 1)\n    return root\n}\n
    space_complexity.js
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n) {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n: number): TreeNode | null {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? buildTree(int n) {\n  if (n == 0) return null;\n  TreeNode root = TreeNode(0);\n  root.left = buildTree(n - 1);\n  root.right = buildTree(n - 1);\n  return root;\n}\n
    space_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfn build_tree(n: i32) -> Option<Rc<RefCell<TreeNode>>> {\n    if n == 0 {\n        return None;\n    };\n    let root = TreeNode::new(0);\n    root.borrow_mut().left = build_tree(n - 1);\n    root.borrow_mut().right = build_tree(n - 1);\n    return Some(root);\n}\n
    space_complexity.c
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return NULL;\n    TreeNode *root = newTreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfun buildTree(n: Int): TreeNode? {\n    if (n == 0)\n        return null\n    val root = TreeNode(0)\n    root.left = buildTree(n - 1)\n    root.right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09###\ndef build_tree(n)\n  return if n == 0\n\n  TreeNode.new.tap do |root|\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n  end\nend\n
    space_complexity.zig
    // \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\nfn buildTree(mem_allocator: std.mem.Allocator, n: i32) !?*inc.TreeNode(i32) {\n    if (n == 0) return null;\n    const root = try mem_allocator.create(inc.TreeNode(i32));\n    root.init(0);\n    root.left = try buildTree(mem_allocator, n - 1);\n    root.right = try buildTree(mem_allocator, n - 1);\n    return root;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-19 \u00a0 Full binary tree generating exponential order space complexity

    "},{"location":"chapter_computational_complexity/space_complexity/#5-logarithmic-order-olog-n","title":"5. \u00a0 Logarithmic order \\(O(\\log n)\\)","text":"

    Logarithmic order is common in divide-and-conquer algorithms. For example, in merge sort, an array of length \\(n\\) is recursively divided in half each round, forming a recursion tree of height \\(\\log n\\), using \\(O(\\log n)\\) stack frame space.

    Another example is converting a number to a string. Given a positive integer \\(n\\), its number of digits is \\(\\log_{10} n + 1\\), corresponding to the length of the string, thus the space complexity is \\(O(\\log_{10} n + 1) = O(\\log n)\\).

    "},{"location":"chapter_computational_complexity/space_complexity/#244-balancing-time-and-space","title":"2.4.4 \u00a0 Balancing time and space","text":"

    Ideally, we aim for both time complexity and space complexity to be optimal. However, in practice, optimizing both simultaneously is often difficult.

    Lowering time complexity usually comes at the cost of increased space complexity, and vice versa. The approach of sacrificing memory space to improve algorithm speed is known as \"space-time tradeoff\"; the reverse is known as \"time-space tradeoff\".

    The choice depends on which aspect we value more. In most cases, time is more precious than space, so \"space-time tradeoff\" is often the more common strategy. Of course, controlling space complexity is also very important when dealing with large volumes of data.

    "},{"location":"chapter_computational_complexity/summary/","title":"2.5 \u00a0 Summary","text":""},{"location":"chapter_computational_complexity/summary/#1-key-review","title":"1. \u00a0 Key review","text":"

    Algorithm Efficiency Assessment

    • Time efficiency and space efficiency are the two main criteria for assessing the merits of an algorithm.
    • We can assess algorithm efficiency through actual testing, but it's challenging to eliminate the influence of the test environment, and it consumes substantial computational resources.
    • Complexity analysis can overcome the disadvantages of actual testing. Its results are applicable across all operating platforms and can reveal the efficiency of algorithms at different data scales.

    Time Complexity

    • Time complexity measures the trend of an algorithm's running time with the increase in data volume, effectively assessing algorithm efficiency. However, it can fail in certain cases, such as with small input data volumes or when time complexities are the same, making it challenging to precisely compare the efficiency of algorithms.
    • Worst-case time complexity is denoted using big O notation, representing the asymptotic upper bound, reflecting the growth level of the number of operations \\(T(n)\\) as \\(n\\) approaches infinity.
    • Calculating time complexity involves two steps: first counting the number of operations, then determining the asymptotic upper bound.
    • Common time complexities, arranged from low to high, include \\(O(1)\\), \\(O(\\log n)\\), \\(O(n)\\), \\(O(n \\log n)\\), \\(O(n^2)\\), \\(O(2^n)\\), and \\(O(n!)\\), among others.
    • The time complexity of some algorithms is not fixed and depends on the distribution of input data. Time complexities are divided into worst, best, and average cases. The best case is rarely used because input data generally needs to meet strict conditions to achieve the best case.
    • Average time complexity reflects the efficiency of an algorithm under random data inputs, closely resembling the algorithm's performance in actual applications. Calculating average time complexity requires accounting for the distribution of input data and the subsequent mathematical expectation.

    Space Complexity

    • Space complexity, similar to time complexity, measures the trend of memory space occupied by an algorithm with the increase in data volume.
    • The relevant memory space used during the algorithm's execution can be divided into input space, temporary space, and output space. Generally, input space is not included in space complexity calculations. Temporary space can be divided into temporary data, stack frame space, and instruction space, where stack frame space usually affects space complexity only in recursive functions.
    • We usually focus only on the worst-case space complexity, which means calculating the space complexity of the algorithm under the worst input data and at the worst moment of operation.
    • Common space complexities, arranged from low to high, include \\(O(1)\\), \\(O(\\log n)\\), \\(O(n)\\), \\(O(n^2)\\), and \\(O(2^n)\\), among others.
    "},{"location":"chapter_computational_complexity/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is the space complexity of tail recursion \\(O(1)\\)?

    Theoretically, the space complexity of a tail-recursive function can be optimized to \\(O(1)\\). However, most programming languages (such as Java, Python, C++, Go, C#) do not support automatic optimization of tail recursion, so it's generally considered to have a space complexity of \\(O(n)\\).

    Q: What is the difference between the terms \"function\" and \"method\"?

    A \"function\" can be executed independently, with all parameters passed explicitly. A \"method\" is associated with an object and is implicitly passed to the object calling it, able to operate on the data contained within an instance of a class.

    Here are some examples from common programming languages:

    • C is a procedural programming language without object-oriented concepts, so it only has functions. However, we can simulate object-oriented programming by creating structures (struct), and functions associated with these structures are equivalent to methods in other programming languages.
    • Java and C# are object-oriented programming languages where code blocks (methods) are typically part of a class. Static methods behave like functions because they are bound to the class and cannot access specific instance variables.
    • C++ and Python support both procedural programming (functions) and object-oriented programming (methods).

    Q: Does the \"Common Types of Space Complexity\" figure reflect the absolute size of occupied space?

    No, the figure shows space complexities, which reflect growth trends, not the absolute size of the occupied space.

    If you take \\(n = 8\\), you might find that the values of each curve don't correspond to their functions. This is because each curve includes a constant term, intended to compress the value range into a visually comfortable range.

    In practice, since we usually don't know the \"constant term\" complexity of each method, it's generally not possible to choose the best solution for \\(n = 8\\) based solely on complexity. However, for \\(n = 8^5\\), it's much easier to choose, as the growth trend becomes dominant.

    "},{"location":"chapter_computational_complexity/time_complexity/","title":"2.3 \u00a0 Time complexity","text":"

    Time complexity is a concept used to measure how the run time of an algorithm increases with the size of the input data. Understanding time complexity is crucial for accurately assessing the efficiency of an algorithm.

    1. Determining the Running Platform: This includes hardware configuration, programming language, system environment, etc., all of which can affect the efficiency of code execution.
    2. Evaluating the Run Time for Various Computational Operations: For instance, an addition operation + might take 1 ns, a multiplication operation * might take 10 ns, a print operation print() might take 5 ns, etc.
    3. Counting All the Computational Operations in the Code: Summing the execution times of all these operations gives the total run time.

    For example, consider the following code with an input size of \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    # Under an operating platform\ndef algorithm(n: int):\n    a = 2      # 1 ns\n    a = a + 1  # 1 ns\n    a = a * 2  # 10 ns\n    # Cycle n times\n    for _ in range(n):  # 1 ns\n        print(0)        # 5 ns\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {  // 1 ns , every round i++ is executed\n        cout << 0 << endl;         // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {  // 1 ns , every round i++ is executed\n        System.out.println(0);     // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid Algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {  // 1 ns , every round i++ is executed\n        Console.WriteLine(0);      // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunc algorithm(n int) {\n    a := 2     // 1 ns\n    a = a + 1  // 1 ns\n    a = a * 2  // 10 ns\n    // Loop n times\n    for i := 0; i < n; i++ {  // 1 ns\n        fmt.Println(a)        // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunc algorithm(n: Int) {\n    var a = 2 // 1 ns\n    a = a + 1 // 1 ns\n    a = a * 2 // 10 ns\n    // Loop n times\n    for _ in 0 ..< n { // 1 ns\n        print(0) // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunction algorithm(n) {\n    var a = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // Loop n times\n    for(let i = 0; i < n; i++) { // 1 ns , every round i++ is executed\n        console.log(0); // 5 ns\n    }\n}\n
    // Under a particular operating platform\nfunction algorithm(n: number): void {\n    var a: number = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // Loop n times\n    for(let i = 0; i < n; i++) { // 1 ns , every round i++ is executed\n        console.log(0); // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n  int a = 2; // 1 ns\n  a = a + 1; // 1 ns\n  a = a * 2; // 10 ns\n  // Loop n times\n  for (int i = 0; i < n; i++) { // 1 ns , every round i++ is executed\n    print(0); // 5 ns\n  }\n}\n
    // Under a particular operating platform\nfn algorithm(n: i32) {\n    let mut a = 2;      // 1 ns\n    a = a + 1;          // 1 ns\n    a = a * 2;          // 10 ns\n    // Loop n times\n    for _ in 0..n {     // 1 ns for each round i++\n        println!(\"{}\", 0);  // 5 ns\n    }\n}\n
    // Under a particular operating platform\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // Loop n times\n    for (int i = 0; i < n; i++) {   // 1 ns , every round i++ is executed\n        printf(\"%d\", 0);            // 5 ns\n    }\n}\n
    \n
    // Under a particular operating platform\nfn algorithm(n: usize) void {\n    var a: i32 = 2; // 1 ns\n    a += 1; // 1 ns\n    a *= 2; // 10 ns\n    // Loop n times\n    for (0..n) |_| { // 1 ns\n        std.debug.print(\"{}\\n\", .{0}); // 5 ns\n    }\n}\n

    Using the above method, the run time of the algorithm can be calculated as \\((6n + 12)\\) ns:

    \\[ 1 + 1 + 10 + (1 + 5) \\times n = 6n + 12 \\]

    However, in practice, counting the run time of an algorithm is neither practical nor reasonable. First, we don't want to tie the estimated time to the running platform, as algorithms need to run on various platforms. Second, it's challenging to know the run time for each type of operation, making the estimation process difficult.

    "},{"location":"chapter_computational_complexity/time_complexity/#231-assessing-time-growth-trend","title":"2.3.1 \u00a0 Assessing time growth trend","text":"

    Time complexity analysis does not count the algorithm's run time, but rather the growth trend of the run time as the data volume increases.

    Let's understand this concept of \"time growth trend\" with an example. Assume the input data size is \\(n\\), and consider three algorithms A, B, and C:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    # Time complexity of algorithm A: constant order\ndef algorithm_A(n: int):\n    print(0)\n# Time complexity of algorithm B: linear order\ndef algorithm_B(n: int):\n    for _ in range(n):\n        print(0)\n# Time complexity of algorithm C: constant order\ndef algorithm_C(n: int):\n    for _ in range(1000000):\n        print(0)\n
    // Time complexity of algorithm A: constant order\nvoid algorithm_A(int n) {\n    cout << 0 << endl;\n}\n// Time complexity of algorithm B: linear order\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        cout << 0 << endl;\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        cout << 0 << endl;\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid algorithm_A(int n) {\n    System.out.println(0);\n}\n// Time complexity of algorithm B: linear order\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        System.out.println(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        System.out.println(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid AlgorithmA(int n) {\n    Console.WriteLine(0);\n}\n// Time complexity of algorithm B: linear order\nvoid AlgorithmB(int n) {\n    for (int i = 0; i < n; i++) {\n        Console.WriteLine(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid AlgorithmC(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        Console.WriteLine(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunc algorithm_A(n int) {\n    fmt.Println(0)\n}\n// Time complexity of algorithm B: linear order\nfunc algorithm_B(n int) {\n    for i := 0; i < n; i++ {\n        fmt.Println(0)\n    }\n}\n// Time complexity of algorithm C: constant order\nfunc algorithm_C(n int) {\n    for i := 0; i < 1000000; i++ {\n        fmt.Println(0)\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunc algorithmA(n: Int) {\n    print(0)\n}\n\n// Time complexity of algorithm B: linear order\nfunc algorithmB(n: Int) {\n    for _ in 0 ..< n {\n        print(0)\n    }\n}\n\n// Time complexity of algorithm C: constant order\nfunc algorithmC(n: Int) {\n    for _ in 0 ..< 1_000_000 {\n        print(0)\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunction algorithm_A(n) {\n    console.log(0);\n}\n// Time complexity of algorithm B: linear order\nfunction algorithm_B(n) {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nfunction algorithm_C(n) {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nfunction algorithm_A(n: number): void {\n    console.log(0);\n}\n// Time complexity of algorithm B: linear order\nfunction algorithm_B(n: number): void {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// Time complexity of algorithm C: constant order\nfunction algorithm_C(n: number): void {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid algorithmA(int n) {\n  print(0);\n}\n// Time complexity of algorithm B: linear order\nvoid algorithmB(int n) {\n  for (int i = 0; i < n; i++) {\n    print(0);\n  }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithmC(int n) {\n  for (int i = 0; i < 1000000; i++) {\n    print(0);\n  }\n}\n
    // Time complexity of algorithm A: constant order\nfn algorithm_A(n: i32) {\n    println!(\"{}\", 0);\n}\n// Time complexity of algorithm B: linear order\nfn algorithm_B(n: i32) {\n    for _ in 0..n {\n        println!(\"{}\", 0);\n    }\n}\n// Time complexity of algorithm C: constant order\nfn algorithm_C(n: i32) {\n    for _ in 0..1000000 {\n        println!(\"{}\", 0);\n    }\n}\n
    // Time complexity of algorithm A: constant order\nvoid algorithm_A(int n) {\n    printf(\"%d\", 0);\n}\n// Time complexity of algorithm B: linear order\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        printf(\"%d\", 0);\n    }\n}\n// Time complexity of algorithm C: constant order\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        printf(\"%d\", 0);\n    }\n}\n
    \n
    // Time complexity of algorithm A: constant order\nfn algorithm_A(n: usize) void {\n    _ = n;\n    std.debug.print(\"{}\\n\", .{0});\n}\n// Time complexity of algorithm B: linear order\nfn algorithm_B(n: i32) void {\n    for (0..n) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n// Time complexity of algorithm C: constant order\nfn algorithm_C(n: i32) void {\n    _ = n;\n    for (0..1000000) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n

    The following figure shows the time complexities of these three algorithms.

    • Algorithm A has just one print operation, and its run time does not grow with \\(n\\). Its time complexity is considered \"constant order.\"
    • Algorithm B involves a print operation looping \\(n\\) times, and its run time grows linearly with \\(n\\). Its time complexity is \"linear order.\"
    • Algorithm C has a print operation looping 1,000,000 times. Although it takes a long time, it is independent of the input data size \\(n\\). Therefore, the time complexity of C is the same as A, which is \"constant order.\"

    Figure 2-7 \u00a0 Time growth trend of algorithms a, b, and c

    Compared to directly counting the run time of an algorithm, what are the characteristics of time complexity analysis?

    • Time complexity effectively assesses algorithm efficiency. For instance, algorithm B has linearly growing run time, which is slower than algorithm A when \\(n > 1\\) and slower than C when \\(n > 1,000,000\\). In fact, as long as the input data size \\(n\\) is sufficiently large, a \"constant order\" complexity algorithm will always be better than a \"linear order\" one, demonstrating the essence of time growth trend.
    • Time complexity analysis is more straightforward. Obviously, the running platform and the types of computational operations are irrelevant to the trend of run time growth. Therefore, in time complexity analysis, we can simply treat the execution time of all computational operations as the same \"unit time,\" simplifying the \"computational operation run time count\" to a \"computational operation count.\" This significantly reduces the complexity of estimation.
    • Time complexity has its limitations. For example, although algorithms A and C have the same time complexity, their actual run times can be quite different. Similarly, even though algorithm B has a higher time complexity than C, it is clearly superior when the input data size \\(n\\) is small. In these cases, it's difficult to judge the efficiency of algorithms based solely on time complexity. Nonetheless, despite these issues, complexity analysis remains the most effective and commonly used method for evaluating algorithm efficiency.
    "},{"location":"chapter_computational_complexity/time_complexity/#232-asymptotic-upper-bound","title":"2.3.2 \u00a0 Asymptotic upper bound","text":"

    Consider a function with an input size of \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def algorithm(n: int):\n    a = 1      # +1\n    a = a + 1  # +1\n    a = a * 2  # +1\n    # Cycle n times\n    for i in range(n):  # +1\n        print(0)        # +1\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) { // +1 (execute i ++ every round)\n        cout << 0 << endl;    // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) { // +1 (execute i ++ every round)\n        System.out.println(0);    // +1\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) {   // +1 (execute i ++ every round)\n        Console.WriteLine(0);   // +1\n    }\n}\n
    func algorithm(n int) {\n    a := 1      // +1\n    a = a + 1   // +1\n    a = a * 2   // +1\n    // Loop n times\n    for i := 0; i < n; i++ {   // +1\n        fmt.Println(a)         // +1\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +1\n    a = a + 1 // +1\n    a = a * 2 // +1\n    // Loop n times\n    for _ in 0 ..< n { // +1\n        print(0) // +1\n    }\n}\n
    function algorithm(n) {\n    var a = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // Loop n times\n    for(let i = 0; i < n; i++){ // +1 (execute i ++ every round)\n        console.log(0); // +1\n    }\n}\n
    function algorithm(n: number): void{\n    var a: number = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // Loop n times\n    for(let i = 0; i < n; i++){ // +1 (execute i ++ every round)\n        console.log(0); // +1\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +1\n  a = a + 1; // +1\n  a = a * 2; // +1\n  // Loop n times\n  for (int i = 0; i < n; i++) { // +1 (execute i ++ every round)\n    print(0); // +1\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;   // +1\n    a = a + 1;      // +1\n    a = a * 2;      // +1\n\n    // Loop n times\n    for _ in 0..n { // +1 (execute i ++ every round)\n        println!(\"{}\", 0); // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // Loop n times\n    for (int i = 0; i < n; i++) {   // +1 (execute i ++ every round)\n        printf(\"%d\", 0);            // +1\n    }\n} \n
    \n
    fn algorithm(n: usize) void {\n    var a: i32 = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // Loop n times\n    for (0..n) |_| { // +1 (execute i ++ every round)\n        std.debug.print(\"{}\\n\", .{0}); // +1\n    }\n}\n

    Given a function that represents the number of operations of an algorithm as a function of the input size \\(n\\), denoted as \\(T(n)\\), consider the following example:

    \\[ T(n) = 3 + 2n \\]

    Since \\(T(n)\\) is a linear function, its growth trend is linear, and therefore, its time complexity is of linear order, denoted as \\(O(n)\\). This mathematical notation, known as \"big-O notation,\" represents the \"asymptotic upper bound\" of the function \\(T(n)\\).

    In essence, time complexity analysis is about finding the asymptotic upper bound of the \"number of operations \\(T(n)\\)\". It has a precise mathematical definition.

    Asymptotic Upper Bound

    If there exist positive real numbers \\(c\\) and \\(n_0\\) such that for all \\(n > n_0\\), \\(T(n) \\leq c \\cdot f(n)\\), then \\(f(n)\\) is considered an asymptotic upper bound of \\(T(n)\\), denoted as \\(T(n) = O(f(n))\\).

    As illustrated below, calculating the asymptotic upper bound involves finding a function \\(f(n)\\) such that, as \\(n\\) approaches infinity, \\(T(n)\\) and \\(f(n)\\) have the same growth order, differing only by a constant factor \\(c\\).

    Figure 2-8 \u00a0 Asymptotic upper bound of a function

    "},{"location":"chapter_computational_complexity/time_complexity/#233-calculation-method","title":"2.3.3 \u00a0 Calculation method","text":"

    While the concept of asymptotic upper bound might seem mathematically dense, you don't need to fully grasp it right away. Let's first understand the method of calculation, which can be practiced and comprehended over time.

    Once \\(f(n)\\) is determined, we obtain the time complexity \\(O(f(n))\\). But how do we determine the asymptotic upper bound \\(f(n)\\)? This process generally involves two steps: counting the number of operations and determining the asymptotic upper bound.

    "},{"location":"chapter_computational_complexity/time_complexity/#1-step-1-counting-the-number-of-operations","title":"1. \u00a0 Step 1: counting the number of operations","text":"

    This step involves going through the code line by line. However, due to the presence of the constant \\(c\\) in \\(c \\cdot f(n)\\), all coefficients and constant terms in \\(T(n)\\) can be ignored. This principle allows for simplification techniques in counting operations.

    1. Ignore constant terms in \\(T(n)\\), as they do not affect the time complexity being independent of \\(n\\).
    2. Omit all coefficients. For example, looping \\(2n\\), \\(5n + 1\\) times, etc., can be simplified to \\(n\\) times since the coefficient before \\(n\\) does not impact the time complexity.
    3. Use multiplication for nested loops. The total number of operations equals the product of the number of operations in each loop, applying the simplification techniques from points 1 and 2 for each loop level.

    Given a function, we can use these techniques to count operations:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    def algorithm(n: int):\n    a = 1      # +0 (trick 1)\n    a = a + n  # +0 (trick 1)\n    # +n (technique 2)\n    for i in range(5 * n + 1):\n        print(0)\n    # +n*n (technique 3)\n    for i in range(2 * n):\n        for j in range(n + 1):\n            print(0)\n
    void algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        cout << 0 << endl;\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            cout << 0 << endl;\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        System.out.println(0);\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            System.out.println(0);\n        }\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        Console.WriteLine(0);\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            Console.WriteLine(0);\n        }\n    }\n}\n
    func algorithm(n int) {\n    a := 1     // +0 (trick 1)\n    a = a + n  // +0 (trick 1)\n    // +n (technique 2)\n    for i := 0; i < 5 * n + 1; i++ {\n        fmt.Println(0)\n    }\n    // +n*n (technique 3)\n    for i := 0; i < 2 * n; i++ {\n        for j := 0; j < n + 1; j++ {\n            fmt.Println(0)\n        }\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +0 (trick 1)\n    a = a + n // +0 (trick 1)\n    // +n (technique 2)\n    for _ in 0 ..< (5 * n + 1) {\n        print(0)\n    }\n    // +n*n (technique 3)\n    for _ in 0 ..< (2 * n) {\n        for _ in 0 ..< (n + 1) {\n            print(0)\n        }\n    }\n}\n
    function algorithm(n) {\n    let a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n (technique 3)\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    function algorithm(n: number): void {\n    let a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n (technique 3)\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +0 (trick 1)\n  a = a + n; // +0 (trick 1)\n  // +n (technique 2)\n  for (int i = 0; i < 5 * n + 1; i++) {\n    print(0);\n  }\n  // +n*n (technique 3)\n  for (int i = 0; i < 2 * n; i++) {\n    for (int j = 0; j < n + 1; j++) {\n      print(0);\n    }\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;     // +0 (trick 1)\n    a = a + n;        // +0 (trick 1)\n\n    // +n (technique 2)\n    for i in 0..(5 * n + 1) {\n        println!(\"{}\", 0);\n    }\n\n    // +n*n (technique 3)\n    for i in 0..(2 * n) {\n        for j in 0..(n + 1) {\n            println!(\"{}\", 0);\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0 (trick 1)\n    a = a + n;  // +0 (trick 1)\n    // +n (technique 2)\n    for (int i = 0; i < 5 * n + 1; i++) {\n        printf(\"%d\", 0);\n    }\n    // +n*n (technique 3)\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            printf(\"%d\", 0);\n        }\n    }\n}\n
    \n
    fn algorithm(n: usize) void {\n    var a: i32 = 1;     // +0 (trick 1)\n    a = a + @as(i32, @intCast(n));        // +0 (trick 1)\n\n    // +n (technique 2)\n    for(0..(5 * n + 1)) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n\n    // +n*n (technique 3)\n    for(0..(2 * n)) |_| {\n        for(0..(n + 1)) |_| {\n            std.debug.print(\"{}\\n\", .{0});\n        }\n    }\n}\n

    The formula below shows the counting results before and after simplification, both leading to a time complexity of \\(O(n^2)\\):

    \\[ \\begin{aligned} T(n) & = 2n(n + 1) + (5n + 1) + 2 & \\text{Complete Count (-.-|||)} \\newline & = 2n^2 + 7n + 3 \\newline T(n) & = n^2 + n & \\text{Simplified Count (o.O)} \\end{aligned} \\]"},{"location":"chapter_computational_complexity/time_complexity/#2-step-2-determining-the-asymptotic-upper-bound","title":"2. \u00a0 Step 2: determining the asymptotic upper bound","text":"

    The time complexity is determined by the highest order term in \\(T(n)\\). This is because, as \\(n\\) approaches infinity, the highest order term dominates, rendering the influence of other terms negligible.

    The following table illustrates examples of different operation counts and their corresponding time complexities. Some exaggerated values are used to emphasize that coefficients cannot alter the order of growth. When \\(n\\) becomes very large, these constants become insignificant.

    Table: Time complexity for different operation counts

    Operation Count \\(T(n)\\) Time Complexity \\(O(f(n))\\) \\(100000\\) \\(O(1)\\) \\(3n + 2\\) \\(O(n)\\) \\(2n^2 + 3n + 2\\) \\(O(n^2)\\) \\(n^3 + 10000n^2\\) \\(O(n^3)\\) \\(2^n + 10000n^{10000}\\) \\(O(2^n)\\)"},{"location":"chapter_computational_complexity/time_complexity/#234-common-types-of-time-complexity","title":"2.3.4 \u00a0 Common types of time complexity","text":"

    Let's consider the input data size as \\(n\\). The common types of time complexities are illustrated below, arranged from lowest to highest:

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n \\log n) < O(n^2) < O(2^n) < O(n!) \\newline \\text{Constant Order} < \\text{Logarithmic Order} < \\text{Linear Order} < \\text{Linear-Logarithmic Order} < \\text{Quadratic Order} < \\text{Exponential Order} < \\text{Factorial Order} \\end{aligned} \\]

    Figure 2-9 \u00a0 Common types of time complexity

    "},{"location":"chapter_computational_complexity/time_complexity/#1-constant-order-o1","title":"1. \u00a0 Constant order \\(O(1)\\)","text":"

    Constant order means the number of operations is independent of the input data size \\(n\\). In the following function, although the number of operations size might be large, the time complexity remains \\(O(1)\\) as it's unrelated to \\(n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def constant(n: int) -> int:\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    count = 0\n    size = 100000\n    for _ in range(size):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u5e38\u6570\u9636 */\nint Constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u5e38\u6570\u9636 */\nfunc constant(n int) int {\n    count := 0\n    size := 100000\n    for i := 0; i < size; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e38\u6570\u9636 */\nfunc constant(n: Int) -> Int {\n    var count = 0\n    let size = 100_000\n    for _ in 0 ..< size {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u5e38\u6570\u9636 */\nfunction constant(n: number): number {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n  int count = 0;\n  int size = 100000;\n  for (var i = 0; i < size; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e38\u6570\u9636 */\nfn constant(n: i32) -> i32 {\n    _ = n;\n    let mut count = 0;\n    let size = 100_000;\n    for _ in 0..size {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    int i = 0;\n    for (int i = 0; i < size; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e38\u6570\u9636 */\nfun constant(n: Int): Int {\n    var count = 0\n    val size = 100000\n    for (i in 0..<size)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u5e38\u6570\u9636 ###\ndef constant(n)\n  count = 0\n  size = 100000\n\n  (0...size).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u5e38\u6570\u9636\nfn constant(n: i32) i32 {\n    _ = n;\n    var count: i32 = 0;\n    const size: i32 = 100_000;\n    var i: i32 = 0;\n    while(i<size) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_computational_complexity/time_complexity/#2-linear-order-on","title":"2. \u00a0 Linear order \\(O(n)\\)","text":"

    Linear order indicates the number of operations grows linearly with the input data size \\(n\\). Linear order commonly appears in single-loop structures:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    count = 0\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636 */\nint Linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc linear(n int) int {\n    count := 0\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) -> Int {\n    var count = 0\n    for _ in 0 ..< n {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): number {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n  int count = 0;\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636 */\nfn linear(n: i32) -> i32 {\n    let mut count = 0;\n    for _ in 0..n {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int): Int {\n    var count = 0\n    for (i in 0..<n)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  count = 0\n  (0...n).each { count += 1 }\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Operations like array traversal and linked list traversal have a time complexity of \\(O(n)\\), where \\(n\\) is the length of the array or list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def array_traversal(nums: list[int]) -> int:\n    \"\"\"\u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for num in nums:\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(vector<int> &nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint ArrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    foreach (int num in nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums []int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for range nums {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums: [Int]) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums: number[]): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(List<int> nums) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for (var _num in nums) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfn array_traversal(nums: &[i32]) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int *nums, int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfun arrayTraversal(nums: IntArray): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (num in nums) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09###\ndef array_traversal(nums)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for num in nums\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\nfn arrayTraversal(nums: []i32) i32 {\n    var count: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (nums) |_| {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    It's important to note that the input data size \\(n\\) should be determined based on the type of input data. For example, in the first example, \\(n\\) represents the input data size, while in the second example, the length of the array \\(n\\) is the data size.

    "},{"location":"chapter_computational_complexity/time_complexity/#3-quadratic-order-on2","title":"3. \u00a0 Quadratic order \\(O(n^2)\\)","text":"

    Quadratic order means the number of operations grows quadratically with the input data size \\(n\\). Quadratic order typically appears in nested loops, where both the outer and inner loops have a time complexity of \\(O(n)\\), resulting in an overall complexity of \\(O(n^2)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def quadratic(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i in range(n):\n        for j in range(n):\n            count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636 */\nint Quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i := 0; i < n; i++ {\n        for j := 0; j < n; j++ {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0 ..< n {\n        for _ in 0 ..< n {\n            count += 1\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for (int i = 0; i < n; i++) {\n    for (int j = 0; j < n; j++) {\n      count++;\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636 */\nfn quadratic(n: i32) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0..n {\n        for _ in 0..n {\n            count += 1;\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (i in 0..<n) {\n        for (j in 0..<n) {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for i in 0...n\n    for j in 0...n\n      count += 1\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            count += 1;\n        }\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    The following image compares constant order, linear order, and quadratic order time complexities.

    Figure 2-10 \u00a0 Constant, linear, and quadratic order time complexities

    For instance, in bubble sort, the outer loop runs \\(n - 1\\) times, and the inner loop runs \\(n-1\\), \\(n-2\\), ..., \\(2\\), \\(1\\) times, averaging \\(n / 2\\) times, resulting in a time complexity of \\(O((n - 1) n / 2) = O(n^2)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def bubble_sort(nums: list[int]) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\"\"\"\n    count = 0  # \u8ba1\u6570\u5668\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(len(nums) - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp: int = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3  # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(vector<int> &nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int[] nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint BubbleSort(int[] nums) {\n    int count = 0;  // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums []int) int {\n    count := 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp := nums[j]\n                nums[j] = nums[j+1]\n                nums[j+1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums: inout [Int]) -> Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums) {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums: number[]): number {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(List<int> nums) {\n  int count = 0; // \u8ba1\u6570\u5668\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (var i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (var j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      }\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfn bubble_sort(nums: &mut [i32]) -> i32 {\n    let mut count = 0; // \u8ba1\u6570\u5668\n\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int *nums, int n) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = n - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfun bubbleSort(nums: IntArray): Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09###\ndef bubble_sort(nums)\n  count = 0  # \u8ba1\u6570\u5668\n\n  # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for i in (nums.length - 1).downto(0)\n    # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for j in 0...i\n      if nums[j] > nums[j + 1]\n        # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        tmp = nums[j]\n        nums[j] = nums[j + 1]\n        nums[j + 1] = tmp\n        count += 3 # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      end\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\nfn bubbleSort(nums: []i32) i32 {\n    var count: i32 = 0;  // \u8ba1\u6570\u5668 \n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: i32 = @as(i32, @intCast(nums.len)) - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_computational_complexity/time_complexity/#4-exponential-order-o2n","title":"4. \u00a0 Exponential order \\(O(2^n)\\)","text":"

    Biological \"cell division\" is a classic example of exponential order growth: starting with one cell, it becomes two after one division, four after two divisions, and so on, resulting in \\(2^n\\) cells after \\(n\\) divisions.

    The following image and code simulate the cell division process, with a time complexity of \\(O(2^n)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exponential(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    base = 1\n    # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in range(n):\n        for _ in range(base):\n            count += 1\n        base *= 2\n    # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Exponential(int n) {\n    int count = 0, bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc exponential(n int) int {\n    count, base := 0, 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for i := 0; i < n; i++ {\n        for j := 0; j < base; j++ {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc exponential(n: Int) -> Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0 ..< n {\n        for _ in 0 ..< base {\n            count += 1\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n) {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n: number): number {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n  int count = 0, base = 1;\n  // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  for (var i = 0; i < n; i++) {\n    for (var j = 0; j < base; j++) {\n      count++;\n    }\n    base *= 2;\n  }\n  // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  return count;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn exponential(n: i32) -> i32 {\n    let mut count = 0;\n    let mut base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0..n {\n        for _ in 0..base {\n            count += 1\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    count\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0;\n    int bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun exponential(n: Int): Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (i in 0..<n) {\n        for (j in 0..<base) {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef exponential(n)\n  count, base = 0, 1\n\n  # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  (0...n).each do\n    (0...base).each { count += 1 }\n    base *= 2\n  end\n\n  # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  count\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn exponential(n: i32) i32 {\n    var count: i32 = 0;\n    var bas: i32 = 1;\n    var i: i32 = 0;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < bas) : (j += 1) {\n            count += 1;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-11 \u00a0 Exponential order time complexity

    In practice, exponential order often appears in recursive functions. For example, in the code below, it recursively splits into two halves, stopping after \\(n\\) divisions:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exp_recur(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 1:\n        return 1\n    return exp_recur(n - 1) + exp_recur(n - 1) + 1\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint ExpRecur(int n) {\n    if (n == 1) return 1;\n    return ExpRecur(n - 1) + ExpRecur(n - 1) + 1;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc expRecur(n int) int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n-1) + expRecur(n-1) + 1\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc expRecur(n: Int) -> Int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n: n - 1) + expRecur(n: n - 1) + 1\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n) {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n: number): number {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n  if (n == 1) return 1;\n  return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn exp_recur(n: i32) -> i32 {\n    if n == 1 {\n        return 1;\n    }\n    exp_recur(n - 1) + exp_recur(n - 1) + 1\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun expRecur(n: Int): Int {\n    if (n == 1) {\n        return 1\n    }\n    return expRecur(n - 1) + expRecur(n - 1) + 1\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef exp_recur(n)\n  return 1 if n == 1\n  exp_recur(n - 1) + exp_recur(n - 1) + 1\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn expRecur(n: i32) i32 {\n    if (n == 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    Code Visualization

    Full Screen >

    Exponential order growth is extremely rapid and is commonly seen in exhaustive search methods (brute force, backtracking, etc.). For large-scale problems, exponential order is unacceptable, often requiring dynamic programming or greedy algorithms as solutions.

    "},{"location":"chapter_computational_complexity/time_complexity/#5-logarithmic-order-olog-n","title":"5. \u00a0 Logarithmic order \\(O(\\log n)\\)","text":"

    In contrast to exponential order, logarithmic order reflects situations where \"the size is halved each round.\" Given an input data size \\(n\\), since the size is halved each round, the number of iterations is \\(\\log_2 n\\), the inverse function of \\(2^n\\).

    The following image and code simulate the \"halving each round\" process, with a time complexity of \\(O(\\log_2 n)\\), commonly abbreviated as \\(O(\\log n)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def logarithmic(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    while n > 1:\n        n = n / 2\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n /= 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc logarithmic(n int) int {\n    count := 0\n    for n > 1 {\n        n = n / 2\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc logarithmic(n: Int) -> Int {\n    var count = 0\n    var n = n\n    while n > 1 {\n        n = n / 2\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n) {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n: number): number {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n  int count = 0;\n  while (n > 1) {\n    n = n ~/ 2;\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn logarithmic(mut n: i32) -> i32 {\n    let mut count = 0;\n    while n > 1 {\n        n = n / 2;\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun logarithmic(n: Int): Int {\n    var n1 = n\n    var count = 0\n    while (n1 > 1) {\n        n1 /= 2\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef logarithmic(n)\n  count = 0\n\n  while n > 1\n    n /= 2\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn logarithmic(n: i32) i32 {\n    var count: i32 = 0;\n    var n_var = n;\n    while (n_var > 1)\n    {\n        n_var = n_var / 2;\n        count +=1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-12 \u00a0 Logarithmic order time complexity

    Like exponential order, logarithmic order also frequently appears in recursive functions. The code below forms a recursive tree of height \\(\\log_2 n\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def log_recur(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 1:\n        return 0\n    return log_recur(n / 2) + 1\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint LogRecur(int n) {\n    if (n <= 1) return 0;\n    return LogRecur(n / 2) + 1;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc logRecur(n int) int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n/2) + 1\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc logRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n: n / 2) + 1\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n) {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n: number): number {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n  if (n <= 1) return 0;\n  return logRecur(n ~/ 2) + 1;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 0;\n    }\n    log_recur(n / 2) + 1\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun logRecur(n: Int): Int {\n    if (n <= 1)\n        return 0\n    return logRecur(n / 2) + 1\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef log_recur(n)\n  return 0 unless n > 1\n  log_recur(n / 2) + 1\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn logRecur(n: i32) i32 {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    Code Visualization

    Full Screen >

    Logarithmic order is typical in algorithms based on the divide-and-conquer strategy, embodying the \"split into many\" and \"simplify complex problems\" approach. It's slow-growing and is the most ideal time complexity after constant order.

    What is the base of \\(O(\\log n)\\)?

    Technically, \"splitting into \\(m\\)\" corresponds to a time complexity of \\(O(\\log_m n)\\). Using the logarithm base change formula, we can equate different logarithmic complexities:

    \\[ O(\\log_m n) = O(\\log_k n / \\log_k m) = O(\\log_k n) \\]

    This means the base \\(m\\) can be changed without affecting the complexity. Therefore, we often omit the base \\(m\\) and simply denote logarithmic order as \\(O(\\log n)\\).

    "},{"location":"chapter_computational_complexity/time_complexity/#6-linear-logarithmic-order-on-log-n","title":"6. \u00a0 Linear-logarithmic order \\(O(n \\log n)\\)","text":"

    Linear-logarithmic order often appears in nested loops, with the complexities of the two loops being \\(O(\\log n)\\) and \\(O(n)\\) respectively. The related code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear_log_recur(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u5bf9\u6570\u9636\"\"\"\n    if n <= 1:\n        return 1\n    count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2)\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint LinearLogRecur(int n) {\n    if (n <= 1) return 1;\n    int count = LinearLogRecur(n / 2) + LinearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n int) int {\n    if n <= 1 {\n        return 1\n    }\n    count := linearLogRecur(n/2) + linearLogRecur(n/2)\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 1\n    }\n    var count = linearLogRecur(n: n / 2) + linearLogRecur(n: n / 2)\n    for _ in stride(from: 0, to: n, by: 1) {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n) {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n: number): number {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n  if (n <= 1) return 1;\n  int count = linearLogRecur(n ~/ 2) + linearLogRecur(n ~/ 2);\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfn linear_log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 1;\n    }\n    let mut count = linear_log_recur(n / 2) + linear_log_recur(n / 2);\n    for _ in 0..n as i32 {\n        count += 1;\n    }\n    return count;\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfun linearLogRecur(n: Int): Int {\n    if (n <= 1)\n        return 1\n    var count = linearLogRecur(n / 2) + linearLogRecur(n / 2)\n    for (i in 0..<n) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u5bf9\u6570\u9636 ###\ndef linear_log_recur(n)\n  return 1 unless n > 1\n\n  count = linear_log_recur(n / 2) + linear_log_recur(n / 2)\n  (0...n).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u5bf9\u6570\u9636\nfn linearLogRecur(n: i32) i32 {\n    if (n <= 1) return 1;\n    var count: i32 = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    The image below demonstrates how linear-logarithmic order is generated. Each level of a binary tree has \\(n\\) operations, and the tree has \\(\\log_2 n + 1\\) levels, resulting in a time complexity of \\(O(n \\log n)\\).

    Figure 2-13 \u00a0 Linear-logarithmic order time complexity

    Mainstream sorting algorithms typically have a time complexity of \\(O(n \\log n)\\), such as quicksort, mergesort, and heapsort.

    "},{"location":"chapter_computational_complexity/time_complexity/#7-factorial-order-on","title":"7. \u00a0 Factorial order \\(O(n!)\\)","text":"

    Factorial order corresponds to the mathematical problem of \"full permutation.\" Given \\(n\\) distinct elements, the total number of possible permutations is:

    \\[ n! = n \\times (n - 1) \\times (n - 2) \\times \\dots \\times 2 \\times 1 \\]

    Factorials are typically implemented using recursion. As shown in the image and code below, the first level splits into \\(n\\) branches, the second level into \\(n - 1\\) branches, and so on, stopping after the \\(n\\)th level:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def factorial_recur(n: int) -> int:\n    \"\"\"\u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 0:\n        return 1\n    count = 0\n    # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in range(n):\n        count += factorial_recur(n - 1)\n    return count\n
    time_complexity.cpp
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint FactorialRecur(int n) {\n    if (n == 0) return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += FactorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n int) int {\n    if n == 0 {\n        return 1\n    }\n    count := 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for i := 0; i < n; i++ {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n: Int) -> Int {\n    if n == 0 {\n        return 1\n    }\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0 ..< n {\n        count += factorialRecur(n: n - 1)\n    }\n    return count\n}\n
    time_complexity.js
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n) {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n: number): number {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n  if (n == 0) return 1;\n  int count = 0;\n  // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  for (var i = 0; i < n; i++) {\n    count += factorialRecur(n - 1);\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn factorial_recur(n: i32) -> i32 {\n    if n == 0 {\n        return 1;\n    }\n    let mut count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0..n {\n        count += factorial_recur(n - 1);\n    }\n    count\n}\n
    time_complexity.c
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun factorialRecur(n: Int): Int {\n    if (n == 0)\n        return 1\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (i in 0..<n) {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef factorial_recur(n)\n  return 1 if n == 0\n\n  count = 0\n  # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  (0...n).each { count += factorial_recur(n - 1) }\n\n  count\nend\n
    time_complexity.zig
    // \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn factorialRecur(n: i32) i32 {\n    if (n == 0) return 1;\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    while (i < n) : (i += 1) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    Code Visualization

    Full Screen >

    Figure 2-14 \u00a0 Factorial order time complexity

    Note that factorial order grows even faster than exponential order; it's unacceptable for larger \\(n\\) values.

    "},{"location":"chapter_computational_complexity/time_complexity/#235-worst-best-and-average-time-complexities","title":"2.3.5 \u00a0 Worst, best, and average time complexities","text":"

    The time efficiency of an algorithm is often not fixed but depends on the distribution of the input data. Assume we have an array nums of length \\(n\\), consisting of numbers from \\(1\\) to \\(n\\), each appearing only once, but in a randomly shuffled order. The task is to return the index of the element \\(1\\). We can draw the following conclusions:

    • When nums = [?, ?, ..., 1], that is, when the last element is \\(1\\), it requires a complete traversal of the array, achieving the worst-case time complexity of \\(O(n)\\).
    • When nums = [1, ?, ?, ...], that is, when the first element is \\(1\\), no matter the length of the array, no further traversal is needed, achieving the best-case time complexity of \\(\\Omega(1)\\).

    The \"worst-case time complexity\" corresponds to the asymptotic upper bound, denoted by the big \\(O\\) notation. Correspondingly, the \"best-case time complexity\" corresponds to the asymptotic lower bound, denoted by \\(\\Omega\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig worst_best_time_complexity.py
    def random_numbers(n: int) -> list[int]:\n    \"\"\"\u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71\"\"\"\n    # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n    nums = [i for i in range(1, n + 1)]\n    # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    random.shuffle(nums)\n    return nums\n\ndef find_one(nums: list[int]) -> int:\n    \"\"\"\u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\"\"\"\n    for i in range(len(nums)):\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1:\n            return i\n    return -1\n
    worst_best_time_complexity.cpp
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nvector<int> randomNumbers(int n) {\n    vector<int> nums(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u4f7f\u7528\u7cfb\u7edf\u65f6\u95f4\u751f\u6210\u968f\u673a\u79cd\u5b50\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    shuffle(nums.begin(), nums.end(), default_random_engine(seed));\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(vector<int> &nums) {\n    for (int i = 0; i < nums.size(); i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.java
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] randomNumbers(int n) {\n    Integer[] nums = new Integer[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    Collections.shuffle(Arrays.asList(nums));\n    // Integer[] -> int[]\n    int[] res = new int[n];\n    for (int i = 0; i < n; i++) {\n        res[i] = nums[i];\n    }\n    return res;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int[] nums) {\n    for (int i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.cs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] RandomNumbers(int n) {\n    int[] nums = new int[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = 0; i < nums.Length; i++) {\n        int index = new Random().Next(i, nums.Length);\n        (nums[i], nums[index]) = (nums[index], nums[i]);\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint FindOne(int[] nums) {\n    for (int i = 0; i < nums.Length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.go
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n int) []int {\n    nums := make([]int, n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for i := 0; i < n; i++ {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    rand.Shuffle(len(nums), func(i, j int) {\n        nums[i], nums[j] = nums[j], nums[i]\n    })\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums []int) int {\n    for i := 0; i < len(nums); i++ {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.swift
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n: Int) -> [Int] {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    var nums = Array(1 ... n)\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums: [Int]) -> Int {\n    for i in nums.indices {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.js
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n) {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums) {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.ts
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n: number): number[] {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums: number[]): number {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.dart
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nList<int> randomNumbers(int n) {\n  final nums = List.filled(n, 0);\n  // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n  for (var i = 0; i < n; i++) {\n    nums[i] = i + 1;\n  }\n  // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle();\n\n  return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(List<int> nums) {\n  for (var i = 0; i < nums.length; i++) {\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    if (nums[i] == 1) return i;\n  }\n\n  return -1;\n}\n
    worst_best_time_complexity.rs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfn random_numbers(n: i32) -> Vec<i32> {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    let mut nums = (1..=n).collect::<Vec<i32>>();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle(&mut thread_rng());\n    nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfn find_one(nums: &[i32]) -> Option<usize> {\n    for i in 0..nums.len() {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return Some(i);\n        }\n    }\n    None\n}\n
    worst_best_time_complexity.c
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint *randomNumbers(int n) {\n    // \u5206\u914d\u5806\u533a\u5185\u5b58\uff08\u521b\u5efa\u4e00\u7ef4\u53ef\u53d8\u957f\u6570\u7ec4\uff1a\u6570\u7ec4\u4e2d\u5143\u7d20\u6570\u91cf\u4e3a n \uff0c\u5143\u7d20\u7c7b\u578b\u4e3a int \uff09\n    int *nums = (int *)malloc(n * sizeof(int));\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = n - 1; i > 0; i--) {\n        int j = rand() % (i + 1);\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int *nums, int n) {\n    for (int i = 0; i < n; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.kt
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfun randomNumbers(n: Int): Array<Int?> {\n    val nums = IntArray(n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (i in 0..<n) {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    val res = arrayOfNulls<Int>(n)\n    for (i in 0..<n) {\n        res[i] = nums[i]\n    }\n    return res\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfun findOne(nums: Array<Int?>): Int {\n    for (i in nums.indices) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i\n    }\n    return -1\n}\n
    worst_best_time_complexity.rb
    ### \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71 ###\ndef random_numbers(n)\n  # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n  nums = Array.new(n) { |i| i + 1 }\n  # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle!\nend\n\n### \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 ###\ndef find_one(nums)\n  for i in 0...nums.length\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    return i if nums[i] == 1\n  end\n\n  -1\nend\n
    worst_best_time_complexity.zig
    // \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71\nfn randomNumbers(comptime n: usize) [n]i32 {\n    var nums: [n]i32 = undefined;\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (&nums, 0..) |*num, i| {\n        num.* = @as(i32, @intCast(i)) + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    const rand = std.crypto.random;\n    rand.shuffle(i32, &nums);\n    return nums;\n}\n\n// \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\nfn findOne(nums: []i32) i32 {\n    for (nums, 0..) |num, i| {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (num == 1) return @intCast(i);\n    }\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    It's important to note that the best-case time complexity is rarely used in practice, as it is usually only achievable under very low probabilities and might be misleading. The worst-case time complexity is more practical as it provides a safety value for efficiency, allowing us to confidently use the algorithm.

    From the above example, it's clear that both the worst-case and best-case time complexities only occur under \"special data distributions,\" which may have a small probability of occurrence and may not accurately reflect the algorithm's run efficiency. In contrast, the average time complexity can reflect the algorithm's efficiency under random input data, denoted by the \\(\\Theta\\) notation.

    For some algorithms, we can simply estimate the average case under a random data distribution. For example, in the aforementioned example, since the input array is shuffled, the probability of element \\(1\\) appearing at any index is equal. Therefore, the average number of loops for the algorithm is half the length of the array \\(n / 2\\), giving an average time complexity of \\(\\Theta(n / 2) = \\Theta(n)\\).

    However, calculating the average time complexity for more complex algorithms can be quite difficult, as it's challenging to analyze the overall mathematical expectation under the data distribution. In such cases, we usually use the worst-case time complexity as the standard for judging the efficiency of the algorithm.

    Why is the \\(\\Theta\\) symbol rarely seen?

    Possibly because the \\(O\\) notation is more commonly spoken, it is often used to represent the average time complexity. However, strictly speaking, this practice is not accurate. In this book and other materials, if you encounter statements like \"average time complexity \\(O(n)\\)\", please understand it directly as \\(\\Theta(n)\\).

    "},{"location":"chapter_data_structure/","title":"Chapter 3. \u00a0 Data structures","text":"

    Abstract

    Data structures serve as a robust and diverse framework.

    They offer a blueprint for the orderly organization of data, upon which algorithms come to life.

    "},{"location":"chapter_data_structure/#chapter-contents","title":"Chapter contents","text":"
    • 3.1 \u00a0 Classification of data structures
    • 3.2 \u00a0 Basic data types
    • 3.3 \u00a0 Number encoding *
    • 3.4 \u00a0 Character encoding *
    • 3.5 \u00a0 Summary
    "},{"location":"chapter_data_structure/basic_data_types/","title":"3.2 \u00a0 Basic data types","text":"

    When discussing data in computers, various forms like text, images, videos, voice and 3D models comes to mind. Despite their different organizational forms, they are all composed of various basic data types.

    Basic data types are those that the CPU can directly operate on and are directly used in algorithms, mainly including the following.

    • Integer types: byte, short, int, long.
    • Floating-point types: float, double, used to represent decimals.
    • Character type: char, used to represent letters, punctuation, and even emojis in various languages.
    • Boolean type: bool, used to represent \"yes\" or \"no\" decisions.

    Basic data types are stored in computers in binary form. One binary digit is 1 bit. In most modern operating systems, 1 byte consists of 8 bits.

    The range of values for basic data types depends on the size of the space they occupy. Below, we take Java as an example.

    • The integer type byte occupies 1 byte = 8 bits and can represent \\(2^8\\) numbers.
    • The integer type int occupies 4 bytes = 32 bits and can represent \\(2^{32}\\) numbers.

    The following table lists the space occupied, value range, and default values of various basic data types in Java. While memorizing this table isn't necessary, having a general understanding of it and referencing it when required is recommended.

    Table 3-1 \u00a0 Space occupied and value range of basic data types

    Type Symbol Space Occupied Minimum Value Maximum Value Default Value Integer byte 1 byte \\(-2^7\\) (\\(-128\\)) \\(2^7 - 1\\) (\\(127\\)) 0 short 2 bytes \\(-2^{15}\\) \\(2^{15} - 1\\) 0 int 4 bytes \\(-2^{31}\\) \\(2^{31} - 1\\) 0 long 8 bytes \\(-2^{63}\\) \\(2^{63} - 1\\) 0 Float float 4 bytes \\(1.175 \\times 10^{-38}\\) \\(3.403 \\times 10^{38}\\) \\(0.0\\text{f}\\) double 8 bytes \\(2.225 \\times 10^{-308}\\) \\(1.798 \\times 10^{308}\\) 0.0 Char char 2 bytes 0 \\(2^{16} - 1\\) 0 Boolean bool 1 byte \\(\\text{false}\\) \\(\\text{true}\\) \\(\\text{false}\\)

    Please note that the above table is specific to Java's basic data types. Every programming language has its own data type definitions, which might differ in space occupied, value ranges, and default values.

    • In Python, the integer type int can be of any size, limited only by available memory; the floating-point float is double precision 64-bit; there is no char type, as a single character is actually a string str of length 1.
    • C and C++ do not specify the size of basic data types, it varies with implementation and platform. The above table follows the LP64 data model, used for Unix 64-bit operating systems including Linux and macOS.
    • The size of char in C and C++ is 1 byte, while in most programming languages, it depends on the specific character encoding method, as detailed in the \"Character Encoding\" chapter.
    • Even though representing a boolean only requires 1 bit (0 or 1), it is usually stored in memory as 1 byte. This is because modern computer CPUs typically use 1 byte as the smallest addressable memory unit.

    So, what is the connection between basic data types and data structures? We know that data structures are ways to organize and store data in computers. The focus here is on \"structure\" rather than \"data\".

    If we want to represent \"a row of numbers\", we naturally think of using an array. This is because the linear structure of an array can represent the adjacency and the ordering of the numbers, but whether the stored content is an integer int, a decimal float, or a character char, is irrelevant to the \"data structure\".

    In other words, basic data types provide the \"content type\" of data, while data structures provide the \"way of organizing\" data. For example, in the following code, we use the same data structure (array) to store and represent different basic data types, including int, float, char, bool, etc.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    # Using various basic data types to initialize arrays\nnumbers: list[int] = [0] * 5\ndecimals: list[float] = [0.0] * 5\n# Python's characters are actually strings of length 1\ncharacters: list[str] = ['0'] * 5\nbools: list[bool] = [False] * 5\n# Python's lists can freely store various basic data types and object references\ndata = [0, 0.0, 'a', False, ListNode(0)]\n
    // Using various basic data types to initialize arrays\nint numbers[5];\nfloat decimals[5];\nchar characters[5];\nbool bools[5];\n
    // Using various basic data types to initialize arrays\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nboolean[] bools = new boolean[5];\n
    // Using various basic data types to initialize arrays\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nbool[] bools = new bool[5];\n
    // Using various basic data types to initialize arrays\nvar numbers = [5]int{}\nvar decimals = [5]float64{}\nvar characters = [5]byte{}\nvar bools = [5]bool{}\n
    // Using various basic data types to initialize arrays\nlet numbers = Array(repeating: 0, count: 5)\nlet decimals = Array(repeating: 0.0, count: 5)\nlet characters: [Character] = Array(repeating: \"a\", count: 5)\nlet bools = Array(repeating: false, count: 5)\n
    // JavaScript's arrays can freely store various basic data types and objects\nconst array = [0, 0.0, 'a', false];\n
    // Using various basic data types to initialize arrays\nconst numbers: number[] = [];\nconst characters: string[] = [];\nconst bools: boolean[] = [];\n
    // Using various basic data types to initialize arrays\nList<int> numbers = List.filled(5, 0);\nList<double> decimals = List.filled(5, 0.0);\nList<String> characters = List.filled(5, 'a');\nList<bool> bools = List.filled(5, false);\n
    // Using various basic data types to initialize arrays\nlet numbers: Vec<i32> = vec![0; 5];\nlet decimals: Vec<f32> = vec![0.0, 5];\nlet characters: Vec<char> = vec!['0'; 5];\nlet bools: Vec<bool> = vec![false; 5];\n
    // Using various basic data types to initialize arrays\nint numbers[10];\nfloat decimals[10];\nchar characters[10];\nbool bools[10];\n
    \n
    // Using various basic data types to initialize arrays\nvar numbers: [5]i32 = undefined;\nvar decimals: [5]f32 = undefined;\nvar characters: [5]u8 = undefined;\nvar bools: [5]bool = undefined;\n
    "},{"location":"chapter_data_structure/character_encoding/","title":"3.4 \u00a0 Character encoding *","text":"

    In the computer system, all data is stored in binary form, and characters (represented by char) are no exception. To represent characters, we need to develop a \"character set\" that defines a one-to-one mapping between each character and binary numbers. With the character set, computers can convert binary numbers to characters by looking up the table.

    "},{"location":"chapter_data_structure/character_encoding/#341-ascii-character-set","title":"3.4.1 \u00a0 ASCII character set","text":"

    The \"ASCII code\" is one of the earliest character sets, officially known as the American Standard Code for Information Interchange. It uses 7 binary digits (the lower 7 bits of a byte) to represent a character, allowing for a maximum of 128 different characters. As shown in the Figure 3-6 , ASCII includes uppercase and lowercase English letters, numbers 0 ~ 9, various punctuation marks, and certain control characters (such as newline and tab).

    Figure 3-6 \u00a0 ASCII code

    However, ASCII can only represent English characters. With the globalization of computers, a character set called \"EASCII\" was developed to represent more languages. It expands from the 7-bit structure of ASCII to 8 bits, enabling the representation of 256 characters.

    Globally, various region-specific EASCII character sets have been introduced. The first 128 characters of these sets are consistent with the ASCII, while the remaining 128 characters are defined differently to accommodate the requirements of different languages.

    "},{"location":"chapter_data_structure/character_encoding/#342-gbk-character-set","title":"3.4.2 \u00a0 GBK character set","text":"

    Later, it was found that EASCII still could not meet the character requirements of many languages. For instance, there are nearly a hundred thousand Chinese characters, with several thousand used regularly. In 1980, the Standardization Administration of China released the \"GB2312\" character set, which included 6763 Chinese characters, essentially fulfilling the computer processing needs for the Chinese language.

    However, GB2312 could not handle some rare and traditional characters. The \"GBK\" character set expands GB2312 and includes 21886 Chinese characters. In the GBK encoding scheme, ASCII characters are represented with one byte, while Chinese characters use two bytes.

    "},{"location":"chapter_data_structure/character_encoding/#343-unicode-character-set","title":"3.4.3 \u00a0 Unicode character set","text":"

    With the rapid evolution of computer technology and a plethora of character sets and encoding standards, numerous problems arose. On the one hand, these character sets generally only defined characters for specific languages and could not function properly in multilingual environments. On the other hand, the existence of multiple character set standards for the same language caused garbled text when information was exchanged between computers using different encoding standards.

    Researchers of that era thought: What if a comprehensive character set encompassing all global languages and symbols was developed? Wouldn't this resolve the issues associated with cross-linguistic environments and garbled text? Inspired by this idea, the extensive character set, Unicode, was born.

    \"Unicode\" is referred to as \"\u7edf\u4e00\u7801\" (Unified Code) in Chinese, theoretically capable of accommodating over a million characters. It aims to incorporate characters from all over the world into a single set, providing a universal character set for processing and displaying various languages and reducing the issues of garbled text due to different encoding standards.

    Since its release in 1991, Unicode has continually expanded to include new languages and characters. As of September 2022, Unicode contains 149,186 characters, including characters, symbols, and even emojis from various languages. In the vast Unicode character set, commonly used characters occupy 2 bytes, while some rare characters may occupy 3 or even 4 bytes.

    Unicode is a universal character set that assigns a number (called a \"code point\") to each character, but it does not specify how these character code points should be stored in a computer system. One might ask: How does a system interpret Unicode code points of varying lengths within a text? For example, given a 2-byte code, how does the system determine if it represents a single 2-byte character or two 1-byte characters?

    A straightforward solution to this problem is to store all characters as equal-length encodings. As shown in the Figure 3-7 , each character in \"Hello\" occupies 1 byte, while each character in \"\u7b97\u6cd5\" (algorithm) occupies 2 bytes. We could encode all characters in \"Hello \u7b97\u6cd5\" as 2 bytes by padding the higher bits with zeros. This method would enable the system to interpret a character every 2 bytes, recovering the content of the phrase.

    Figure 3-7 \u00a0 Unicode encoding example

    However, as ASCII has shown us, encoding English only requires 1 byte. Using the above approach would double the space occupied by English text compared to ASCII encoding, which is a waste of memory space. Therefore, a more efficient Unicode encoding method is needed.

    "},{"location":"chapter_data_structure/character_encoding/#344-utf-8-encoding","title":"3.4.4 \u00a0 UTF-8 encoding","text":"

    Currently, UTF-8 has become the most widely used Unicode encoding method internationally. It is a variable-length encoding, using 1 to 4 bytes to represent a character, depending on the complexity of the character. ASCII characters need only 1 byte, Latin and Greek letters require 2 bytes, commonly used Chinese characters need 3 bytes, and some other rare characters need 4 bytes.

    The encoding rules for UTF-8 are not complex and can be divided into two cases:

    • For 1-byte characters, set the highest bit to \\(0\\), and the remaining 7 bits to the Unicode code point. Notably, ASCII characters occupy the first 128 code points in the Unicode set. This means that UTF-8 encoding is backward compatible with ASCII. This implies that UTF-8 can be used to parse ancient ASCII text.
    • For characters of length \\(n\\) bytes (where \\(n > 1\\)), set the highest \\(n\\) bits of the first byte to \\(1\\), and the \\((n + 1)^{\\text{th}}\\) bit to \\(0\\); starting from the second byte, set the highest 2 bits of each byte to \\(10\\); the rest of the bits are used to fill the Unicode code point.

    The Figure 3-8 shows the UTF-8 encoding for \"Hello\u7b97\u6cd5\". It can be observed that since the highest \\(n\\) bits are set to \\(1\\), the system can determine the length of the character as \\(n\\) by counting the number of highest bits set to \\(1\\).

    But why set the highest 2 bits of the remaining bytes to \\(10\\)? Actually, this \\(10\\) serves as a kind of checksum. If the system starts parsing text from an incorrect byte, the \\(10\\) at the beginning of the byte can help the system quickly detect anomalies.

    The reason for using \\(10\\) as a checksum is that, under UTF-8 encoding rules, it's impossible for the highest two bits of a character to be \\(10\\). This can be proven by contradiction: If the highest two bits of a character are \\(10\\), it indicates that the character's length is \\(1\\), corresponding to ASCII. However, the highest bit of an ASCII character should be \\(0\\), which contradicts the assumption.

    Figure 3-8 \u00a0 UTF-8 encoding example

    Apart from UTF-8, other common encoding methods include:

    • UTF-16 encoding: Uses 2 or 4 bytes to represent a character. All ASCII characters and commonly used non-English characters are represented with 2 bytes; a few characters require 4 bytes. For 2-byte characters, the UTF-16 encoding equals the Unicode code point.
    • UTF-32 encoding: Every character uses 4 bytes. This means UTF-32 occupies more space than UTF-8 and UTF-16, especially for texts with a high proportion of ASCII characters.

    From the perspective of storage space, using UTF-8 to represent English characters is very efficient because it only requires 1 byte; using UTF-16 to encode some non-English characters (such as Chinese) can be more efficient because it only requires 2 bytes, while UTF-8 might need 3 bytes.

    From a compatibility perspective, UTF-8 is the most versatile, with many tools and libraries supporting UTF-8 as a priority.

    "},{"location":"chapter_data_structure/character_encoding/#345-character-encoding-in-programming-languages","title":"3.4.5 \u00a0 Character encoding in programming languages","text":"

    Historically, many programming languages utilized fixed-length encodings such as UTF-16 or UTF-32 for processing strings during program execution. This allows strings to be handled as arrays, offering several advantages:

    • Random access: Strings encoded in UTF-16 can be accessed randomly with ease. For UTF-8, which is a variable-length encoding, locating the \\(i^{th}\\) character requires traversing the string from the start to the \\(i^{th}\\) position, taking \\(O(n)\\) time.
    • Character counting: Similar to random access, counting the number of characters in a UTF-16 encoded string is an \\(O(1)\\) operation. However, counting characters in a UTF-8 encoded string requires traversing the entire string.
    • String operations: Many string operations like splitting, concatenating, inserting, and deleting are easier on UTF-16 encoded strings. These operations generally require additional computation on UTF-8 encoded strings to ensure the validity of the UTF-8 encoding.

    The design of character encoding schemes in programming languages is an interesting topic involving various factors:

    • Java\u2019s String type uses UTF-16 encoding, with each character occupying 2 bytes. This was based on the initial belief that 16 bits were sufficient to represent all possible characters and proven incorrect later. As the Unicode standard expanded beyond 16 bits, characters in Java may now be represented by a pair of 16-bit values, known as \u201csurrogate pairs.\u201d
    • JavaScript and TypeScript use UTF-16 encoding for similar reasons as Java. When JavaScript was first introduced by Netscape in 1995, Unicode was still in its early stages, and 16-bit encoding was sufficient to represent all Unicode characters.
    • C# uses UTF-16 encoding, largely because the .NET platform, designed by Microsoft, and many Microsoft technologies, including the Windows operating system, extensively use UTF-16 encoding.

    Due to the underestimation of character counts, these languages had to use \"surrogate pairs\" to represent Unicode characters exceeding 16 bits. This approach has its drawbacks: strings containing surrogate pairs may have characters occupying 2 or 4 bytes, losing the advantage of fixed-length encoding. Additionally, handling surrogate pairs adds complexity and debugging difficulty to programming.

    Addressing these challenges, some languages have adopted alternative encoding strategies:

    • Python\u2019s str type uses Unicode encoding with a flexible representation where the storage length of characters depends on the largest Unicode code point in the string. If all characters are ASCII, each character occupies 1 byte, 2 bytes for characters within the Basic Multilingual Plane (BMP), and 4 bytes for characters beyond the BMP.
    • Go\u2019s string type internally uses UTF-8 encoding. Go also provides the rune type for representing individual Unicode code points.
    • Rust\u2019s str and String types use UTF-8 encoding internally. Rust also offers the char type for individual Unicode code points.

    It\u2019s important to note that the above discussion pertains to how strings are stored in programming languages, which is different from how strings are stored in files or transmitted over networks. For file storage or network transmission, strings are usually encoded in UTF-8 format for optimal compatibility and space efficiency.

    "},{"location":"chapter_data_structure/classification_of_data_structure/","title":"3.1 \u00a0 Classification of data structures","text":"

    Common data structures include arrays, linked lists, stacks, queues, hash tables, trees, heaps, and graphs. They can be classified into \"logical structure\" and \"physical structure\".

    "},{"location":"chapter_data_structure/classification_of_data_structure/#311-logical-structure-linear-and-non-linear","title":"3.1.1 \u00a0 Logical structure: linear and non-linear","text":"

    The logical structures reveal the logical relationships between data elements. In arrays and linked lists, data are arranged in a specific sequence, demonstrating the linear relationship between data; while in trees, data are arranged hierarchically from the top down, showing the derived relationship between \"ancestors\" and \"descendants\"; and graphs are composed of nodes and edges, reflecting the intricate network relationship.

    As shown in the Figure 3-1 , logical structures can be divided into two major categories: \"linear\" and \"non-linear\". Linear structures are more intuitive, indicating data is arranged linearly in logical relationships; non-linear structures, conversely, are arranged non-linearly.

    • Linear data structures: Arrays, Linked Lists, Stacks, Queues, Hash Tables.
    • Non-linear data structures: Trees, Heaps, Graphs, Hash Tables.

    Figure 3-1 \u00a0 Linear and non-linear data structures

    Non-linear data structures can be further divided into tree structures and network structures.

    • Linear structures: Arrays, linked lists, queues, stacks, and hash tables, where elements have a one-to-one sequential relationship.
    • Tree structures: Trees, Heaps, Hash Tables, where elements have a one-to-many relationship.
    • Network structures: Graphs, where elements have a many-to-many relationships.
    "},{"location":"chapter_data_structure/classification_of_data_structure/#312-physical-structure-contiguous-and-dispersed","title":"3.1.2 \u00a0 Physical structure: contiguous and dispersed","text":"

    During the execution of an algorithm, the data being processed is stored in memory. The Figure 3-2 shows a computer memory stick where each black square is a physical memory space. We can think of memory as a vast Excel spreadsheet, with each cell capable of storing a certain amount of data.

    The system accesses the data at the target location by means of a memory address. As shown in the Figure 3-2 , the computer assigns a unique identifier to each cell in the table according to specific rules, ensuring that each memory space has a unique memory address. With these addresses, the program can access the data stored in memory.

    Figure 3-2 \u00a0 Memory stick, memory spaces, memory addresses

    Tip

    It's worth noting that comparing memory to an Excel spreadsheet is a simplified analogy. The actual working mechanism of memory is more complex, involving concepts like address space, memory management, cache mechanisms, virtual memory, and physical memory.

    Memory is a shared resource for all programs. When a block of memory is occupied by one program, it cannot be simultaneously used by other programs. Therefore, considering memory resources is crucial in designing data structures and algorithms. For instance, the algorithm's peak memory usage should not exceed the remaining free memory of the system; if there is a lack of contiguous memory blocks, then the data structure chosen must be able to be stored in non-contiguous memory blocks.

    As illustrated in the Figure 3-3 , the physical structure reflects the way data is stored in computer memory and it can be divided into contiguous space storage (arrays) and non-contiguous space storage (linked lists). The two types of physical structures exhibit complementary characteristics in terms of time efficiency and space efficiency.

    Figure 3-3 \u00a0 Contiguous space storage and dispersed space storage

    It is worth noting that all data structures are implemented based on arrays, linked lists, or a combination of both. For example, stacks and queues can be implemented using either arrays or linked lists; while implementations of hash tables may involve both arrays and linked lists. - Array-based implementations: Stacks, Queues, Hash Tables, Trees, Heaps, Graphs, Matrices, Tensors (arrays with dimensions \\(\\geq 3\\)). - Linked-list-based implementations: Stacks, Queues, Hash Tables, Trees, Heaps, Graphs, etc.

    Data structures implemented based on arrays are also called \u201cStatic Data Structures,\u201d meaning their length cannot be changed after initialization. Conversely, those based on linked lists are called \u201cDynamic Data Structures,\u201d which can still adjust their size during program execution.

    Tip

    If you find it challenging to comprehend the physical structure, it is recommended that you read the next chapter, \"Arrays and Linked Lists,\" and revisit this section later.

    "},{"location":"chapter_data_structure/number_encoding/","title":"3.3 \u00a0 Number encoding *","text":"

    Tip

    In this book, chapters marked with an asterisk '*' are optional readings. If you are short on time or find them challenging, you may skip these initially and return to them after completing the essential chapters.

    "},{"location":"chapter_data_structure/number_encoding/#331-integer-encoding","title":"3.3.1 \u00a0 Integer encoding","text":"

    In the table from the previous section, we observed that all integer types can represent one more negative number than positive numbers, such as the byte range of \\([-128, 127]\\). This phenomenon seems counterintuitive, and its underlying reason involves knowledge of sign-magnitude, one's complement, and two's complement encoding.

    Firstly, it's important to note that numbers are stored in computers using the two's complement form. Before analyzing why this is the case, let's define these three encoding methods:

    • Sign-magnitude: The highest bit of a binary representation of a number is considered the sign bit, where \\(0\\) represents a positive number and \\(1\\) represents a negative number. The remaining bits represent the value of the number.
    • One's complement: The one's complement of a positive number is the same as its sign-magnitude. For negative numbers, it's obtained by inverting all bits except the sign bit.
    • Two's complement: The two's complement of a positive number is the same as its sign-magnitude. For negative numbers, it's obtained by adding \\(1\\) to their one's complement.

    The following diagram illustrates the conversions among sign-magnitude, one's complement, and two's complement:

    Figure 3-4 \u00a0 Conversions between sign-magnitude, one's complement, and two's complement

    Although sign-magnitude is the most intuitive, it has limitations. For one, negative numbers in sign-magnitude cannot be directly used in calculations. For example, in sign-magnitude, calculating \\(1 + (-2)\\) results in \\(-3\\), which is incorrect.

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 + 1000 \\; 0010 \\newline & = 1000 \\; 0011 \\newline & \\rightarrow -3 \\end{aligned} \\]

    To address this, computers introduced the one's complement. If we convert to one's complement and calculate \\(1 + (-2)\\), then convert the result back to sign-magnitude, we get the correct result of \\(-1\\).

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 \\; \\text{(Sign-magnitude)} + 1000 \\; 0010 \\; \\text{(Sign-magnitude)} \\newline & = 0000 \\; 0001 \\; \\text{(One's complement)} + 1111 \\; 1101 \\; \\text{(One's complement)} \\newline & = 1111 \\; 1110 \\; \\text{(One's complement)} \\newline & = 1000 \\; 0001 \\; \\text{(Sign-magnitude)} \\newline & \\rightarrow -1 \\end{aligned} \\]

    Additionally, there are two representations of zero in sign-magnitude: \\(+0\\) and \\(-0\\). This means two different binary encodings for zero, which could lead to ambiguity. For example, in conditional checks, not differentiating between positive and negative zero might result in incorrect outcomes. Addressing this ambiguity would require additional checks, potentially reducing computational efficiency.

    \\[ \\begin{aligned} +0 & \\rightarrow 0000 \\; 0000 \\newline -0 & \\rightarrow 1000 \\; 0000 \\end{aligned} \\]

    Like sign-magnitude, one's complement also suffers from the positive and negative zero ambiguity. Therefore, computers further introduced the two's complement. Let's observe the conversion process for negative zero in sign-magnitude, one's complement, and two's complement:

    \\[ \\begin{aligned} -0 \\rightarrow \\; & 1000 \\; 0000 \\; \\text{(Sign-magnitude)} \\newline = \\; & 1111 \\; 1111 \\; \\text{(One's complement)} \\newline = 1 \\; & 0000 \\; 0000 \\; \\text{(Two's complement)} \\newline \\end{aligned} \\]

    Adding \\(1\\) to the one's complement of negative zero produces a carry, but with byte length being only 8 bits, the carried-over \\(1\\) to the 9th bit is discarded. Therefore, the two's complement of negative zero is \\(0000 \\; 0000\\), the same as positive zero, thus resolving the ambiguity.

    One last puzzle is the \\([-128, 127]\\) range for byte, with an additional negative number, \\(-128\\). We observe that for the interval \\([-127, +127]\\), all integers have corresponding sign-magnitude, one's complement, and two's complement, allowing for mutual conversion between them.

    However, the two's complement \\(1000 \\; 0000\\) is an exception without a corresponding sign-magnitude. According to the conversion method, its sign-magnitude would be \\(0000 \\; 0000\\), indicating zero. This presents a contradiction because its two's complement should represent itself. Computers designate this special two's complement \\(1000 \\; 0000\\) as representing \\(-128\\). In fact, the calculation of \\((-1) + (-127)\\) in two's complement results in \\(-128\\).

    \\[ \\begin{aligned} & (-127) + (-1) \\newline & \\rightarrow 1111 \\; 1111 \\; \\text{(Sign-magnitude)} + 1000 \\; 0001 \\; \\text{(Sign-magnitude)} \\newline & = 1000 \\; 0000 \\; \\text{(One's complement)} + 1111 \\; 1110 \\; \\text{(One's complement)} \\newline & = 1000 \\; 0001 \\; \\text{(Two's complement)} + 1111 \\; 1111 \\; \\text{(Two's complement)} \\newline & = 1000 \\; 0000 \\; \\text{(Two's complement)} \\newline & \\rightarrow -128 \\end{aligned} \\]

    As you might have noticed, all these calculations are additions, hinting at an important fact: computers' internal hardware circuits are primarily designed around addition operations. This is because addition is simpler to implement in hardware compared to other operations like multiplication, division, and subtraction, allowing for easier parallelization and faster computation.

    It's important to note that this doesn't mean computers can only perform addition. By combining addition with basic logical operations, computers can execute a variety of other mathematical operations. For example, the subtraction \\(a - b\\) can be translated into \\(a + (-b)\\); multiplication and division can be translated into multiple additions or subtractions.

    We can now summarize the reason for using two's complement in computers: with two's complement representation, computers can use the same circuits and operations to handle both positive and negative number addition, eliminating the need for special hardware circuits for subtraction and avoiding the ambiguity of positive and negative zero. This greatly simplifies hardware design and enhances computational efficiency.

    The design of two's complement is quite ingenious, and due to space constraints, we'll stop here. Interested readers are encouraged to explore further.

    "},{"location":"chapter_data_structure/number_encoding/#332-floating-point-number-encoding","title":"3.3.2 \u00a0 Floating-point number encoding","text":"

    You might have noticed something intriguing: despite having the same length of 4 bytes, why does a float have a much larger range of values compared to an int? This seems counterintuitive, as one would expect the range to shrink for float since it needs to represent fractions.

    In fact, this is due to the different representation method used by floating-point numbers (float). Let's consider a 32-bit binary number as:

    \\[ b_{31} b_{30} b_{29} \\ldots b_2 b_1 b_0 \\]

    According to the IEEE 754 standard, a 32-bit float consists of the following three parts:

    • Sign bit \\(\\mathrm{S}\\): Occupies 1 bit, corresponding to \\(b_{31}\\).
    • Exponent bit \\(\\mathrm{E}\\): Occupies 8 bits, corresponding to \\(b_{30} b_{29} \\ldots b_{23}\\).
    • Fraction bit \\(\\mathrm{N}\\): Occupies 23 bits, corresponding to \\(b_{22} b_{21} \\ldots b_0\\).

    The value of a binary float number is calculated as:

    \\[ \\text{val} = (-1)^{b_{31}} \\times 2^{\\left(b_{30} b_{29} \\ldots b_{23}\\right)_2 - 127} \\times \\left(1 . b_{22} b_{21} \\ldots b_0\\right)_2 \\]

    Converted to a decimal formula, this becomes:

    \\[ \\text{val} = (-1)^{\\mathrm{S}} \\times 2^{\\mathrm{E} - 127} \\times (1 + \\mathrm{N}) \\]

    The range of each component is:

    \\[ \\begin{aligned} \\mathrm{S} \\in & \\{ 0, 1\\}, \\quad \\mathrm{E} \\in \\{ 1, 2, \\dots, 254 \\} \\newline (1 + \\mathrm{N}) = & (1 + \\sum_{i=1}^{23} b_{23-i} \\times 2^{-i}) \\subset [1, 2 - 2^{-23}] \\end{aligned} \\]

    Figure 3-5 \u00a0 Example calculation of a float in IEEE 754 standard

    Observing the diagram, given an example data \\(\\mathrm{S} = 0\\), \\(\\mathrm{E} = 124\\), \\(\\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\\), we have:

    \\[ \\text{val} = (-1)^0 \\times 2^{124 - 127} \\times (1 + 0.375) = 0.171875 \\]

    Now we can answer the initial question: The representation of float includes an exponent bit, leading to a much larger range than int. Based on the above calculation, the maximum positive number representable by float is approximately \\(2^{254 - 127} \\times (2 - 2^{-23}) \\approx 3.4 \\times 10^{38}\\), and the minimum negative number is obtained by switching the sign bit.

    However, the trade-off for float's expanded range is a sacrifice in precision. The integer type int uses all 32 bits to represent the number, with values evenly distributed; but due to the exponent bit, the larger the value of a float, the greater the difference between adjacent numbers.

    As shown in the Table 3-2 , exponent bits \\(\\mathrm{E} = 0\\) and \\(\\mathrm{E} = 255\\) have special meanings, used to represent zero, infinity, \\(\\mathrm{NaN}\\), etc.

    Table 3-2 \u00a0 Meaning of exponent bits

    Exponent Bit E Fraction Bit \\(\\mathrm{N} = 0\\) Fraction Bit \\(\\mathrm{N} \\ne 0\\) Calculation Formula \\(0\\) \\(\\pm 0\\) Subnormal Numbers \\((-1)^{\\mathrm{S}} \\times 2^{-126} \\times (0.\\mathrm{N})\\) \\(1, 2, \\dots, 254\\) Normal Numbers Normal Numbers \\((-1)^{\\mathrm{S}} \\times 2^{(\\mathrm{E} -127)} \\times (1.\\mathrm{N})\\) \\(255\\) \\(\\pm \\infty\\) \\(\\mathrm{NaN}\\)

    It's worth noting that subnormal numbers significantly improve the precision of floating-point numbers. The smallest positive normal number is \\(2^{-126}\\), and the smallest positive subnormal number is \\(2^{-126} \\times 2^{-23}\\).

    Double-precision double also uses a similar representation method to float, which is not elaborated here for brevity.

    "},{"location":"chapter_data_structure/summary/","title":"3.5 \u00a0 Summary","text":""},{"location":"chapter_data_structure/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Data structures can be categorized from two perspectives: logical structure and physical structure. Logical structure describes the logical relationships between data elements, while physical structure describes how data is stored in computer memory.
    • Common logical structures include linear, tree-like, and network structures. We generally classify data structures into linear (arrays, linked lists, stacks, queues) and non-linear (trees, graphs, heaps) based on their logical structure. The implementation of hash tables may involve both linear and non-linear data structures.
    • When a program runs, data is stored in computer memory. Each memory space has a corresponding memory address, and the program accesses data through these addresses.
    • Physical structures are primarily divided into contiguous space storage (arrays) and dispersed space storage (linked lists). All data structures are implemented using arrays, linked lists, or a combination of both.
    • Basic data types in computers include integers (byte, short, int, long), floating-point numbers (float, double), characters (char), and booleans (boolean). Their range depends on the size of the space occupied and the representation method.
    • Original code, complement code, and two's complement code are three methods of encoding numbers in computers, and they can be converted into each other. The highest bit of the original code of an integer is the sign bit, and the remaining bits represent the value of the number.
    • Integers are stored in computers in the form of two's complement. In this representation, the computer can treat the addition of positive and negative numbers uniformly, without the need for special hardware circuits for subtraction, and there is no ambiguity of positive and negative zero.
    • The encoding of floating-point numbers consists of 1 sign bit, 8 exponent bits, and 23 fraction bits. Due to the presence of the exponent bit, the range of floating-point numbers is much greater than that of integers, but at the cost of sacrificing precision.
    • ASCII is the earliest English character set, 1 byte in length, and includes 127 characters. The GBK character set is a commonly used Chinese character set, including more than 20,000 Chinese characters. Unicode strives to provide a complete character set standard, including characters from various languages worldwide, thus solving the problem of garbled characters caused by inconsistent character encoding methods.
    • UTF-8 is the most popular Unicode encoding method, with excellent universality. It is a variable-length encoding method with good scalability and effectively improves the efficiency of space usage. UTF-16 and UTF-32 are fixed-length encoding methods. When encoding Chinese characters, UTF-16 occupies less space than UTF-8. Programming languages like Java and C# use UTF-16 encoding by default.
    "},{"location":"chapter_data_structure/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Why does a hash table contain both linear and non-linear data structures?

    The underlying structure of a hash table is an array. To resolve hash collisions, we may use \"chaining\": each bucket in the array points to a linked list, which, when exceeding a certain threshold, might be transformed into a tree (usually a red-black tree). From a storage perspective, the foundation of a hash table is an array, where each bucket slot might contain a value, a linked list, or a tree. Therefore, hash tables may contain both linear data structures (arrays, linked lists) and non-linear data structures (trees).

    Q: Is the length of the char type 1 byte?

    The length of the char type is determined by the encoding method used by the programming language. For example, Java, JavaScript, TypeScript, and C# all use UTF-16 encoding (to save Unicode code points), so the length of the char type is 2 bytes.

    Q: Is there ambiguity in calling data structures based on arrays \"static data structures\"? Because operations like push and pop on stacks are \"dynamic\".

    While stacks indeed allow for dynamic data operations, the data structure itself remains \"static\" (with unchangeable length). Even though data structures based on arrays can dynamically add or remove elements, their capacity is fixed. If the data volume exceeds the pre-allocated size, a new, larger array needs to be created, and the contents of the old array copied into it.

    Q: When building stacks (queues) without specifying their size, why are they considered \"static data structures\"?

    In high-level programming languages, we don't need to manually specify the initial capacity of stacks (queues); this task is automatically handled internally by the class. For example, the initial capacity of Java's ArrayList is usually 10. Furthermore, the expansion operation is also implemented automatically. See the subsequent \"List\" chapter for details.

    "},{"location":"chapter_divide_and_conquer/","title":"Chapter 12. \u00a0 Divide and conquer","text":"

    Abstract

    Difficult problems are decomposed layer by layer, each decomposition making them simpler.

    Divide and conquer reveals an important truth: start with simplicity, and nothing is complex anymore.

    "},{"location":"chapter_divide_and_conquer/#chapter-contents","title":"Chapter contents","text":"
    • 12.1 \u00a0 Divide and conquer algorithms
    • 12.2 \u00a0 Divide and conquer search strategy
    • 12.3 \u00a0 Building binary tree problem
    • 12.4 \u00a0 Tower of Hanoi Problem
    • 12.5 \u00a0 Summary
    "},{"location":"chapter_divide_and_conquer/binary_search_recur/","title":"12.2 \u00a0 Divide and conquer search strategy","text":"

    We have learned that search algorithms fall into two main categories.

    • Brute-force search: It is implemented by traversing the data structure, with a time complexity of \\(O(n)\\).
    • Adaptive search: It utilizes a unique data organization form or prior information, and its time complexity can reach \\(O(\\log n)\\) or even \\(O(1)\\).

    In fact, search algorithms with a time complexity of \\(O(\\log n)\\) are usually based on the divide-and-conquer strategy, such as binary search and trees.

    • Each step of binary search divides the problem (searching for a target element in an array) into a smaller problem (searching for the target element in half of the array), continuing until the array is empty or the target element is found.
    • Trees represent the divide-and-conquer idea, where in data structures like binary search trees, AVL trees, and heaps, the time complexity of various operations is \\(O(\\log n)\\).

    The divide-and-conquer strategy of binary search is as follows.

    • The problem can be divided: Binary search recursively divides the original problem (searching in an array) into subproblems (searching in half of the array), achieved by comparing the middle element with the target element.
    • Subproblems are independent: In binary search, each round handles one subproblem, unaffected by other subproblems.
    • The solutions of subproblems do not need to be merged: Binary search aims to find a specific element, so there is no need to merge the solutions of subproblems. When a subproblem is solved, the original problem is also solved.

    Divide-and-conquer can enhance search efficiency because brute-force search can only eliminate one option per round, whereas divide-and-conquer can eliminate half of the options.

    "},{"location":"chapter_divide_and_conquer/binary_search_recur/#1-implementing-binary-search-based-on-divide-and-conquer","title":"1. \u00a0 Implementing binary search based on divide-and-conquer","text":"

    In previous chapters, binary search was implemented based on iteration. Now, we implement it based on divide-and-conquer (recursion).

    Question

    Given an ordered array nums of length \\(n\\), where all elements are unique, please find the element target.

    From a divide-and-conquer perspective, we denote the subproblem corresponding to the search interval \\([i, j]\\) as \\(f(i, j)\\).

    Starting from the original problem \\(f(0, n-1)\\), perform the binary search through the following steps.

    1. Calculate the midpoint \\(m\\) of the search interval \\([i, j]\\), and use it to eliminate half of the search interval.
    2. Recursively solve the subproblem reduced by half in size, which could be \\(f(i, m-1)\\) or \\(f(m+1, j)\\).
    3. Repeat steps 1. and 2., until target is found or the interval is empty and returns.

    The diagram below shows the divide-and-conquer process of binary search for element \\(6\\) in an array.

    Figure 12-4 \u00a0 The divide-and-conquer process of binary search

    In the implementation code, we declare a recursive function dfs() to solve the problem \\(f(i, j)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_recur.py
    def dfs(nums: list[int], target: int, i: int, j: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j)\"\"\"\n    # \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j:\n        return -1\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) // 2\n    if nums[m] < target:\n        # \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j)\n    elif nums[m] > target:\n        # \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1)\n    else:\n        # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n\ndef binary_search(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\"\"\"\n    n = len(nums)\n    # \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1)\n
    binary_search_recur.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(vector<int> &nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(vector<int> &nums, int target) {\n    int n = nums.size();\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.java
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(int[] nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(int[] nums, int target) {\n    int n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.cs
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint DFS(int[] nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return DFS(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return DFS(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint BinarySearch(int[] nums, int target) {\n    int n = nums.Length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return DFS(nums, target, 0, n - 1);\n}\n
    binary_search_recur.go
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunc dfs(nums []int, target, i, j int) int {\n    // \u5982\u679c\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u6ca1\u6709\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1\n    }\n    //    \u8ba1\u7b97\u7d22\u5f15\u4e2d\u70b9\n    m := i + ((j - i) >> 1)\n    //\u5224\u65ad\u4e2d\u70b9\u4e0e\u76ee\u6807\u5143\u7d20\u5927\u5c0f\n    if nums[m] < target {\n        // \u5c0f\u4e8e\u5219\u9012\u5f52\u53f3\u534a\u6570\u7ec4\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m+1, j)\n    } else if nums[m] > target {\n        // \u5c0f\u4e8e\u5219\u9012\u5f52\u5de6\u534a\u6570\u7ec4\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m-1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunc binarySearch(nums []int, target int) int {\n    n := len(nums)\n    return dfs(nums, target, 0, n-1)\n}\n
    binary_search_recur.swift
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunc dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    let m = (i + j) / 2\n    if nums[m] < target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums: nums, target: target, i: m + 1, j: j)\n    } else if nums[m] > target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums: nums, target: target, i: i, j: m - 1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunc binarySearch(nums: [Int], target: Int) -> Int {\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    dfs(nums: nums, target: target, i: nums.startIndex, j: nums.endIndex - 1)\n}\n
    binary_search_recur.js
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunction dfs(nums, target, i, j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    const m = i + ((j - i) >> 1);\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunction binarySearch(nums, target) {\n    const n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.ts
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunction dfs(nums: number[], target: number, i: number, j: number): number {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    const m = i + ((j - i) >> 1);\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunction binarySearch(nums: number[], target: number): number {\n    const n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.dart
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(List<int> nums, int target, int i, int j) {\n  // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n  if (i > j) {\n    return -1;\n  }\n  // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n  int m = (i + j) ~/ 2;\n  if (nums[m] < target) {\n    // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n    return dfs(nums, target, m + 1, j);\n  } else if (nums[m] > target) {\n    // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n    return dfs(nums, target, i, m - 1);\n  } else {\n    // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return m;\n  }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(List<int> nums, int target) {\n  int n = nums.length;\n  // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n  return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.rs
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfn dfs(nums: &[i32], target: i32, i: i32, j: i32) -> i32 {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1;\n    }\n    let m: i32 = (i + j) / 2;\n    if nums[m as usize] < target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if nums[m as usize] > target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfn binary_search(nums: &[i32], target: i32) -> i32 {\n    let n = nums.len() as i32;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    dfs(nums, target, 0, n - 1)\n}\n
    binary_search_recur.c
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(int nums[], int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(int nums[], int target, int numsSize) {\n    int n = numsSize;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.kt
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfun dfs(\n    nums: IntArray,\n    target: Int,\n    i: Int,\n    j: Int\n): Int {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    val m = (i + j) / 2\n    return if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        dfs(nums, target, m + 1, j)\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        dfs(nums, target, i, m - 1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfun binarySearch(nums: IntArray, target: Int): Int {\n    val n = nums.size\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1)\n}\n
    binary_search_recur.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{binary_search}\n
    binary_search_recur.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{binarySearch}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/","title":"12.3 \u00a0 Building binary tree problem","text":"

    Question

    Given the preorder traversal preorder and inorder traversal inorder of a binary tree, construct the binary tree and return the root node of the binary tree. Assume that there are no duplicate values in the nodes of the binary tree (as shown in the diagram below).

    Figure 12-5 \u00a0 Example data for building a binary tree

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#1-determining-if-it-is-a-divide-and-conquer-problem","title":"1. \u00a0 Determining if it is a divide and conquer problem","text":"

    The original problem of constructing a binary tree from preorder and inorder is a typical divide and conquer problem.

    • The problem can be decomposed: From the perspective of divide and conquer, we can divide the original problem into two subproblems: building the left subtree and building the right subtree, plus one operation: initializing the root node. For each subtree (subproblem), we can still use the above division method, dividing it into smaller subtrees (subproblems), until the smallest subproblem (empty subtree) is reached.
    • The subproblems are independent: The left and right subtrees are independent of each other, with no overlap. When building the left subtree, we only need to focus on the parts of the inorder and preorder traversals that correspond to the left subtree. The same applies to the right subtree.
    • Solutions to subproblems can be combined: Once the solutions for the left and right subtrees (solutions to subproblems) are obtained, we can link them to the root node to obtain the solution to the original problem.
    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#2-how-to-divide-the-subtrees","title":"2. \u00a0 How to divide the subtrees","text":"

    Based on the above analysis, this problem can be solved using divide and conquer, but how do we use the preorder traversal preorder and inorder traversal inorder to divide the left and right subtrees?

    By definition, preorder and inorder can be divided into three parts.

    • Preorder traversal: [ Root | Left Subtree | Right Subtree ], for example, the tree in the diagram corresponds to [ 3 | 9 | 2 1 7 ].
    • Inorder traversal: [ Left Subtree | Root | Right Subtree ], for example, the tree in the diagram corresponds to [ 9 | 3 | 1 2 7 ].

    Using the data in the diagram above, we can obtain the division results as shown in the steps below.

    1. The first element 3 in the preorder traversal is the value of the root node.
    2. Find the index of the root node 3 in inorder, and use this index to divide inorder into [ 9 | 3 \uff5c 1 2 7 ].
    3. Based on the division results of inorder, it is easy to determine the number of nodes in the left and right subtrees as 1 and 3, respectively, thus dividing preorder into [ 3 | 9 | 2 1 7 ].

    Figure 12-6 \u00a0 Dividing the subtrees in preorder and inorder traversals

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#3-describing-subtree-intervals-based-on-variables","title":"3. \u00a0 Describing subtree intervals based on variables","text":"

    Based on the above division method, we have now obtained the index intervals of the root, left subtree, and right subtree in preorder and inorder. To describe these index intervals, we need the help of several pointer variables.

    • Let the index of the current tree's root node in preorder be denoted as \\(i\\).
    • Let the index of the current tree's root node in inorder be denoted as \\(m\\).
    • Let the index interval of the current tree in inorder be denoted as \\([l, r]\\).

    As shown in the Table 12-1 , the above variables can represent the index of the root node in preorder as well as the index intervals of the subtrees in inorder.

    Table 12-1 \u00a0 Indexes of the root node and subtrees in preorder and inorder traversals

    Root node index in preorder Subtree index interval in inorder Current tree \\(i\\) \\([l, r]\\) Left subtree \\(i + 1\\) \\([l, m-1]\\) Right subtree \\(i + 1 + (m - l)\\) \\([m+1, r]\\)

    Please note, the meaning of \\((m-l)\\) in the right subtree root index is \"the number of nodes in the left subtree\", which is suggested to be understood in conjunction with the diagram below.

    Figure 12-7 \u00a0 Indexes of the root node and left and right subtrees

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#4-code-implementation","title":"4. \u00a0 Code implementation","text":"

    To improve the efficiency of querying \\(m\\), we use a hash table hmap to store the mapping of elements in inorder to their indexes:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig build_tree.py
    def dfs(\n    preorder: list[int],\n    inorder_map: dict[int, int],\n    i: int,\n    l: int,\n    r: int,\n) -> TreeNode | None:\n    \"\"\"\u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb\"\"\"\n    # \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0:\n        return None\n    # \u521d\u59cb\u5316\u6839\u8282\u70b9\n    root = TreeNode(preorder[i])\n    # \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    m = inorder_map[preorder[i]]\n    # \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorder_map, i + 1, l, m - 1)\n    # \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r)\n    # \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n\ndef build_tree(preorder: list[int], inorder: list[int]) -> TreeNode | None:\n    \"\"\"\u6784\u5efa\u4e8c\u53c9\u6811\"\"\"\n    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    inorder_map = {val: i for i, val in enumerate(inorder)}\n    root = dfs(preorder, inorder_map, 0, 0, len(inorder) - 1)\n    return root\n
    build_tree.cpp
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode *dfs(vector<int> &preorder, unordered_map<int, int> &inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return NULL;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode *root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    unordered_map<int, int> inorderMap;\n    for (int i = 0; i < inorder.size(); i++) {\n        inorderMap[inorder[i]] = i;\n    }\n    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorder.size() - 1);\n    return root;\n}\n
    build_tree.java
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode dfs(int[] preorder, Map<Integer, Integer> inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode buildTree(int[] preorder, int[] inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    Map<Integer, Integer> inorderMap = new HashMap<>();\n    for (int i = 0; i < inorder.length; i++) {\n        inorderMap.put(inorder[i], i);\n    }\n    TreeNode root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.cs
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode? DFS(int[] preorder, Dictionary<int, int> inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode root = new(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = DFS(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = DFS(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode? BuildTree(int[] preorder, int[] inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    Dictionary<int, int> inorderMap = [];\n    for (int i = 0; i < inorder.Length; i++) {\n        inorderMap.TryAdd(inorder[i], i);\n    }\n    TreeNode? root = DFS(preorder, inorderMap, 0, 0, inorder.Length - 1);\n    return root;\n}\n
    build_tree.go
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunc dfsBuildTree(preorder []int, inorderMap map[int]int, i, l, r int) *TreeNode {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r-l < 0 {\n        return nil\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    root := NewTreeNode(preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    m := inorderMap[preorder[i]]\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.Left = dfsBuildTree(preorder, inorderMap, i+1, l, m-1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.Right = dfsBuildTree(preorder, inorderMap, i+1+m-l, m+1, r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunc buildTree(preorder, inorder []int) *TreeNode {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    inorderMap := make(map[int]int, len(inorder))\n    for i := 0; i < len(inorder); i++ {\n        inorderMap[inorder[i]] = i\n    }\n\n    root := dfsBuildTree(preorder, inorderMap, 0, 0, len(inorder)-1)\n    return root\n}\n
    build_tree.swift
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunc dfs(preorder: [Int], inorderMap: [Int: Int], i: Int, l: Int, r: Int) -> TreeNode? {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0 {\n        return nil\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    let root = TreeNode(x: preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    let m = inorderMap[preorder[i]]!\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1, l: l, r: m - 1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1 + m - l, l: m + 1, r: r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunc buildTree(preorder: [Int], inorder: [Int]) -> TreeNode? {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = inorder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }\n    return dfs(preorder: preorder, inorderMap: inorderMap, i: inorder.startIndex, l: inorder.startIndex, r: inorder.endIndex - 1)\n}\n
    build_tree.js
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunction dfs(preorder, inorderMap, i, l, r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    const root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    const m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunction buildTree(preorder, inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = new Map();\n    for (let i = 0; i < inorder.length; i++) {\n        inorderMap.set(inorder[i], i);\n    }\n    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.ts
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunction dfs(\n    preorder: number[],\n    inorderMap: Map<number, number>,\n    i: number,\n    l: number,\n    r: number\n): TreeNode | null {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    const root: TreeNode = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    const m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunction buildTree(preorder: number[], inorder: number[]): TreeNode | null {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = new Map<number, number>();\n    for (let i = 0; i < inorder.length; i++) {\n        inorderMap.set(inorder[i], i);\n    }\n    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.dart
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode? dfs(\n  List<int> preorder,\n  Map<int, int> inorderMap,\n  int i,\n  int l,\n  int r,\n) {\n  // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n  if (r - l < 0) {\n    return null;\n  }\n  // \u521d\u59cb\u5316\u6839\u8282\u70b9\n  TreeNode? root = TreeNode(preorder[i]);\n  // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n  int m = inorderMap[preorder[i]]!;\n  // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n  root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n  // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n  root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n  // \u8fd4\u56de\u6839\u8282\u70b9\n  return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode? buildTree(List<int> preorder, List<int> inorder) {\n  // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n  Map<int, int> inorderMap = {};\n  for (int i = 0; i < inorder.length; i++) {\n    inorderMap[inorder[i]] = i;\n  }\n  TreeNode? root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n  return root;\n}\n
    build_tree.rs
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfn dfs(\n    preorder: &[i32],\n    inorder_map: &HashMap<i32, i32>,\n    i: i32,\n    l: i32,\n    r: i32,\n) -> Option<Rc<RefCell<TreeNode>>> {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0 {\n        return None;\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    let root = TreeNode::new(preorder[i as usize]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    let m = inorder_map.get(&preorder[i as usize]).unwrap();\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.borrow_mut().left = dfs(preorder, inorder_map, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.borrow_mut().right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    Some(root)\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfn build_tree(preorder: &[i32], inorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let mut inorder_map: HashMap<i32, i32> = HashMap::new();\n    for i in 0..inorder.len() {\n        inorder_map.insert(inorder[i], i as i32);\n    }\n    let root = dfs(preorder, &inorder_map, 0, 0, inorder.len() as i32 - 1);\n    root\n}\n
    build_tree.c
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode *dfs(int *preorder, int *inorderMap, int i, int l, int r, int size) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return NULL;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));\n    root->val = preorder[i];\n    root->left = NULL;\n    root->right = NULL;\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1, size);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r, size);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    int *inorderMap = (int *)malloc(sizeof(int) * MAX_SIZE);\n    for (int i = 0; i < inorderSize; i++) {\n        inorderMap[inorder[i]] = i;\n    }\n    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorderSize - 1, inorderSize);\n    free(inorderMap);\n    return root;\n}\n
    build_tree.kt
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfun dfs(\n    preorder: IntArray,\n    inorderMap: Map<Int?, Int?>,\n    i: Int,\n    l: Int,\n    r: Int\n): TreeNode? {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    val root = TreeNode(preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    val m = inorderMap[preorder[i]]!!\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    val inorderMap = HashMap<Int?, Int?>()\n    for (i in inorder.indices) {\n        inorderMap[inorder[i]] = i\n    }\n    val root = dfs(preorder, inorderMap, 0, 0, inorder.size - 1)\n    return root\n}\n
    build_tree.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{build_tree}\n
    build_tree.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{buildTree}\n
    Code Visualization

    Full Screen >

    The diagram below shows the recursive process of building the binary tree, where each node is established during the \"descending\" process, and each edge (reference) is established during the \"ascending\" process.

    <1><2><3><4><5><6><7><8><9>

    Figure 12-8 \u00a0 Recursive process of building a binary tree

    Each recursive function's division results of preorder and inorder are shown in the diagram below.

    Figure 12-9 \u00a0 Division results in each recursive function

    Assuming the number of nodes in the tree is \\(n\\), initializing each node (executing a recursive function dfs()) takes \\(O(1)\\) time. Thus, the overall time complexity is \\(O(n)\\).

    The hash table stores the mapping of inorder elements to their indexes, with a space complexity of \\(O(n)\\). In the worst case, when the binary tree degenerates into a linked list, the recursive depth reaches \\(n\\), using \\(O(n)\\) stack frame space. Therefore, the overall space complexity is \\(O(n)\\).

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/","title":"12.1 \u00a0 Divide and conquer algorithms","text":"

    Divide and conquer, fully referred to as \"divide and rule\", is an extremely important and common algorithm strategy. Divide and conquer is usually based on recursion and includes two steps: \"divide\" and \"conquer\".

    1. Divide (partition phase): Recursively decompose the original problem into two or more sub-problems until the smallest sub-problem is reached and the process terminates.
    2. Conquer (merge phase): Starting from the smallest sub-problem with a known solution, merge the solutions of the sub-problems from bottom to top to construct the solution to the original problem.

    As shown in the Figure 12-1 , \"merge sort\" is one of the typical applications of the divide and conquer strategy.

    1. Divide: Recursively divide the original array (original problem) into two sub-arrays (sub-problems), until the sub-array has only one element (smallest sub-problem).
    2. Conquer: Merge the ordered sub-arrays (solutions to the sub-problems) from bottom to top to obtain an ordered original array (solution to the original problem).

    Figure 12-1 \u00a0 Merge sort's divide and conquer strategy

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1211-how-to-identify-divide-and-conquer-problems","title":"12.1.1 \u00a0 How to identify divide and conquer problems","text":"

    Whether a problem is suitable for a divide and conquer solution can usually be judged based on the following criteria.

    1. The problem can be decomposed: The original problem can be decomposed into smaller, similar sub-problems and can be recursively divided in the same manner.
    2. Sub-problems are independent: There is no overlap between sub-problems, and they are independent and can be solved separately.
    3. Solutions to sub-problems can be merged: The solution to the original problem is obtained by merging the solutions of the sub-problems.

    Clearly, merge sort meets these three criteria.

    1. The problem can be decomposed: Recursively divide the array (original problem) into two sub-arrays (sub-problems).
    2. Sub-problems are independent: Each sub-array can be sorted independently (sub-problems can be solved independently).
    3. Solutions to sub-problems can be merged: Two ordered sub-arrays (solutions to the sub-problems) can be merged into one ordered array (solution to the original problem).
    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1212-improving-efficiency-through-divide-and-conquer","title":"12.1.2 \u00a0 Improving efficiency through divide and conquer","text":"

    Divide and conquer can not only effectively solve algorithm problems but often also improve algorithm efficiency. In sorting algorithms, quicksort, merge sort, and heap sort are faster than selection, bubble, and insertion sorts because they apply the divide and conquer strategy.

    Then, we may ask: Why can divide and conquer improve algorithm efficiency, and what is the underlying logic? In other words, why are the steps of decomposing a large problem into multiple sub-problems, solving the sub-problems, and merging the solutions of the sub-problems into the solution of the original problem more efficient than directly solving the original problem? This question can be discussed from the aspects of the number of operations and parallel computation.

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1-optimization-of-operation-count","title":"1. \u00a0 Optimization of operation count","text":"

    Taking \"bubble sort\" as an example, it requires \\(O(n^2)\\) time to process an array of length \\(n\\). Suppose we divide the array from the midpoint into two sub-arrays as shown in the Figure 12-2 , then the division requires \\(O(n)\\) time, sorting each sub-array requires \\(O((n / 2)^2)\\) time, and merging the two sub-arrays requires \\(O(n)\\) time, with the total time complexity being:

    \\[ O(n + (\\frac{n}{2})^2 \\times 2 + n) = O(\\frac{n^2}{2} + 2n) \\]

    Figure 12-2 \u00a0 Bubble sort before and after array partition

    Next, we calculate the following inequality, where the left and right sides are the total number of operations before and after the partition, respectively:

    \\[ \\begin{aligned} n^2 & > \\frac{n^2}{2} + 2n \\newline n^2 - \\frac{n^2}{2} - 2n & > 0 \\newline n(n - 4) & > 0 \\end{aligned} \\]

    This means that when \\(n > 4\\), the number of operations after partitioning is fewer, and the sorting efficiency should be higher. Please note that the time complexity after partitioning is still quadratic \\(O(n^2)\\), but the constant factor in the complexity has decreased.

    Further, what if we keep dividing the sub-arrays from their midpoints into two sub-arrays until the sub-arrays have only one element left? This idea is actually \"merge sort,\" with a time complexity of \\(O(n \\log n)\\).

    Furthermore, what if we set several more partition points and evenly divide the original array into \\(k\\) sub-arrays? This situation is very similar to \"bucket sort,\" which is very suitable for sorting massive data, and theoretically, the time complexity can reach \\(O(n + k)\\).

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#2-optimization-through-parallel-computation","title":"2. \u00a0 Optimization through parallel computation","text":"

    We know that the sub-problems generated by divide and conquer are independent of each other, thus they can usually be solved in parallel. This means that divide and conquer can not only reduce the algorithm's time complexity, but also facilitate parallel optimization by the operating system.

    Parallel optimization is especially effective in environments with multiple cores or processors, as the system can process multiple sub-problems simultaneously, making fuller use of computing resources and significantly reducing the overall runtime.

    For example, in the \"bucket sort\" shown in the Figure 12-3 , we distribute massive data evenly across various buckets, then the sorting tasks of all buckets can be distributed to different computing units, and the results are merged after completion.

    Figure 12-3 \u00a0 Bucket sort's parallel computation

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1213-common-applications-of-divide-and-conquer","title":"12.1.3 \u00a0 Common applications of divide and conquer","text":"

    On one hand, divide and conquer can be used to solve many classic algorithm problems.

    • Finding the closest point pair: This algorithm first divides the set of points into two parts, then finds the closest point pair in each part, and finally finds the closest point pair that spans the two parts.
    • Large integer multiplication: For example, the Karatsuba algorithm, which breaks down large integer multiplication into several smaller integer multiplications and additions.
    • Matrix multiplication: For example, the Strassen algorithm, which decomposes large matrix multiplication into multiple small matrix multiplications and additions.
    • Tower of Hanoi problem: The Tower of Hanoi problem can be solved recursively, a typical application of the divide and conquer strategy.
    • Solving inverse pairs: In a sequence, if a number in front is greater than a number behind, these two numbers form an inverse pair. Solving the inverse pair problem can utilize the idea of divide and conquer, with the aid of merge sort.

    On the other hand, divide and conquer is very widely applied in the design of algorithms and data structures.

    • Binary search: Binary search divides an ordered array from the midpoint index into two parts, then decides which half to exclude based on the comparison result between the target value and the middle element value, and performs the same binary operation in the remaining interval.
    • Merge sort: Already introduced at the beginning of this section, no further elaboration is needed.
    • Quicksort: Quicksort selects a pivot value, then divides the array into two sub-arrays, one with elements smaller than the pivot and the other with elements larger than the pivot, and then performs the same partitioning operation on these two parts until the sub-array has only one element.
    • Bucket sort: The basic idea of bucket sort is to distribute data to multiple buckets, then sort the elements within each bucket, and finally retrieve the elements from the buckets in order to obtain an ordered array.
    • Trees: For example, binary search trees, AVL trees, red-black trees, B-trees, B+ trees, etc., their operations such as search, insertion, and deletion can all be considered applications of the divide and conquer strategy.
    • Heap: A heap is a special type of complete binary tree, whose various operations, such as insertion, deletion, and heapification, actually imply the idea of divide and conquer.
    • Hash table: Although hash tables do not directly apply divide and conquer, some hash collision resolution solutions indirectly apply the divide and conquer strategy, for example, long lists in chained addressing being converted to red-black trees to improve query efficiency.

    It can be seen that divide and conquer is a subtly pervasive algorithmic idea, embedded within various algorithms and data structures.

    "},{"location":"chapter_divide_and_conquer/hanota_problem/","title":"12.4 \u00a0 Tower of Hanoi Problem","text":"

    In both merge sorting and building binary trees, we decompose the original problem into two subproblems, each half the size of the original problem. However, for the Tower of Hanoi, we adopt a different decomposition strategy.

    Question

    Given three pillars, denoted as A, B, and C. Initially, pillar A is stacked with \\(n\\) discs, arranged in order from top to bottom from smallest to largest. Our task is to move these \\(n\\) discs to pillar C, maintaining their original order (as shown below). The following rules must be followed during the disc movement process:

    1. A disc can only be picked up from the top of a pillar and placed on top of another pillar.
    2. Only one disc can be moved at a time.
    3. A smaller disc must always be on top of a larger disc.

    Figure 12-10 \u00a0 Example of the Tower of Hanoi

    We denote the Tower of Hanoi of size \\(i\\) as \\(f(i)\\). For example, \\(f(3)\\) represents the Tower of Hanoi of moving \\(3\\) discs from A to C.

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#1-consider-the-base-case","title":"1. \u00a0 Consider the base case","text":"

    As shown below, for the problem \\(f(1)\\), i.e., when there is only one disc, we can directly move it from A to C.

    <1><2>

    Figure 12-11 \u00a0 Solution for a problem of size 1

    As shown below, for the problem \\(f(2)\\), i.e., when there are two discs, since the smaller disc must always be above the larger disc, B is needed to assist in the movement.

    1. First, move the smaller disc from A to B.
    2. Then move the larger disc from A to C.
    3. Finally, move the smaller disc from B to C.
    <1><2><3><4>

    Figure 12-12 \u00a0 Solution for a problem of size 2

    The process of solving the problem \\(f(2)\\) can be summarized as: moving two discs from A to C with the help of B. Here, C is called the target pillar, and B is called the buffer pillar.

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#2-decomposition-of-subproblems","title":"2. \u00a0 Decomposition of subproblems","text":"

    For the problem \\(f(3)\\), i.e., when there are three discs, the situation becomes slightly more complicated.

    Since we already know the solutions to \\(f(1)\\) and \\(f(2)\\), we can think from a divide-and-conquer perspective and consider the two top discs on A as a unit, performing the steps shown below. This way, the three discs are successfully moved from A to C.

    1. Let B be the target pillar and C the buffer pillar, and move the two discs from A to B.
    2. Move the remaining disc from A directly to C.
    3. Let C be the target pillar and A the buffer pillar, and move the two discs from B to C.
    <1><2><3><4>

    Figure 12-13 \u00a0 Solution for a problem of size 3

    Essentially, we divide the problem \\(f(3)\\) into two subproblems \\(f(2)\\) and one subproblem \\(f(1)\\). By solving these three subproblems in order, the original problem is resolved. This indicates that the subproblems are independent, and their solutions can be merged.

    From this, we can summarize the divide-and-conquer strategy for solving the Tower of Hanoi shown in the following image: divide the original problem \\(f(n)\\) into two subproblems \\(f(n-1)\\) and one subproblem \\(f(1)\\), and solve these three subproblems in the following order.

    1. Move \\(n-1\\) discs with the help of C from A to B.
    2. Move the remaining one disc directly from A to C.
    3. Move \\(n-1\\) discs with the help of A from B to C.

    For these two subproblems \\(f(n-1)\\), they can be recursively divided in the same manner until the smallest subproblem \\(f(1)\\) is reached. The solution to \\(f(1)\\) is already known and requires only one move.

    Figure 12-14 \u00a0 Divide and conquer strategy for solving the Tower of Hanoi

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#3-code-implementation","title":"3. \u00a0 Code implementation","text":"

    In the code, we declare a recursive function dfs(i, src, buf, tar) whose role is to move the \\(i\\) discs on top of pillar src with the help of buffer pillar buf to the target pillar tar:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hanota.py
    def move(src: list[int], tar: list[int]):\n    \"\"\"\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\"\"\"\n    # \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    pan = src.pop()\n    # \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.append(pan)\n\ndef dfs(i: int, src: list[int], buf: list[int], tar: list[int]):\n    \"\"\"\u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i)\"\"\"\n    # \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1:\n        move(src, tar)\n        return\n    # \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf)\n    # \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    # \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar)\n\ndef solve_hanota(A: list[int], B: list[int], C: list[int]):\n    \"\"\"\u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898\"\"\"\n    n = len(A)\n    # \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C)\n
    hanota.cpp
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(vector<int> &src, vector<int> &tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src.back();\n    src.pop_back();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push_back(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, vector<int> &src, vector<int> &buf, vector<int> &tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(vector<int> &A, vector<int> &B, vector<int> &C) {\n    int n = A.size();\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.java
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(List<Integer> src, List<Integer> tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    Integer pan = src.remove(src.size() - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, List<Integer> src, List<Integer> buf, List<Integer> tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(List<Integer> A, List<Integer> B, List<Integer> C) {\n    int n = A.size();\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.cs
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid Move(List<int> src, List<int> tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src[^1];\n    src.RemoveAt(src.Count - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.Add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid DFS(int i, List<int> src, List<int> buf, List<int> tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        Move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    DFS(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    Move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    DFS(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid SolveHanota(List<int> A, List<int> B, List<int> C) {\n    int n = A.Count;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    DFS(n, A, B, C);\n}\n
    hanota.go
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunc move(src, tar *list.List) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    pan := src.Back()\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.PushBack(pan.Value)\n    // \u79fb\u9664 src \u9876\u90e8\u5706\u76d8\n    src.Remove(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunc dfsHanota(i int, src, buf, tar *list.List) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move(src, tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfsHanota(i-1, src, tar, buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfsHanota(i-1, buf, src, tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunc solveHanota(A, B, C *list.List) {\n    n := A.Len()\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfsHanota(n, A, B, C)\n}\n
    hanota.swift
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunc move(src: inout [Int], tar: inout [Int]) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    let pan = src.popLast()!\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.append(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunc dfs(i: Int, src: inout [Int], buf: inout [Int], tar: inout [Int]) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move(src: &src, tar: &tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i: i - 1, src: &src, buf: &tar, tar: &buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src: &src, tar: &tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i: i - 1, src: &buf, buf: &src, tar: &tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunc solveHanota(A: inout [Int], B: inout [Int], C: inout [Int]) {\n    let n = A.count\n    // \u5217\u8868\u5c3e\u90e8\u662f\u67f1\u5b50\u9876\u90e8\n    // \u5c06 src \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(i: n, src: &A, buf: &B, tar: &C)\n}\n
    hanota.js
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunction move(src, tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    const pan = src.pop();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunction dfs(i, src, buf, tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i === 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunction solveHanota(A, B, C) {\n    const n = A.length;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.ts
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunction move(src: number[], tar: number[]): void {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    const pan = src.pop();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunction dfs(i: number, src: number[], buf: number[], tar: number[]): void {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i === 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunction solveHanota(A: number[], B: number[], C: number[]): void {\n    const n = A.length;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.dart
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(List<int> src, List<int> tar) {\n  // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n  int pan = src.removeLast();\n  // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n  tar.add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, List<int> src, List<int> buf, List<int> tar) {\n  // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n  if (i == 1) {\n    move(src, tar);\n    return;\n  }\n  // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n  dfs(i - 1, src, tar, buf);\n  // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n  move(src, tar);\n  // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n  dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(List<int> A, List<int> B, List<int> C) {\n  int n = A.length;\n  // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n  dfs(n, A, B, C);\n}\n
    hanota.rs
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfn move_pan(src: &mut Vec<i32>, tar: &mut Vec<i32>) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    let pan = src.remove(src.len() - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfn dfs(i: i32, src: &mut Vec<i32>, buf: &mut Vec<i32>, tar: &mut Vec<i32>) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move_pan(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move_pan(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfn solve_hanota(A: &mut Vec<i32>, B: &mut Vec<i32>, C: &mut Vec<i32>) {\n    let n = A.len() as i32;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.c
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(int *src, int *srcSize, int *tar, int *tarSize) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src[*srcSize - 1];\n    src[*srcSize - 1] = 0;\n    (*srcSize)--;\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar[*tarSize] = pan;\n    (*tarSize)++;\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, int *src, int *srcSize, int *buf, int *bufSize, int *tar, int *tarSize) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, srcSize, tar, tarSize);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, srcSize, tar, tarSize, buf, bufSize);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, srcSize, tar, tarSize);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, bufSize, src, srcSize, tar, tarSize);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(int *A, int *ASize, int *B, int *BSize, int *C, int *CSize) {\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(*ASize, A, ASize, B, BSize, C, CSize);\n}\n
    hanota.kt
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfun move(src: MutableList<Int>, tar: MutableList<Int>) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    val pan = src.removeAt(src.size - 1)\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.add(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfun dfs(i: Int, src: MutableList<Int>, buf: MutableList<Int>, tar: MutableList<Int>) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfun solveHanota(A: MutableList<Int>, B: MutableList<Int>, C: MutableList<Int>) {\n    val n = A.size\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C)\n}\n
    hanota.rb
    [class]{}-[func]{move}\n\n[class]{}-[func]{dfs}\n\n[class]{}-[func]{solve_hanota}\n
    hanota.zig
    [class]{}-[func]{move}\n\n[class]{}-[func]{dfs}\n\n[class]{}-[func]{solveHanota}\n
    Code Visualization

    Full Screen >

    As shown below, the Tower of Hanoi forms a recursive tree with a height of \\(n\\), each node representing a subproblem, corresponding to an open dfs() function, thus the time complexity is \\(O(2^n)\\), and the space complexity is \\(O(n)\\).

    Figure 12-15 \u00a0 Recursive tree of the Tower of Hanoi

    Quote

    The Tower of Hanoi originates from an ancient legend. In a temple in ancient India, monks had three tall diamond pillars and \\(64\\) differently sized golden discs. The monks continuously moved the discs, believing that when the last disc is correctly placed, the world would end.

    However, even if the monks moved a disc every second, it would take about \\(2^{64} \\approx 1.84\u00d710^{19}\\) seconds, approximately 585 billion years, far exceeding current estimates of the age of the universe. Thus, if the legend is true, we probably do not need to worry about the world ending.

    "},{"location":"chapter_divide_and_conquer/summary/","title":"12.5 \u00a0 Summary","text":"
    • Divide and conquer is a common algorithm design strategy, which includes dividing (partitioning) and conquering (merging) two stages, usually implemented based on recursion.
    • The basis for judging whether it is a divide and conquer algorithm problem includes: whether the problem can be decomposed, whether the subproblems are independent, and whether the subproblems can be merged.
    • Merge sort is a typical application of the divide and conquer strategy, which recursively divides the array into two equal-length subarrays until only one element remains, and then starts merging layer by layer to complete the sorting.
    • Introducing the divide and conquer strategy can often improve algorithm efficiency. On one hand, the divide and conquer strategy reduces the number of operations; on the other hand, it is conducive to parallel optimization of the system after division.
    • Divide and conquer can solve many algorithm problems and is widely used in data structure and algorithm design, where its presence is ubiquitous.
    • Compared to brute force search, adaptive search is more efficient. Search algorithms with a time complexity of \\(O(\\log n)\\) are usually based on the divide and conquer strategy.
    • Binary search is another typical application of the divide and conquer strategy, which does not include the step of merging the solutions of subproblems. We can implement binary search through recursive divide and conquer.
    • In the problem of constructing binary trees, building the tree (original problem) can be divided into building the left and right subtree (subproblems), which can be achieved by partitioning the index intervals of the preorder and inorder traversals.
    • In the Tower of Hanoi problem, a problem of size \\(n\\) can be divided into two subproblems of size \\(n-1\\) and one subproblem of size \\(1\\). By solving these three subproblems in sequence, the original problem is consequently resolved.
    "},{"location":"chapter_dynamic_programming/","title":"Chapter 14. \u00a0 Dynamic programming","text":"

    Abstract

    Streams merge into rivers, and rivers merge into the sea.

    Dynamic programming combines the solutions of small problems to solve bigger problems, step by step leading us to the solution.

    "},{"location":"chapter_dynamic_programming/#chapter-contents","title":"Chapter contents","text":"
    • 14.1 \u00a0 Introduction to dynamic programming
    • 14.2 \u00a0 Characteristics of DP problems
    • 14.3 \u00a0 DP problem-solving approach\u00b6
    • 14.4 \u00a0 0-1 Knapsack problem
    • 14.5 \u00a0 Unbounded knapsack problem
    • 14.6 \u00a0 Edit distance problem
    • 14.7 \u00a0 Summary
    "},{"location":"chapter_dynamic_programming/dp_problem_features/","title":"14.2 \u00a0 Characteristics of dynamic programming problems","text":"

    In the previous section, we learned how dynamic programming solves the original problem by decomposing it into subproblems. In fact, subproblem decomposition is a general algorithmic approach, with different emphases in divide and conquer, dynamic programming, and backtracking.

    • Divide and conquer algorithms recursively divide the original problem into multiple independent subproblems until the smallest subproblems are reached, and combine the solutions of the subproblems during backtracking to ultimately obtain the solution to the original problem.
    • Dynamic programming also decomposes the problem recursively, but the main difference from divide and conquer algorithms is that the subproblems in dynamic programming are interdependent, and many overlapping subproblems will appear during the decomposition process.
    • Backtracking algorithms exhaust all possible solutions through trial and error and avoid unnecessary search branches by pruning. The solution to the original problem consists of a series of decision steps, and we can consider each sub-sequence before each decision step as a subproblem.

    In fact, dynamic programming is commonly used to solve optimization problems, which not only include overlapping subproblems but also have two other major characteristics: optimal substructure and statelessness.

    "},{"location":"chapter_dynamic_programming/dp_problem_features/#1421-optimal-substructure","title":"14.2.1 \u00a0 Optimal substructure","text":"

    We make a slight modification to the stair climbing problem to make it more suitable to demonstrate the concept of optimal substructure.

    Minimum cost of climbing stairs

    Given a staircase, you can step up 1 or 2 steps at a time, and each step on the staircase has a non-negative integer representing the cost you need to pay at that step. Given a non-negative integer array \\(cost\\), where \\(cost[i]\\) represents the cost you need to pay at the \\(i\\)-th step, \\(cost[0]\\) is the ground (starting point). What is the minimum cost required to reach the top?

    As shown in the Figure 14-6 , if the costs of the 1st, 2nd, and 3rd steps are \\(1\\), \\(10\\), and \\(1\\) respectively, then the minimum cost to climb to the 3rd step from the ground is \\(2\\).

    Figure 14-6 \u00a0 Minimum cost to climb to the 3rd step

    Let \\(dp[i]\\) be the cumulative cost of climbing to the \\(i\\)-th step. Since the \\(i\\)-th step can only come from the \\(i-1\\) or \\(i-2\\) step, \\(dp[i]\\) can only be either \\(dp[i-1] + cost[i]\\) or \\(dp[i-2] + cost[i]\\). To minimize the cost, we should choose the smaller of the two:

    \\[ dp[i] = \\min(dp[i-1], dp[i-2]) + cost[i] \\]

    This leads us to the meaning of optimal substructure: The optimal solution to the original problem is constructed from the optimal solutions of subproblems.

    This problem obviously has optimal substructure: we select the better one from the optimal solutions of the two subproblems, \\(dp[i-1]\\) and \\(dp[i-2]\\), and use it to construct the optimal solution for the original problem \\(dp[i]\\).

    So, does the stair climbing problem from the previous section have optimal substructure? Its goal is to solve for the number of solutions, which seems to be a counting problem, but if we ask in another way: \"Solve for the maximum number of solutions\". We surprisingly find that although the problem has changed, the optimal substructure has emerged: the maximum number of solutions at the \\(n\\)-th step equals the sum of the maximum number of solutions at the \\(n-1\\) and \\(n-2\\) steps. Thus, the interpretation of optimal substructure is quite flexible and will have different meanings in different problems.

    According to the state transition equation, and the initial states \\(dp[1] = cost[1]\\) and \\(dp[2] = cost[2]\\), we can obtain the dynamic programming code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp(cost: list[int]) -> int:\n    \"\"\"\u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(cost) - 1\n    if n == 1 or n == 2:\n        return cost[n]\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [0] * (n + 1)\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1], dp[2] = cost[1], cost[2]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    return dp[n]\n
    min_cost_climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(vector<int> &cost) {\n    int n = cost.size() - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<int> dp(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.java
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(int[] cost) {\n    int n = cost.length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint MinCostClimbingStairsDP(int[] cost) {\n    int n = cost.Length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = Math.Min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.go
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDP(cost []int) int {\n    n := len(cost) - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    min := func(a, b int) int {\n        if a < b {\n            return a\n        }\n        return b\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i] = min(dp[i-1], dp[i-2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDP(cost: [Int]) -> Int {\n    let n = cost.count - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: 0, count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.js
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDP(cost) {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDP(cost: Array<number>): number {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(List<int> cost) {\n  int n = cost.length - 1;\n  if (n == 1 || n == 2) return cost[n];\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<int> dp = List.filled(n + 1, 0);\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1] = cost[1];\n  dp[2] = cost[2];\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];\n  }\n  return dp[n];\n}\n
    min_cost_climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfn min_cost_climbing_stairs_dp(cost: &[i32]) -> i32 {\n    let n = cost.len() - 1;\n    if n == 1 || n == 2 {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![-1; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i] = cmp::min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    dp[n]\n}\n
    min_cost_climbing_stairs_dp.c
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(int cost[], int costSize) {\n    int n = costSize - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int *dp = calloc(n + 1, sizeof(int));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = myMin(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    int res = dp[n];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    min_cost_climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfun minCostClimbingStairsDP(cost: IntArray): Int {\n    val n = cost.size - 1\n    if (n == 1 || n == 2) return cost[n]\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = IntArray(n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp}\n
    min_cost_climbing_stairs_dp.zig
    // \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212\nfn minCostClimbingStairsDP(comptime cost: []i32) i32 {\n    comptime var n = cost.len - 1;\n    if (n == 1 or n == 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_]i32{-1} ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i] = @min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    Code Visualization

    Full Screen >

    The Figure 14-7 shows the dynamic programming process for the above code.

    Figure 14-7 \u00a0 Dynamic programming process for minimum cost of climbing stairs

    This problem can also be space-optimized, compressing one dimension to zero, reducing the space complexity from \\(O(n)\\) to \\(O(1)\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp_comp(cost: list[int]) -> int:\n    \"\"\"\u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(cost) - 1\n    if n == 1 or n == 2:\n        return cost[n]\n    a, b = cost[1], cost[2]\n    for i in range(3, n + 1):\n        a, b = b, min(a, b) + cost[i]\n    return b\n
    min_cost_climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(vector<int> &cost) {\n    int n = cost.size() - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.java
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(int[] cost) {\n    int n = cost.length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint MinCostClimbingStairsDPComp(int[] cost) {\n    int n = cost.Length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = Math.Min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.go
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDPComp(cost []int) int {\n    n := len(cost) - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    min := func(a, b int) int {\n        if a < b {\n            return a\n        }\n        return b\n    }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    a, b := cost[1], cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        tmp := b\n        b = min(a, tmp) + cost[i]\n        a = tmp\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDPComp(cost: [Int]) -> Int {\n    let n = cost.count - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    var (a, b) = (cost[1], cost[2])\n    for i in 3 ... n {\n        (a, b) = (b, min(a, b) + cost[i])\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.js
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDPComp(cost) {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    let a = cost[1],\n        b = cost[2];\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDPComp(cost: Array<number>): number {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    let a = cost[1],\n        b = cost[2];\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(List<int> cost) {\n  int n = cost.length - 1;\n  if (n == 1 || n == 2) return cost[n];\n  int a = cost[1], b = cost[2];\n  for (int i = 3; i <= n; i++) {\n    int tmp = b;\n    b = min(a, tmp) + cost[i];\n    a = tmp;\n  }\n  return b;\n}\n
    min_cost_climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn min_cost_climbing_stairs_dp_comp(cost: &[i32]) -> i32 {\n    let n = cost.len() - 1;\n    if n == 1 || n == 2 {\n        return cost[n];\n    };\n    let (mut a, mut b) = (cost[1], cost[2]);\n    for i in 3..=n {\n        let tmp = b;\n        b = cmp::min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    b\n}\n
    min_cost_climbing_stairs_dp.c
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(int cost[], int costSize) {\n    int n = costSize - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = myMin(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun minCostClimbingStairsDPComp(cost: IntArray): Int {\n    val n = cost.size - 1\n    if (n == 1 || n == 2) return cost[n]\n    var a = cost[1]\n    var b = cost[2]\n    for (i in 3..n) {\n        val tmp = b\n        b = min(a, tmp) + cost[i]\n        a = tmp\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp_comp}\n
    min_cost_climbing_stairs_dp.zig
    // \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn minCostClimbingStairsDPComp(cost: []i32) i32 {\n    var n = cost.len - 1;\n    if (n == 1 or n == 2) {\n        return cost[n];\n    }\n    var a = cost[1];\n    var b = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        var tmp = b;\n        b = @min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/dp_problem_features/#1422-statelessness","title":"14.2.2 \u00a0 Statelessness","text":"

    Statelessness is one of the important characteristics that make dynamic programming effective in solving problems. Its definition is: Given a certain state, its future development is only related to the current state and unrelated to all past states experienced.

    Taking the stair climbing problem as an example, given state \\(i\\), it will develop into states \\(i+1\\) and \\(i+2\\), corresponding to jumping 1 step and 2 steps respectively. When making these two choices, we do not need to consider the states before state \\(i\\), as they do not affect the future of state \\(i\\).

    However, if we add a constraint to the stair climbing problem, the situation changes.

    Stair climbing with constraints

    Given a staircase with \\(n\\) steps, you can go up 1 or 2 steps each time, but you cannot jump 1 step twice in a row. How many ways are there to climb to the top?

    As shown in the Figure 14-8 , there are only 2 feasible options for climbing to the 3rd step, among which the option of jumping 1 step three times in a row does not meet the constraint condition and is therefore discarded.

    Figure 14-8 \u00a0 Number of feasible options for climbing to the 3rd step with constraints

    In this problem, if the last round was a jump of 1 step, then the next round must be a jump of 2 steps. This means that the next step choice cannot be independently determined by the current state (current stair step), but also depends on the previous state (last round's stair step).

    It is not difficult to find that this problem no longer satisfies statelessness, and the state transition equation \\(dp[i] = dp[i-1] + dp[i-2]\\) also fails, because \\(dp[i-1]\\) represents this round's jump of 1 step, but it includes many \"last round was a jump of 1 step\" options, which, to meet the constraint, cannot be directly included in \\(dp[i]\\).

    For this, we need to expand the state definition: State \\([i, j]\\) represents being on the \\(i\\)-th step and the last round was a jump of \\(j\\) steps, where \\(j \\in \\{1, 2\\}\\). This state definition effectively distinguishes whether the last round was a jump of 1 step or 2 steps, and we can judge accordingly where the current state came from.

    • When the last round was a jump of 1 step, the round before last could only choose to jump 2 steps, that is, \\(dp[i, 1]\\) can only be transferred from \\(dp[i-1, 2]\\).
    • When the last round was a jump of 2 steps, the round before last could choose to jump 1 step or 2 steps, that is, \\(dp[i, 2]\\) can be transferred from \\(dp[i-2, 1]\\) or \\(dp[i-2, 2]\\).

    As shown in the Figure 14-9 , \\(dp[i, j]\\) represents the number of solutions for state \\([i, j]\\). At this point, the state transition equation is:

    \\[ \\begin{cases} dp[i, 1] = dp[i-1, 2] \\\\ dp[i, 2] = dp[i-2, 1] + dp[i-2, 2] \\end{cases} \\]

    Figure 14-9 \u00a0 Recursive relationship considering constraints

    In the end, returning \\(dp[n, 1] + dp[n, 2]\\) will do, the sum of the two representing the total number of solutions for climbing to the \\(n\\)-th step:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_constraint_dp.py
    def climbing_stairs_constraint_dp(n: int) -> int:\n    \"\"\"\u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return 1\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [[0] * 3 for _ in range(n + 1)]\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1], dp[1][2] = 1, 0\n    dp[2][1], dp[2][2] = 0, 1\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    return dp[n][1] + dp[n][2]\n
    climbing_stairs_constraint_dp.cpp
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<vector<int>> dp(n + 1, vector<int>(3, 0));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.java
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[][] dp = new int[n + 1][3];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.cs
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[,] dp = new int[n + 1, 3];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1, 1] = 1;\n    dp[1, 2] = 0;\n    dp[2, 1] = 0;\n    dp[2, 2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i, 1] = dp[i - 1, 2];\n        dp[i, 2] = dp[i - 2, 1] + dp[i - 2, 2];\n    }\n    return dp[n, 1] + dp[n, 2];\n}\n
    climbing_stairs_constraint_dp.go
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsConstraintDP(n int) int {\n    if n == 1 || n == 2 {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([][3]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i][1] = dp[i-1][2]\n        dp[i][2] = dp[i-2][1] + dp[i-2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.swift
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsConstraintDP(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: Array(repeating: 0, count: 3), count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.js
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsConstraintDP(n) {\n    if (n === 1 || n === 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = Array.from(new Array(n + 1), () => new Array(3));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.ts
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsConstraintDP(n: number): number {\n    if (n === 1 || n === 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = Array.from({ length: n + 1 }, () => new Array(3));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.dart
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n  if (n == 1 || n == 2) {\n    return 1;\n  }\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(3, 0));\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1][1] = 1;\n  dp[1][2] = 0;\n  dp[2][1] = 0;\n  dp[2][2] = 1;\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i][1] = dp[i - 1][2];\n    dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n  }\n  return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.rs
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_constraint_dp(n: usize) -> i32 {\n    if n == 1 || n == 2 {\n        return 1;\n    };\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![vec![-1; 3]; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.c
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(3, sizeof(int));\n    }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    int res = dp[n][1] + dp[n][2];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    climbing_stairs_constraint_dp.kt
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsConstraintDP(n: Int): Int {\n    if (n == 1 || n == 2) {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = Array(n + 1) { IntArray(3) }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.rb
    [class]{}-[func]{climbing_stairs_constraint_dp}\n
    climbing_stairs_constraint_dp.zig
    // \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\nfn climbingStairsConstraintDP(comptime n: usize) i32 {\n    if (n == 1 or n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_][3]i32{ [_]i32{ -1, -1, -1 } } ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    Code Visualization

    Full Screen >

    In the above cases, since we only need to consider the previous state, we can still meet the statelessness by expanding the state definition. However, some problems have very serious \"state effects\".

    Stair climbing with obstacle generation

    Given a staircase with \\(n\\) steps, you can go up 1 or 2 steps each time. It is stipulated that when climbing to the \\(i\\)-th step, the system automatically places an obstacle on the \\(2i\\)-th step, and thereafter all rounds are not allowed to jump to the \\(2i\\)-th step. For example, if the first two rounds jump to the 2nd and 3rd steps, then later you cannot jump to the 4th and 6th steps. How many ways are there to climb to the top?

    In this problem, the next jump depends on all past states, as each jump places obstacles on higher steps, affecting future jumps. For such problems, dynamic programming often struggles to solve.

    In fact, many complex combinatorial optimization problems (such as the traveling salesman problem) do not satisfy statelessness. For these kinds of problems, we usually choose to use other methods, such as heuristic search, genetic algorithms, reinforcement learning, etc., to obtain usable local optimal solutions within a limited time.

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/","title":"14.3 \u00a0 Dynamic programming problem-solving approach","text":"

    The last two sections introduced the main characteristics of dynamic programming problems. Next, let's explore two more practical issues together.

    1. How to determine whether a problem is a dynamic programming problem?
    2. What are the complete steps to solve a dynamic programming problem?
    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1431-problem-determination","title":"14.3.1 \u00a0 Problem determination","text":"

    Generally speaking, if a problem contains overlapping subproblems, optimal substructure, and exhibits no aftereffects, it is usually suitable for dynamic programming solutions. However, it is often difficult to directly extract these characteristics from the problem description. Therefore, we usually relax the conditions and first observe whether the problem is suitable for resolution using backtracking (exhaustive search).

    Problems suitable for backtracking usually fit the \"decision tree model\", which can be described using a tree structure, where each node represents a decision, and each path represents a sequence of decisions.

    In other words, if the problem contains explicit decision concepts, and the solution is produced through a series of decisions, then it fits the decision tree model and can usually be solved using backtracking.

    On this basis, there are some \"bonus points\" for determining dynamic programming problems.

    • The problem contains descriptions of maximization (minimization) or finding the most (least) optimal solution.
    • The problem's states can be represented using a list, multi-dimensional matrix, or tree, and a state has a recursive relationship with its surrounding states.

    Correspondingly, there are also some \"penalty points\".

    • The goal of the problem is to find all possible solutions, not just the optimal solution.
    • The problem description has obvious characteristics of permutations and combinations, requiring the return of specific multiple solutions.

    If a problem fits the decision tree model and has relatively obvious \"bonus points\", we can assume it is a dynamic programming problem and verify it during the solution process.

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1432-problem-solving-steps","title":"14.3.2 \u00a0 Problem-solving steps","text":"

    The dynamic programming problem-solving process varies with the nature and difficulty of the problem but generally follows these steps: describe decisions, define states, establish a \\(dp\\) table, derive state transition equations, and determine boundary conditions, etc.

    To illustrate the problem-solving steps more vividly, we use a classic problem, \"Minimum Path Sum\", as an example.

    Question

    Given an \\(n \\times m\\) two-dimensional grid grid, each cell in the grid contains a non-negative integer representing the cost of that cell. The robot starts from the top-left cell and can only move down or right at each step until it reaches the bottom-right cell. Return the minimum path sum from the top-left to the bottom-right.

    The following figure shows an example, where the given grid's minimum path sum is \\(13\\).

    Figure 14-10 \u00a0 Minimum Path Sum Example Data

    First step: Think about each round of decisions, define the state, and thereby obtain the \\(dp\\) table

    Each round of decisions in this problem is to move one step down or right from the current cell. Suppose the row and column indices of the current cell are \\([i, j]\\), then after moving down or right, the indices become \\([i+1, j]\\) or \\([i, j+1]\\). Therefore, the state should include two variables: the row index and the column index, denoted as \\([i, j]\\).

    The state \\([i, j]\\) corresponds to the subproblem: the minimum path sum from the starting point \\([0, 0]\\) to \\([i, j]\\), denoted as \\(dp[i, j]\\).

    Thus, we obtain the two-dimensional \\(dp\\) matrix shown below, whose size is the same as the input grid \\(grid\\).

    Figure 14-11 \u00a0 State definition and DP table

    Note

    Dynamic programming and backtracking can be described as a sequence of decisions, while a state consists of all decision variables. It should include all variables that describe the progress of solving the problem, containing enough information to derive the next state.

    Each state corresponds to a subproblem, and we define a \\(dp\\) table to store the solutions to all subproblems. Each independent variable of the state is a dimension of the \\(dp\\) table. Essentially, the \\(dp\\) table is a mapping between states and solutions to subproblems.

    Second step: Identify the optimal substructure, then derive the state transition equation

    For the state \\([i, j]\\), it can only be derived from the cell above \\([i-1, j]\\) or the cell to the left \\([i, j-1]\\). Therefore, the optimal substructure is: the minimum path sum to reach \\([i, j]\\) is determined by the smaller of the minimum path sums of \\([i, j-1]\\) and \\([i-1, j]\\).

    Based on the above analysis, the state transition equation shown in the following figure can be derived:

    \\[ dp[i, j] = \\min(dp[i-1, j], dp[i, j-1]) + grid[i, j] \\]

    Figure 14-12 \u00a0 Optimal substructure and state transition equation

    Note

    Based on the defined \\(dp\\) table, think about the relationship between the original problem and the subproblems, and find out how to construct the optimal solution to the original problem from the optimal solutions to the subproblems, i.e., the optimal substructure.

    Once we have identified the optimal substructure, we can use it to build the state transition equation.

    Third step: Determine boundary conditions and state transition order

    In this problem, the states in the first row can only come from the states to their left, and the states in the first column can only come from the states above them, so the first row \\(i = 0\\) and the first column \\(j = 0\\) are the boundary conditions.

    As shown in the Figure 14-13 , since each cell is derived from the cell to its left and the cell above it, we use loops to traverse the matrix, the outer loop iterating over the rows and the inner loop iterating over the columns.

    Figure 14-13 \u00a0 Boundary conditions and state transition order

    Note

    Boundary conditions are used in dynamic programming to initialize the \\(dp\\) table, and in search to prune.

    The core of the state transition order is to ensure that when calculating the solution to the current problem, all the smaller subproblems it depends on have already been correctly calculated.

    Based on the above analysis, we can directly write the dynamic programming code. However, the decomposition of subproblems is a top-down approach, so implementing it in the order of \"brute-force search \u2192 memoized search \u2192 dynamic programming\" is more in line with habitual thinking.

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1-method-1-brute-force-search","title":"1. \u00a0 Method 1: Brute-force search","text":"

    Start searching from the state \\([i, j]\\), constantly decomposing it into smaller states \\([i-1, j]\\) and \\([i, j-1]\\). The recursive function includes the following elements.

    • Recursive parameter: state \\([i, j]\\).
    • Return value: the minimum path sum from \\([0, 0]\\) to \\([i, j]\\) \\(dp[i, j]\\).
    • Termination condition: when \\(i = 0\\) and \\(j = 0\\), return the cost \\(grid[0, 0]\\).
    • Pruning: when \\(i < 0\\) or \\(j < 0\\) index out of bounds, return the cost \\(+\\infty\\), representing infeasibility.

    Implementation code as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dfs(grid: list[list[int]], i: int, j: int) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22\"\"\"\n    # \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 and j == 0:\n        return grid[0][0]\n    # \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 or j < 0:\n        return inf\n    # \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up = min_path_sum_dfs(grid, i - 1, j)\n    left = min_path_sum_dfs(grid, i, j - 1)\n    # \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(vector<vector<int>> &grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(int[][] grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Integer.MAX_VALUE;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint MinPathSumDFS(int[][] grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return int.MaxValue;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = MinPathSumDFS(grid, i - 1, j);\n    int left = MinPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.Min(left, up) + grid[i][j];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc minPathSumDFS(grid [][]int, i, j int) int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return math.MaxInt\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up := minPathSumDFS(grid, i-1, j)\n    left := minPathSumDFS(grid, i, j-1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return int(math.Min(float64(left), float64(up))) + grid[i][j]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc minPathSumDFS(grid: [[Int]], i: Int, j: Int) -> Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0, j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return .max\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = minPathSumDFS(grid: grid, i: i - 1, j: j)\n    let left = minPathSumDFS(grid: grid, i: i, j: j - 1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction minPathSumDFS(grid, i, j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFS(grid, i - 1, j);\n    const left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction minPathSumDFS(\n    grid: Array<Array<number>>,\n    i: number,\n    j: number\n): number {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFS(grid, i - 1, j);\n    const left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(List<List<int>> grid, int i, int j) {\n  // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n  if (i == 0 && j == 0) {\n    return grid[0][0];\n  }\n  // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n  if (i < 0 || j < 0) {\n    // \u5728 Dart \u4e2d\uff0cint \u7c7b\u578b\u662f\u56fa\u5b9a\u8303\u56f4\u7684\u6574\u6570\uff0c\u4e0d\u5b58\u5728\u8868\u793a\u201c\u65e0\u7a77\u5927\u201d\u7684\u503c\n    return BigInt.from(2).pow(31).toInt();\n  }\n  // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  int up = minPathSumDFS(grid, i - 1, j);\n  int left = minPathSumDFS(grid, i, j - 1);\n  // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  return min(left, up) + grid[i][j];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfn min_path_sum_dfs(grid: &Vec<Vec<i32>>, i: i32, j: i32) -> i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return i32::MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = min_path_sum_dfs(grid, i - 1, j);\n    let left = min_path_sum_dfs(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    std::cmp::min(left, up) + grid[i as usize][j as usize]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(int grid[MAX_SIZE][MAX_SIZE], int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfun minPathSumDFS(grid: Array<IntArray>, i: Int, j: Int): Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Int.MAX_VALUE\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    val up = minPathSumDFS(grid, i - 1, j)\n    val left = minPathSumDFS(grid, i, j - 1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22\nfn minPathSumDFS(grid: anytype, i: i32, j: i32) i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 and j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 or j < 0) {\n        return std.math.maxInt(i32);\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    var up = minPathSumDFS(grid, i - 1, j);\n    var left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n}\n
    Code Visualization

    Full Screen >

    The following figure shows the recursive tree rooted at \\(dp[2, 1]\\), which includes some overlapping subproblems, the number of which increases sharply as the size of the grid grid increases.

    Essentially, the reason for overlapping subproblems is: there are multiple paths to reach a certain cell from the top-left corner.

    Figure 14-14 \u00a0 Brute-force search recursive tree

    Each state has two choices, down and right, so the total number of steps from the top-left corner to the bottom-right corner is \\(m + n - 2\\), so the worst-case time complexity is \\(O(2^{m + n})\\). Please note that this calculation method does not consider the situation near the grid edge, where there is only one choice left when reaching the network edge, so the actual number of paths will be less.

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#2-method-2-memoized-search","title":"2. \u00a0 Method 2: Memoized search","text":"

    We introduce a memo list mem of the same size as the grid grid, used to record the solutions to various subproblems, and prune overlapping subproblems:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dfs_mem(\n    grid: list[list[int]], mem: list[list[int]], i: int, j: int\n) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 and j == 0:\n        return grid[0][0]\n    # \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 or j < 0:\n        return inf\n    # \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1:\n        return mem[i][j]\n    # \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up = min_path_sum_dfs_mem(grid, mem, i - 1, j)\n    left = min_path_sum_dfs_mem(grid, mem, i, j - 1)\n    # \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(vector<vector<int>> &grid, vector<vector<int>> &mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;\n    return mem[i][j];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Integer.MAX_VALUE;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint MinPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return int.MaxValue;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = MinPathSumDFSMem(grid, mem, i - 1, j);\n    int left = MinPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.Min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc minPathSumDFSMem(grid, mem [][]int, i, j int) int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return math.MaxInt\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1 {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up := minPathSumDFSMem(grid, mem, i-1, j)\n    left := minPathSumDFSMem(grid, mem, i, j-1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = int(math.Min(float64(left), float64(up))) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc minPathSumDFSMem(grid: [[Int]], mem: inout [[Int]], i: Int, j: Int) -> Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0, j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return .max\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1 {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = minPathSumDFSMem(grid: grid, mem: &mem, i: i - 1, j: j)\n    let left = minPathSumDFSMem(grid: grid, mem: &mem, i: i, j: j - 1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction minPathSumDFSMem(grid, mem, i, j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] !== -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFSMem(grid, mem, i - 1, j);\n    const left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction minPathSumDFSMem(\n    grid: Array<Array<number>>,\n    mem: Array<Array<number>>,\n    i: number,\n    j: number\n): number {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFSMem(grid, mem, i - 1, j);\n    const left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(List<List<int>> grid, List<List<int>> mem, int i, int j) {\n  // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n  if (i == 0 && j == 0) {\n    return grid[0][0];\n  }\n  // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n  if (i < 0 || j < 0) {\n    // \u5728 Dart \u4e2d\uff0cint \u7c7b\u578b\u662f\u56fa\u5b9a\u8303\u56f4\u7684\u6574\u6570\uff0c\u4e0d\u5b58\u5728\u8868\u793a\u201c\u65e0\u7a77\u5927\u201d\u7684\u503c\n    return BigInt.from(2).pow(31).toInt();\n  }\n  // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  if (mem[i][j] != -1) {\n    return mem[i][j];\n  }\n  // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  int up = minPathSumDFSMem(grid, mem, i - 1, j);\n  int left = minPathSumDFSMem(grid, mem, i, j - 1);\n  // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  mem[i][j] = min(left, up) + grid[i][j];\n  return mem[i][j];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn min_path_sum_dfs_mem(grid: &Vec<Vec<i32>>, mem: &mut Vec<Vec<i32>>, i: i32, j: i32) -> i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return i32::MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i as usize][j as usize] != -1 {\n        return mem[i as usize][j as usize];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = min_path_sum_dfs_mem(grid, mem, i - 1, j);\n    let left = min_path_sum_dfs_mem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i as usize][j as usize] = std::cmp::min(left, up) + grid[i as usize][j as usize];\n    mem[i as usize][j as usize]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(int grid[MAX_SIZE][MAX_SIZE], int mem[MAX_SIZE][MAX_SIZE], int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;\n    return mem[i][j];\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun minPathSumDFSMem(\n    grid: Array<IntArray>,\n    mem: Array<IntArray>,\n    i: Int,\n    j: Int\n): Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Int.MAX_VALUE\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    val up = minPathSumDFSMem(grid, mem, i - 1, j)\n    val left = minPathSumDFSMem(grid, mem, i, j - 1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs_mem}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn minPathSumDFSMem(grid: anytype, mem: anytype, i: i32, j: i32) i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 and j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 or j < 0) {\n        return std.math.maxInt(i32);\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] != -1) {\n        return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    var up = minPathSumDFSMem(grid, mem, i - 1, j);\n    var left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] = @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n    return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n}\n
    Code Visualization

    Full Screen >

    As shown in the Figure 14-15 , after introducing memoization, all subproblem solutions only need to be calculated once, so the time complexity depends on the total number of states, i.e., the grid size \\(O(nm)\\).

    Figure 14-15 \u00a0 Memoized search recursive tree

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#3-method-3-dynamic-programming","title":"3. \u00a0 Method 3: Dynamic programming","text":"

    Implement the dynamic programming solution iteratively, code as shown below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dp(grid: list[list[int]]) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(grid), len(grid[0])\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * m for _ in range(n)]\n    dp[0][0] = grid[0][0]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in range(1, m):\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in range(1, n):\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n):\n        for j in range(1, m):\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n    return dp[n - 1][m - 1]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(vector<vector<int>> &grid) {\n    int n = grid.size(), m = grid[0].size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n, vector<int>(m));\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(int[][] grid) {\n    int n = grid.length, m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n][m];\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint MinPathSumDP(int[][] grid) {\n    int n = grid.Length, m = grid[0].Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n, m];\n    dp[0, 0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0, j] = dp[0, j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i, 0] = dp[i - 1, 0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i, j] = Math.Min(dp[i, j - 1], dp[i - 1, j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1, m - 1];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDP(grid [][]int) int {\n    n, m := len(grid), len(grid[0])\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n)\n    for i := 0; i < n; i++ {\n        dp[i] = make([]int, m)\n    }\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j := 1; j < m; j++ {\n        dp[0][j] = dp[0][j-1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i := 1; i < n; i++ {\n        dp[i][0] = dp[i-1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i < n; i++ {\n        for j := 1; j < m; j++ {\n            dp[i][j] = int(math.Min(float64(dp[i][j-1]), float64(dp[i-1][j]))) + grid[i][j]\n        }\n    }\n    return dp[n-1][m-1]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDP(grid: [[Int]]) -> Int {\n    let n = grid.count\n    let m = grid[0].count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: m), count: n)\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1 ..< m {\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in 1 ..< n {\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ..< n {\n        for j in 1 ..< m {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n        }\n    }\n    return dp[n - 1][m - 1]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDP(grid) {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n }, () =>\n        Array.from({ length: m }, () => 0)\n    );\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (let i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i < n; i++) {\n        for (let j = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDP(grid: Array<Array<number>>): number {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n }, () =>\n        Array.from({ length: m }, () => 0)\n    );\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (let i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i < n; i++) {\n        for (let j: number = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(List<List<int>> grid) {\n  int n = grid.length, m = grid[0].length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n, (i) => List.filled(m, 0));\n  dp[0][0] = grid[0][0];\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n  for (int j = 1; j < m; j++) {\n    dp[0][j] = dp[0][j - 1] + grid[0][j];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n  for (int i = 1; i < n; i++) {\n    dp[i][0] = dp[i - 1][0] + grid[i][0];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i < n; i++) {\n    for (int j = 1; j < m; j++) {\n      dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n    }\n  }\n  return dp[n - 1][m - 1];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfn min_path_sum_dp(grid: &Vec<Vec<i32>>) -> i32 {\n    let (n, m) = (grid.len(), grid[0].len());\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; m]; n];\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1..m {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in 1..n {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..n {\n        for j in 1..m {\n            dp[i][j] = std::cmp::min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    dp[n - 1][m - 1]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc(n * sizeof(int *));\n    for (int i = 0; i < n; i++) {\n        dp[i] = calloc(m, sizeof(int));\n    }\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = myMin(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    int res = dp[n - 1][m - 1];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i < n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfun minPathSumDP(grid: Array<IntArray>): Int {\n    val n = grid.size\n    val m = grid[0].size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n) { IntArray(m) }\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (j in 1..<m) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (i in 1..<n) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..<n) {\n        for (j in 1..<m) {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n        }\n    }\n    return dp[n - 1][m - 1]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212\nfn minPathSumDP(comptime grid: anytype) i32 {\n    comptime var n = grid.len;\n    comptime var m = grid[0].len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][m]i32{[_]i32{0} ** m} ** n;\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (1..m) |j| {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (1..n) |i| {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n) |i| {\n        for (1..m) |j| {\n            dp[i][j] = @min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    Code Visualization

    Full Screen >

    The following figures show the state transition process of the minimum path sum, traversing the entire grid, thus the time complexity is \\(O(nm)\\).

    The array dp is of size \\(n \\times m\\), therefore the space complexity is \\(O(nm)\\).

    <1><2><3><4><5><6><7><8><9><10><11><12>

    Figure 14-16 \u00a0 Dynamic programming process of minimum path sum

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#4-space-optimization","title":"4. \u00a0 Space optimization","text":"

    Since each cell is only related to the cell to its left and above, we can use a single-row array to implement the \\(dp\\) table.

    Please note, since the array dp can only represent the state of one row, we cannot initialize the first column state in advance, but update it as we traverse each row:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dp_comp(grid: list[list[int]]) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(grid), len(grid[0])\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * m\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j in range(1, m):\n        dp[j] = dp[j - 1] + grid[0][j]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in range(1, n):\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in range(1, m):\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n    return dp[m - 1]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(vector<vector<int>> &grid) {\n    int n = grid.size(), m = grid[0].size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(int[][] grid) {\n    int n = grid.length, m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[m];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint MinPathSumDPComp(int[][] grid) {\n    int n = grid.Length, m = grid[0].Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[m];\n    dp[0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = Math.Min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDPComp(grid [][]int) int {\n    n, m := len(grid), len(grid[0])\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j := 1; j < m; j++ {\n        dp[j] = dp[j-1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i < n; i++ {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j := 1; j < m; j++ {\n            dp[j] = int(math.Min(float64(dp[j-1]), float64(dp[j]))) + grid[i][j]\n        }\n    }\n    return dp[m-1]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDPComp(grid: [[Int]]) -> Int {\n    let n = grid.count\n    let m = grid[0].count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j in 1 ..< m {\n        dp[j] = dp[j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1 ..< n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1 ..< m {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n        }\n    }\n    return dp[m - 1]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDPComp(grid) {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = new Array(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (let j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDPComp(grid: Array<Array<number>>): number {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = new Array(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (let j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(List<List<int>> grid) {\n  int n = grid.length, m = grid[0].length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(m, 0);\n  dp[0] = grid[0][0];\n  for (int j = 1; j < m; j++) {\n    dp[j] = dp[j - 1] + grid[0][j];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n  for (int i = 1; i < n; i++) {\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    dp[0] = dp[0] + grid[i][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n    for (int j = 1; j < m; j++) {\n      dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];\n    }\n  }\n  return dp[m - 1];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn min_path_sum_dp_comp(grid: &Vec<Vec<i32>>) -> i32 {\n    let (n, m) = (grid.len(), grid[0].len());\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; m];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for j in 1..m {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1..n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1..m {\n            dp[j] = std::cmp::min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    dp[m - 1]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(m, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = myMin(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    int res = dp[m - 1];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun minPathSumDPComp(grid: Array<IntArray>): Int {\n    val n = grid.size\n    val m = grid[0].size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for (j in 1..<m) {\n        dp[j] = dp[j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (i in 1..<n) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (j in 1..<m) {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n        }\n    }\n    return dp[m - 1]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp_comp}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn minPathSumDPComp(comptime grid: anytype) i32 {\n    comptime var n = grid.len;\n    comptime var m = grid[0].len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** m;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (1..m) |j| {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (1..n) |i| {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        for (1..m) |j| {\n            dp[j] = @min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/","title":"14.6 \u00a0 Edit distance problem","text":"

    Edit distance, also known as Levenshtein distance, refers to the minimum number of modifications required to transform one string into another, commonly used in information retrieval and natural language processing to measure the similarity between two sequences.

    Question

    Given two strings \\(s\\) and \\(t\\), return the minimum number of edits required to transform \\(s\\) into \\(t\\).

    You can perform three types of edits on a string: insert a character, delete a character, or replace a character with any other character.

    As shown in the Figure 14-27 , transforming kitten into sitting requires 3 edits, including 2 replacements and 1 insertion; transforming hello into algo requires 3 steps, including 2 replacements and 1 deletion.

    Figure 14-27 \u00a0 Example data of edit distance

    The edit distance problem can naturally be explained with a decision tree model. Strings correspond to tree nodes, and a round of decision (an edit operation) corresponds to an edge of the tree.

    As shown in the Figure 14-28 , with unrestricted operations, each node can derive many edges, each corresponding to one operation, meaning there are many possible paths to transform hello into algo.

    From the perspective of the decision tree, the goal of this problem is to find the shortest path between the node hello and the node algo.

    Figure 14-28 \u00a0 Edit distance problem represented based on decision tree model

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#1-dynamic-programming-approach","title":"1. \u00a0 Dynamic programming approach","text":"

    Step one: Think about each round of decision, define the state, thus obtaining the \\(dp\\) table

    Each round of decision involves performing one edit operation on string \\(s\\).

    We aim to gradually reduce the problem size during the edit process, which enables us to construct subproblems. Let the lengths of strings \\(s\\) and \\(t\\) be \\(n\\) and \\(m\\), respectively. We first consider the tail characters of both strings \\(s[n-1]\\) and \\(t[m-1]\\).

    • If \\(s[n-1]\\) and \\(t[m-1]\\) are the same, we can skip them and directly consider \\(s[n-2]\\) and \\(t[m-2]\\).
    • If \\(s[n-1]\\) and \\(t[m-1]\\) are different, we need to perform one edit on \\(s\\) (insert, delete, replace) so that the tail characters of the two strings match, allowing us to skip them and consider a smaller-scale problem.

    Thus, each round of decision (edit operation) in string \\(s\\) changes the remaining characters in \\(s\\) and \\(t\\) to be matched. Therefore, the state is the \\(i\\)-th and \\(j\\)-th characters currently considered in \\(s\\) and \\(t\\), denoted as \\([i, j]\\).

    State \\([i, j]\\) corresponds to the subproblem: The minimum number of edits required to change the first \\(i\\) characters of \\(s\\) into the first \\(j\\) characters of \\(t\\).

    From this, we obtain a two-dimensional \\(dp\\) table of size \\((i+1) \\times (j+1)\\).

    Step two: Identify the optimal substructure and then derive the state transition equation

    Consider the subproblem \\(dp[i, j]\\), whose corresponding tail characters of the two strings are \\(s[i-1]\\) and \\(t[j-1]\\), which can be divided into three scenarios as shown below.

    1. Add \\(t[j-1]\\) after \\(s[i-1]\\), then the remaining subproblem is \\(dp[i, j-1]\\).
    2. Delete \\(s[i-1]\\), then the remaining subproblem is \\(dp[i-1, j]\\).
    3. Replace \\(s[i-1]\\) with \\(t[j-1]\\), then the remaining subproblem is \\(dp[i-1, j-1]\\).

    Figure 14-29 \u00a0 State transition of edit distance

    Based on the analysis above, we can determine the optimal substructure: The minimum number of edits for \\(dp[i, j]\\) is the minimum among \\(dp[i, j-1]\\), \\(dp[i-1, j]\\), and \\(dp[i-1, j-1]\\), plus the edit step \\(1\\). The corresponding state transition equation is:

    \\[ dp[i, j] = \\min(dp[i, j-1], dp[i-1, j], dp[i-1, j-1]) + 1 \\]

    Please note, when \\(s[i-1]\\) and \\(t[j-1]\\) are the same, no edit is required for the current character, in which case the state transition equation is:

    \\[ dp[i, j] = dp[i-1, j-1] \\]

    Step three: Determine the boundary conditions and the order of state transitions

    When both strings are empty, the number of edits is \\(0\\), i.e., \\(dp[0, 0] = 0\\). When \\(s\\) is empty but \\(t\\) is not, the minimum number of edits equals the length of \\(t\\), that is, the first row \\(dp[0, j] = j\\). When \\(s\\) is not empty but \\(t\\) is, the minimum number of edits equals the length of \\(s\\), that is, the first column \\(dp[i, 0] = i\\).

    Observing the state transition equation, solving \\(dp[i, j]\\) depends on the solutions to the left, above, and upper left, so a double loop can be used to traverse the entire \\(dp\\) table in the correct order.

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#2-code-implementation","title":"2. \u00a0 Code implementation","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig edit_distance.py
    def edit_distance_dp(s: str, t: str) -> int:\n    \"\"\"\u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(s), len(t)\n    dp = [[0] * (m + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in range(1, n + 1):\n        dp[i][0] = i\n    for j in range(1, m + 1):\n        dp[0][j] = j\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n + 1):\n        for j in range(1, m + 1):\n            if s[i - 1] == t[j - 1]:\n                # \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            else:\n                # \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1\n    return dp[n][m]\n
    edit_distance.cpp
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(string s, string t) {\n    int n = s.length(), m = t.length();\n    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.java
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(String s, String t) {\n    int n = s.length(), m = t.length();\n    int[][] dp = new int[n + 1][m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) == t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.cs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint EditDistanceDP(string s, string t) {\n    int n = s.Length, m = t.Length;\n    int[,] dp = new int[n + 1, m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i, 0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0, j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i, j] = dp[i - 1, j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i, j] = Math.Min(Math.Min(dp[i, j - 1], dp[i - 1, j]), dp[i - 1, j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n, m];\n}\n
    edit_distance.go
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDP(s string, t string) int {\n    n := len(s)\n    m := len(t)\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, m+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i := 1; i <= n; i++ {\n        dp[i][0] = i\n    }\n    for j := 1; j <= m; j++ {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= m; j++ {\n            if s[i-1] == t[j-1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i-1][j-1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = MinInt(MinInt(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.swift
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDP(s: String, t: String) -> Int {\n    let n = s.utf8CString.count\n    let m = t.utf8CString.count\n    var dp = Array(repeating: Array(repeating: 0, count: m + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in 1 ... n {\n        dp[i][0] = i\n    }\n    for j in 1 ... m {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ... n {\n        for j in 1 ... m {\n            if s.utf8CString[i - 1] == t.utf8CString[j - 1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.js
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDP(s, t) {\n    const n = s.length,\n        m = t.length;\n    const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (let j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.ts
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDP(s: string, t: string): number {\n    const n = s.length,\n        m = t.length;\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: m + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (let j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.dart
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(String s, String t) {\n  int n = s.length, m = t.length;\n  List<List<int>> dp = List.generate(n + 1, (_) => List.filled(m + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n  for (int i = 1; i <= n; i++) {\n    dp[i][0] = i;\n  }\n  for (int j = 1; j <= m; j++) {\n    dp[0][j] = j;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i <= n; i++) {\n    for (int j = 1; j <= m; j++) {\n      if (s[i - 1] == t[j - 1]) {\n        // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n        dp[i][j] = dp[i - 1][j - 1];\n      } else {\n        // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n        dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n      }\n    }\n  }\n  return dp[n][m];\n}\n
    edit_distance.rs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfn edit_distance_dp(s: &str, t: &str) -> i32 {\n    let (n, m) = (s.len(), t.len());\n    let mut dp = vec![vec![0; m + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in 1..=n {\n        dp[i][0] = i as i32;\n    }\n    for j in 1..m {\n        dp[0][j] = j as i32;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..=n {\n        for j in 1..=m {\n            if s.chars().nth(i - 1) == t.chars().nth(j - 1) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    std::cmp::min(std::cmp::min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    dp[n][m]\n}\n
    edit_distance.c
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(char *s, char *t, int n, int m) {\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(m + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = myMin(myMin(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    int res = dp[n][m];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    edit_distance.kt
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfun editDistanceDP(s: String, t: String): Int {\n    val n = s.length\n    val m = t.length\n    val dp = Array(n + 1) { IntArray(m + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (i in 1..n) {\n        dp[i][0] = i\n    }\n    for (j in 1..m) {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..n) {\n        for (j in 1..m) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.rb
    [class]{}-[func]{edit_distance_dp}\n
    edit_distance.zig
    // \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212\nfn editDistanceDP(comptime s: []const u8, comptime t: []const u8) i32 {\n    comptime var n = s.len;\n    comptime var m = t.len;\n    var dp = [_][m + 1]i32{[_]i32{0} ** (m + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (1..n + 1) |i| {\n        dp[i][0] = @intCast(i);\n    }\n    for (1..m + 1) |j| {\n        dp[0][j] = @intCast(j);\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n + 1) |i| {\n        for (1..m + 1) |j| {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = @min(@min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    Code Visualization

    Full Screen >

    As shown below, the process of state transition in the edit distance problem is very similar to that in the knapsack problem, which can be seen as filling a two-dimensional grid.

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>

    Figure 14-30 \u00a0 Dynamic programming process of edit distance

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#3-space-optimization","title":"3. \u00a0 Space optimization","text":"

    Since \\(dp[i, j]\\) is derived from the solutions above \\(dp[i-1, j]\\), to the left \\(dp[i, j-1]\\), and to the upper left \\(dp[i-1, j-1]\\), and direct traversal will lose the upper left solution \\(dp[i-1, j-1]\\), and reverse traversal cannot build \\(dp[i, j-1]\\) in advance, therefore, both traversal orders are not feasible.

    For this reason, we can use a variable leftup to temporarily store the solution from the upper left \\(dp[i-1, j-1]\\), thus only needing to consider the solutions to the left and above. This situation is similar to the unbounded knapsack problem, allowing for direct traversal. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig edit_distance.py
    def edit_distance_dp_comp(s: str, t: str) -> int:\n    \"\"\"\u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(s), len(t)\n    dp = [0] * (m + 1)\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in range(1, m + 1):\n        dp[j] = j\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in range(1, n + 1):\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        leftup = dp[0]  # \u6682\u5b58 dp[i-1, j-1]\n        dp[0] += 1\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in range(1, m + 1):\n            temp = dp[j]\n            if s[i - 1] == t[j - 1]:\n                # \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            else:\n                # \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(dp[j - 1], dp[j], leftup) + 1\n            leftup = temp  # \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n    return dp[m]\n
    edit_distance.cpp
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(string s, string t) {\n    int n = s.length(), m = t.length();\n    vector<int> dp(m + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.java
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(String s, String t) {\n    int n = s.length(), m = t.length();\n    int[] dp = new int[m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s.charAt(i - 1) == t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(Math.min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.cs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint EditDistanceDPComp(string s, string t) {\n    int n = s.Length, m = t.Length;\n    int[] dp = new int[m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.Min(Math.Min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.go
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDPComp(s string, t string) int {\n    n := len(s)\n    m := len(t)\n    dp := make([]int, m+1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j := 1; j <= m; j++ {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i := 1; i <= n; i++ {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        leftUp := dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j := 1; j <= m; j++ {\n            temp := dp[j]\n            if s[i-1] == t[j-1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftUp\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = MinInt(MinInt(dp[j-1], dp[j]), leftUp) + 1\n            }\n            leftUp = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.swift
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDPComp(s: String, t: String) -> Int {\n    let n = s.utf8CString.count\n    let m = t.utf8CString.count\n    var dp = Array(repeating: 0, count: m + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1 ... m {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1 ... n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1 ... m {\n            let temp = dp[j]\n            if s.utf8CString[i - 1] == t.utf8CString[j - 1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1\n            }\n            leftup = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.js
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDPComp(s, t) {\n    const n = s.length,\n        m = t.length;\n    const dp = new Array(m + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j <= m; j++) {\n            const temp = dp[j];\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(dp[j - 1], dp[j], leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.ts
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDPComp(s: string, t: string): number {\n    const n = s.length,\n        m = t.length;\n    const dp = new Array(m + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j <= m; j++) {\n            const temp = dp[j];\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(dp[j - 1], dp[j], leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.dart
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(String s, String t) {\n  int n = s.length, m = t.length;\n  List<int> dp = List.filled(m + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n  for (int j = 1; j <= m; j++) {\n    dp[j] = j;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n  for (int i = 1; i <= n; i++) {\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n    dp[0] = i;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n    for (int j = 1; j <= m; j++) {\n      int temp = dp[j];\n      if (s[i - 1] == t[j - 1]) {\n        // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n        dp[j] = leftup;\n      } else {\n        // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n        dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1;\n      }\n      leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n    }\n  }\n  return dp[m];\n}\n
    edit_distance.rs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn edit_distance_dp_comp(s: &str, t: &str) -> i32 {\n    let (n, m) = (s.len(), t.len());\n    let mut dp = vec![0; m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1..m {\n        dp[j] = j as i32;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1..=n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let mut leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i as i32;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1..=m {\n            let temp = dp[j];\n            if s.chars().nth(i - 1) == t.chars().nth(j - 1) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = std::cmp::min(std::cmp::min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    dp[m]\n}\n
    edit_distance.c
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(char *s, char *t, int n, int m) {\n    int *dp = calloc(m + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = myMin(myMin(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    int res = dp[m];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    edit_distance.kt
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun editDistanceDPComp(s: String, t: String): Int {\n    val n = s.length\n    val m = t.length\n    val dp = IntArray(m + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (j in 1..m) {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (i in 1..n) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (j in 1..m) {\n            val temp = dp[j]\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1\n            }\n            leftup = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.rb
    [class]{}-[func]{edit_distance_dp_comp}\n
    edit_distance.zig
    // \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn editDistanceDPComp(comptime s: []const u8, comptime t: []const u8) i32 {\n    comptime var n = s.len;\n    comptime var m = t.len;\n    var dp = [_]i32{0} ** (m + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (1..m + 1) |j| {\n        dp[j] = @intCast(j);\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (1..n + 1) |i| {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = @intCast(i);\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (1..m + 1) |j| {\n            var temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = @min(@min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/","title":"14.1 \u00a0 Introduction to dynamic programming","text":"

    Dynamic programming is an important algorithmic paradigm that decomposes a problem into a series of smaller subproblems, and stores the solutions of these subproblems to avoid redundant computations, thereby significantly improving time efficiency.

    In this section, we start with a classic problem, first presenting its brute force backtracking solution, observing the overlapping subproblems contained within, and then gradually deriving a more efficient dynamic programming solution.

    Climbing stairs

    Given a staircase with \\(n\\) steps, where you can climb \\(1\\) or \\(2\\) steps at a time, how many different ways are there to reach the top?

    As shown in the Figure 14-1 , there are \\(3\\) ways to reach the top of a \\(3\\)-step staircase.

    Figure 14-1 \u00a0 Number of ways to reach the 3rd step

    The goal of this problem is to determine the number of ways, considering using backtracking to exhaust all possibilities. Specifically, imagine climbing stairs as a multi-round choice process: starting from the ground, choosing to go up \\(1\\) or \\(2\\) steps each round, adding one to the count of ways upon reaching the top of the stairs, and pruning the process when exceeding the top. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_backtrack.py
    def backtrack(choices: list[int], state: int, n: int, res: list[int]) -> int:\n    \"\"\"\u56de\u6eaf\"\"\"\n    # \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n:\n        res[0] += 1\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res)\n        # \u56de\u9000\n\ndef climbing_stairs_backtrack(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u56de\u6eaf\"\"\"\n    choices = [1, 2]  # \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    state = 0  # \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    res = [0]  # \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res)\n    return res[0]\n
    climbing_stairs_backtrack.cpp
    /* \u56de\u6eaf */\nvoid backtrack(vector<int> &choices, int state, int n, vector<int> &res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (auto &choice : choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    vector<int> choices = {1, 2}; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0;                // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    vector<int> res = {0};        // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res[0];\n}\n
    climbing_stairs_backtrack.java
    /* \u56de\u6eaf */\nvoid backtrack(List<Integer> choices, int state, int n, List<Integer> res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Integer choice : choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    List<Integer> choices = Arrays.asList(1, 2); // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    List<Integer> res = new ArrayList<>();\n    res.add(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.cs
    /* \u56de\u6eaf */\nvoid Backtrack(List<int> choices, int state, int n, List<int> res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (int choice in choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        Backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint ClimbingStairsBacktrack(int n) {\n    List<int> choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    List<int> res = [0]; // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    Backtrack(choices, state, n, res);\n    return res[0];\n}\n
    climbing_stairs_backtrack.go
    /* \u56de\u6eaf */\nfunc backtrack(choices []int, state, n int, res []int) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] = res[0] + 1\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state+choice > n {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state+choice, n, res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunc climbingStairsBacktrack(n int) int {\n    // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    choices := []int{1, 2}\n    // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    state := 0\n    res := make([]int, 1)\n    // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    res[0] = 0\n    backtrack(choices, state, n, res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.swift
    /* \u56de\u6eaf */\nfunc backtrack(choices: [Int], state: Int, n: Int, res: inout [Int]) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] += 1\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices: choices, state: state + choice, n: n, res: &res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunc climbingStairsBacktrack(n: Int) -> Int {\n    let choices = [1, 2] // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    let state = 0 // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    var res: [Int] = []\n    res.append(0) // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices: choices, state: state, n: n, res: &res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.js
    /* \u56de\u6eaf */\nfunction backtrack(choices, state, n, res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state === n) res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunction climbingStairsBacktrack(n) {\n    const choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    const state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    const res = new Map();\n    res.set(0, 0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.ts
    /* \u56de\u6eaf */\nfunction backtrack(\n    choices: number[],\n    state: number,\n    n: number,\n    res: Map<0, any>\n): void {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state === n) res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunction climbingStairsBacktrack(n: number): number {\n    const choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    const state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    const res = new Map();\n    res.set(0, 0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.dart
    /* \u56de\u6eaf */\nvoid backtrack(List<int> choices, int state, int n, List<int> res) {\n  // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n  if (state == n) {\n    res[0]++;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int choice in choices) {\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n    if (state + choice > n) continue;\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n    backtrack(choices, state + choice, n, res);\n    // \u56de\u9000\n  }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n  List<int> choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n  int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n  List<int> res = [];\n  res.add(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n  backtrack(choices, state, n, res);\n  return res[0];\n}\n
    climbing_stairs_backtrack.rs
    /* \u56de\u6eaf */\nfn backtrack(choices: &[i32], state: i32, n: i32, res: &mut [i32]) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] = res[0] + 1;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for &choice in choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfn climbing_stairs_backtrack(n: usize) -> i32 {\n    let choices = vec![1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    let state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    let mut res = Vec::new();\n    res.push(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(&choices, state, n as i32, &mut res);\n    res[0]\n}\n
    climbing_stairs_backtrack.c
    /* \u56de\u6eaf */\nvoid backtrack(int *choices, int state, int n, int *res, int len) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < len; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res, len);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    int choices[2] = {1, 2}; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0;           // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    int *res = (int *)malloc(sizeof(int));\n    *res = 0; // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    int len = sizeof(choices) / sizeof(int);\n    backtrack(choices, state, n, res, len);\n    int result = *res;\n    free(res);\n    return result;\n}\n
    climbing_stairs_backtrack.kt
    /* \u56de\u6eaf */\nfun backtrack(\n    choices: MutableList<Int>,\n    state: Int,\n    n: Int,\n    res: MutableList<Int>\n) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0] = res[0] + 1\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfun climbingStairsBacktrack(n: Int): Int {\n    val choices = mutableListOf(1, 2) // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    val state = 0 // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    val res = mutableListOf<Int>()\n    res.add(0) // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{climbing_stairs_backtrack}\n
    climbing_stairs_backtrack.zig
    // \u56de\u6eaf\nfn backtrack(choices: []i32, state: i32, n: i32, res: std.ArrayList(i32)) void {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n) {\n        res.items[0] = res.items[0] + 1;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choices) |choice| {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n// \u722c\u697c\u68af\uff1a\u56de\u6eaf\nfn climbingStairsBacktrack(n: usize) !i32 {\n    var choices = [_]i32{ 1, 2 }; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    var state: i32 = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    var res = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer res.deinit();\n    try res.append(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(&choices, state, @intCast(n), res);\n    return res.items[0];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1411-method-1-brute-force-search","title":"14.1.1 \u00a0 Method 1: Brute force search","text":"

    Backtracking algorithms do not explicitly decompose the problem but treat solving the problem as a series of decision steps, searching for all possible solutions through exploration and pruning.

    We can try to analyze this problem from the perspective of decomposition. Let \\(dp[i]\\) be the number of ways to reach the \\(i^{th}\\) step, then \\(dp[i]\\) is the original problem, and its subproblems include:

    \\[ dp[i-1], dp[i-2], \\dots, dp[2], dp[1] \\]

    Since each round can only advance \\(1\\) or \\(2\\) steps, when we stand on the \\(i^{th}\\) step, the previous round must have been either on the \\(i-1^{th}\\) or the \\(i-2^{th}\\) step. In other words, we can only step from the \\(i-1^{th}\\) or the \\(i-2^{th}\\) step to the \\(i^{th}\\) step.

    This leads to an important conclusion: the number of ways to reach the \\(i-1^{th}\\) step plus the number of ways to reach the \\(i-2^{th}\\) step equals the number of ways to reach the \\(i^{th}\\) step. The formula is as follows:

    \\[ dp[i] = dp[i-1] + dp[i-2] \\]

    This means that in the stair climbing problem, there is a recursive relationship between the subproblems, the solution to the original problem can be constructed from the solutions to the subproblems. The following image shows this recursive relationship.

    Figure 14-2 \u00a0 Recursive relationship of solution counts

    We can obtain the brute force search solution according to the recursive formula. Starting with \\(dp[n]\\), recursively decompose a larger problem into the sum of two smaller problems, until reaching the smallest subproblems \\(dp[1]\\) and \\(dp[2]\\) where the solutions are known, with \\(dp[1] = 1\\) and \\(dp[2] = 2\\), representing \\(1\\) and \\(2\\) ways to climb to the first and second steps, respectively.

    Observe the following code, which, like standard backtracking code, belongs to depth-first search but is more concise:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dfs.py
    def dfs(i: int) -> int:\n    \"\"\"\u641c\u7d22\"\"\"\n    # \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 or i == 2:\n        return i\n    # dp[i] = dp[i-1] + dp[i-2]\n    count = dfs(i - 1) + dfs(i - 2)\n    return count\n\ndef climbing_stairs_dfs(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u641c\u7d22\"\"\"\n    return dfs(n)\n
    climbing_stairs_dfs.cpp
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.java
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.cs
    /* \u641c\u7d22 */\nint DFS(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = DFS(i - 1) + DFS(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint ClimbingStairsDFS(int n) {\n    return DFS(n);\n}\n
    climbing_stairs_dfs.go
    /* \u641c\u7d22 */\nfunc dfs(i int) int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    count := dfs(i-1) + dfs(i-2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunc climbingStairsDFS(n int) int {\n    return dfs(n)\n}\n
    climbing_stairs_dfs.swift
    /* \u641c\u7d22 */\nfunc dfs(i: Int) -> Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i: i - 1) + dfs(i: i - 2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunc climbingStairsDFS(n: Int) -> Int {\n    dfs(i: n)\n}\n
    climbing_stairs_dfs.js
    /* \u641c\u7d22 */\nfunction dfs(i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunction climbingStairsDFS(n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.ts
    /* \u641c\u7d22 */\nfunction dfs(i: number): number {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunction climbingStairsDFS(n: number): number {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.dart
    /* \u641c\u7d22 */\nint dfs(int i) {\n  // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n  if (i == 1 || i == 2) return i;\n  // dp[i] = dp[i-1] + dp[i-2]\n  int count = dfs(i - 1) + dfs(i - 2);\n  return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n  return dfs(n);\n}\n
    climbing_stairs_dfs.rs
    /* \u641c\u7d22 */\nfn dfs(i: usize) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i as i32;\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i - 1) + dfs(i - 2);\n    count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfn climbing_stairs_dfs(n: usize) -> i32 {\n    dfs(n)\n}\n
    climbing_stairs_dfs.c
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.kt
    /* \u641c\u7d22 */\nfun dfs(i: Int): Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2) return i\n    // dp[i] = dp[i-1] + dp[i-2]\n    val count = dfs(i - 1) + dfs(i - 2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfun climbingStairsDFS(n: Int): Int {\n    return dfs(n)\n}\n
    climbing_stairs_dfs.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{climbing_stairs_dfs}\n
    climbing_stairs_dfs.zig
    // \u641c\u7d22\nfn dfs(i: usize) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 or i == 2) {\n        return @intCast(i);\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    var count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n// \u722c\u697c\u68af\uff1a\u641c\u7d22\nfn climbingStairsDFS(comptime n: usize) i32 {\n    return dfs(n);\n}\n
    Code Visualization

    Full Screen >

    The following image shows the recursive tree formed by brute force search. For the problem \\(dp[n]\\), the depth of its recursive tree is \\(n\\), with a time complexity of \\(O(2^n)\\). Exponential order represents explosive growth, and entering a long wait if a relatively large \\(n\\) is input.

    Figure 14-3 \u00a0 Recursive tree for climbing stairs

    Observing the above image, the exponential time complexity is caused by 'overlapping subproblems'. For example, \\(dp[9]\\) is decomposed into \\(dp[8]\\) and \\(dp[7]\\), \\(dp[8]\\) into \\(dp[7]\\) and \\(dp[6]\\), both containing the subproblem \\(dp[7]\\).

    Thus, subproblems include even smaller overlapping subproblems, endlessly. A vast majority of computational resources are wasted on these overlapping subproblems.

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1412-method-2-memoized-search","title":"14.1.2 \u00a0 Method 2: Memoized search","text":"

    To enhance algorithm efficiency, we hope that all overlapping subproblems are calculated only once. For this purpose, we declare an array mem to record the solution of each subproblem, and prune overlapping subproblems during the search process.

    1. When \\(dp[i]\\) is calculated for the first time, we record it in mem[i] for later use.
    2. When \\(dp[i]\\) needs to be calculated again, we can directly retrieve the result from mem[i], thus avoiding redundant calculations of that subproblem.

    The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dfs_mem.py
    def dfs(i: int, mem: list[int]) -> int:\n    \"\"\"\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 or i == 2:\n        return i\n    # \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1:\n        return mem[i]\n    # dp[i] = dp[i-1] + dp[i-2]\n    count = dfs(i - 1, mem) + dfs(i - 2, mem)\n    # \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n\ndef climbing_stairs_dfs_mem(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    mem = [-1] * (n + 1)\n    return dfs(n, mem)\n
    climbing_stairs_dfs_mem.cpp
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, vector<int> &mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    vector<int> mem(n + 1, -1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.java
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, int[] mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int[] mem = new int[n + 1];\n    Arrays.fill(mem, -1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.cs
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint DFS(int i, int[] mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = DFS(i - 1, mem) + DFS(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint ClimbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int[] mem = new int[n + 1];\n    Array.Fill(mem, -1);\n    return DFS(n, mem);\n}\n
    climbing_stairs_dfs_mem.go
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc dfsMem(i int, mem []int) int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i]\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    count := dfsMem(i-1, mem) + dfsMem(i-2, mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc climbingStairsDFSMem(n int) int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    mem := make([]int, n+1)\n    for i := range mem {\n        mem[i] = -1\n    }\n    return dfsMem(n, mem)\n}\n
    climbing_stairs_dfs_mem.swift
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc dfs(i: Int, mem: inout [Int]) -> Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i]\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i: i - 1, mem: &mem) + dfs(i: i - 2, mem: &mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc climbingStairsDFSMem(n: Int) -> Int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    var mem = Array(repeating: -1, count: n + 1)\n    return dfs(i: n, mem: &mem)\n}\n
    climbing_stairs_dfs_mem.js
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction dfs(i, mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction climbingStairsDFSMem(n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    const mem = new Array(n + 1).fill(-1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.ts
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction dfs(i: number, mem: number[]): number {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction climbingStairsDFSMem(n: number): number {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    const mem = new Array(n + 1).fill(-1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.dart
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, List<int> mem) {\n  // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n  if (i == 1 || i == 2) return i;\n  // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n  if (mem[i] != -1) return mem[i];\n  // dp[i] = dp[i-1] + dp[i-2]\n  int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n  // \u8bb0\u5f55 dp[i]\n  mem[i] = count;\n  return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n  // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n  List<int> mem = List.filled(n + 1, -1);\n  return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.rs
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn dfs(i: usize, mem: &mut [i32]) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i as i32;\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i];\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn climbing_stairs_dfs_mem(n: usize) -> i32 {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    let mut mem = vec![-1; n + 1];\n    dfs(n, &mut mem)\n}\n
    climbing_stairs_dfs_mem.c
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, int *mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int *mem = (int *)malloc((n + 1) * sizeof(int));\n    for (int i = 0; i <= n; i++) {\n        mem[i] = -1;\n    }\n    int result = dfs(n, mem);\n    free(mem);\n    return result;\n}\n
    climbing_stairs_dfs_mem.kt
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun dfs(i: Int, mem: IntArray): Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2) return i\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i]\n    // dp[i] = dp[i-1] + dp[i-2]\n    val count = dfs(i - 1, mem) + dfs(i - 2, mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun climbingStairsDFSMem(n: Int): Int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    val mem = IntArray(n + 1)\n    mem.fill(-1)\n    return dfs(n, mem)\n}\n
    climbing_stairs_dfs_mem.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{climbing_stairs_dfs_mem}\n
    climbing_stairs_dfs_mem.zig
    // \u8bb0\u5fc6\u5316\u641c\u7d22\nfn dfs(i: usize, mem: []i32) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 or i == 2) {\n        return @intCast(i);\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) {\n        return mem[i];\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    var count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n// \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn climbingStairsDFSMem(comptime n: usize) i32 {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    var mem = [_]i32{ -1 } ** (n + 1);\n    return dfs(n, &mem);\n}\n
    Code Visualization

    Full Screen >

    Observe the following image, after memoization, all overlapping subproblems need to be calculated only once, optimizing the time complexity to \\(O(n)\\), which is a significant leap.

    Figure 14-4 \u00a0 Recursive tree with memoized search

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1413-method-3-dynamic-programming","title":"14.1.3 \u00a0 Method 3: Dynamic programming","text":"

    Memoized search is a 'top-down' method: we start with the original problem (root node), recursively decompose larger subproblems into smaller ones until the solutions to the smallest known subproblems (leaf nodes) are reached. Subsequently, by backtracking, we collect the solutions of the subproblems, constructing the solution to the original problem.

    On the contrary, dynamic programming is a 'bottom-up' method: starting with the solutions to the smallest subproblems, iteratively construct the solutions to larger subproblems until the original problem is solved.

    Since dynamic programming does not include a backtracking process, it only requires looping iteration to implement, without needing recursion. In the following code, we initialize an array dp to store the solutions to the subproblems, serving the same recording function as the array mem in memoized search:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dp.py
    def climbing_stairs_dp(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return n\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [0] * (n + 1)\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1], dp[2] = 1, 2\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i] = dp[i - 1] + dp[i - 2]\n    return dp[n]\n
    climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<int> dp(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.java
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.go
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDP(n int) int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i] = dp[i-1] + dp[i-2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDP(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: 0, count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i] = dp[i - 1] + dp[i - 2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.js
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDP(n) {\n    if (n === 1 || n === 2) return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1).fill(-1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDP(n: number): number {\n    if (n === 1 || n === 2) return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1).fill(-1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n  if (n == 1 || n == 2) return n;\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<int> dp = List.filled(n + 1, 0);\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1] = 1;\n  dp[2] = 2;\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i] = dp[i - 1] + dp[i - 2];\n  }\n  return dp[n];\n}\n
    climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_dp(n: usize) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if n == 1 || n == 2 {\n        return n as i32;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![-1; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    dp[n]\n}\n
    climbing_stairs_dp.c
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int *dp = (int *)malloc((n + 1) * sizeof(int));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    int result = dp[n];\n    free(dp);\n    return result;\n}\n
    climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsDP(n: Int): Int {\n    if (n == 1 || n == 2) return n\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = IntArray(n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i] = dp[i - 1] + dp[i - 2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.rb
    [class]{}-[func]{climbing_stairs_dp}\n
    climbing_stairs_dp.zig
    // \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\nfn climbingStairsDP(comptime n: usize) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (n == 1 or n == 2) {\n        return @intCast(n);\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_]i32{-1} ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    Code Visualization

    Full Screen >

    The image below simulates the execution process of the above code.

    Figure 14-5 \u00a0 Dynamic programming process for climbing stairs

    Like the backtracking algorithm, dynamic programming also uses the concept of \"states\" to represent specific stages in problem solving, each state corresponding to a subproblem and its local optimal solution. For example, the state of the climbing stairs problem is defined as the current step number \\(i\\).

    Based on the above content, we can summarize the commonly used terminology in dynamic programming.

    • The array dp is referred to as the DP table, with \\(dp[i]\\) representing the solution to the subproblem corresponding to state \\(i\\).
    • The states corresponding to the smallest subproblems (steps \\(1\\) and \\(2\\)) are called initial states.
    • The recursive formula \\(dp[i] = dp[i-1] + dp[i-2]\\) is called the state transition equation.
    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1414-space-optimization","title":"14.1.4 \u00a0 Space optimization","text":"

    Observant readers may have noticed that since \\(dp[i]\\) is only related to \\(dp[i-1]\\) and \\(dp[i-2]\\), we do not need to use an array dp to store the solutions to all subproblems, but can simply use two variables to progress iteratively. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dp.py
    def climbing_stairs_dp_comp(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return n\n    a, b = 1, 2\n    for _ in range(3, n + 1):\n        a, b = b, a + b\n    return b\n
    climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.java
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.go
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDPComp(n int) int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    a, b := 1, 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        a, b = b, a+b\n    }\n    return b\n}\n
    climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDPComp(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    var a = 1\n    var b = 2\n    for _ in 3 ... n {\n        (a, b) = (b, a + b)\n    }\n    return b\n}\n
    climbing_stairs_dp.js
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDPComp(n) {\n    if (n === 1 || n === 2) return n;\n    let a = 1,\n        b = 2;\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDPComp(n: number): number {\n    if (n === 1 || n === 2) return n;\n    let a = 1,\n        b = 2;\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n  if (n == 1 || n == 2) return n;\n  int a = 1, b = 2;\n  for (int i = 3; i <= n; i++) {\n    int tmp = b;\n    b = a + b;\n    a = tmp;\n  }\n  return b;\n}\n
    climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_dp_comp(n: usize) -> i32 {\n    if n == 1 || n == 2 {\n        return n as i32;\n    }\n    let (mut a, mut b) = (1, 2);\n    for _ in 3..=n {\n        let tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    b\n}\n
    climbing_stairs_dp.c
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsDPComp(n: Int): Int {\n    if (n == 1 || n == 2) return n\n    var a = 1\n    var b = 2\n    for (i in 3..n) {\n        val temp = b\n        b += a\n        a = temp\n    }\n    return b\n}\n
    climbing_stairs_dp.rb
    [class]{}-[func]{climbing_stairs_dp_comp}\n
    climbing_stairs_dp.zig
    // \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn climbingStairsDPComp(comptime n: usize) i32 {\n    if (n == 1 or n == 2) {\n        return @intCast(n);\n    }\n    var a: i32 = 1;\n    var b: i32 = 2;\n    for (3..n + 1) |_| {\n        var tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    Code Visualization

    Full Screen >

    Observing the above code, since the space occupied by the array dp is eliminated, the space complexity is reduced from \\(O(n)\\) to \\(O(1)\\).

    In dynamic programming problems, the current state is often only related to a limited number of previous states, allowing us to retain only the necessary states and save memory space by \"dimension reduction\". This space optimization technique is known as 'rolling variable' or 'rolling array'.

    "},{"location":"chapter_dynamic_programming/knapsack_problem/","title":"14.4 \u00a0 0-1 Knapsack problem","text":"

    The knapsack problem is an excellent introductory problem for dynamic programming and is the most common type of problem in dynamic programming. It has many variants, such as the 0-1 knapsack problem, the unbounded knapsack problem, and the multiple knapsack problem, etc.

    In this section, we will first solve the most common 0-1 knapsack problem.

    Question

    Given \\(n\\) items, the weight of the \\(i\\)-th item is \\(wgt[i-1]\\) and its value is \\(val[i-1]\\), and a knapsack with a capacity of \\(cap\\). Each item can be chosen only once. What is the maximum value of items that can be placed in the knapsack under the capacity limit?

    Observe the following figure, since the item number \\(i\\) starts counting from 1, and the array index starts from 0, thus the weight of item \\(i\\) corresponds to \\(wgt[i-1]\\) and the value corresponds to \\(val[i-1]\\).

    Figure 14-17 \u00a0 Example data of the 0-1 knapsack

    We can consider the 0-1 knapsack problem as a process consisting of \\(n\\) rounds of decisions, where for each item there are two decisions: not to put it in or to put it in, thus the problem fits the decision tree model.

    The objective of this problem is to \"maximize the value of the items that can be put in the knapsack under the limited capacity,\" thus it is more likely a dynamic programming problem.

    First step: Think about each round of decisions, define states, thereby obtaining the \\(dp\\) table

    For each item, if not put into the knapsack, the capacity remains unchanged; if put in, the capacity is reduced. From this, the state definition can be obtained: the current item number \\(i\\) and knapsack capacity \\(c\\), denoted as \\([i, c]\\).

    State \\([i, c]\\) corresponds to the sub-problem: the maximum value of the first \\(i\\) items in a knapsack of capacity \\(c\\), denoted as \\(dp[i, c]\\).

    The solution we are looking for is \\(dp[n, cap]\\), so we need a two-dimensional \\(dp\\) table of size \\((n+1) \\times (cap+1)\\).

    Second step: Identify the optimal substructure, then derive the state transition equation

    After making the decision for item \\(i\\), what remains is the sub-problem of decisions for the first \\(i-1\\) items, which can be divided into two cases.

    • Not putting item \\(i\\): The knapsack capacity remains unchanged, state changes to \\([i-1, c]\\).
    • Putting item \\(i\\): The knapsack capacity decreases by \\(wgt[i-1]\\), and the value increases by \\(val[i-1]\\), state changes to \\([i-1, c-wgt[i-1]]\\).

    The above analysis reveals the optimal substructure of this problem: the maximum value \\(dp[i, c]\\) is equal to the larger value of the two schemes of not putting item \\(i\\) and putting item \\(i\\). From this, the state transition equation can be derived:

    \\[ dp[i, c] = \\max(dp[i-1, c], dp[i-1, c - wgt[i-1]] + val[i-1]) \\]

    It is important to note that if the current item's weight \\(wgt[i - 1]\\) exceeds the remaining knapsack capacity \\(c\\), then the only option is not to put it in the knapsack.

    Third step: Determine the boundary conditions and the order of state transitions

    When there are no items or the knapsack capacity is \\(0\\), the maximum value is \\(0\\), i.e., the first column \\(dp[i, 0]\\) and the first row \\(dp[0, c]\\) are both equal to \\(0\\).

    The current state \\([i, c]\\) transitions from the state directly above \\([i-1, c]\\) and the state to the upper left \\([i-1, c-wgt[i-1]]\\), thus, the entire \\(dp\\) table is traversed in order through two layers of loops.

    Following the above analysis, we will next implement the solutions in the order of brute force search, memoized search, and dynamic programming.

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#1-method-one-brute-force-search","title":"1. \u00a0 Method one: Brute force search","text":"

    The search code includes the following elements.

    • Recursive parameters: State \\([i, c]\\).
    • Return value: Solution to the sub-problem \\(dp[i, c]\\).
    • Termination condition: When the item number is out of bounds \\(i = 0\\) or the remaining capacity of the knapsack is \\(0\\), terminate the recursion and return the value \\(0\\).
    • Pruning: If the current item's weight exceeds the remaining capacity of the knapsack, the only option is not to put it in the knapsack.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dfs(wgt: list[int], val: list[int], i: int, c: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22\"\"\"\n    # \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 or c == 0:\n        return 0\n    # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c:\n        return knapsack_dfs(wgt, val, i - 1, c)\n    # \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no = knapsack_dfs(wgt, val, i - 1, c)\n    yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]\n    # \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(vector<int> &wgt, vector<int> &val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes);\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(int[] wgt, int[] val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint KnapsackDFS(int[] weight, int[] val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (weight[i - 1] > c) {\n        return KnapsackDFS(weight, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = KnapsackDFS(weight, val, i - 1, c);\n    int yes = KnapsackDFS(weight, val, i - 1, c - weight[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.Max(no, yes);\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc knapsackDFS(wgt, val []int, i, c int) int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i-1] > c {\n        return knapsackDFS(wgt, val, i-1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no := knapsackDFS(wgt, val, i-1, c)\n    yes := knapsackDFS(wgt, val, i-1, c-wgt[i-1]) + val[i-1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return int(math.Max(float64(no), float64(yes)))\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc knapsackDFS(wgt: [Int], val: [Int], i: Int, c: Int) -> Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c {\n        return knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c)\n    let yes = knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c - wgt[i - 1]) + val[i - 1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction knapsackDFS(wgt, val, i, c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFS(wgt, val, i - 1, c);\n    const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction knapsackDFS(\n    wgt: Array<number>,\n    val: Array<number>,\n    i: number,\n    c: number\n): number {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFS(wgt, val, i - 1, c);\n    const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(List<int> wgt, List<int> val, int i, int c) {\n  // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n  if (i == 0 || c == 0) {\n    return 0;\n  }\n  // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n  if (wgt[i - 1] > c) {\n    return knapsackDFS(wgt, val, i - 1, c);\n  }\n  // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n  int no = knapsackDFS(wgt, val, i - 1, c);\n  int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n  // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n  return max(no, yes);\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfn knapsack_dfs(wgt: &[i32], val: &[i32], i: usize, c: usize) -> i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c as i32 {\n        return knapsack_dfs(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsack_dfs(wgt, val, i - 1, c);\n    let yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1] as usize) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    std::cmp::max(no, yes)\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(int wgt[], int val[], int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return myMax(no, yes);\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfun knapsackDFS(\n    wgt: IntArray,\n    _val: IntArray,\n    i: Int,\n    c: Int\n): Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, _val, i - 1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    val no = knapsackDFS(wgt, _val, i - 1, c)\n    val yes = knapsackDFS(wgt, _val, i - 1, c - wgt[i - 1]) + _val[i - 1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dfs}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22\nfn knapsackDFS(wgt: []i32, val: []i32, i: usize, c: usize) i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 or c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    var no = knapsackDFS(wgt, val, i - 1, c);\n    var yes = knapsackDFS(wgt, val, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return @max(no, yes);\n}\n
    Code Visualization

    Full Screen >

    As shown in the Figure 14-18 , since each item generates two search branches of not selecting and selecting, the time complexity is \\(O(2^n)\\).

    Observing the recursive tree, it is easy to see that there are overlapping sub-problems, such as \\(dp[1, 10]\\), etc. When there are many items and the knapsack capacity is large, especially when there are many items of the same weight, the number of overlapping sub-problems will increase significantly.

    Figure 14-18 \u00a0 The brute force search recursive tree of the 0-1 knapsack problem

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#2-method-two-memoized-search","title":"2. \u00a0 Method two: Memoized search","text":"

    To ensure that overlapping sub-problems are only calculated once, we use a memoization list mem to record the solutions to sub-problems, where mem[i][c] corresponds to \\(dp[i, c]\\).

    After introducing memoization, the time complexity depends on the number of sub-problems, which is \\(O(n \\times cap)\\). The implementation code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dfs_mem(\n    wgt: list[int], val: list[int], mem: list[list[int]], i: int, c: int\n) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 or c == 0:\n        return 0\n    # \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1:\n        return mem[i][c]\n    # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c:\n        return knapsack_dfs_mem(wgt, val, mem, i - 1, c)\n    # \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no = knapsack_dfs_mem(wgt, val, mem, i - 1, c)\n    yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1]\n    # \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(vector<int> &wgt, vector<int> &val, vector<vector<int>> &mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(int[] wgt, int[] val, int[][] mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint KnapsackDFSMem(int[] weight, int[] val, int[][] mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (weight[i - 1] > c) {\n        return KnapsackDFSMem(weight, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = KnapsackDFSMem(weight, val, mem, i - 1, c);\n    int yes = KnapsackDFSMem(weight, val, mem, i - 1, c - weight[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.Max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc knapsackDFSMem(wgt, val []int, mem [][]int, i, c int) int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i-1] > c {\n        return knapsackDFSMem(wgt, val, mem, i-1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no := knapsackDFSMem(wgt, val, mem, i-1, c)\n    yes := knapsackDFSMem(wgt, val, mem, i-1, c-wgt[i-1]) + val[i-1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = int(math.Max(float64(no), float64(yes)))\n    return mem[i][c]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc knapsackDFSMem(wgt: [Int], val: [Int], mem: inout [[Int]], i: Int, c: Int) -> Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c {\n        return knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c)\n    let yes = knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c - wgt[i - 1]) + val[i - 1]\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction knapsackDFSMem(wgt, val, mem, i, c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] !== -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    const yes =\n        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction knapsackDFSMem(\n    wgt: Array<number>,\n    val: Array<number>,\n    mem: Array<Array<number>>,\n    i: number,\n    c: number\n): number {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] !== -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    const yes =\n        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(\n  List<int> wgt,\n  List<int> val,\n  List<List<int>> mem,\n  int i,\n  int c,\n) {\n  // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n  if (i == 0 || c == 0) {\n    return 0;\n  }\n  // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  if (mem[i][c] != -1) {\n    return mem[i][c];\n  }\n  // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n  if (wgt[i - 1] > c) {\n    return knapsackDFSMem(wgt, val, mem, i - 1, c);\n  }\n  // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n  int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n  int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n  // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n  mem[i][c] = max(no, yes);\n  return mem[i][c];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn knapsack_dfs_mem(wgt: &[i32], val: &[i32], mem: &mut Vec<Vec<i32>>, i: usize, c: usize) -> i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c as i32 {\n        return knapsack_dfs_mem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsack_dfs_mem(wgt, val, mem, i - 1, c);\n    let yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1] as usize) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = std::cmp::max(no, yes);\n    mem[i][c]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(int wgt[], int val[], int memCols, int **mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, memCols, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = myMax(no, yes);\n    return mem[i][c];\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun knapsackDFSMem(\n    wgt: IntArray,\n    _val: IntArray,\n    mem: Array<IntArray>,\n    i: Int,\n    c: Int\n): Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, _val, mem, i - 1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    val no = knapsackDFSMem(wgt, _val, mem, i - 1, c)\n    val yes = knapsackDFSMem(wgt, _val, mem, i - 1, c - wgt[i - 1]) + _val[i - 1]\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dfs_mem}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn knapsackDFSMem(wgt: []i32, val: []i32, mem: anytype, i: usize, c: usize) i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 or c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    var no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    var yes = knapsackDFSMem(wgt, val, mem, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = @max(no, yes);\n    return mem[i][c];\n}\n
    Code Visualization

    Full Screen >

    The following figure shows the search branches that are pruned in memoized search.

    Figure 14-19 \u00a0 The memoized search recursive tree of the 0-1 knapsack problem

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#3-method-three-dynamic-programming","title":"3. \u00a0 Method three: Dynamic programming","text":"

    Dynamic programming essentially involves filling the \\(dp\\) table during the state transition, the code is shown below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (cap + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1])\n    return dp[n][cap]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint KnapsackDP(int[] weight, int[] val, int cap) {\n    int n = weight.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (weight[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i, c] = dp[i - 1, c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i, c] = Math.Max(dp[i - 1, c - weight[i - 1]] + val[i - 1], dp[i - 1, c]);\n            }\n        }\n    }\n    return dp[n, cap];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDP(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, cap+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i-1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = int(math.Max(float64(dp[i-1][c]), float64(dp[i-1][c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDP(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(n + 1)\n        .fill(0)\n        .map(() => Array(cap + 1).fill(0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDP(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(cap + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[i][c] = dp[i - 1][c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[n][cap];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfn knapsack_dp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; cap + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = std::cmp::max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1] as usize] + val[i - 1],\n                );\n            }\n        }\n    }\n    dp[n][cap]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(cap + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = myMax(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[n][cap];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfun knapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(cap + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dp}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\nfn knapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = @max(dp[i - 1][c], dp[i - 1][c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    Code Visualization

    Full Screen >

    As shown in the figures below, both the time complexity and space complexity are determined by the size of the array dp, i.e., \\(O(n \\times cap)\\).

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14>

    Figure 14-20 \u00a0 The dynamic programming process of the 0-1 knapsack problem

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#4-space-optimization","title":"4. \u00a0 Space optimization","text":"

    Since each state is only related to the state in the row above it, we can use two arrays to roll forward, reducing the space complexity from \\(O(n^2)\\) to \\(O(n)\\).

    Further thinking, can we use just one array to achieve space optimization? It can be observed that each state is transferred from the cell directly above or from the upper left cell. If there is only one array, when starting to traverse the \\(i\\)-th row, that array still stores the state of row \\(i-1\\).

    • If using normal order traversal, then when traversing to \\(dp[i, j]\\), the values from the upper left \\(dp[i-1, 1]\\) ~ \\(dp[i-1, j-1]\\) may have already been overwritten, thus the correct state transition result cannot be obtained.
    • If using reverse order traversal, there will be no overwriting problem, and the state transition can be conducted correctly.

    The figures below show the transition process from row \\(i = 1\\) to row \\(i = 2\\) in a single array. Please think about the differences between normal order traversal and reverse order traversal.

    <1><2><3><4><5><6>

    Figure 14-21 \u00a0 The space-optimized dynamic programming process of the 0-1 knapsack

    In the code implementation, we only need to delete the first dimension \\(i\\) of the array dp and change the inner loop to reverse traversal:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (cap + 1)\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u5012\u5e8f\u904d\u5386\n        for c in range(cap, 0, -1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n    return dp[cap]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(cap + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint KnapsackDPComp(int[] weight, int[] val, int cap) {\n    int n = weight.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c > 0; c--) {\n            if (weight[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.Max(dp[c], dp[c - weight[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDPComp(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, cap+1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u5012\u5e8f\u904d\u5386\n        for c := cap; c >= 1; c-- {\n            if wgt[i-1] <= c {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = int(math.Max(float64(dp[c]), float64(dp[c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        // \u5012\u5e8f\u904d\u5386\n        for c in (1 ... cap).reversed() {\n            if wgt[i - 1] <= c {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDPComp(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(cap + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (let c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDPComp(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(cap + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (let c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(cap + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    // \u5012\u5e8f\u904d\u5386\n    for (int c = cap; c >= 1; c--) {\n      if (wgt[i - 1] <= c) {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[cap];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn knapsack_dp_comp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        // \u5012\u5e8f\u904d\u5386\n        for c in (1..=cap).rev() {\n            if wgt[i - 1] <= c as i32 {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = std::cmp::max(dp[c], dp[c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    dp[cap]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(cap + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = myMax(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[cap];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun knapsackDPComp(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        // \u5012\u5e8f\u904d\u5386\n        for (c in cap downTo 1) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dp_comp}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn knapsackDPComp(wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (cap + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        // \u5012\u5e8f\u904d\u5386\n        var c = cap;\n        while (c > 0) : (c -= 1) {\n            if (wgt[i - 1] < c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = @max(dp[c], dp[c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/summary/","title":"14.7 \u00a0 Summary","text":"
    • Dynamic programming decomposes problems and improves computational efficiency by avoiding redundant computations through storing solutions of subproblems.
    • Without considering time, all dynamic programming problems can be solved using backtracking (brute force search), but the recursion tree has many overlapping subproblems, resulting in very low efficiency. By introducing a memorization list, it's possible to store solutions of all computed subproblems, ensuring that overlapping subproblems are only computed once.
    • Memorization search is a top-down recursive solution, whereas dynamic programming corresponds to a bottom-up iterative approach, akin to \"filling out a table.\" Since the current state only depends on certain local states, we can eliminate one dimension of the dp table to reduce space complexity.
    • Decomposition of subproblems is a universal algorithmic approach, differing in characteristics among divide and conquer, dynamic programming, and backtracking.
    • Dynamic programming problems have three main characteristics: overlapping subproblems, optimal substructure, and no aftereffects.
    • If the optimal solution of the original problem can be constructed from the optimal solutions of its subproblems, it has an optimal substructure.
    • No aftereffects mean that the future development of a state depends only on the current state and not on all past states experienced. Many combinatorial optimization problems do not have this property and cannot be quickly solved using dynamic programming.

    Knapsack problem

    • The knapsack problem is one of the most typical dynamic programming problems, with variants including the 0-1 knapsack, unbounded knapsack, and multiple knapsacks.
    • The state definition of the 0-1 knapsack is the maximum value in a knapsack of capacity \\(c\\) with the first \\(i\\) items. Based on decisions not to include or to include an item in the knapsack, optimal substructures can be identified and state transition equations constructed. In space optimization, since each state depends on the state directly above and to the upper left, the list should be traversed in reverse order to avoid overwriting the upper left state.
    • In the unbounded knapsack problem, there is no limit on the number of each kind of item that can be chosen, thus the state transition for including items differs from the 0-1 knapsack. Since the state depends on the state directly above and to the left, space optimization should involve forward traversal.
    • The coin change problem is a variant of the unbounded knapsack problem, shifting from seeking the \u201cmaximum\u201d value to seeking the \u201cminimum\u201d number of coins, thus the state transition equation should change \\(\\max()\\) to \\(\\min()\\). From pursuing \u201cnot exceeding\u201d the capacity of the knapsack to seeking exactly the target amount, thus use \\(amt + 1\\) to represent the invalid solution of \u201cunable to make up the target amount.\u201d
    • Coin Change Problem II shifts from seeking the \u201cminimum number of coins\u201d to seeking the \u201cnumber of coin combinations,\u201d changing the state transition equation accordingly from \\(\\min()\\) to summation operator.

    Edit distance problem

    • Edit distance (Levenshtein distance) measures the similarity between two strings, defined as the minimum number of editing steps needed to change one string into another, with editing operations including adding, deleting, or replacing.
    • The state definition for the edit distance problem is the minimum number of editing steps needed to change the first \\(i\\) characters of \\(s\\) into the first \\(j\\) characters of \\(t\\). When \\(s[i] \\ne t[j]\\), there are three decisions: add, delete, replace, each with their corresponding residual subproblems. From this, optimal substructures can be identified, and state transition equations built. When \\(s[i] = t[j]\\), no editing of the current character is necessary.
    • In edit distance, the state depends on the state directly above, to the left, and to the upper left. Therefore, after space optimization, neither forward nor reverse traversal can correctly perform state transitions. To address this, we use a variable to temporarily store the upper left state, making it equivalent to the situation in the unbounded knapsack problem, allowing for forward traversal after space optimization.
    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/","title":"14.5 \u00a0 Unbounded knapsack problem","text":"

    In this section, we first solve another common knapsack problem: the unbounded knapsack, and then explore a special case of it: the coin change problem.

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1451-unbounded-knapsack-problem","title":"14.5.1 \u00a0 Unbounded knapsack problem","text":"

    Question

    Given \\(n\\) items, where the weight of the \\(i^{th}\\) item is \\(wgt[i-1]\\) and its value is \\(val[i-1]\\), and a backpack with a capacity of \\(cap\\). Each item can be selected multiple times. What is the maximum value of the items that can be put into the backpack without exceeding its capacity? See the example below.

    Figure 14-22 \u00a0 Example data for the unbounded knapsack problem

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1-dynamic-programming-approach","title":"1. \u00a0 Dynamic programming approach","text":"

    The unbounded knapsack problem is very similar to the 0-1 knapsack problem, the only difference being that there is no limit on the number of times an item can be chosen.

    • In the 0-1 knapsack problem, there is only one of each item, so after placing item \\(i\\) into the backpack, you can only choose from the previous \\(i-1\\) items.
    • In the unbounded knapsack problem, the quantity of each item is unlimited, so after placing item \\(i\\) in the backpack, you can still choose from the previous \\(i\\) items.

    Under the rules of the unbounded knapsack problem, the state \\([i, c]\\) can change in two ways.

    • Not putting item \\(i\\) in: As with the 0-1 knapsack problem, transition to \\([i-1, c]\\).
    • Putting item \\(i\\) in: Unlike the 0-1 knapsack problem, transition to \\([i, c-wgt[i-1]]\\).

    The state transition equation thus becomes:

    \\[ dp[i, c] = \\max(dp[i-1, c], dp[i, c - wgt[i-1]] + val[i-1]) \\]"},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2-code-implementation","title":"2. \u00a0 Code implementation","text":"

    Comparing the code for the two problems, the state transition changes from \\(i-1\\) to \\(i\\), the rest is completely identical:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig unbounded_knapsack.py
    def unbounded_knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (cap + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1])\n    return dp[n][cap]\n
    unbounded_knapsack.cpp
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.java
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.cs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint UnboundedKnapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i, c] = dp[i - 1, c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i, c] = Math.Max(dp[i - 1, c], dp[i, c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n, cap];\n}\n
    unbounded_knapsack.go
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDP(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, cap+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i-1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = int(math.Max(float64(dp[i-1][c]), float64(dp[i][c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.swift
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.js
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDP(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.ts
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDP(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.dart
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(cap + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[i][c] = dp[i - 1][c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[n][cap];\n}\n
    unbounded_knapsack.rs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfn unbounded_knapsack_dp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; cap + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = std::cmp::max(dp[i - 1][c], dp[i][c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.c
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(cap + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = myMax(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[n][cap];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    unbounded_knapsack.kt
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfun unboundedKnapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(cap + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.rb
    [class]{}-[func]{unbounded_knapsack_dp}\n
    unbounded_knapsack.zig
    // \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\nfn unboundedKnapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = @max(dp[i - 1][c], dp[i][c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3-space-optimization","title":"3. \u00a0 Space optimization","text":"

    Since the current state comes from the state to the left and above, the space-optimized solution should perform a forward traversal for each row in the \\(dp\\) table.

    This traversal order is the opposite of that for the 0-1 knapsack. Please refer to the following figures to understand the difference.

    <1><2><3><4><5><6>

    Figure 14-23 \u00a0 Dynamic programming process for the unbounded knapsack problem after space optimization

    The code implementation is quite simple, just remove the first dimension of the array dp:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig unbounded_knapsack.py
    def unbounded_knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (cap + 1)\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n    return dp[cap]\n
    unbounded_knapsack.cpp
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(cap + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.java
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.cs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint UnboundedKnapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.Max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.go
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDPComp(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, cap+1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = int(math.Max(float64(dp[c]), float64(dp[c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.swift
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.js
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDPComp(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: cap + 1 }, () => 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.ts
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDPComp(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: cap + 1 }, () => 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.dart
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(cap + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[c] = dp[c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[cap];\n}\n
    unbounded_knapsack.rs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn unbounded_knapsack_dp_comp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = std::cmp::max(dp[c], dp[c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    dp[cap]\n}\n
    unbounded_knapsack.c
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(cap + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = myMax(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[cap];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    unbounded_knapsack.kt
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun unboundedKnapsackDPComp(\n    wgt: IntArray,\n    _val: IntArray,\n    cap: Int\n): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.rb
    [class]{}-[func]{unbounded_knapsack_dp_comp}\n
    unbounded_knapsack.zig
    // \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn unboundedKnapsackDPComp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (cap + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = @max(dp[c], dp[c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1452-coin-change-problem","title":"14.5.2 \u00a0 Coin change problem","text":"

    The knapsack problem is a representative of a large class of dynamic programming problems and has many variants, such as the coin change problem.

    Question

    Given \\(n\\) types of coins, the denomination of the \\(i^{th}\\) type of coin is \\(coins[i - 1]\\), and the target amount is \\(amt\\). Each type of coin can be selected multiple times. What is the minimum number of coins needed to make up the target amount? If it is impossible to make up the target amount, return \\(-1\\). See the example below.

    Figure 14-24 \u00a0 Example data for the coin change problem

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1-dynamic-programming-approach_1","title":"1. \u00a0 Dynamic programming approach","text":"

    The coin change can be seen as a special case of the unbounded knapsack problem, sharing the following similarities and differences.

    • The two problems can be converted into each other: \"item\" corresponds to \"coin\", \"item weight\" corresponds to \"coin denomination\", and \"backpack capacity\" corresponds to \"target amount\".
    • The optimization goals are opposite: the unbounded knapsack problem aims to maximize the value of items, while the coin change problem aims to minimize the number of coins.
    • The unbounded knapsack problem seeks solutions \"not exceeding\" the backpack capacity, while the coin change seeks solutions that \"exactly\" make up the target amount.

    First step: Think through each round's decision-making, define the state, and thus derive the \\(dp\\) table

    The state \\([i, a]\\) corresponds to the sub-problem: the minimum number of coins that can make up the amount \\(a\\) using the first \\(i\\) types of coins, denoted as \\(dp[i, a]\\).

    The two-dimensional \\(dp\\) table is of size \\((n+1) \\times (amt+1)\\).

    Second step: Identify the optimal substructure and derive the state transition equation

    This problem differs from the unbounded knapsack problem in two aspects of the state transition equation.

    • This problem seeks the minimum, so the operator \\(\\max()\\) needs to be changed to \\(\\min()\\).
    • The optimization is focused on the number of coins, so simply add \\(+1\\) when a coin is chosen.
    \\[ dp[i, a] = \\min(dp[i-1, a], dp[i, a - coins[i-1]] + 1) \\]

    Third step: Define boundary conditions and state transition order

    When the target amount is \\(0\\), the minimum number of coins needed to make it up is \\(0\\), so all \\(dp[i, 0]\\) in the first column are \\(0\\).

    When there are no coins, it is impossible to make up any amount >0, which is an invalid solution. To allow the \\(\\min()\\) function in the state transition equation to recognize and filter out invalid solutions, consider using \\(+\\infty\\) to represent them, i.e., set all \\(dp[0, a]\\) in the first row to \\(+\\infty\\).

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2-code-implementation_1","title":"2. \u00a0 Code implementation","text":"

    Most programming languages do not provide a \\(+\\infty\\) variable, only the maximum value of an integer int can be used as a substitute. This can lead to overflow: the \\(+1\\) operation in the state transition equation may overflow.

    For this reason, we use the number \\(amt + 1\\) to represent an invalid solution, because the maximum number of coins needed to make up \\(amt\\) is at most \\(amt\\). Before returning the result, check if \\(dp[n, amt]\\) equals \\(amt + 1\\), and if so, return \\(-1\\), indicating that the target amount cannot be made up. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change.py
    def coin_change_dp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    MAX = amt + 1\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (amt + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in range(1, amt + 1):\n        dp[0][a] = MAX\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n + 1):\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n    return dp[n][amt] if dp[n][amt] != MAX else -1\n
    coin_change.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(vector<int> &coins, int amt) {\n    int n = coins.size();\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(amt + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(int[] coins, int amt) {\n    int n = coins.length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][amt + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint CoinChangeDP(int[] coins, int amt) {\n    int n = coins.Length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, amt + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0, a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i, a] = dp[i - 1, a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i, a] = Math.Min(dp[i - 1, a], dp[i, a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n, amt] != MAX ? dp[n, amt] : -1;\n}\n
    coin_change.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDP(coins []int, amt int) int {\n    n := len(coins)\n    max := amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, amt+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a := 1; a <= amt; a++ {\n        dp[0][a] = max\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i-1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = int(math.Min(float64(dp[i-1][a]), float64(dp[i][a-coins[i-1]]+1)))\n            }\n        }\n    }\n    if dp[n][amt] != max {\n        return dp[n][amt]\n    }\n    return -1\n}\n
    coin_change.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDP(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    let MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in 1 ... amt {\n        dp[0][a] = MAX\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1\n}\n
    coin_change.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDP(coins, amt) {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] !== MAX ? dp[n][amt] : -1;\n}\n
    coin_change.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDP(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] !== MAX ? dp[n][amt] : -1;\n}\n
    coin_change.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(List<int> coins, int amt) {\n  int n = coins.length;\n  int MAX = amt + 1;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(amt + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n  for (int a = 1; a <= amt; a++) {\n    dp[0][a] = MAX;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[i][a] = dp[i - 1][a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n        dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n      }\n    }\n  }\n  return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfn coin_change_dp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    let max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; amt + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in 1..=amt {\n        dp[0][a] = max;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = std::cmp::min(dp[i - 1][a], dp[i][a - coins[i - 1] as usize] + 1);\n            }\n        }\n    }\n    if dp[n][amt] != max {\n        return dp[n][amt] as i32;\n    } else {\n        -1\n    }\n}\n
    coin_change.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(amt + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = myMin(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    int res = dp[n][amt] != MAX ? dp[n][amt] : -1;\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    coin_change.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfun coinChangeDP(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    val MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(amt + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (a in 1..amt) {\n        dp[0][a] = MAX\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return if (dp[n][amt] != MAX) dp[n][amt] else -1\n}\n
    coin_change.rb
    [class]{}-[func]{coin_change_dp}\n
    coin_change.zig
    // \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212\nfn coinChangeDP(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    comptime var max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (1..amt + 1) |a| {\n        dp[0][a] = max;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = @min(dp[i - 1][a], dp[i][a - @as(usize, @intCast(coins[i - 1]))] + 1);\n            }\n        }\n    }\n    if (dp[n][amt] != max) {\n        return @intCast(dp[n][amt]);\n    } else {\n        return -1;\n    }\n}\n
    Code Visualization

    Full Screen >

    The following images show the dynamic programming process for the coin change problem, which is very similar to the unbounded knapsack problem.

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>

    Figure 14-25 \u00a0 Dynamic programming process for the coin change problem

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3-space-optimization_1","title":"3. \u00a0 Space optimization","text":"

    The space optimization for the coin change problem is handled in the same way as for the unbounded knapsack problem:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change.py
    def coin_change_dp_comp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    MAX = amt + 1\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [MAX] * (amt + 1)\n    dp[0] = 0\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n    return dp[amt] if dp[amt] != MAX else -1\n
    coin_change.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(vector<int> &coins, int amt) {\n    int n = coins.size();\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(amt + 1, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(int[] coins, int amt) {\n    int n = coins.length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    Arrays.fill(dp, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint CoinChangeDPComp(int[] coins, int amt) {\n    int n = coins.Length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    Array.Fill(dp, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.Min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDPComp(coins []int, amt int) int {\n    n := len(coins)\n    max := amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, amt+1)\n    for i := 1; i <= amt; i++ {\n        dp[i] = max\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u6b63\u5e8f\u904d\u5386\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = int(math.Min(float64(dp[a]), float64(dp[a-coins[i-1]]+1)))\n            }\n        }\n    }\n    if dp[amt] != max {\n        return dp[amt]\n    }\n    return -1\n}\n
    coin_change.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDPComp(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    let MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: MAX, count: amt + 1)\n    dp[0] = 0\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1\n}\n
    coin_change.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDPComp(coins, amt) {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] !== MAX ? dp[amt] : -1;\n}\n
    coin_change.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDPComp(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] !== MAX ? dp[amt] : -1;\n}\n
    coin_change.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(List<int> coins, int amt) {\n  int n = coins.length;\n  int MAX = amt + 1;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(amt + 1, MAX);\n  dp[0] = 0;\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[a] = dp[a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n        dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1);\n      }\n    }\n  }\n  return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn coin_change_dp_comp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    let max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; amt + 1];\n    dp.fill(max);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = std::cmp::min(dp[a], dp[a - coins[i - 1] as usize] + 1);\n            }\n        }\n    }\n    if dp[amt] != max {\n        return dp[amt] as i32;\n    } else {\n        -1\n    }\n}\n
    coin_change.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = malloc((amt + 1) * sizeof(int));\n    for (int j = 1; j <= amt; j++) {\n        dp[j] = MAX;\n    } \n    dp[0] = 0;\n\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = myMin(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    int res = dp[amt] != MAX ? dp[amt] : -1;\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    coin_change.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun coinChangeDPComp(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    val MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(amt + 1)\n    dp.fill(MAX)\n    dp[0] = 0\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return if (dp[amt] != MAX) dp[amt] else -1\n}\n
    coin_change.rb
    [class]{}-[func]{coin_change_dp_comp}\n
    coin_change.zig
    // \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn coinChangeDPComp(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    comptime var max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (amt + 1);\n    @memset(&dp, max);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = @min(dp[a], dp[a - @as(usize, @intCast(coins[i - 1]))] + 1);\n            }\n        }\n    }\n    if (dp[amt] != max) {\n        return @intCast(dp[amt]);\n    } else {\n        return -1;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1453-coin-change-problem-ii","title":"14.5.3 \u00a0 Coin change problem II","text":"

    Question

    Given \\(n\\) types of coins, where the denomination of the \\(i^{th}\\) type of coin is \\(coins[i - 1]\\), and the target amount is \\(amt\\). Each type of coin can be selected multiple times, ask how many combinations of coins can make up the target amount. See the example below.

    Figure 14-26 \u00a0 Example data for Coin Change Problem II

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1-dynamic-programming-approach_2","title":"1. \u00a0 Dynamic programming approach","text":"

    Compared to the previous problem, the goal of this problem is to determine the number of combinations, so the sub-problem becomes: the number of combinations that can make up amount \\(a\\) using the first \\(i\\) types of coins. The \\(dp\\) table remains a two-dimensional matrix of size \\((n+1) \\times (amt + 1)\\).

    The number of combinations for the current state is the sum of the combinations from not selecting the current coin and selecting the current coin. The state transition equation is:

    \\[ dp[i, a] = dp[i-1, a] + dp[i, a - coins[i-1]] \\]

    When the target amount is \\(0\\), no coins are needed to make up the target amount, so all \\(dp[i, 0]\\) in the first column should be initialized to \\(1\\). When there are no coins, it is impossible to make up any amount >0, so all \\(dp[0, a]\\) in the first row should be set to \\(0\\).

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2-code-implementation_2","title":"2. \u00a0 Code implementation","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_ii.py
    def coin_change_ii_dp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (amt + 1) for _ in range(n + 1)]\n    # \u521d\u59cb\u5316\u9996\u5217\n    for i in range(n + 1):\n        dp[i][0] = 1\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n    return dp[n][amt]\n
    coin_change_ii.cpp
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(vector<int> &coins, int amt) {\n    int n = coins.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(amt + 1, 0));\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.java
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(int[] coins, int amt) {\n    int n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][amt + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.cs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint CoinChangeIIDP(int[] coins, int amt) {\n    int n = coins.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, amt + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i, 0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i, a] = dp[i - 1, a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i, a] = dp[i - 1, a] + dp[i, a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n, amt];\n}\n
    coin_change_ii.go
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDP(coins []int, amt int) int {\n    n := len(coins)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, amt+1)\n    }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i := 0; i <= n; i++ {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i-1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i-1][a] + dp[i][a-coins[i-1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.swift
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDP(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i in 0 ... n {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.js
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDP(coins, amt) {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (let i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.ts
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDP(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (let i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.dart
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(List<int> coins, int amt) {\n  int n = coins.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(amt + 1, 0));\n  // \u521d\u59cb\u5316\u9996\u5217\n  for (int i = 0; i <= n; i++) {\n    dp[i][0] = 1;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[i][a] = dp[i - 1][a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n        dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n      }\n    }\n  }\n  return dp[n][amt];\n}\n
    coin_change_ii.rs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfn coin_change_ii_dp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; amt + 1]; n + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i in 0..=n {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1] as usize];\n            }\n        }\n    }\n    dp[n][amt]\n}\n
    coin_change_ii.c
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(amt + 1, sizeof(int));\n    }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    int res = dp[n][amt];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    coin_change_ii.kt
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfun coinChangeIIDP(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(amt + 1) }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (i in 0..n) {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.rb
    [class]{}-[func]{coin_change_ii_dp}\n
    coin_change_ii.zig
    // \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212\nfn coinChangeIIDP(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1);\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (0..n + 1) |i| {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - @as(usize, @intCast(coins[i - 1]))];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3-space-optimization_2","title":"3. \u00a0 Space optimization","text":"

    The space optimization approach is the same, just remove the coin dimension:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_ii.py
    def coin_change_ii_dp_comp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (amt + 1)\n    dp[0] = 1\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n    return dp[amt]\n
    coin_change_ii.cpp
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(vector<int> &coins, int amt) {\n    int n = coins.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(amt + 1, 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.java
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(int[] coins, int amt) {\n    int n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.cs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint CoinChangeIIDPComp(int[] coins, int amt) {\n    int n = coins.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.go
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDPComp(coins []int, amt int) int {\n    n := len(coins)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, amt+1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u6b63\u5e8f\u904d\u5386\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a-coins[i-1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.swift
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDPComp(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: amt + 1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.js
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDPComp(coins, amt) {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.ts
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDPComp(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.dart
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(List<int> coins, int amt) {\n  int n = coins.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(amt + 1, 0);\n  dp[0] = 1;\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[a] = dp[a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n        dp[a] = dp[a] + dp[a - coins[i - 1]];\n      }\n    }\n  }\n  return dp[amt];\n}\n
    coin_change_ii.rs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn coin_change_ii_dp_comp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1] as usize];\n            }\n        }\n    }\n    dp[amt]\n}\n
    coin_change_ii.c
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(amt + 1, sizeof(int));\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    int res = dp[amt];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    coin_change_ii.kt
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun coinChangeIIDPComp(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(amt + 1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.rb
    [class]{}-[func]{coin_change_ii_dp_comp}\n
    coin_change_ii.zig
    // \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn coinChangeIIDPComp(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (amt + 1);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = dp[a] + dp[a - @as(usize, @intCast(coins[i - 1]))];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_graph/","title":"Chapter 9. \u00a0 Graph","text":"

    Abstract

    In the journey of life, we are like individual nodes, connected by countless invisible edges.

    Each encounter and parting leaves a distinctive imprint on this vast network graph.

    "},{"location":"chapter_graph/#chapter-contents","title":"Chapter contents","text":"
    • 9.1 \u00a0 Graph
    • 9.2 \u00a0 Basic graph operations
    • 9.3 \u00a0 Graph traversal
    • 9.4 \u00a0 Summary
    "},{"location":"chapter_graph/graph/","title":"9.1 \u00a0 Graph","text":"

    A \"graph\" is a type of nonlinear data structure, consisting of \"vertices\" and \"edges\". A graph \\(G\\) can be abstractly represented as a collection of a set of vertices \\(V\\) and a set of edges \\(E\\). The following example shows a graph containing 5 vertices and 7 edges.

    \\[ \\begin{aligned} V & = \\{ 1, 2, 3, 4, 5 \\} \\newline E & = \\{ (1,2), (1,3), (1,5), (2,3), (2,4), (2,5), (4,5) \\} \\newline G & = \\{ V, E \\} \\newline \\end{aligned} \\]

    If vertices are viewed as nodes and edges as references (pointers) connecting the nodes, graphs can be seen as a data structure that extends from linked lists. As shown below, compared to linear relationships (linked lists) and divide-and-conquer relationships (trees), network relationships (graphs) are more complex due to their higher degree of freedom.

    Figure 9-1 \u00a0 Relationship between linked lists, trees, and graphs

    "},{"location":"chapter_graph/graph/#911-common-types-of-graphs","title":"9.1.1 \u00a0 Common types of graphs","text":"

    Based on whether edges have direction, graphs can be divided into \"undirected graphs\" and \"directed graphs\", as shown below.

    • In undirected graphs, edges represent a \"bidirectional\" connection between two vertices, for example, the \"friendship\" in WeChat or QQ.
    • In directed graphs, edges have directionality, that is, the edges \\(A \\rightarrow B\\) and \\(A \\leftarrow B\\) are independent of each other, for example, the \"follow\" and \"be followed\" relationship on Weibo or TikTok.

    Figure 9-2 \u00a0 Directed and undirected graphs

    Based on whether all vertices are connected, graphs can be divided into \"connected graphs\" and \"disconnected graphs\", as shown below.

    • For connected graphs, it is possible to reach any other vertex starting from a certain vertex.
    • For disconnected graphs, there is at least one vertex that cannot be reached from a certain starting vertex.

    Figure 9-3 \u00a0 Connected and disconnected graphs

    We can also add a \"weight\" variable to edges, resulting in \"weighted graphs\" as shown below. For example, in mobile games like \"Honor of Kings\", the system calculates the \"closeness\" between players based on shared gaming time, and this closeness network can be represented with a weighted graph.

    Figure 9-4 \u00a0 Weighted and unweighted graphs

    Graph data structures include the following commonly used terms.

    • \"Adjacency\": When there is an edge connecting two vertices, these two vertices are said to be \"adjacent\". In the above figure, the adjacent vertices of vertex 1 are vertices 2, 3, and 5.
    • \"Path\": The sequence of edges passed from vertex A to vertex B is called a \"path\" from A to B. In the above figure, the edge sequence 1-5-2-4 is a path from vertex 1 to vertex 4.
    • \"Degree\": The number of edges a vertex has. For directed graphs, \"in-degree\" refers to how many edges point to the vertex, and \"out-degree\" refers to how many edges point out from the vertex.
    "},{"location":"chapter_graph/graph/#912-representation-of-graphs","title":"9.1.2 \u00a0 Representation of graphs","text":"

    Common representations of graphs include \"adjacency matrices\" and \"adjacency lists\". The following examples use undirected graphs.

    "},{"location":"chapter_graph/graph/#1-adjacency-matrix","title":"1. \u00a0 Adjacency matrix","text":"

    Let the number of vertices in the graph be \\(n\\), the \"adjacency matrix\" uses an \\(n \\times n\\) matrix to represent the graph, where each row (column) represents a vertex, and the matrix elements represent edges, with \\(1\\) or \\(0\\) indicating whether there is an edge between two vertices.

    As shown below, let the adjacency matrix be \\(M\\), and the list of vertices be \\(V\\), then the matrix element \\(M[i, j] = 1\\) indicates there is an edge between vertex \\(V[i]\\) and vertex \\(V[j]\\), conversely \\(M[i, j] = 0\\) indicates there is no edge between the two vertices.

    Figure 9-5 \u00a0 Representation of a graph with an adjacency matrix

    Adjacency matrices have the following characteristics.

    • A vertex cannot be connected to itself, so the elements on the main diagonal of the adjacency matrix are meaningless.
    • For undirected graphs, edges in both directions are equivalent, thus the adjacency matrix is symmetric about the main diagonal.
    • By replacing the elements of the adjacency matrix from \\(1\\) and \\(0\\) to weights, it can represent weighted graphs.

    When representing graphs with adjacency matrices, it is possible to directly access matrix elements to obtain edges, thus operations of addition, deletion, lookup, and modification are very efficient, all with a time complexity of \\(O(1)\\). However, the space complexity of the matrix is \\(O(n^2)\\), which consumes more memory.

    "},{"location":"chapter_graph/graph/#2-adjacency-list","title":"2. \u00a0 Adjacency list","text":"

    The \"adjacency list\" uses \\(n\\) linked lists to represent the graph, with each linked list node representing a vertex. The \\(i\\)-th linked list corresponds to vertex \\(i\\) and contains all adjacent vertices (vertices connected to that vertex). The Figure 9-6 shows an example of a graph stored using an adjacency list.

    Figure 9-6 \u00a0 Representation of a graph with an adjacency list

    The adjacency list only stores actual edges, and the total number of edges is often much less than \\(n^2\\), making it more space-efficient. However, finding edges in the adjacency list requires traversing the linked list, so its time efficiency is not as good as that of the adjacency matrix.

    Observing the above figure, the structure of the adjacency list is very similar to the \"chaining\" in hash tables, hence we can use similar methods to optimize efficiency. For example, when the linked list is long, it can be transformed into an AVL tree or red-black tree, thus optimizing the time efficiency from \\(O(n)\\) to \\(O(\\log n)\\); the linked list can also be transformed into a hash table, thus reducing the time complexity to \\(O(1)\\).

    "},{"location":"chapter_graph/graph/#913-common-applications-of-graphs","title":"9.1.3 \u00a0 Common applications of graphs","text":"

    As shown in the Table 9-1 , many real-world systems can be modeled with graphs, and corresponding problems can be reduced to graph computing problems.

    Table 9-1 \u00a0 Common graphs in real life

    Vertices Edges Graph Computing Problem Social Networks Users Friendships Potential Friend Recommendations Subway Lines Stations Connectivity Between Stations Shortest Route Recommendations Solar System Celestial Bodies Gravitational Forces Between Celestial Bodies Planetary Orbit Calculations"},{"location":"chapter_graph/graph_operations/","title":"9.2 \u00a0 Basic operations on graphs","text":"

    The basic operations on graphs can be divided into operations on \"edges\" and operations on \"vertices\". Under the two representation methods of \"adjacency matrix\" and \"adjacency list\", the implementation methods are different.

    "},{"location":"chapter_graph/graph_operations/#921-implementation-based-on-adjacency-matrix","title":"9.2.1 \u00a0 Implementation based on adjacency matrix","text":"

    Given an undirected graph with \\(n\\) vertices, the various operations are implemented as shown in the Figure 9-7 .

    • Adding or removing an edge: Directly modify the specified edge in the adjacency matrix, using \\(O(1)\\) time. Since it is an undirected graph, it is necessary to update the edges in both directions simultaneously.
    • Adding a vertex: Add a row and a column at the end of the adjacency matrix and fill them all with \\(0\\)s, using \\(O(n)\\) time.
    • Removing a vertex: Delete a row and a column in the adjacency matrix. The worst case is when the first row and column are removed, requiring \\((n-1)^2\\) elements to be \"moved up and to the left\", thus using \\(O(n^2)\\) time.
    • Initialization: Pass in \\(n\\) vertices, initialize a vertex list vertices of length \\(n\\), using \\(O(n)\\) time; initialize an \\(n \\times n\\) size adjacency matrix adjMat, using \\(O(n^2)\\) time.
    Initialize adjacency matrixAdd an edgeRemove an edgeAdd a vertexRemove a vertex

    Figure 9-7 \u00a0 Initialization, adding and removing edges, adding and removing vertices in adjacency matrix

    Below is the implementation code for graphs represented using an adjacency matrix:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_matrix.py
    class GraphAdjMat:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, vertices: list[int], edges: list[list[int]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.vertices: list[int] = []\n        # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.adj_mat: list[list[int]] = []\n        # \u6dfb\u52a0\u9876\u70b9\n        for val in vertices:\n            self.add_vertex(val)\n        # \u6dfb\u52a0\u8fb9\n        # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges:\n            self.add_edge(e[0], e[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.vertices)\n\n    def add_vertex(self, val: int):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        n = self.size()\n        # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.append(val)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        new_row = [0] * n\n        self.adj_mat.append(new_row)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in self.adj_mat:\n            row.append(0)\n\n    def remove_vertex(self, index: int):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if index >= self.size():\n            raise IndexError()\n        # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in self.adj_mat:\n            row.pop(index)\n\n    def add_edge(self, i: int, j: int):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1\n        self.adj_mat[j][i] = 1\n\n    def remove_edge(self, i: int, j: int):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        self.adj_mat[i][j] = 0\n        self.adj_mat[j][i] = 0\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u77e9\u9635\"\"\"\n        print(\"\u9876\u70b9\u5217\u8868 =\", self.vertices)\n        print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        print_matrix(self.adj_mat)\n
    graph_adjacency_matrix.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vector<int> vertices;       // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vector<vector<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjMat(const vector<int> &vertices, const vector<vector<int>> &edges) {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const vector<int> &edge : edges) {\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() const {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.push_back(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        adjMat.emplace_back(vector<int>(n, 0));\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (vector<int> &row : adjMat) {\n            row.push_back(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(int index) {\n        if (index >= size()) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.erase(vertices.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.erase(adjMat.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (vector<int> &row : adjMat) {\n            row.erase(row.begin() + index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    void print() {\n        cout << \"\u9876\u70b9\u5217\u8868 = \";\n        printVector(vertices);\n        cout << \"\u90bb\u63a5\u77e9\u9635 =\" << endl;\n        printVectorMatrix(adjMat);\n    }\n};\n
    graph_adjacency_matrix.java
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<Integer> vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<Integer>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = new ArrayList<>();\n        this.adjMat = new ArrayList<>();\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (int[] e : edges) {\n            addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<Integer> newRow = new ArrayList<>(n);\n        for (int j = 0; j < n; j++) {\n            newRow.add(0);\n        }\n        adjMat.add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (List<Integer> row : adjMat) {\n            row.add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(int index) {\n        if (index >= size())\n            throw new IndexOutOfBoundsException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (List<Integer> row : adjMat) {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat.get(i).set(j, 1);\n        adjMat.get(j).set(i, 1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        adjMat.get(i).set(j, 0);\n        adjMat.get(j).set(i, 0);\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void print() {\n        System.out.print(\"\u9876\u70b9\u5217\u8868 = \");\n        System.out.println(vertices);\n        System.out.println(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.printMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<int> vertices;     // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        foreach (int val in vertices) {\n            AddVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        foreach (int[] e in edges) {\n            AddEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return vertices.Count;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(int val) {\n        int n = Size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.Add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<int> newRow = new(n);\n        for (int j = 0; j < n; j++) {\n            newRow.Add(0);\n        }\n        adjMat.Add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        foreach (List<int> row in adjMat) {\n            row.Add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(int index) {\n        if (index >= Size())\n            throw new IndexOutOfRangeException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        foreach (List<int> row in adjMat) {\n            row.RemoveAt(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void AddEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void RemoveEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void Print() {\n        Console.Write(\"\u9876\u70b9\u5217\u8868 = \");\n        PrintUtil.PrintList(vertices);\n        Console.WriteLine(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.PrintMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.go
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjMat struct {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vertices []int\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat [][]int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjMat(vertices []int, edges [][]int) *graphAdjMat {\n    // \u6dfb\u52a0\u9876\u70b9\n    n := len(vertices)\n    adjMat := make([][]int, n)\n    for i := range adjMat {\n        adjMat[i] = make([]int, n)\n    }\n    // \u521d\u59cb\u5316\u56fe\n    g := &graphAdjMat{\n        vertices: vertices,\n        adjMat:   adjMat,\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for i := range edges {\n        g.addEdge(edges[i][0], edges[i][1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjMat) size() int {\n    return len(g.vertices)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjMat) addVertex(val int) {\n    n := g.size()\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    g.vertices = append(g.vertices, val)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    newRow := make([]int, n)\n    g.adjMat = append(g.adjMat, newRow)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i], 0)\n    }\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjMat) removeVertex(index int) {\n    if index >= g.size() {\n        return\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    g.vertices = append(g.vertices[:index], g.vertices[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    g.adjMat = append(g.adjMat[:index], g.adjMat[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i][:index], g.adjMat[i][index+1:]...)\n    }\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) addEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    g.adjMat[i][j] = 1\n    g.adjMat[j][i] = 1\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) removeEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    g.adjMat[i][j] = 0\n    g.adjMat[j][i] = 0\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nfunc (g *graphAdjMat) print() {\n    fmt.Printf(\"\\t\u9876\u70b9\u5217\u8868 = %v\\n\", g.vertices)\n    fmt.Printf(\"\\t\u90bb\u63a5\u77e9\u9635 = \\n\")\n    for i := range g.adjMat {\n        fmt.Printf(\"\\t\\t\\t%v\\n\", g.adjMat[i])\n    }\n}\n
    graph_adjacency_matrix.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    private var vertices: [Int] // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    private var adjMat: [[Int]] // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(vertices: [Int], edges: [[Int]]) {\n        self.vertices = []\n        adjMat = []\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            addVertex(val: val)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges {\n            addEdge(i: e[0], j: e[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    func size() -> Int {\n        vertices.count\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    func addVertex(val: Int) {\n        let n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.append(val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        let newRow = Array(repeating: 0, count: n)\n        adjMat.append(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for i in adjMat.indices {\n            adjMat[i].append(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    func removeVertex(index: Int) {\n        if index >= size() {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for i in adjMat.indices {\n            adjMat[i].remove(at: index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    func print() {\n        Swift.print(\"\u9876\u70b9\u5217\u8868 = \", terminator: \"\")\n        Swift.print(vertices)\n        Swift.print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        PrintUtil.printMatrix(matrix: adjMat)\n    }\n}\n
    graph_adjacency_matrix.js
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices, edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val) {\n        const n = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow = [];\n        for (let j = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index) {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print() {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices: number[]; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat: number[][]; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices: number[], edges: number[][]) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val: number): void {\n        const n: number = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow: number[] = [];\n        for (let j: number = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index: number): void {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print(): void {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n  List<int> vertices = []; // \u9876\u70b9\u5143\u7d20\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n  List<List<int>> adjMat = []; //\u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjMat(List<int> vertices, List<List<int>> edges) {\n    this.vertices = [];\n    this.adjMat = [];\n    // \u6dfb\u52a0\u9876\u70b9\n    for (int val in vertices) {\n      addVertex(val);\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for (List<int> e in edges) {\n      addEdge(e[0], e[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return vertices.length;\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(int val) {\n    int n = size();\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    vertices.add(val);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    List<int> newRow = List.filled(n, 0, growable: true);\n    adjMat.add(newRow);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for (List<int> row in adjMat) {\n      row.add(0);\n    }\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(int index) {\n    if (index >= size()) {\n      throw IndexError;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    vertices.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    adjMat.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (List<int> row in adjMat) {\n      row.removeAt(index);\n    }\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void addEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    adjMat[i][j] = 1;\n    adjMat[j][i] = 1;\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void removeEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    adjMat[i][j] = 0;\n    adjMat[j][i] = 0;\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n  void printAdjMat() {\n    print(\"\u9876\u70b9\u5217\u8868 = $vertices\");\n    print(\"\u90bb\u63a5\u77e9\u9635 = \");\n    printMatrix(adjMat);\n  }\n}\n
    graph_adjacency_matrix.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjMat {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub vertices: Vec<i32>,\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub adj_mat: Vec<Vec<i32>>,\n}\n\nimpl GraphAdjMat {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(vertices: Vec<i32>, edges: Vec<[usize; 2]>) -> Self {\n        let mut graph = GraphAdjMat {\n            vertices: vec![],\n            adj_mat: vec![],\n        };\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            graph.add_vertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for edge in edges {\n            graph.add_edge(edge[0], edge[1])\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    pub fn size(&self) -> usize {\n        self.vertices.len()\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, val: i32) {\n        let n = self.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        self.adj_mat.push(vec![0; n]);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in &mut self.adj_mat {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    pub fn remove_vertex(&mut self, index: usize) {\n        if index >= self.size() {\n            panic!(\"index error\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in &mut self.adj_mat {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1;\n        self.adj_mat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    pub fn remove_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        self.adj_mat[i][j] = 0;\n        self.adj_mat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    pub fn print(&self) {\n        println!(\"\u9876\u70b9\u5217\u8868 = {:?}\", self.vertices);\n        println!(\"\u90bb\u63a5\u77e9\u9635 =\");\n        println!(\"[\");\n        for row in &self.adj_mat {\n            println!(\"  {:?},\", row);\n        }\n        println!(\"]\")\n    }\n}\n
    graph_adjacency_matrix.c
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int vertices[MAX_SIZE];\n    int adjMat[MAX_SIZE][MAX_SIZE];\n    int size;\n} GraphAdjMat;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjMat *newGraphAdjMat() {\n    GraphAdjMat *graph = (GraphAdjMat *)malloc(sizeof(GraphAdjMat));\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        for (int j = 0; j < MAX_SIZE; j++) {\n            graph->adjMat[i][j] = 0;\n        }\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjMat(GraphAdjMat *graph) {\n    free(graph);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjMat *graph, int val) {\n    if (graph->size == MAX_SIZE) {\n        fprintf(stderr, \"\u56fe\u7684\u9876\u70b9\u6570\u91cf\u5df2\u8fbe\u6700\u5927\u503c\\n\");\n        return;\n    }\n    // \u6dfb\u52a0\u7b2c n \u4e2a\u9876\u70b9\uff0c\u5e76\u5c06\u7b2c n \u884c\u548c\u5217\u7f6e\u96f6\n    int n = graph->size;\n    graph->vertices[n] = val;\n    for (int i = 0; i <= n; i++) {\n        graph->adjMat[n][i] = graph->adjMat[i][n] = 0;\n    }\n    graph->size++;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjMat *graph, int index) {\n    if (index < 0 || index >= graph->size) {\n        fprintf(stderr, \"\u9876\u70b9\u7d22\u5f15\u8d8a\u754c\\n\");\n        return;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    for (int i = index; i < graph->size - 1; i++) {\n        graph->vertices[i] = graph->vertices[i + 1];\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    for (int i = index; i < graph->size - 1; i++) {\n        for (int j = 0; j < graph->size; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i + 1][j];\n        }\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (int i = 0; i < graph->size; i++) {\n        for (int j = index; j < graph->size - 1; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i][j + 1];\n        }\n    }\n    graph->size--;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid addEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 1;\n    graph->adjMat[j][i] = 1;\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid removeEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 0;\n    graph->adjMat[j][i] = 0;\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nvoid printGraphAdjMat(GraphAdjMat *graph) {\n    printf(\"\u9876\u70b9\u5217\u8868 = \");\n    printArray(graph->vertices, graph->size);\n    printf(\"\u90bb\u63a5\u77e9\u9635 =\\n\");\n    for (int i = 0; i < graph->size; i++) {\n        printArray(graph->adjMat[i], graph->size);\n    }\n}\n
    graph_adjacency_matrix.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat(vertices: IntArray, edges: Array<IntArray>) {\n    val vertices = mutableListOf<Int>() // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    val adjMat = mutableListOf<MutableList<Int>>() // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (vertex in vertices) {\n            addVertex(vertex)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (edge in edges) {\n            addEdge(edge[0], edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return vertices.size\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(_val: Int) {\n        val n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(_val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        val newRow = mutableListOf<Int>()\n        for (j in 0..<n) {\n            newRow.add(0)\n        }\n        adjMat.add(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (row in adjMat) {\n            row.add(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(index: Int) {\n        if (index >= size())\n            throw IndexOutOfBoundsException()\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (row in adjMat) {\n            row.removeAt(index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    fun print() {\n        print(\"\u9876\u70b9\u5217\u8868 = \")\n        println(vertices)\n        println(\"\u90bb\u63a5\u77e9\u9635 =\")\n        printMatrix(adjMat)\n    }\n}\n
    graph_adjacency_matrix.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjMat\n  def initialize(vertices, edges)\n    ### \u6784\u9020\u65b9\u6cd5 ###\n    # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @vertices = []\n    # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @adj_mat = []\n    # \u6dfb\u52a0\u9876\u70b9\n    vertices.each { |val| add_vertex(val) }\n    # \u6dfb\u52a0\u8fb9\n    # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    edges.each { |e| add_edge(e[0], e[1]) }\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @vertices.length\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(val)\n    n = size\n    # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    @vertices << val\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    new_row = Array.new(n, 0)\n    @adj_mat << new_row\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    @adj_mat.each { |row| row << 0 }\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(index)\n    raise IndexError if index >= size\n\n    # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    @vertices.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    @adj_mat.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    @adj_mat.each { |row| row.delete_at(index) }\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    @adj_mat[i][j] = 1\n    @adj_mat[j][i] = 1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    @adj_mat[i][j] = 0\n    @adj_mat[j][i] = 0\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u77e9\u9635 ###\n  def __print__\n    puts \"\u9876\u70b9\u5217\u8868 = #{@vertices}\"\n    puts '\u90bb\u63a5\u77e9\u9635 ='\n    print_matrix(@adj_mat)\n  end\nend\n
    graph_adjacency_matrix.zig
    [class]{GraphAdjMat}-[func]{}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_graph/graph_operations/#922-implementation-based-on-adjacency-list","title":"9.2.2 \u00a0 Implementation based on adjacency list","text":"

    Given an undirected graph with a total of \\(n\\) vertices and \\(m\\) edges, the various operations can be implemented as shown in the Figure 9-8 .

    • Adding an edge: Simply add the edge at the end of the corresponding vertex's linked list, using \\(O(1)\\) time. Because it is an undirected graph, it is necessary to add edges in both directions simultaneously.
    • Removing an edge: Find and remove the specified edge in the corresponding vertex's linked list, using \\(O(m)\\) time. In an undirected graph, it is necessary to remove edges in both directions simultaneously.
    • Adding a vertex: Add a linked list in the adjacency list and make the new vertex the head node of the list, using \\(O(1)\\) time.
    • Removing a vertex: It is necessary to traverse the entire adjacency list, removing all edges that include the specified vertex, using \\(O(n + m)\\) time.
    • Initialization: Create \\(n\\) vertices and \\(2m\\) edges in the adjacency list, using \\(O(n + m)\\) time.
    Initialize adjacency listAdd an edgeRemove an edgeAdd a vertexRemove a vertex

    Figure 9-8 \u00a0 Initialization, adding and removing edges, adding and removing vertices in adjacency list

    Below is the adjacency list code implementation. Compared to the above diagram, the actual code has the following differences.

    • For convenience in adding and removing vertices, and to simplify the code, we use lists (dynamic arrays) instead of linked lists.
    • Use a hash table to store the adjacency list, key being the vertex instance, value being the list (linked list) of adjacent vertices of that vertex.

    Additionally, we use the Vertex class to represent vertices in the adjacency list. The reason for this is: if, like with the adjacency matrix, list indexes were used to distinguish different vertices, then suppose you want to delete the vertex at index \\(i\\), you would need to traverse the entire adjacency list and decrement all indexes greater than \\(i\\) by \\(1\\), which is very inefficient. However, if each vertex is a unique Vertex instance, then deleting a vertex does not require any changes to other vertices.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_list.py
    class GraphAdjList:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, edges: list[list[Vertex]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        self.adj_list = dict[Vertex, list[Vertex]]()\n        # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges:\n            self.add_vertex(edge[0])\n            self.add_vertex(edge[1])\n            self.add_edge(edge[0], edge[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.adj_list)\n\n    def add_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list[vet1].append(vet2)\n        self.adj_list[vet2].append(vet1)\n\n    def remove_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list[vet1].remove(vet2)\n        self.adj_list[vet2].remove(vet1)\n\n    def add_vertex(self, vet: Vertex):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        if vet in self.adj_list:\n            return\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list[vet] = []\n\n    def remove_vertex(self, vet: Vertex):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if vet not in self.adj_list:\n            raise ValueError()\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.pop(vet)\n        # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for vertex in self.adj_list:\n            if vet in self.adj_list[vertex]:\n                self.adj_list[vertex].remove(vet)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u8868\"\"\"\n        print(\"\u90bb\u63a5\u8868 =\")\n        for vertex in self.adj_list:\n            tmp = [v.val for v in self.adj_list[vertex]]\n            print(f\"{vertex.val}: {tmp},\")\n
    graph_adjacency_list.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  public:\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    unordered_map<Vertex *, vector<Vertex *>> adjList;\n\n    /* \u5728 vector \u4e2d\u5220\u9664\u6307\u5b9a\u8282\u70b9 */\n    void remove(vector<Vertex *> &vec, Vertex *vet) {\n        for (int i = 0; i < vec.size(); i++) {\n            if (vec[i] == vet) {\n                vec.erase(vec.begin() + i);\n                break;\n            }\n        }\n    }\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjList(const vector<vector<Vertex *>> &edges) {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const vector<Vertex *> &edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    void addEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].push_back(vet2);\n        adjList[vet2].push_back(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    void removeEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        remove(adjList[vet1], vet2);\n        remove(adjList[vet2], vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(Vertex *vet) {\n        if (adjList.count(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = vector<Vertex *>();\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(Vertex *vet) {\n        if (!adjList.count(vet))\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.erase(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (auto &adj : adjList) {\n            remove(adj.second, vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    void print() {\n        cout << \"\u90bb\u63a5\u8868 =\" << endl;\n        for (auto &adj : adjList) {\n            const auto &key = adj.first;\n            const auto &vec = adj.second;\n            cout << key->val << \": \";\n            printVector(vetsToVals(vec));\n        }\n    }\n};\n
    graph_adjacency_list.java
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    Map<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjList(Vertex[][] edges) {\n        this.adjList = new HashMap<>();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (Vertex[] edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void addEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList.get(vet1).add(vet2);\n        adjList.get(vet2).add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void removeEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList.get(vet1).remove(vet2);\n        adjList.get(vet2).remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(Vertex vet) {\n        if (adjList.containsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.put(vet, new ArrayList<>());\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(Vertex vet) {\n        if (!adjList.containsKey(vet))\n            throw new IllegalArgumentException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (List<Vertex> list : adjList.values()) {\n            list.remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void print() {\n        System.out.println(\"\u90bb\u63a5\u8868 =\");\n        for (Map.Entry<Vertex, List<Vertex>> pair : adjList.entrySet()) {\n            List<Integer> tmp = new ArrayList<>();\n            for (Vertex vertex : pair.getValue())\n                tmp.add(vertex.val);\n            System.out.println(pair.getKey().val + \": \" + tmp + \",\");\n        }\n    }\n}\n
    graph_adjacency_list.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public Dictionary<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjList(Vertex[][] edges) {\n        adjList = [];\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        foreach (Vertex[] edge in edges) {\n            AddVertex(edge[0]);\n            AddVertex(edge[1]);\n            AddEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return adjList.Count;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void AddEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].Add(vet2);\n        adjList[vet2].Add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void RemoveEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1].Remove(vet2);\n        adjList[vet2].Remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(Vertex vet) {\n        if (adjList.ContainsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.Add(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(Vertex vet) {\n        if (!adjList.ContainsKey(vet))\n            throw new InvalidOperationException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.Remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        foreach (List<Vertex> list in adjList.Values) {\n            list.Remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void Print() {\n        Console.WriteLine(\"\u90bb\u63a5\u8868 =\");\n        foreach (KeyValuePair<Vertex, List<Vertex>> pair in adjList) {\n            List<int> tmp = [];\n            foreach (Vertex vertex in pair.Value)\n                tmp.Add(vertex.val);\n            Console.WriteLine(pair.Key.val + \": [\" + string.Join(\", \", tmp) + \"],\");\n        }\n    }\n}\n
    graph_adjacency_list.go
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjList struct {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList map[Vertex][]Vertex\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjList(edges [][]Vertex) *graphAdjList {\n    g := &graphAdjList{\n        adjList: make(map[Vertex][]Vertex),\n    }\n    // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for _, edge := range edges {\n        g.addVertex(edge[0])\n        g.addVertex(edge[1])\n        g.addEdge(edge[0], edge[1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjList) size() int {\n    return len(g.adjList)\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nfunc (g *graphAdjList) addEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2, \u6dfb\u52a0\u533f\u540d struct{},\n    g.adjList[vet1] = append(g.adjList[vet1], vet2)\n    g.adjList[vet2] = append(g.adjList[vet2], vet1)\n}\n\n/* \u5220\u9664\u8fb9 */\nfunc (g *graphAdjList) removeEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    g.adjList[vet1] = DeleteSliceElms(g.adjList[vet1], vet2)\n    g.adjList[vet2] = DeleteSliceElms(g.adjList[vet2], vet1)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjList) addVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if ok {\n        return\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    g.adjList[vet] = make([]Vertex, 0)\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjList) removeVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if !ok {\n        panic(\"error\")\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    delete(g.adjList, vet)\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for v, list := range g.adjList {\n        g.adjList[v] = DeleteSliceElms(list, vet)\n    }\n}\n\n/* \u6253\u5370\u90bb\u63a5\u8868 */\nfunc (g *graphAdjList) print() {\n    var builder strings.Builder\n    fmt.Printf(\"\u90bb\u63a5\u8868 = \\n\")\n    for k, v := range g.adjList {\n        builder.WriteString(\"\\t\\t\" + strconv.Itoa(k.Val) + \": \")\n        for _, vet := range v {\n            builder.WriteString(strconv.Itoa(vet.Val) + \" \")\n        }\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    graph_adjacency_list.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public private(set) var adjList: [Vertex: [Vertex]]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public init(edges: [[Vertex]]) {\n        adjList = [:]\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            addVertex(vet: edge[0])\n            addVertex(vet: edge[1])\n            addEdge(vet1: edge[0], vet2: edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public func size() -> Int {\n        adjList.count\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public func addEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.append(vet2)\n        adjList[vet2]?.append(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public func removeEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.removeAll { $0 == vet2 }\n        adjList[vet2]?.removeAll { $0 == vet1 }\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public func addVertex(vet: Vertex) {\n        if adjList[vet] != nil {\n            return\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = []\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public func removeVertex(vet: Vertex) {\n        if adjList[vet] == nil {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.removeValue(forKey: vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for key in adjList.keys {\n            adjList[key]?.removeAll { $0 == vet }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public func print() {\n        Swift.print(\"\u90bb\u63a5\u8868 =\")\n        for (vertex, list) in adjList {\n            let list = list.map { $0.val }\n            Swift.print(\"\\(vertex.val): \\(list),\")\n        }\n    }\n}\n
    graph_adjacency_list.js
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet) {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet) {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print() {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList: Map<Vertex, Vertex[]>;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges: Vertex[][]) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet: Vertex): void {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet: Vertex): void {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index: number = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print(): void {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList.entries()) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  Map<Vertex, List<Vertex>> adjList = {};\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjList(List<List<Vertex>> edges) {\n    for (List<Vertex> edge in edges) {\n      addVertex(edge[0]);\n      addVertex(edge[1]);\n      addEdge(edge[0], edge[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return adjList.length;\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  void addEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    adjList[vet1]!.add(vet2);\n    adjList[vet2]!.add(vet1);\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  void removeEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    adjList[vet1]!.remove(vet2);\n    adjList[vet2]!.remove(vet1);\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(Vertex vet) {\n    if (adjList.containsKey(vet)) return;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    adjList[vet] = [];\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(Vertex vet) {\n    if (!adjList.containsKey(vet)) {\n      throw ArgumentError;\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    adjList.remove(vet);\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    adjList.forEach((key, value) {\n      value.remove(vet);\n    });\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u8868 */\n  void printAdjList() {\n    print(\"\u90bb\u63a5\u8868 =\");\n    adjList.forEach((key, value) {\n      List<int> tmp = [];\n      for (Vertex vertex in value) {\n        tmp.add(vertex.val);\n      }\n      print(\"${key.val}: $tmp,\");\n    });\n  }\n}\n
    graph_adjacency_list.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    pub adj_list: HashMap<Vertex, Vec<Vertex>>,\n}\n\nimpl GraphAdjList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(edges: Vec<[Vertex; 2]>) -> Self {\n        let mut graph = GraphAdjList {\n            adj_list: HashMap::new(),\n        };\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            graph.add_vertex(edge[0]);\n            graph.add_vertex(edge[1]);\n            graph.add_edge(edge[0], edge[1]);\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    #[allow(unused)]\n    pub fn size(&self) -> usize {\n        self.adj_list.len()\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list.get_mut(&vet1).unwrap().push(vet2);\n        self.adj_list.get_mut(&vet2).unwrap().push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    #[allow(unused)]\n    pub fn remove_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list\n            .get_mut(&vet1)\n            .unwrap()\n            .retain(|&vet| vet != vet2);\n        self.adj_list\n            .get_mut(&vet2)\n            .unwrap()\n            .retain(|&vet| vet != vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, vet: Vertex) {\n        if self.adj_list.contains_key(&vet) {\n            return;\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list.insert(vet, vec![]);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    #[allow(unused)]\n    pub fn remove_vertex(&mut self, vet: Vertex) {\n        if !self.adj_list.contains_key(&vet) {\n            panic!(\"value error\");\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.remove(&vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for list in self.adj_list.values_mut() {\n            list.retain(|&v| v != vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    pub fn print(&self) {\n        println!(\"\u90bb\u63a5\u8868 =\");\n        for (vertex, list) in &self.adj_list {\n            let list = list.iter().map(|vertex| vertex.val).collect::<Vec<i32>>();\n            println!(\"{}: {:?},\", vertex.val, list);\n        }\n    }\n}\n
    graph_adjacency_list.c
    /* \u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct AdjListNode {\n    Vertex *vertex;           // \u9876\u70b9\n    struct AdjListNode *next; // \u540e\u7ee7\u8282\u70b9\n} AdjListNode;\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid addEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *node = (AdjListNode *)malloc(sizeof(AdjListNode));\n    node->vertex = vet;\n    // \u5934\u63d2\u6cd5\n    node->next = head->next;\n    head->next = node;\n}\n\n/* \u5220\u9664\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid removeEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *pre = head;\n    AdjListNode *cur = head->next;\n    // \u5728\u94fe\u8868\u4e2d\u641c\u7d22 vet \u5bf9\u5e94\u8282\u70b9\n    while (cur != NULL && cur->vertex != vet) {\n        pre = cur;\n        cur = cur->next;\n    }\n    if (cur == NULL)\n        return;\n    // \u5c06 vet \u5bf9\u5e94\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u5220\u9664\n    pre->next = cur->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(cur);\n}\n\n/* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntypedef struct {\n    AdjListNode *heads[MAX_SIZE]; // \u8282\u70b9\u6570\u7ec4\n    int size;                     // \u8282\u70b9\u6570\u91cf\n} GraphAdjList;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjList *newGraphAdjList() {\n    GraphAdjList *graph = (GraphAdjList *)malloc(sizeof(GraphAdjList));\n    if (!graph) {\n        return NULL;\n    }\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        graph->heads[i] = NULL;\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjList(GraphAdjList *graph) {\n    for (int i = 0; i < graph->size; i++) {\n        AdjListNode *cur = graph->heads[i];\n        while (cur != NULL) {\n            AdjListNode *next = cur->next;\n            if (cur != graph->heads[i]) {\n                free(cur);\n            }\n            cur = next;\n        }\n        free(graph->heads[i]->vertex);\n        free(graph->heads[i]);\n    }\n    free(graph);\n}\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nvoid addEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL && head1 != head2);\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    addEdgeHelper(head1, vet2);\n    addEdgeHelper(head2, vet1);\n}\n\n/* \u5220\u9664\u8fb9 */\nvoid removeEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL);\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    removeEdgeHelper(head1, head2->vertex);\n    removeEdgeHelper(head2, head1->vertex);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjList *graph, Vertex *vet) {\n    assert(graph != NULL && graph->size < MAX_SIZE);\n    AdjListNode *head = (AdjListNode *)malloc(sizeof(AdjListNode));\n    head->vertex = vet;\n    head->next = NULL;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    graph->heads[graph->size++] = head;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjList *graph, Vertex *vet) {\n    AdjListNode *node = findNode(graph, vet);\n    assert(node != NULL);\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    AdjListNode *cur = node, *pre = NULL;\n    while (cur) {\n        pre = cur;\n        cur = cur->next;\n        free(pre);\n    }\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for (int i = 0; i < graph->size; i++) {\n        cur = graph->heads[i];\n        pre = NULL;\n        while (cur) {\n            pre = cur;\n            cur = cur->next;\n            if (cur && cur->vertex == vet) {\n                pre->next = cur->next;\n                free(cur);\n                break;\n            }\n        }\n    }\n    // \u5c06\u8be5\u9876\u70b9\u4e4b\u540e\u7684\u9876\u70b9\u5411\u524d\u79fb\u52a8\uff0c\u4ee5\u586b\u8865\u7a7a\u7f3a\n    int i;\n    for (i = 0; i < graph->size; i++) {\n        if (graph->heads[i] == node)\n            break;\n    }\n    for (int j = i; j < graph->size - 1; j++) {\n        graph->heads[j] = graph->heads[j + 1];\n    }\n    graph->size--;\n    free(vet);\n}\n
    graph_adjacency_list.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList(edges: Array<Array<Vertex?>>) {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    val adjList = HashMap<Vertex, MutableList<Vertex>>()\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (edge in edges) {\n            addVertex(edge[0]!!)\n            addVertex(edge[1]!!)\n            addEdge(edge[0]!!, edge[1]!!)\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return adjList.size\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    fun addEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.add(vet2)\n        adjList[vet2]?.add(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    fun removeEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.remove(vet2)\n        adjList[vet2]?.remove(vet1)\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(vet: Vertex) {\n        if (adjList.containsKey(vet))\n            return\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = mutableListOf()\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(vet: Vertex) {\n        if (!adjList.containsKey(vet))\n            throw IllegalArgumentException()\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (list in adjList.values) {\n            list.remove(vet)\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    fun print() {\n        println(\"\u90bb\u63a5\u8868 =\")\n        for (pair in adjList.entries) {\n            val tmp = mutableListOf<Int>()\n            for (vertex in pair.value) {\n                tmp.add(vertex._val)\n            }\n            println(\"${pair.key._val}: $tmp,\")\n        }\n    }\n}\n
    graph_adjacency_list.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjList\n  attr_reader :adj_list\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(edges)\n    # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    @adj_list = {}\n    # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for edge in edges\n      add_vertex(edge[0])\n      add_vertex(edge[1])\n      add_edge(edge[0], edge[1])\n    end\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @adj_list.length\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    @adj_list[vet1] << vet2\n    @adj_list[vet2] << vet1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    # \u5220\u9664\u8fb9 vet1 - vet2\n    @adj_list[vet1].delete(vet2)\n    @adj_list[vet2].delete(vet1)\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(vet)\n    return if @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    @adj_list[vet] = []\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(vet)\n    raise ArgumentError unless @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    @adj_list.delete(vet)\n    # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for vertex in @adj_list\n      @adj_list[vertex.first].delete(vet) if @adj_list[vertex.first].include?(vet)\n    end\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u8868 ###\n  def __print__\n    puts '\u90bb\u63a5\u8868 ='\n    for vertex in @adj_list\n      tmp = @adj_list[vertex.first].map { |v| v.val }\n      puts \"#{vertex.first.val}: #{tmp},\"\n    end\n  end\nend\n
    graph_adjacency_list.zig
    [class]{GraphAdjList}-[func]{}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_graph/graph_operations/#923-efficiency-comparison","title":"9.2.3 \u00a0 Efficiency comparison","text":"

    Assuming there are \\(n\\) vertices and \\(m\\) edges in the graph, the Table 9-2 compares the time efficiency and space efficiency of the adjacency matrix and adjacency list.

    Table 9-2 \u00a0 Comparison of adjacency matrix and adjacency list

    Adjacency matrix Adjacency list (Linked list) Adjacency list (Hash table) Determine adjacency \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) Add an edge \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) Remove an edge \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) Add a vertex \\(O(n)\\) \\(O(1)\\) \\(O(1)\\) Remove a vertex \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n)\\) Memory space usage \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n + m)\\)

    Observing the Table 9-2 , it seems that the adjacency list (hash table) has the best time efficiency and space efficiency. However, in practice, operating on edges in the adjacency matrix is more efficient, requiring only a single array access or assignment operation. Overall, the adjacency matrix exemplifies the principle of \"space for time\", while the adjacency list exemplifies \"time for space\".

    "},{"location":"chapter_graph/graph_traversal/","title":"9.3 \u00a0 Graph traversal","text":"

    Trees represent a \"one-to-many\" relationship, while graphs have a higher degree of freedom and can represent any \"many-to-many\" relationship. Therefore, we can consider trees as a special case of graphs. Clearly, tree traversal operations are also a special case of graph traversal operations.

    Both graphs and trees require the application of search algorithms to implement traversal operations. Graph traversal can be divided into two types: \"Breadth-First Search (BFS)\" and \"Depth-First Search (DFS)\".

    "},{"location":"chapter_graph/graph_traversal/#931-breadth-first-search","title":"9.3.1 \u00a0 Breadth-first search","text":"

    Breadth-first search is a near-to-far traversal method, starting from a certain node, always prioritizing the visit to the nearest vertices and expanding outwards layer by layer. As shown in the Figure 9-9 , starting from the top left vertex, first traverse all adjacent vertices of that vertex, then traverse all adjacent vertices of the next vertex, and so on, until all vertices have been visited.

    Figure 9-9 \u00a0 Breadth-first traversal of a graph

    "},{"location":"chapter_graph/graph_traversal/#1-algorithm-implementation","title":"1. \u00a0 Algorithm implementation","text":"

    BFS is usually implemented with the help of a queue, as shown in the code below. The queue has a \"first in, first out\" property, which aligns with the BFS idea of traversing \"from near to far\".

    1. Add the starting vertex startVet to the queue and start the loop.
    2. In each iteration of the loop, pop the vertex at the front of the queue and record it as visited, then add all adjacent vertices of that vertex to the back of the queue.
    3. Repeat step 2. until all vertices have been visited.

    To prevent revisiting vertices, we use a hash table visited to record which nodes have been visited.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_bfs.py
    def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]([start_vet])\n    # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    que = deque[Vertex]([start_vet])\n    # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while len(que) > 0:\n        vet = que.popleft()  # \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adj_vet in graph.adj_list[vet]:\n            if adj_vet in visited:\n                continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.append(adj_vet)  # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adj_vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n
    graph_bfs.cpp
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphBFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited = {startVet};\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    queue<Vertex *> que;\n    que.push(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.empty()) {\n        Vertex *vet = que.front();\n        que.pop();          // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push_back(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (auto adjVet : graph.adjList[vet]) {\n            if (visited.count(adjVet))\n                continue;            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.push(adjVet);        // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.emplace(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.java
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new LinkedList<>();\n    que.offer(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        Vertex vet = que.poll(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet);            // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (Vertex adjVet : graph.adjList.get(vet)) {\n            if (visited.contains(adjVet))\n                continue;        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.cs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [startVet];\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new();\n    que.Enqueue(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.Count > 0) {\n        Vertex vet = que.Dequeue(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.Add(vet);               // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        foreach (Vertex adjVet in graph.adjList[vet]) {\n            if (visited.Contains(adjVet)) {\n                continue;          // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.Enqueue(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.Add(adjVet);   // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.go
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    visited[startVet] = struct{}{}\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS, \u4f7f\u7528\u5207\u7247\u6a21\u62df\u961f\u5217\n    queue := make([]Vertex, 0)\n    queue = append(queue, startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    for len(queue) > 0 {\n        // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        vet := queue[0]\n        queue = queue[1:]\n        // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        res = append(res, vet)\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for _, adjVet := range g.adjList[vet] {\n            _, isExist := visited[adjVet]\n            // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            if !isExist {\n                queue = append(queue, adjVet)\n                visited[adjVet] = struct{}{}\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.swift
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = [startVet]\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    var que: [Vertex] = [startVet]\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.isEmpty {\n        let vet = que.removeFirst() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adjVet in graph.adjList[vet] ?? [] {\n            if visited.contains(adjVet) {\n                continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.append(adjVet) // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.insert(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.js
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.ts
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.dart
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n  // \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  visited.add(startVet);\n  // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  Queue<Vertex> que = Queue();\n  que.add(startVet);\n  // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while (que.isNotEmpty) {\n    Vertex vet = que.removeFirst(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet in graph.adjList[vet]!) {\n      if (visited.contains(adjVet)) {\n        continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      }\n      que.add(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    }\n  }\n  // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  return res;\n}\n
    graph_bfs.rs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    visited.insert(start_vet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    let mut que = VecDeque::new();\n    que.push_back(start_vet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.is_empty() {\n        let vet = que.pop_front().unwrap(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        if let Some(adj_vets) = graph.adj_list.get(&vet) {\n            for &adj_vet in adj_vets {\n                if visited.contains(&adj_vet) {\n                    continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n                }\n                que.push_back(adj_vet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited.insert(adj_vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res\n}\n
    graph_bfs.c
    /* \u8282\u70b9\u961f\u5217\u7ed3\u6784\u4f53 */\ntypedef struct {\n    Vertex *vertices[MAX_SIZE];\n    int front, rear, size;\n} Queue;\n\n/* \u6784\u9020\u51fd\u6570 */\nQueue *newQueue() {\n    Queue *q = (Queue *)malloc(sizeof(Queue));\n    q->front = q->rear = q->size = 0;\n    return q;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nint isEmpty(Queue *q) {\n    return q->size == 0;\n}\n\n/* \u5165\u961f\u64cd\u4f5c */\nvoid enqueue(Queue *q, Vertex *vet) {\n    q->vertices[q->rear] = vet;\n    q->rear = (q->rear + 1) % MAX_SIZE;\n    q->size++;\n}\n\n/* \u51fa\u961f\u64cd\u4f5c */\nVertex *dequeue(Queue *q) {\n    Vertex *vet = q->vertices[q->front];\n    q->front = (q->front + 1) % MAX_SIZE;\n    q->size--;\n    return vet;\n}\n\n/* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **visited, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (visited[i] == vet)\n            return 1;\n    }\n    return 0;\n}\n\n/* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphBFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize, Vertex **visited, int *visitedSize) {\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue *queue = newQueue();\n    enqueue(queue, startVet);\n    visited[(*visitedSize)++] = startVet;\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!isEmpty(queue)) {\n        Vertex *vet = dequeue(queue); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res[(*resSize)++] = vet;      // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        AdjListNode *node = findNode(graph, vet);\n        while (node != NULL) {\n            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            if (!isVisited(visited, *visitedSize, node->vertex)) {\n                enqueue(queue, node->vertex);             // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited[(*visitedSize)++] = node->vertex; // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n            node = node->next;\n        }\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(queue);\n}\n
    graph_bfs.kt
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphBFS(graph: GraphAdjList, startVet: Vertex): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex>()\n    visited.add(startVet)\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    val que = LinkedList<Vertex>()\n    que.offer(startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        val vet = que.poll() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet)         // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (adjVet in graph.adjList[vet]!!) {\n            if (visited.contains(adjVet))\n                continue        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet)   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.rb
    ### \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_bfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new([start_vet])\n  # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  que = [start_vet]\n  # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while que.length > 0\n    vet = que.shift # \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adj_vet in graph.adj_list[vet]\n      next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      que << adj_vet # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adj_vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    end\n  end\n  # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res\nend\n
    graph_bfs.zig
    [class]{}-[func]{graphBFS}\n
    Code Visualization

    Full Screen >

    The code is relatively abstract, it is suggested to compare with the following figure to deepen the understanding.

    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 9-10 \u00a0 Steps of breadth-first search of a graph

    Is the sequence of breadth-first traversal unique?

    Not unique. Breadth-first traversal only requires traversing in a \"from near to far\" order, and the traversal order of multiple vertices at the same distance can be arbitrarily shuffled. For example, in the above figure, the visitation order of vertices \\(1\\) and \\(3\\) can be switched, as can the order of vertices \\(2\\), \\(4\\), and \\(6\\).

    "},{"location":"chapter_graph/graph_traversal/#2-complexity-analysis","title":"2. \u00a0 Complexity analysis","text":"

    Time complexity: All vertices will be enqueued and dequeued once, using \\(O(|V|)\\) time; in the process of traversing adjacent vertices, since it is an undirected graph, all edges will be visited \\(2\\) times, using \\(O(2|E|)\\) time; overall using \\(O(|V| + |E|)\\) time.

    Space complexity: The maximum number of vertices in list res, hash table visited, and queue que is \\(|V|\\), using \\(O(|V|)\\) space.

    "},{"location":"chapter_graph/graph_traversal/#932-depth-first-search","title":"9.3.2 \u00a0 Depth-first search","text":"

    Depth-first search is a traversal method that prioritizes going as far as possible and then backtracks when no further paths are available. As shown in the Figure 9-11 , starting from the top left vertex, visit some adjacent vertex of the current vertex until no further path is available, then return and continue until all vertices are traversed.

    Figure 9-11 \u00a0 Depth-first traversal of a graph

    "},{"location":"chapter_graph/graph_traversal/#1-algorithm-implementation_1","title":"1. \u00a0 Algorithm implementation","text":"

    This \"go as far as possible and then return\" algorithm paradigm is usually implemented based on recursion. Similar to breadth-first search, in depth-first search, we also need the help of a hash table visited to record the visited vertices to avoid revisiting.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_dfs.py
    def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570\"\"\"\n    res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adj_list[vet]:\n        if adjVet in visited:\n            continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n\ndef graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]()\n    dfs(graph, visited, res, start_vet)\n    return res\n
    graph_dfs.cpp
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList &graph, unordered_set<Vertex *> &visited, vector<Vertex *> &res, Vertex *vet) {\n    res.push_back(vet);   // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.emplace(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex *adjVet : graph.adjList[vet]) {\n        if (visited.count(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphDFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited;\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.java
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList graph, Set<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet : graph.adjList.get(vet)) {\n        if (visited.contains(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.cs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid DFS(GraphAdjList graph, HashSet<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.Add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.Add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    foreach (Vertex adjVet in graph.adjList[vet]) {\n        if (visited.Contains(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9                             \n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        DFS(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [];\n    DFS(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.go
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(g *graphAdjList, visited map[Vertex]struct{}, res *[]Vertex, vet Vertex) {\n    // append \u64cd\u4f5c\u4f1a\u8fd4\u56de\u65b0\u7684\u7684\u5f15\u7528\uff0c\u5fc5\u987b\u8ba9\u539f\u5f15\u7528\u91cd\u65b0\u8d4b\u503c\u4e3a\u65b0slice\u7684\u5f15\u7528\n    *res = append(*res, vet)\n    visited[vet] = struct{}{}\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for _, adjVet := range g.adjList[vet] {\n        _, isExist := visited[adjVet]\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        if !isExist {\n            dfs(g, visited, res, adjVet)\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    dfs(g, visited, &res, startVet)\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_dfs.swift
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], vet: Vertex) {\n    res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adjList[vet] ?? [] {\n        if visited.contains(adjVet) {\n            continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph: graph, visited: &visited, res: &res, vet: adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = []\n    dfs(graph: graph, visited: &visited, res: &res, vet: startVet)\n    return res\n}\n
    graph_dfs.js
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction dfs(graph, visited, res, vet) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.ts
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunction dfs(\n    graph: GraphAdjList,\n    visited: Set<Vertex>,\n    res: Vertex[],\n    vet: Vertex\n): void {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.dart
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(\n  GraphAdjList graph,\n  Set<Vertex> visited,\n  List<Vertex> res,\n  Vertex vet,\n) {\n  res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for (Vertex adjVet in graph.adjList[vet]!) {\n    if (visited.contains(adjVet)) {\n      continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    }\n    // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adjVet);\n  }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  dfs(graph, visited, res, startVet);\n  return res;\n}\n
    graph_dfs.rs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex>, vet: Vertex) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n                         // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    if let Some(adj_vets) = graph.adj_list.get(&vet) {\n        for &adj_vet in adj_vets {\n            if visited.contains(&adj_vet) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, visited, res, adj_vet);\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    dfs(&graph, &mut visited, &mut res, start_vet);\n\n    res\n}\n
    graph_dfs.c
    /* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **res, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (res[i] == vet) {\n            return 1;\n        }\n    }\n    return 0;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList *graph, Vertex **res, int *resSize, Vertex *vet) {\n    // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    res[(*resSize)++] = vet;\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    AdjListNode *node = findNode(graph, vet);\n    while (node != NULL) {\n        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        if (!isVisited(res, *resSize, node->vertex)) {\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, res, resSize, node->vertex);\n        }\n        node = node->next;\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphDFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize) {\n    dfs(graph, res, resSize, startVet);\n}\n
    graph_dfs.kt
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfun dfs(\n    graph: GraphAdjList,\n    visited: MutableSet<Vertex?>,\n    res: MutableList<Vertex?>,\n    vet: Vertex?\n) {\n    res.add(vet)     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (adjVet in graph.adjList[vet]!!) {\n        if (visited.contains(adjVet))\n            continue  // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphDFS(graph: GraphAdjList, startVet: Vertex?): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex?>()\n    dfs(graph, visited, res, startVet)\n    return res\n}\n
    graph_dfs.rb
    ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 ###\ndef dfs(graph, visited, res, vet)\n  res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for adj_vet in graph.adj_list[vet]\n    next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adj_vet)\n  end\nend\n\n### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_dfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new\n  dfs(graph, visited, res, start_vet)\n  res\nend\n
    graph_dfs.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{graphDFS}\n
    Code Visualization

    Full Screen >

    The algorithm process of depth-first search is shown in the following figure.

    • Dashed lines represent downward recursion, indicating that a new recursive method has been initiated to visit a new vertex.
    • Curved dashed lines represent upward backtracking, indicating that this recursive method has returned to the position where this method was initiated.

    To deepen the understanding, it is suggested to combine the following figure with the code to simulate (or draw) the entire DFS process in your mind, including when each recursive method is initiated and when it returns.

    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 9-12 \u00a0 Steps of depth-first search of a graph

    Is the sequence of depth-first traversal unique?

    Similar to breadth-first traversal, the order of the depth-first traversal sequence is also not unique. Given a certain vertex, exploring in any direction first is possible, that is, the order of adjacent vertices can be arbitrarily shuffled, all being part of depth-first traversal.

    Taking tree traversal as an example, \"root \\(\\rightarrow\\) left \\(\\rightarrow\\) right\", \"left \\(\\rightarrow\\) root \\(\\rightarrow\\) right\", \"left \\(\\rightarrow\\) right \\(\\rightarrow\\) root\" correspond to preorder, inorder, and postorder traversals, respectively. They showcase three types of traversal priorities, yet all three are considered depth-first traversal.

    "},{"location":"chapter_graph/graph_traversal/#2-complexity-analysis_1","title":"2. \u00a0 Complexity analysis","text":"

    Time complexity: All vertices will be visited once, using \\(O(|V|)\\) time; all edges will be visited twice, using \\(O(2|E|)\\) time; overall using \\(O(|V| + |E|)\\) time.

    Space complexity: The maximum number of vertices in list res, hash table visited is \\(|V|\\), and the maximum recursion depth is \\(|V|\\), therefore using \\(O(|V|)\\) space.

    "},{"location":"chapter_graph/summary/","title":"9.4 \u00a0 Summary","text":""},{"location":"chapter_graph/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • A graph consists of vertices and edges and can be represented as a set comprising a group of vertices and a group of edges.
    • Compared to linear relationships (linked lists) and divide-and-conquer relationships (trees), network relationships (graphs) have a higher degree of freedom and are therefore more complex.
    • The edges of a directed graph have directionality, any vertex in a connected graph is reachable, and each edge in a weighted graph contains a weight variable.
    • Adjacency matrices use matrices to represent graphs, with each row (column) representing a vertex and matrix elements representing edges, using \\(1\\) or \\(0\\) to indicate the presence or absence of an edge between two vertices. Adjacency matrices are highly efficient for add, delete, find, and modify operations, but they consume more space.
    • Adjacency lists use multiple linked lists to represent graphs, with the \\(i^{th}\\) list corresponding to vertex \\(i\\), containing all its adjacent vertices. Adjacency lists save more space compared to adjacency matrices, but since it is necessary to traverse the list to find edges, their time efficiency is lower.
    • When the linked lists in the adjacency list are too long, they can be converted into red-black trees or hash tables to improve query efficiency.
    • From the perspective of algorithmic thinking, adjacency matrices embody the principle of \"space for time,\" while adjacency lists embody \"time for space.\"
    • Graphs can be used to model various real systems, such as social networks, subway routes, etc.
    • A tree is a special case of a graph, and tree traversal is also a special case of graph traversal.
    • Breadth-first traversal of a graph is a search method that expands layer by layer from near to far, usually implemented with a queue.
    • Depth-first traversal of a graph is a search method that prefers to go as deep as possible and backtracks when no further paths are available, often based on recursion.
    "},{"location":"chapter_graph/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is a path defined as a sequence of vertices or a sequence of edges?

    Definitions vary between different language versions on Wikipedia: the English version defines a path as \"a sequence of edges,\" while the Chinese version defines it as \"a sequence of vertices.\" Here is the original text from the English version: In graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices.

    In this document, a path is considered a sequence of edges, rather than a sequence of vertices. This is because there might be multiple edges connecting two vertices, in which case each edge corresponds to a path.

    Q: In a disconnected graph, are there points that cannot be traversed to?

    In a disconnected graph, starting from a certain vertex, there is at least one vertex that cannot be reached. Traversing a disconnected graph requires setting multiple starting points to traverse all connected components of the graph.

    Q: In an adjacency list, does the order of \"all vertices connected to that vertex\" matter?

    It can be in any order. However, in practical applications, it might be necessary to sort according to certain rules, such as the order in which vertices are added, or the order of vertex values, etc., to facilitate the quick search for vertices with certain extremal values.

    "},{"location":"chapter_greedy/","title":"Chapter 15. \u00a0 Greedy","text":"

    Abstract

    Sunflowers turn towards the sun, always seeking the greatest possible growth for themselves.

    Greedy strategy guides to the best answer step by step through rounds of simple choices.

    "},{"location":"chapter_greedy/#chapter-contents","title":"Chapter contents","text":"
    • 15.1 \u00a0 Greedy algorithms
    • 15.2 \u00a0 Fractional knapsack problem
    • 15.3 \u00a0 Maximum capacity problem
    • 15.4 \u00a0 Maximum product cutting problem
    • 15.5 \u00a0 Summary
    "},{"location":"chapter_greedy/fractional_knapsack_problem/","title":"15.2 \u00a0 Fractional knapsack problem","text":"

    Question

    Given \\(n\\) items, the weight of the \\(i\\)-th item is \\(wgt[i-1]\\) and its value is \\(val[i-1]\\), and a knapsack with a capacity of \\(cap\\). Each item can be chosen only once, but a part of the item can be selected, with its value calculated based on the proportion of the weight chosen, what is the maximum value of the items in the knapsack under the limited capacity? An example is shown below.

    Figure 15-3 \u00a0 Example data of the fractional knapsack problem

    The fractional knapsack problem is very similar overall to the 0-1 knapsack problem, involving the current item \\(i\\) and capacity \\(c\\), aiming to maximize the value within the limited capacity of the knapsack.

    The difference is that, in this problem, only a part of an item can be chosen. As shown in the Figure 15-4 , we can arbitrarily split the items and calculate the corresponding value based on the weight proportion.

    1. For item \\(i\\), its value per unit weight is \\(val[i-1] / wgt[i-1]\\), referred to as the unit value.
    2. Suppose we put a part of item \\(i\\) with weight \\(w\\) into the knapsack, then the value added to the knapsack is \\(w \\times val[i-1] / wgt[i-1]\\).

    Figure 15-4 \u00a0 Value per unit weight of the item

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#1-greedy-strategy-determination","title":"1. \u00a0 Greedy strategy determination","text":"

    Maximizing the total value of the items in the knapsack essentially means maximizing the value per unit weight. From this, the greedy strategy shown below can be deduced.

    1. Sort the items by their unit value from high to low.
    2. Iterate over all items, greedily choosing the item with the highest unit value in each round.
    3. If the remaining capacity of the knapsack is insufficient, use part of the current item to fill the knapsack.

    Figure 15-5 \u00a0 Greedy strategy of the fractional knapsack problem

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#2-code-implementation","title":"2. \u00a0 Code implementation","text":"

    We have created an Item class in order to sort the items by their unit value. We loop and make greedy choices until the knapsack is full, then exit and return the solution:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig fractional_knapsack.py
    class Item:\n    \"\"\"\u7269\u54c1\"\"\"\n\n    def __init__(self, w: int, v: int):\n        self.w = w  # \u7269\u54c1\u91cd\u91cf\n        self.v = v  # \u7269\u54c1\u4ef7\u503c\n\ndef fractional_knapsack(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3\"\"\"\n    # \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    items = [Item(w, v) for w, v in zip(wgt, val)]\n    # \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort(key=lambda item: item.v / item.w, reverse=True)\n    # \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    res = 0\n    for item in items:\n        if item.w <= cap:\n            # \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v\n            cap -= item.w\n        else:\n            # \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap\n            # \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n    return res\n
    fractional_knapsack.cpp
    /* \u7269\u54c1 */\nclass Item {\n  public:\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n\n    Item(int w, int v) : w(w), v(v) {\n    }\n};\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(vector<int> &wgt, vector<int> &val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    vector<Item> items;\n    for (int i = 0; i < wgt.size(); i++) {\n        items.push_back(Item(wgt[i], val[i]));\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    sort(items.begin(), items.end(), [](Item &a, Item &b) { return (double)a.v / a.w > (double)b.v / b.w; });\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    for (auto &item : items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double)item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.java
    /* \u7269\u54c1 */\nclass Item {\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n\n    public Item(int w, int v) {\n        this.w = w;\n        this.v = v;\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(int[] wgt, int[] val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item[] items = new Item[wgt.length];\n    for (int i = 0; i < wgt.length; i++) {\n        items[i] = new Item(wgt[i], val[i]);\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    Arrays.sort(items, Comparator.comparingDouble(item -> -((double) item.v / item.w)));\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    for (Item item : items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double) item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.cs
    /* \u7269\u54c1 */\nclass Item(int w, int v) {\n    public int w = w; // \u7269\u54c1\u91cd\u91cf\n    public int v = v; // \u7269\u54c1\u4ef7\u503c\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble FractionalKnapsack(int[] wgt, int[] val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item[] items = new Item[wgt.Length];\n    for (int i = 0; i < wgt.Length; i++) {\n        items[i] = new Item(wgt[i], val[i]);\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    Array.Sort(items, (x, y) => (y.v / y.w).CompareTo(x.v / x.w));\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    foreach (Item item in items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double)item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.go
    /* \u7269\u54c1 */\ntype Item struct {\n    w int // \u7269\u54c1\u91cd\u91cf\n    v int // \u7269\u54c1\u4ef7\u503c\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunc fractionalKnapsack(wgt []int, val []int, cap int) float64 {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    items := make([]Item, len(wgt))\n    for i := 0; i < len(wgt); i++ {\n        items[i] = Item{wgt[i], val[i]}\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    sort.Slice(items, func(i, j int) bool {\n        return float64(items[i].v)/float64(items[i].w) > float64(items[j].v)/float64(items[j].w)\n    })\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    res := 0.0\n    for _, item := range items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += float64(item.v)\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += float64(item.v) / float64(item.w) * float64(cap)\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.swift
    /* \u7269\u54c1 */\nclass Item {\n    var w: Int // \u7269\u54c1\u91cd\u91cf\n    var v: Int // \u7269\u54c1\u4ef7\u503c\n\n    init(w: Int, v: Int) {\n        self.w = w\n        self.v = v\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunc fractionalKnapsack(wgt: [Int], val: [Int], cap: Int) -> Double {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    var items = zip(wgt, val).map { Item(w: $0, v: $1) }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    var res = 0.0\n    var cap = cap\n    for item in items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += Double(item.v)\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += Double(item.v) / Double(item.w) * Double(cap)\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.js
    /* \u7269\u54c1 */\nclass Item {\n    constructor(w, v) {\n        this.w = w; // \u7269\u54c1\u91cd\u91cf\n        this.v = v; // \u7269\u54c1\u4ef7\u503c\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunction fractionalKnapsack(wgt, val, cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    const items = wgt.map((w, i) => new Item(w, val[i]));\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort((a, b) => b.v / b.w - a.v / a.w);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let res = 0;\n    for (const item of items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.ts
    /* \u7269\u54c1 */\nclass Item {\n    w: number; // \u7269\u54c1\u91cd\u91cf\n    v: number; // \u7269\u54c1\u4ef7\u503c\n\n    constructor(w: number, v: number) {\n        this.w = w;\n        this.v = v;\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunction fractionalKnapsack(wgt: number[], val: number[], cap: number): number {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    const items: Item[] = wgt.map((w, i) => new Item(w, val[i]));\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort((a, b) => b.v / b.w - a.v / a.w);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let res = 0;\n    for (const item of items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.dart
    /* \u7269\u54c1 */\nclass Item {\n  int w; // \u7269\u54c1\u91cd\u91cf\n  int v; // \u7269\u54c1\u4ef7\u503c\n\n  Item(this.w, this.v);\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(List<int> wgt, List<int> val, int cap) {\n  // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n  List<Item> items = List.generate(wgt.length, (i) => Item(wgt[i], val[i]));\n  // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n  items.sort((a, b) => (b.v / b.w).compareTo(a.v / a.w));\n  // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n  double res = 0;\n  for (Item item in items) {\n    if (item.w <= cap) {\n      // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n      res += item.v;\n      cap -= item.w;\n    } else {\n      // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n      res += item.v / item.w * cap;\n      // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n      break;\n    }\n  }\n  return res;\n}\n
    fractional_knapsack.rs
    /* \u7269\u54c1 */\nstruct Item {\n    w: i32, // \u7269\u54c1\u91cd\u91cf\n    v: i32, // \u7269\u54c1\u4ef7\u503c\n}\n\nimpl Item {\n    fn new(w: i32, v: i32) -> Self {\n        Self { w, v }\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfn fractional_knapsack(wgt: &[i32], val: &[i32], mut cap: i32) -> f64 {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    let mut items = wgt\n        .iter()\n        .zip(val.iter())\n        .map(|(&w, &v)| Item::new(w, v))\n        .collect::<Vec<Item>>();\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort_by(|a, b| {\n        (b.v as f64 / b.w as f64)\n            .partial_cmp(&(a.v as f64 / a.w as f64))\n            .unwrap()\n    });\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let mut res = 0.0;\n    for item in &items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v as f64;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += item.v as f64 / item.w as f64 * cap as f64;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    res\n}\n
    fractional_knapsack.c
    /* \u7269\u54c1 */\ntypedef struct {\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n} Item;\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfloat fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item *items = malloc(sizeof(Item) * itemCount);\n    for (int i = 0; i < itemCount; i++) {\n        items[i] = (Item){.w = wgt[i], .v = val[i]};\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    qsort(items, (size_t)itemCount, sizeof(Item), sortByValueDensity);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    float res = 0.0;\n    for (int i = 0; i < itemCount; i++) {\n        if (items[i].w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += items[i].v;\n            cap -= items[i].w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (float)cap / items[i].w * items[i].v;\n            cap = 0;\n            break;\n        }\n    }\n    free(items);\n    return res;\n}\n
    fractional_knapsack.kt
    /* \u7269\u54c1 */\nclass Item(\n    val w: Int, // \u7269\u54c1\n    val v: Int  // \u7269\u54c1\u4ef7\u503c\n)\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfun fractionalKnapsack(wgt: IntArray, _val: IntArray, c: Int): Double {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    var cap = c\n    val items = arrayOfNulls<Item>(wgt.size)\n    for (i in wgt.indices) {\n        items[i] = Item(wgt[i], _val[i])\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sortBy { item: Item? -> -(item!!.v.toDouble() / item.w) }\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    var res = 0.0\n    for (item in items) {\n        if (item!!.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += item.v.toDouble() / item.w * cap\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.rb
    [class]{Item}-[func]{}\n\n[class]{}-[func]{fractional_knapsack}\n
    fractional_knapsack.zig
    [class]{Item}-[func]{}\n\n[class]{}-[func]{fractionalKnapsack}\n
    Code Visualization

    Full Screen >

    Apart from sorting, in the worst case, the entire list of items needs to be traversed, hence the time complexity is \\(O(n)\\), where \\(n\\) is the number of items.

    Since an Item object list is initialized, the space complexity is \\(O(n)\\).

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#3-correctness-proof","title":"3. \u00a0 Correctness proof","text":"

    Using proof by contradiction. Suppose item \\(x\\) has the highest unit value, and some algorithm yields a maximum value res, but the solution does not include item \\(x\\).

    Now remove a unit weight of any item from the knapsack and replace it with a unit weight of item \\(x\\). Since the unit value of item \\(x\\) is the highest, the total value after replacement will definitely be greater than res. This contradicts the assumption that res is the optimal solution, proving that the optimal solution must include item \\(x\\).

    For other items in this solution, we can also construct the above contradiction. Overall, items with greater unit value are always better choices, proving that the greedy strategy is effective.

    As shown in the Figure 15-6 , if the item weight and unit value are viewed as the horizontal and vertical axes of a two-dimensional chart respectively, the fractional knapsack problem can be transformed into \"seeking the largest area enclosed within a limited horizontal axis range\". This analogy can help us understand the effectiveness of the greedy strategy from a geometric perspective.

    Figure 15-6 \u00a0 Geometric representation of the fractional knapsack problem

    "},{"location":"chapter_greedy/greedy_algorithm/","title":"15.1 \u00a0 Greedy algorithms","text":"

    Greedy algorithm is a common algorithm for solving optimization problems, which fundamentally involves making the seemingly best choice at each decision-making stage of the problem, i.e., greedily making locally optimal decisions in hopes of finding a globally optimal solution. Greedy algorithms are concise and efficient, and are widely used in many practical problems.

    Greedy algorithms and dynamic programming are both commonly used to solve optimization problems. They share some similarities, such as relying on the property of optimal substructure, but they operate differently.

    • Dynamic programming considers all previous decisions at the current decision stage and uses solutions to past subproblems to construct solutions for the current subproblem.
    • Greedy algorithms do not consider past decisions; instead, they proceed with greedy choices, continually narrowing the scope of the problem until it is solved.

    Let's first understand the working principle of the greedy algorithm through the example of \"coin change,\" which has been introduced in the \"Complete Knapsack Problem\" chapter. I believe you are already familiar with it.

    Question

    Given \\(n\\) types of coins, where the denomination of the \\(i\\)th type of coin is \\(coins[i - 1]\\), and the target amount is \\(amt\\), with each type of coin available indefinitely, what is the minimum number of coins needed to make up the target amount? If it is not possible to make up the target amount, return \\(-1\\).

    The greedy strategy adopted in this problem is shown in the following figure. Given the target amount, we greedily choose the coin that is closest to and not greater than it, repeatedly following this step until the target amount is met.

    Figure 15-1 \u00a0 Greedy strategy for coin change

    The implementation code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_greedy.py
    def coin_change_greedy(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3\"\"\"\n    # \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    i = len(coins) - 1\n    count = 0\n    # \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0:\n        # \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 and coins[i] > amt:\n            i -= 1\n        # \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count += 1\n    # \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return count if amt == 0 else -1\n
    coin_change_greedy.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(vector<int> &coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.size() - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(int[] coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.length - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint CoinChangeGreedy(int[] coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.Length - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunc coinChangeGreedy(coins []int, amt int) int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    i := len(coins) - 1\n    count := 0\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    for amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        for i > 0 && coins[i] > amt {\n            i--\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count++\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    if amt != 0 {\n        return -1\n    }\n    return count\n}\n
    coin_change_greedy.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunc coinChangeGreedy(coins: [Int], amt: Int) -> Int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    var i = coins.count - 1\n    var count = 0\n    var amt = amt\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 && coins[i] > amt {\n            i -= 1\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count += 1\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1\n}\n
    coin_change_greedy.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunction coinChangeGreedy(coins, amt) {\n    // \u5047\u8bbe coins \u6570\u7ec4\u6709\u5e8f\n    let i = coins.length - 1;\n    let count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt === 0 ? count : -1;\n}\n
    coin_change_greedy.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunction coinChangeGreedy(coins: number[], amt: number): number {\n    // \u5047\u8bbe coins \u6570\u7ec4\u6709\u5e8f\n    let i = coins.length - 1;\n    let count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt === 0 ? count : -1;\n}\n
    coin_change_greedy.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(List<int> coins, int amt) {\n  // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n  int i = coins.length - 1;\n  int count = 0;\n  // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n  while (amt > 0) {\n    // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n    while (i > 0 && coins[i] > amt) {\n      i--;\n    }\n    // \u9009\u62e9 coins[i]\n    amt -= coins[i];\n    count++;\n  }\n  // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n  return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfn coin_change_greedy(coins: &[i32], mut amt: i32) -> i32 {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    let mut i = coins.len() - 1;\n    let mut count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 && coins[i] > amt {\n            i -= 1;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count += 1;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    if amt == 0 {\n        count\n    } else {\n        -1\n    }\n}\n
    coin_change_greedy.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(int *coins, int size, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = size - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfun coinChangeGreedy(coins: IntArray, amt: Int): Int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    var am = amt\n    var i = coins.size - 1\n    var count = 0\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (am > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > am) {\n            i--\n        }\n        // \u9009\u62e9 coins[i]\n        am -= coins[i]\n        count++\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return if (am == 0) count else -1\n}\n
    coin_change_greedy.rb
    [class]{}-[func]{coin_change_greedy}\n
    coin_change_greedy.zig
    [class]{}-[func]{coinChangeGreedy}\n
    Code Visualization

    Full Screen >

    You might exclaim: So clean! The greedy algorithm solves the coin change problem in about ten lines of code.

    "},{"location":"chapter_greedy/greedy_algorithm/#1511-advantages-and-limitations-of-greedy-algorithms","title":"15.1.1 \u00a0 Advantages and limitations of greedy algorithms","text":"

    Greedy algorithms are not only straightforward and simple to implement, but they are also usually very efficient. In the code above, if the smallest coin denomination is \\(\\min(coins)\\), the greedy choice loops at most \\(amt / \\min(coins)\\) times, giving a time complexity of \\(O(amt / \\min(coins))\\). This is an order of magnitude smaller than the time complexity of the dynamic programming solution, which is \\(O(n \\times amt)\\).

    However, for some combinations of coin denominations, greedy algorithms cannot find the optimal solution. The following figure provides two examples.

    • Positive example \\(coins = [1, 5, 10, 20, 50, 100]\\): In this coin combination, given any \\(amt\\), the greedy algorithm can find the optimal solution.
    • Negative example \\(coins = [1, 20, 50]\\): Suppose \\(amt = 60\\), the greedy algorithm can only find the combination \\(50 + 1 \\times 10\\), totaling 11 coins, but dynamic programming can find the optimal solution of \\(20 + 20 + 20\\), needing only 3 coins.
    • Negative example \\(coins = [1, 49, 50]\\): Suppose \\(amt = 98\\), the greedy algorithm can only find the combination \\(50 + 1 \\times 48\\), totaling 49 coins, but dynamic programming can find the optimal solution of \\(49 + 49\\), needing only 2 coins.

    Figure 15-2 \u00a0 Examples where greedy algorithms do not find the optimal solution

    This means that for the coin change problem, greedy algorithms cannot guarantee finding the globally optimal solution, and they might find a very poor solution. They are better suited for dynamic programming.

    Generally, the suitability of greedy algorithms falls into two categories.

    1. Guaranteed to find the optimal solution: In these cases, greedy algorithms are often the best choice, as they tend to be more efficient than backtracking or dynamic programming.
    2. Can find a near-optimal solution: Greedy algorithms are also applicable here. For many complex problems, finding the global optimal solution is very challenging, and being able to find a high-efficiency suboptimal solution is also very commendable.
    "},{"location":"chapter_greedy/greedy_algorithm/#1512-characteristics-of-greedy-algorithms","title":"15.1.2 \u00a0 Characteristics of greedy algorithms","text":"

    So, what kind of problems are suitable for solving with greedy algorithms? Or rather, under what conditions can greedy algorithms guarantee to find the optimal solution?

    Compared to dynamic programming, greedy algorithms have stricter usage conditions, focusing mainly on two properties of the problem.

    • Greedy choice property: Only when the locally optimal choice can always lead to a globally optimal solution can greedy algorithms guarantee to obtain the optimal solution.
    • Optimal substructure: The optimal solution to the original problem contains the optimal solutions to its subproblems.

    Optimal substructure has already been introduced in the \"Dynamic Programming\" chapter, so it is not discussed further here. It's important to note that some problems do not have an obvious optimal substructure, but can still be solved using greedy algorithms.

    We mainly explore the method for determining the greedy choice property. Although its description seems simple, in practice, proving the greedy choice property for many problems is not easy.

    For example, in the coin change problem, although we can easily cite counterexamples to disprove the greedy choice property, proving it is much more challenging. If asked, what conditions must a coin combination meet to be solvable using a greedy algorithm? We often have to rely on intuition or examples to provide an ambiguous answer, as it is difficult to provide a rigorous mathematical proof.

    Quote

    A paper presents an algorithm with a time complexity of \\(O(n^3)\\) for determining whether a coin combination can use a greedy algorithm to find the optimal solution for any amount.

    Pearson, D. A polynomial-time algorithm for the change-making problem[J]. Operations Research Letters, 2005, 33(3): 231-234.

    "},{"location":"chapter_greedy/greedy_algorithm/#1513-steps-for-solving-problems-with-greedy-algorithms","title":"15.1.3 \u00a0 Steps for solving problems with greedy algorithms","text":"

    The problem-solving process for greedy problems can generally be divided into the following three steps.

    1. Problem analysis: Sort out and understand the characteristics of the problem, including state definition, optimization objectives, and constraints, etc. This step is also involved in backtracking and dynamic programming.
    2. Determine the greedy strategy: Determine how to make a greedy choice at each step. This strategy can reduce the scale of the problem at each step and eventually solve the entire problem.
    3. Proof of correctness: It is usually necessary to prove that the problem has both a greedy choice property and optimal substructure. This step may require mathematical proofs, such as induction or reductio ad absurdum.

    Determining the greedy strategy is the core step in solving the problem, but it may not be easy to implement, mainly for the following reasons.

    • Greedy strategies vary greatly between different problems. For many problems, the greedy strategy is fairly straightforward, and we can come up with it through some general thinking and attempts. However, for some complex problems, the greedy strategy may be very elusive, which is a real test of individual problem-solving experience and algorithmic capability.
    • Some greedy strategies are quite misleading. When we confidently design a greedy strategy, write the code, and submit it for testing, it is quite possible that some test cases will not pass. This is because the designed greedy strategy is only \"partially correct,\" as described above with the coin change example.

    To ensure accuracy, we should provide rigorous mathematical proofs for the greedy strategy, usually involving reductio ad absurdum or mathematical induction.

    However, proving correctness may not be an easy task. If we are at a loss, we usually choose to debug the code based on test cases, modifying and verifying the greedy strategy step by step.

    "},{"location":"chapter_greedy/greedy_algorithm/#1514-typical-problems-solved-by-greedy-algorithms","title":"15.1.4 \u00a0 Typical problems solved by greedy algorithms","text":"

    Greedy algorithms are often applied to optimization problems that satisfy the properties of greedy choice and optimal substructure. Below are some typical greedy algorithm problems.

    • Coin change problem: In some coin combinations, the greedy algorithm always provides the optimal solution.
    • Interval scheduling problem: Suppose you have several tasks, each of which takes place over a period of time. Your goal is to complete as many tasks as possible. If you always choose the task that ends the earliest, then the greedy algorithm can achieve the optimal solution.
    • Fractional knapsack problem: Given a set of items and a carrying capacity, your goal is to select a set of items such that the total weight does not exceed the carrying capacity and the total value is maximized. If you always choose the item with the highest value-to-weight ratio (value / weight), the greedy algorithm can achieve the optimal solution in some cases.
    • Stock trading problem: Given a set of historical stock prices, you can make multiple trades, but you cannot buy again until after you have sold if you already own stocks. The goal is to achieve the maximum profit.
    • Huffman coding: Huffman coding is a greedy algorithm used for lossless data compression. By constructing a Huffman tree, it always merges the two nodes with the lowest frequency, resulting in a Huffman tree with the minimum weighted path length (coding length).
    • Dijkstra's algorithm: It is a greedy algorithm for solving the shortest path problem from a given source vertex to all other vertices.
    "},{"location":"chapter_greedy/max_capacity_problem/","title":"15.3 \u00a0 Maximum capacity problem","text":"

    Question

    Input an array \\(ht\\), where each element represents the height of a vertical partition. Any two partitions in the array, along with the space between them, can form a container.

    The capacity of the container is the product of the height and the width (area), where the height is determined by the shorter partition, and the width is the difference in array indices between the two partitions.

    Please select two partitions in the array that maximize the container's capacity and return this maximum capacity. An example is shown in the following figure.

    Figure 15-7 \u00a0 Example data for the maximum capacity problem

    The container is formed by any two partitions, therefore the state of this problem is represented by the indices of the two partitions, denoted as \\([i, j]\\).

    According to the problem statement, the capacity equals the product of height and width, where the height is determined by the shorter partition, and the width is the difference in array indices between the two partitions. The formula for capacity \\(cap[i, j]\\) is:

    \\[ cap[i, j] = \\min(ht[i], ht[j]) \\times (j - i) \\]

    Assuming the length of the array is \\(n\\), the number of combinations of two partitions (total number of states) is \\(C_n^2 = \\frac{n(n - 1)}{2}\\). The most straightforward approach is to enumerate all possible states, resulting in a time complexity of \\(O(n^2)\\).

    "},{"location":"chapter_greedy/max_capacity_problem/#1-determination-of-a-greedy-strategy","title":"1. \u00a0 Determination of a greedy strategy","text":"

    There is a more efficient solution to this problem. As shown in the following figure, we select a state \\([i, j]\\) where the indices \\(i < j\\) and the height \\(ht[i] < ht[j]\\), meaning \\(i\\) is the shorter partition, and \\(j\\) is the taller one.

    Figure 15-8 \u00a0 Initial state

    As shown in the following figure, if we move the taller partition \\(j\\) closer to the shorter partition \\(i\\), the capacity will definitely decrease.

    This is because when moving the taller partition \\(j\\), the width \\(j-i\\) definitely decreases; and since the height is determined by the shorter partition, the height can only remain the same (if \\(i\\) remains the shorter partition) or decrease (if the moved \\(j\\) becomes the shorter partition).

    Figure 15-9 \u00a0 State after moving the taller partition inward

    Conversely, we can only possibly increase the capacity by moving the shorter partition \\(i\\) inward. Although the width will definitely decrease, the height may increase (if the moved shorter partition \\(i\\) becomes taller). For example, in the Figure 15-10 , the area increases after moving the shorter partition.

    Figure 15-10 \u00a0 State after moving the shorter partition inward

    This leads us to the greedy strategy for this problem: initialize two pointers at the ends of the container, and in each round, move the pointer corresponding to the shorter partition inward until the two pointers meet.

    The following figures illustrate the execution of the greedy strategy.

    1. Initially, the pointers \\(i\\) and \\(j\\) are positioned at the ends of the array.
    2. Calculate the current state's capacity \\(cap[i, j]\\) and update the maximum capacity.
    3. Compare the heights of partitions \\(i\\) and \\(j\\), and move the shorter partition inward by one step.
    4. Repeat steps 2. and 3. until \\(i\\) and \\(j\\) meet.
    <1><2><3><4><5><6><7><8><9>

    Figure 15-11 \u00a0 The greedy process for maximum capacity problem

    "},{"location":"chapter_greedy/max_capacity_problem/#2-implementation","title":"2. \u00a0 Implementation","text":"

    The code loops at most \\(n\\) times, thus the time complexity is \\(O(n)\\).

    The variables \\(i\\), \\(j\\), and \\(res\\) use a constant amount of extra space, thus the space complexity is \\(O(1)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig max_capacity.py
    def max_capacity(ht: list[int]) -> int:\n    \"\"\"\u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3\"\"\"\n    # \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    i, j = 0, len(ht) - 1\n    # \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    res = 0\n    # \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j:\n        # \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        # \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j]:\n            i += 1\n        else:\n            j -= 1\n    return res\n
    max_capacity.cpp
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(vector<int> &ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.size() - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = min(ht[i], ht[j]) * (j - i);\n        res = max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.java
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(int[] ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.cs
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint MaxCapacity(int[] ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.Length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = Math.Min(ht[i], ht[j]) * (j - i);\n        res = Math.Max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.go
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunc maxCapacity(ht []int) int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    i, j := 0, len(ht)-1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    res := 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    for i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        capacity := int(math.Min(float64(ht[i]), float64(ht[j]))) * (j - i)\n        res = int(math.Max(float64(res), float64(capacity)))\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i++\n        } else {\n            j--\n        }\n    }\n    return res\n}\n
    max_capacity.swift
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunc maxCapacity(ht: [Int]) -> Int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    var i = ht.startIndex, j = ht.endIndex - 1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    var res = 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        let cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i += 1\n        } else {\n            j -= 1\n        }\n    }\n    return res\n}\n
    max_capacity.js
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunction maxCapacity(ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let i = 0,\n        j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        const cap = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    return res;\n}\n
    max_capacity.ts
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunction maxCapacity(ht: number[]): number {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let i = 0,\n        j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        const cap: number = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    return res;\n}\n
    max_capacity.dart
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(List<int> ht) {\n  // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n  int i = 0, j = ht.length - 1;\n  // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n  int res = 0;\n  // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n  while (i < j) {\n    // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n    int cap = min(ht[i], ht[j]) * (j - i);\n    res = max(res, cap);\n    // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n    if (ht[i] < ht[j]) {\n      i++;\n    } else {\n      j--;\n    }\n  }\n  return res;\n}\n
    max_capacity.rs
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfn max_capacity(ht: &[i32]) -> i32 {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let mut i = 0;\n    let mut j = ht.len() - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let mut res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        let cap = std::cmp::min(ht[i], ht[j]) * (j - i) as i32;\n        res = std::cmp::max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    res\n}\n
    max_capacity.c
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(int ht[], int htLength) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0;\n    int j = htLength - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int capacity = myMin(ht[i], ht[j]) * (j - i);\n        res = myMax(res, capacity);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.kt
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfun maxCapacity(ht: IntArray): Int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    var i = 0\n    var j = ht.size - 1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    var res = 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        val cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++\n        } else {\n            j--\n        }\n    }\n    return res\n}\n
    max_capacity.rb
    [class]{}-[func]{max_capacity}\n
    max_capacity.zig
    [class]{}-[func]{maxCapacity}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_greedy/max_capacity_problem/#3-proof-of-correctness","title":"3. \u00a0 Proof of correctness","text":"

    The reason why the greedy method is faster than enumeration is that each round of greedy selection \"skips\" some states.

    For example, under the state \\(cap[i, j]\\) where \\(i\\) is the shorter partition and \\(j\\) is the taller partition, greedily moving the shorter partition \\(i\\) inward by one step leads to the \"skipped\" states shown below. This means that these states' capacities cannot be verified later.

    \\[ cap[i, i+1], cap[i, i+2], \\dots, cap[i, j-2], cap[i, j-1] \\]

    Figure 15-12 \u00a0 States skipped by moving the shorter partition

    It is observed that these skipped states are actually all states where the taller partition \\(j\\) is moved inward. We have already proven that moving the taller partition inward will definitely decrease the capacity. Therefore, the skipped states cannot possibly be the optimal solution, and skipping them does not lead to missing the optimal solution.

    The analysis shows that the operation of moving the shorter partition is \"safe\", and the greedy strategy is effective.

    "},{"location":"chapter_greedy/max_product_cutting_problem/","title":"15.4 \u00a0 Maximum product cutting problem","text":"

    Question

    Given a positive integer \\(n\\), split it into at least two positive integers that sum up to \\(n\\), and find the maximum product of these integers, as illustrated below.

    Figure 15-13 \u00a0 Definition of the maximum product cutting problem

    Assume we split \\(n\\) into \\(m\\) integer factors, where the \\(i\\)-th factor is denoted as \\(n_i\\), that is,

    \\[ n = \\sum_{i=1}^{m}n_i \\]

    The goal of this problem is to find the maximum product of all integer factors, namely,

    \\[ \\max(\\prod_{i=1}^{m}n_i) \\]

    We need to consider: How large should the number of splits \\(m\\) be, and what should each \\(n_i\\) be?

    "},{"location":"chapter_greedy/max_product_cutting_problem/#1-greedy-strategy-determination","title":"1. \u00a0 Greedy strategy determination","text":"

    Experience suggests that the product of two integers is often greater than their sum. Suppose we split a factor of \\(2\\) from \\(n\\), then their product is \\(2(n-2)\\). Compare this product with \\(n\\):

    \\[ \\begin{aligned} 2(n-2) & \\geq n \\newline 2n - n - 4 & \\geq 0 \\newline n & \\geq 4 \\end{aligned} \\]

    As shown below, when \\(n \\geq 4\\), splitting out a \\(2\\) increases the product, which indicates that integers greater than or equal to \\(4\\) should be split.

    Greedy strategy one: If the splitting scheme includes factors \\(\\geq 4\\), they should be further split. The final split should only include factors \\(1\\), \\(2\\), and \\(3\\).

    Figure 15-14 \u00a0 Product increase due to splitting

    Next, consider which factor is optimal. Among the factors \\(1\\), \\(2\\), and \\(3\\), clearly \\(1\\) is the worst, as \\(1 \\times (n-1) < n\\) always holds, meaning splitting out \\(1\\) actually decreases the product.

    As shown below, when \\(n = 6\\), \\(3 \\times 3 > 2 \\times 2 \\times 2\\). This means splitting out \\(3\\) is better than splitting out \\(2\\).

    Greedy strategy two: In the splitting scheme, there should be at most two \\(2\\)s. Because three \\(2\\)s can always be replaced by two \\(3\\)s to obtain a higher product.

    Figure 15-15 \u00a0 Optimal splitting factors

    From the above, the following greedy strategies can be derived.

    1. Input integer \\(n\\), continually split out factor \\(3\\) until the remainder is \\(0\\), \\(1\\), or \\(2\\).
    2. When the remainder is \\(0\\), it means \\(n\\) is a multiple of \\(3\\), so no further action is taken.
    3. When the remainder is \\(2\\), do not continue to split, keep it.
    4. When the remainder is \\(1\\), since \\(2 \\times 2 > 1 \\times 3\\), the last \\(3\\) should be replaced with \\(2\\).
    "},{"location":"chapter_greedy/max_product_cutting_problem/#2-code-implementation","title":"2. \u00a0 Code implementation","text":"

    As shown below, we do not need to use loops to split the integer but can use the floor division operation to get the number of \\(3\\)s, \\(a\\), and the modulo operation to get the remainder, \\(b\\), thus:

    \\[ n = 3a + b \\]

    Please note, for the boundary case where \\(n \\leq 3\\), a \\(1\\) must be split out, with a product of \\(1 \\times (n - 1)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig max_product_cutting.py
    def max_product_cutting(n: int) -> int:\n    \"\"\"\u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3\"\"\"\n    # \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3:\n        return 1 * (n - 1)\n    # \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    a, b = n // 3, n % 3\n    if b == 1:\n        # \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return int(math.pow(3, a - 1)) * 2 * 2\n    if b == 2:\n        # \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return int(math.pow(3, a)) * 2\n    # \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return int(math.pow(3, a))\n
    max_product_cutting.cpp
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int)pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int)pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int)pow(3, a);\n}\n
    max_product_cutting.java
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int) Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int) Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int) Math.pow(3, a);\n}\n
    max_product_cutting.cs
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint MaxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int)Math.Pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int)Math.Pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int)Math.Pow(3, a);\n}\n
    max_product_cutting.go
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunc maxProductCutting(n int) int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    a := n / 3\n    b := n % 3\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return int(math.Pow(3, float64(a-1))) * 2 * 2\n    }\n    if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return int(math.Pow(3, float64(a))) * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return int(math.Pow(3, float64(a)))\n}\n
    max_product_cutting.swift
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunc maxProductCutting(n: Int) -> Int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = n / 3\n    let b = n % 3\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return pow(3, a - 1) * 2 * 2\n    }\n    if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return pow(3, a) * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return pow(3, a)\n}\n
    max_product_cutting.js
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunction maxProductCutting(n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = Math.floor(n / 3);\n    let b = n % 3;\n    if (b === 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b === 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return Math.pow(3, a);\n}\n
    max_product_cutting.ts
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunction maxProductCutting(n: number): number {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a: number = Math.floor(n / 3);\n    let b: number = n % 3;\n    if (b === 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b === 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return Math.pow(3, a);\n}\n
    max_product_cutting.dart
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n  // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n  if (n <= 3) {\n    return 1 * (n - 1);\n  }\n  // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n  int a = n ~/ 3;\n  int b = n % 3;\n  if (b == 1) {\n    // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n    return (pow(3, a - 1) * 2 * 2).toInt();\n  }\n  if (b == 2) {\n    // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (pow(3, a) * 2).toInt();\n  }\n  // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n  return pow(3, a).toInt();\n}\n
    max_product_cutting.rs
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfn max_product_cutting(n: i32) -> i32 {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = n / 3;\n    let b = n % 3;\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        3_i32.pow(a as u32 - 1) * 2 * 2\n    } else if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        3_i32.pow(a as u32) * 2\n    } else {\n        // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        3_i32.pow(a as u32)\n    }\n}\n
    max_product_cutting.c
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return pow(3, a);\n}\n
    max_product_cutting.kt
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfun maxProductCutting(n: Int): Int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    val a = n / 3\n    val b = n % 3\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return 3.0.pow((a - 1)).toInt() * 2 * 2\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return 3.0.pow(a).toInt() * 2 * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return 3.0.pow(a).toInt()\n}\n
    max_product_cutting.rb
    [class]{}-[func]{max_product_cutting}\n
    max_product_cutting.zig
    [class]{}-[func]{maxProductCutting}\n
    Code Visualization

    Full Screen >

    Figure 15-16 \u00a0 Calculation method of the maximum product after cutting

    Time complexity depends on the implementation of the power operation in the programming language. For Python, the commonly used power calculation functions are three types:

    • Both the operator ** and the function pow() have a time complexity of \\(O(\\log\u2061 a)\\).
    • The math.pow() function internally calls the C language library's pow() function, performing floating-point exponentiation, with a time complexity of \\(O(1)\\).

    Variables \\(a\\) and \\(b\\) use constant size of extra space, hence the space complexity is \\(O(1)\\).

    "},{"location":"chapter_greedy/max_product_cutting_problem/#3-correctness-proof","title":"3. \u00a0 Correctness proof","text":"

    Using the proof by contradiction, only analyze cases where \\(n \\geq 3\\).

    1. All factors \\(\\leq 3\\): Assume the optimal splitting scheme includes a factor \\(x \\geq 4\\), then it can definitely be further split into \\(2(x-2)\\), obtaining a larger product. This contradicts the assumption.
    2. The splitting scheme does not contain \\(1\\): Assume the optimal splitting scheme includes a factor of \\(1\\), then it can definitely be merged into another factor to obtain a larger product. This contradicts the assumption.
    3. The splitting scheme contains at most two \\(2\\)s: Assume the optimal splitting scheme includes three \\(2\\)s, then they can definitely be replaced by two \\(3\\)s, achieving a higher product. This contradicts the assumption.
    "},{"location":"chapter_greedy/summary/","title":"15.5 \u00a0 Summary","text":"
    • Greedy algorithms are often used to solve optimization problems, where the principle is to make locally optimal decisions at each decision stage in order to achieve a globally optimal solution.
    • Greedy algorithms iteratively make one greedy choice after another, transforming the problem into a smaller sub-problem with each round, until the problem is resolved.
    • Greedy algorithms are not only simple to implement but also have high problem-solving efficiency. Compared to dynamic programming, greedy algorithms generally have a lower time complexity.
    • In the problem of coin change, greedy algorithms can guarantee the optimal solution for certain combinations of coins; for others, however, the greedy algorithm might find a very poor solution.
    • Problems suitable for greedy algorithm solutions possess two main properties: greedy-choice property and optimal substructure. The greedy-choice property represents the effectiveness of the greedy strategy.
    • For some complex problems, proving the greedy-choice property is not straightforward. Contrarily, proving the invalidity is often easier, such as with the coin change problem.
    • Solving greedy problems mainly consists of three steps: problem analysis, determining the greedy strategy, and proving correctness. Among these, determining the greedy strategy is the key step, while proving correctness often poses the challenge.
    • The fractional knapsack problem builds on the 0-1 knapsack problem by allowing the selection of a part of the items, hence it can be solved using a greedy algorithm. The correctness of the greedy strategy can be proved by contradiction.
    • The maximum capacity problem can be solved using the exhaustive method, with a time complexity of \\(O(n^2)\\). By designing a greedy strategy, each round moves inwardly shortening the board, optimizing the time complexity to \\(O(n)\\).
    • In the problem of maximum product after cutting, we deduce two greedy strategies: integers \\(\\geq 4\\) should continue to be cut, with the optimal cutting factor being \\(3\\). The code includes power operations, and the time complexity depends on the method of implementing power operations, generally being \\(O(1)\\) or \\(O(\\log n)\\).
    "},{"location":"chapter_hashing/","title":"Chapter 6. \u00a0 Hash table","text":"

    Abstract

    In the world of computing, a hash table is akin to an intelligent librarian.

    It understands how to compute index numbers, enabling swift retrieval of the desired book.

    "},{"location":"chapter_hashing/#chapter-contents","title":"Chapter contents","text":"
    • 6.1 \u00a0 Hash table
    • 6.2 \u00a0 Hash collision
    • 6.3 \u00a0 Hash algorithm
    • 6.4 \u00a0 Summary
    "},{"location":"chapter_hashing/hash_algorithm/","title":"6.3 \u00a0 Hash algorithms","text":"

    The previous two sections introduced the working principle of hash tables and the methods to handle hash collisions. However, both open addressing and chaining can only ensure that the hash table functions normally when collisions occur, but cannot reduce the frequency of hash collisions.

    If hash collisions occur too frequently, the performance of the hash table will deteriorate drastically. As shown in the Figure 6-8 , for a chaining hash table, in the ideal case, the key-value pairs are evenly distributed across the buckets, achieving optimal query efficiency; in the worst case, all key-value pairs are stored in the same bucket, degrading the time complexity to \\(O(n)\\).

    Figure 6-8 \u00a0 Ideal and worst cases of hash collisions

    The distribution of key-value pairs is determined by the hash function. Recalling the steps of calculating a hash function, first compute the hash value, then modulo it by the array length:

    index = hash(key) % capacity\n

    Observing the above formula, when the hash table capacity capacity is fixed, the hash algorithm hash() determines the output value, thereby determining the distribution of key-value pairs in the hash table.

    This means that, to reduce the probability of hash collisions, we should focus on the design of the hash algorithm hash().

    "},{"location":"chapter_hashing/hash_algorithm/#631-goals-of-hash-algorithms","title":"6.3.1 \u00a0 Goals of hash algorithms","text":"

    To achieve a \"fast and stable\" hash table data structure, hash algorithms should have the following characteristics:

    • Determinism: For the same input, the hash algorithm should always produce the same output. Only then can the hash table be reliable.
    • High efficiency: The process of computing the hash value should be fast enough. The smaller the computational overhead, the more practical the hash table.
    • Uniform distribution: The hash algorithm should ensure that key-value pairs are evenly distributed in the hash table. The more uniform the distribution, the lower the probability of hash collisions.

    In fact, hash algorithms are not only used to implement hash tables but are also widely applied in other fields.

    • Password storage: To protect the security of user passwords, systems usually do not store the plaintext passwords but rather the hash values of the passwords. When a user enters a password, the system calculates the hash value of the input and compares it with the stored hash value. If they match, the password is considered correct.
    • Data integrity check: The data sender can calculate the hash value of the data and send it along; the receiver can recalculate the hash value of the received data and compare it with the received hash value. If they match, the data is considered intact.

    For cryptographic applications, to prevent reverse engineering such as deducing the original password from the hash value, hash algorithms need higher-level security features.

    • Unidirectionality: It should be impossible to deduce any information about the input data from the hash value.
    • Collision resistance: It should be extremely difficult to find two different inputs that produce the same hash value.
    • Avalanche effect: Minor changes in the input should lead to significant and unpredictable changes in the output.

    Note that \"Uniform Distribution\" and \"Collision Resistance\" are two separate concepts. Satisfying uniform distribution does not necessarily mean collision resistance. For example, under random input key, the hash function key % 100 can produce a uniformly distributed output. However, this hash algorithm is too simple, and all key with the same last two digits will have the same output, making it easy to deduce a usable key from the hash value, thereby cracking the password.

    "},{"location":"chapter_hashing/hash_algorithm/#632-design-of-hash-algorithms","title":"6.3.2 \u00a0 Design of hash algorithms","text":"

    The design of hash algorithms is a complex issue that requires consideration of many factors. However, for some less demanding scenarios, we can also design some simple hash algorithms.

    • Additive hash: Add up the ASCII codes of each character in the input and use the total sum as the hash value.
    • Multiplicative hash: Utilize the non-correlation of multiplication, multiplying each round by a constant, accumulating the ASCII codes of each character into the hash value.
    • XOR hash: Accumulate the hash value by XORing each element of the input data.
    • Rotating hash: Accumulate the ASCII code of each character into a hash value, performing a rotation operation on the hash value before each accumulation.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig simple_hash.py
    def add_hash(key: str) -> int:\n    \"\"\"\u52a0\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash += ord(c)\n    return hash % modulus\n\ndef mul_hash(key: str) -> int:\n    \"\"\"\u4e58\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = 31 * hash + ord(c)\n    return hash % modulus\n\ndef xor_hash(key: str) -> int:\n    \"\"\"\u5f02\u6216\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash ^= ord(c)\n    return hash % modulus\n\ndef rot_hash(key: str) -> int:\n    \"\"\"\u65cb\u8f6c\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = (hash << 4) ^ (hash >> 28) ^ ord(c)\n    return hash % modulus\n
    simple_hash.cpp
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (31 * hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash ^= (int)c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.java
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (31 * hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n    int hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash ^= (int) c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n
    simple_hash.cs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint AddHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint MulHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (31 * hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint XorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash ^= c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint RotHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.go
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (31*hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key string) int {\n    hash := 0\n    modulus := 1000000007\n    for _, b := range []byte(key) {\n        fmt.Println(int(b))\n        hash ^= int(b)\n        hash = (31*hash + int(b)) % modulus\n    }\n    return hash & modulus\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ int64(b)) % modulus\n    }\n    return int(hash)\n}\n
    simple_hash.swift
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (31 * hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash ^= Int(scalar.value)\n        }\n    }\n    return hash & MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = ((hash << 4) ^ (hash >> 28) ^ Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n
    simple_hash.js
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.ts
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.dart
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (31 * hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash ^= key.codeUnitAt(i);\n  }\n  return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = ((hash << 4) ^ (hash >> 28) ^ key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n
    simple_hash.rs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfn add_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfn mul_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (31 * hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfn xor_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash ^= c as i64;\n    }\n\n    (hash & MODULUS) as i32\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfn rot_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n
    simple_hash.c
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (31 * hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(char *key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n\n    for (int i = 0; i < strlen(key); i++) {\n        hash ^= (unsigned char)key[i];\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (unsigned char)key[i]) % MODULUS;\n    }\n\n    return (int)hash;\n}\n
    simple_hash.kt
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfun addHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfun mulHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (31 * hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfun xorHash(key: String): Int {\n    var hash = 0\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = hash xor c.code\n    }\n    return hash and MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfun rotHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = ((hash shl 4) xor (hash shr 28) xor c.code.toLong()) % MODULUS\n    }\n    return hash.toInt()\n}\n
    simple_hash.rb
    ### \u52a0\u6cd5\u54c8\u5e0c ###\ndef add_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash += c.ord }\n\n  hash % modulus\nend\n\n### \u4e58\u6cd5\u54c8\u5e0c ###\ndef mul_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = 31 * hash + c.ord }\n\n  hash % modulus\nend\n\n### \u5f02\u6216\u54c8\u5e0c ###\ndef xor_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash ^= c.ord }\n\n  hash % modulus\nend\n\n### \u65cb\u8f6c\u54c8\u5e0c ###\ndef rot_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = (hash << 4) ^ (hash >> 28) ^ c.ord }\n\n  hash % modulus\nend\n
    simple_hash.zig
    [class]{}-[func]{addHash}\n\n[class]{}-[func]{mulHash}\n\n[class]{}-[func]{xorHash}\n\n[class]{}-[func]{rotHash}\n
    Code Visualization

    Full Screen >

    It is observed that the last step of each hash algorithm is to take the modulus of the large prime number \\(1000000007\\) to ensure that the hash value is within an appropriate range. It is worth pondering why emphasis is placed on modulo a prime number, or what are the disadvantages of modulo a composite number? This is an interesting question.

    To conclude: Using a large prime number as the modulus can maximize the uniform distribution of hash values. Since a prime number does not share common factors with other numbers, it can reduce the periodic patterns caused by the modulo operation, thus avoiding hash collisions.

    For example, suppose we choose the composite number \\(9\\) as the modulus, which can be divided by \\(3\\), then all key divisible by \\(3\\) will be mapped to hash values \\(0\\), \\(3\\), \\(6\\).

    \\[ \\begin{aligned} \\text{modulus} & = 9 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 0, 3, 6, 0, 3, 6, 0, 3, 6,\\dots \\} \\end{aligned} \\]

    If the input key happens to have this kind of arithmetic sequence distribution, then the hash values will cluster, thereby exacerbating hash collisions. Now, suppose we replace modulus with the prime number \\(13\\), since there are no common factors between key and modulus, the uniformity of the output hash values will be significantly improved.

    \\[ \\begin{aligned} \\text{modulus} & = 13 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 9, 12, 2, 5, 8, 11, 1, 4, 7, \\dots \\} \\end{aligned} \\]

    It is worth noting that if the key is guaranteed to be randomly and uniformly distributed, then choosing a prime number or a composite number as the modulus can both produce uniformly distributed hash values. However, when the distribution of key has some periodicity, modulo a composite number is more likely to result in clustering.

    In summary, we usually choose a prime number as the modulus, and this prime number should be large enough to eliminate periodic patterns as much as possible, enhancing the robustness of the hash algorithm.

    "},{"location":"chapter_hashing/hash_algorithm/#633-common-hash-algorithms","title":"6.3.3 \u00a0 Common hash algorithms","text":"

    It is not hard to see that the simple hash algorithms mentioned above are quite \"fragile\" and far from reaching the design goals of hash algorithms. For example, since addition and XOR obey the commutative law, additive hash and XOR hash cannot distinguish strings with the same content but in different order, which may exacerbate hash collisions and cause security issues.

    In practice, we usually use some standard hash algorithms, such as MD5, SHA-1, SHA-2, and SHA-3. They can map input data of any length to a fixed-length hash value.

    Over the past century, hash algorithms have been in a continuous process of upgrading and optimization. Some researchers strive to improve the performance of hash algorithms, while others, including hackers, are dedicated to finding security issues in hash algorithms. The Table 6-2 shows hash algorithms commonly used in practical applications.

    • MD5 and SHA-1 have been successfully attacked multiple times and are thus abandoned in various security applications.
    • SHA-2 series, especially SHA-256, is one of the most secure hash algorithms to date, with no successful attacks reported, hence commonly used in various security applications and protocols.
    • SHA-3 has lower implementation costs and higher computational efficiency compared to SHA-2, but its current usage coverage is not as extensive as the SHA-2 series.

    Table 6-2 \u00a0 Common hash algorithms

    MD5 SHA-1 SHA-2 SHA-3 Release Year 1992 1995 2002 2008 Output Length 128 bit 160 bit 256/512 bit 224/256/384/512 bit Hash Collisions Frequent Frequent Rare Rare Security Level Low, has been successfully attacked Low, has been successfully attacked High High Applications Abandoned, still used for data integrity checks Abandoned Cryptocurrency transaction verification, digital signatures, etc. Can be used to replace SHA-2"},{"location":"chapter_hashing/hash_algorithm/#hash-values-in-data-structures","title":"Hash values in data structures","text":"

    We know that the keys in a hash table can be of various data types such as integers, decimals, or strings. Programming languages usually provide built-in hash algorithms for these data types to calculate the bucket indices in the hash table. Taking Python as an example, we can use the hash() function to compute the hash values for various data types.

    • The hash values of integers and booleans are their own values.
    • The calculation of hash values for floating-point numbers and strings is more complex, and interested readers are encouraged to study this on their own.
    • The hash value of a tuple is a combination of the hash values of each of its elements, resulting in a single hash value.
    • The hash value of an object is generated based on its memory address. By overriding the hash method of an object, hash values can be generated based on content.

    Tip

    Be aware that the definition and methods of the built-in hash value calculation functions in different programming languages vary.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig built_in_hash.py
    num = 3\nhash_num = hash(num)\n# Hash value of integer 3 is 3\n\nbol = True\nhash_bol = hash(bol)\n# Hash value of boolean True is 1\n\ndec = 3.14159\nhash_dec = hash(dec)\n# Hash value of decimal 3.14159 is 326484311674566659\n\nstr = \"Hello \u7b97\u6cd5\"\nhash_str = hash(str)\n# Hash value of string \"Hello \u7b97\u6cd5\" is 4617003410720528961\n\ntup = (12836, \"\u5c0f\u54c8\")\nhash_tup = hash(tup)\n# Hash value of tuple (12836, '\u5c0f\u54c8') is 1029005403108185979\n\nobj = ListNode(0)\nhash_obj = hash(obj)\n# Hash value of ListNode object at 0x1058fd810 is 274267521\n
    built_in_hash.cpp
    int num = 3;\nsize_t hashNum = hash<int>()(num);\n// Hash value of integer 3 is 3\n\nbool bol = true;\nsize_t hashBol = hash<bool>()(bol);\n// Hash value of boolean 1 is 1\n\ndouble dec = 3.14159;\nsize_t hashDec = hash<double>()(dec);\n// Hash value of decimal 3.14159 is 4614256650576692846\n\nstring str = \"Hello \u7b97\u6cd5\";\nsize_t hashStr = hash<string>()(str);\n// Hash value of string \"Hello \u7b97\u6cd5\" is 15466937326284535026\n\n// In C++, built-in std::hash() only provides hash values for basic data types\n// Hash values for arrays and objects need to be implemented separately\n
    built_in_hash.java
    int num = 3;\nint hashNum = Integer.hashCode(num);\n// Hash value of integer 3 is 3\n\nboolean bol = true;\nint hashBol = Boolean.hashCode(bol);\n// Hash value of boolean true is 1231\n\ndouble dec = 3.14159;\nint hashDec = Double.hashCode(dec);\n// Hash value of decimal 3.14159 is -1340954729\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode();\n// Hash value of string \"Hello \u7b97\u6cd5\" is -727081396\n\nObject[] arr = { 12836, \"\u5c0f\u54c8\" };\nint hashTup = Arrays.hashCode(arr);\n// Hash value of array [12836, \u5c0f\u54c8] is 1151158\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode();\n// Hash value of ListNode object utils.ListNode@7dc5e7b4 is 2110121908\n
    built_in_hash.cs
    int num = 3;\nint hashNum = num.GetHashCode();\n// Hash value of integer 3 is 3;\n\nbool bol = true;\nint hashBol = bol.GetHashCode();\n// Hash value of boolean true is 1;\n\ndouble dec = 3.14159;\nint hashDec = dec.GetHashCode();\n// Hash value of decimal 3.14159 is -1340954729;\n\nstring str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.GetHashCode();\n// Hash value of string \"Hello \u7b97\u6cd5\" is -586107568;\n\nobject[] arr = [12836, \"\u5c0f\u54c8\"];\nint hashTup = arr.GetHashCode();\n// Hash value of array [12836, \u5c0f\u54c8] is 42931033;\n\nListNode obj = new(0);\nint hashObj = obj.GetHashCode();\n// Hash value of ListNode object 0 is 39053774;\n
    built_in_hash.go
    // Go does not provide built-in hash code functions\n
    built_in_hash.swift
    let num = 3\nlet hashNum = num.hashValue\n// Hash value of integer 3 is 9047044699613009734\n\nlet bol = true\nlet hashBol = bol.hashValue\n// Hash value of boolean true is -4431640247352757451\n\nlet dec = 3.14159\nlet hashDec = dec.hashValue\n// Hash value of decimal 3.14159 is -2465384235396674631\n\nlet str = \"Hello \u7b97\u6cd5\"\nlet hashStr = str.hashValue\n// Hash value of string \"Hello \u7b97\u6cd5\" is -7850626797806988787\n\nlet arr = [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")]\nlet hashTup = arr.hashValue\n// Hash value of array [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")] is -2308633508154532996\n\nlet obj = ListNode(x: 0)\nlet hashObj = obj.hashValue\n// Hash value of ListNode object utils.ListNode is -2434780518035996159\n
    built_in_hash.js
    // JavaScript does not provide built-in hash code functions\n
    built_in_hash.ts
    // TypeScript does not provide built-in hash code functions\n
    built_in_hash.dart
    int num = 3;\nint hashNum = num.hashCode;\n// Hash value of integer 3 is 34803\n\nbool bol = true;\nint hashBol = bol.hashCode;\n// Hash value of boolean true is 1231\n\ndouble dec = 3.14159;\nint hashDec = dec.hashCode;\n// Hash value of decimal 3.14159 is 2570631074981783\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode;\n// Hash value of string \"Hello \u7b97\u6cd5\" is 468167534\n\nList arr = [12836, \"\u5c0f\u54c8\"];\nint hashArr = arr.hashCode;\n// Hash value of array [12836, \u5c0f\u54c8] is 976512528\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode;\n// Hash value of ListNode object Instance of 'ListNode' is 1033450432\n
    built_in_hash.rs
    use std::collections::hash_map::DefaultHasher;\nuse std::hash::{Hash, Hasher};\n\nlet num = 3;\nlet mut num_hasher = DefaultHasher::new();\nnum.hash(&mut num_hasher);\nlet hash_num = num_hasher.finish();\n// Hash value of integer 3 is 568126464209439262\n\nlet bol = true;\nlet mut bol_hasher = DefaultHasher::new();\nbol.hash(&mut bol_hasher);\nlet hash_bol = bol_hasher.finish();\n// Hash value of boolean true is 4952851536318644461\n\nlet dec: f32 = 3.14159;\nlet mut dec_hasher = DefaultHasher::new();\ndec.to_bits().hash(&mut dec_hasher);\nlet hash_dec = dec_hasher.finish();\n// Hash value of decimal 3.14159 is 2566941990314602357\n\nlet str = \"Hello \u7b97\u6cd5\";\nlet mut str_hasher = DefaultHasher::new();\nstr.hash(&mut str_hasher);\nlet hash_str = str_hasher.finish();\n// Hash value of string \"Hello \u7b97\u6cd5\" is 16092673739211250988\n\nlet arr = (&12836, &\"\u5c0f\u54c8\");\nlet mut tup_hasher = DefaultHasher::new();\narr.hash(&mut tup_hasher);\nlet hash_tup = tup_hasher.finish();\n// Hash value of tuple (12836, \"\u5c0f\u54c8\") is 1885128010422702749\n\nlet node = ListNode::new(42);\nlet mut hasher = DefaultHasher::new();\nnode.borrow().val.hash(&mut hasher);\nlet hash = hasher.finish();\n// Hash value of ListNode object RefCell { value: ListNode { val: 42, next: None } } is 15387811073369036852\n
    built_in_hash.c
    // C does not provide built-in hash code functions\n
    built_in_hash.kt
    \n
    built_in_hash.zig
    \n
    Code Visualization

    Full Screen >

    In many programming languages, only immutable objects can serve as the key in a hash table. If we use a list (dynamic array) as a key, when the contents of the list change, its hash value also changes, and we would no longer be able to find the original value in the hash table.

    Although the member variables of a custom object (such as a linked list node) are mutable, it is hashable. This is because the hash value of an object is usually generated based on its memory address, and even if the contents of the object change, the memory address remains the same, so the hash value remains unchanged.

    You might have noticed that the hash values output in different consoles are different. This is because the Python interpreter adds a random salt to the string hash function each time it starts up. This approach effectively prevents HashDoS attacks and enhances the security of the hash algorithm.

    "},{"location":"chapter_hashing/hash_collision/","title":"6.2 \u00a0 Hash collision","text":"

    As mentioned in the previous section, usually the input space of a hash function is much larger than its output space, making hash collisions theoretically inevitable. For example, if the input space consists of all integers and the output space is the size of the array capacity, multiple integers will inevitably map to the same bucket index.

    Hash collisions can lead to incorrect query results, severely affecting the usability of hash tables. To solve this problem, we expand the hash table whenever a hash collision occurs, until the collision is resolved. This method is simple and effective but inefficient due to the extensive data transfer and hash value computation involved in resizing the hash table. To improve efficiency, we can adopt the following strategies:

    1. Improve the data structure of the hash table, allowing it to function normally in the event of a hash collision.
    2. Only perform resizing when necessary, i.e., when hash collisions are severe.

    There are mainly two methods for improving the structure of hash tables: \"Separate Chaining\" and \"Open Addressing\".

    "},{"location":"chapter_hashing/hash_collision/#621-separate-chaining","title":"6.2.1 \u00a0 Separate chaining","text":"

    In the original hash table, each bucket can store only one key-value pair. \"Separate chaining\" transforms individual elements into a linked list, with key-value pairs as list nodes, storing all colliding key-value pairs in the same list. The Figure 6-5 shows an example of a hash table with separate chaining.

    Figure 6-5 \u00a0 Separate chaining hash table

    The operations of a hash table implemented with separate chaining have changed as follows:

    • Querying elements: Input key, pass through the hash function to obtain the bucket index, access the head node of the list, then traverse the list and compare key to find the target key-value pair.
    • Adding elements: First access the list head node via the hash function, then add the node (key-value pair) to the list.
    • Deleting elements: Access the list head based on the hash function's result, then traverse the list to find and remove the target node.

    Separate chaining has the following limitations:

    • Increased space usage: The linked list contains node pointers, which consume more memory space than arrays.
    • Reduced query efficiency: Due to the need for linear traversal of the list to find the corresponding element.

    The code below provides a simple implementation of a separate chaining hash table, with two things to note:

    • Lists (dynamic arrays) are used instead of linked lists for simplicity. In this setup, the hash table (array) contains multiple buckets, each of which is a list.
    • This implementation includes a method for resizing the hash table. When the load factor exceeds \\(\\frac{2}{3}\\), we resize the hash table to twice its original size.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_chaining.py
    class HashMapChaining:\n    \"\"\"\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets = [[] for _ in range(self.capacity)]  # \u6876\u6570\u7ec4\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def get(self, key: int) -> str | None:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket:\n            if pair.key == key:\n                return pair.val\n        # \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket:\n            if pair.key == key:\n                pair.val = val\n                return\n        # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        pair = Pair(key, val)\n        bucket.append(pair)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for pair in bucket:\n            if pair.key == key:\n                bucket.remove(pair)\n                self.size -= 1\n                break\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [[] for _ in range(self.capacity)]\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets:\n            for pair in bucket:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for bucket in self.buckets:\n            res = []\n            for pair in bucket:\n                res.append(str(pair.key) + \" -> \" + pair.val)\n            print(res)\n
    hash_map_chaining.cpp
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  private:\n    int size;                       // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;                   // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres;               // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;                // \u6269\u5bb9\u500d\u6570\n    vector<vector<Pair *>> buckets; // \u6876\u6570\u7ec4\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapChaining() : size(0), capacity(4), loadThres(2.0 / 3.0), extendRatio(2) {\n        buckets.resize(capacity);\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapChaining() {\n        for (auto &bucket : buckets) {\n            for (Pair *pair : bucket) {\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / (double)capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                return pair->val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                pair->val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].push_back(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        auto &bucket = buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (int i = 0; i < bucket.size(); i++) {\n            if (bucket[i]->key == key) {\n                Pair *tmp = bucket[i];\n                bucket.erase(bucket.begin() + i); // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n                delete tmp;                       // \u91ca\u653e\u5185\u5b58\n                size--;\n                return;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<vector<Pair *>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets.clear();\n        buckets.resize(capacity);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (auto &bucket : bucketsTmp) {\n            for (Pair *pair : bucket) {\n                put(pair->key, pair->val);\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (auto &bucket : buckets) {\n            cout << \"[\";\n            for (Pair *pair : bucket) {\n                cout << pair->key << \" -> \" << pair->val << \", \";\n            }\n            cout << \"]\\n\";\n        }\n    }\n};\n
    hash_map_chaining.java
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    String get(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        Pair pair = new Pair(key, val);\n        bucket.add(pair);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (List<Pair> bucket : bucketsTmp) {\n            for (Pair pair : bucket) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (List<Pair> bucket : buckets) {\n            List<String> res = new ArrayList<>();\n            for (Pair pair : bucket) {\n                res.add(pair.key + \" -> \" + pair.val);\n            }\n            System.out.println(res);\n        }\n    }\n}\n
    hash_map_chaining.cs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].Add(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        foreach (Pair pair in buckets[index].ToList()) {\n            if (pair.key == key) {\n                buckets[index].Remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (List<Pair> bucket in bucketsTmp) {\n            foreach (Pair pair in bucket) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (List<Pair> bucket in buckets) {\n            List<string> res = [];\n            foreach (Pair pair in bucket) {\n                res.Add(pair.key + \" -> \" + pair.val);\n            }\n            foreach (string kv in res) {\n                Console.WriteLine(kv);\n            }\n        }\n    }\n}\n
    hash_map_chaining.go
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntype hashMapChaining struct {\n    size        int      // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int      // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64  // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int      // \u6269\u5bb9\u500d\u6570\n    buckets     [][]pair // \u6876\u6570\u7ec4\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapChaining() *hashMapChaining {\n    buckets := make([][]pair, 4)\n    for i := 0; i < 4; i++ {\n        buckets[i] = make([]pair, 0)\n    }\n    return &hashMapChaining{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     buckets,\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (m *hashMapChaining) hashFunc(key int) int {\n    return key % m.capacity\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (m *hashMapChaining) loadFactor() float64 {\n    return float64(m.size) / float64(m.capacity)\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (m *hashMapChaining) get(key int) string {\n    idx := m.hashFunc(key)\n    bucket := m.buckets[idx]\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for _, p := range bucket {\n        if p.key == key {\n            return p.val\n        }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (m *hashMapChaining) put(key int, val string) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if m.loadFactor() > m.loadThres {\n        m.extend()\n    }\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for i := range m.buckets[idx] {\n        if m.buckets[idx][i].key == key {\n            m.buckets[idx][i].val = val\n            return\n        }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    p := pair{\n        key: key,\n        val: val,\n    }\n    m.buckets[idx] = append(m.buckets[idx], p)\n    m.size += 1\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (m *hashMapChaining) remove(key int) {\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for i, p := range m.buckets[idx] {\n        if p.key == key {\n            // \u5207\u7247\u5220\u9664\n            m.buckets[idx] = append(m.buckets[idx][:i], m.buckets[idx][i+1:]...)\n            m.size -= 1\n            break\n        }\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    tmpBuckets := make([][]pair, len(m.buckets))\n    for i := 0; i < len(m.buckets); i++ {\n        tmpBuckets[i] = make([]pair, len(m.buckets[i]))\n        copy(tmpBuckets[i], m.buckets[i])\n    }\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    m.capacity *= m.extendRatio\n    m.buckets = make([][]pair, m.capacity)\n    for i := 0; i < m.capacity; i++ {\n        m.buckets[i] = make([]pair, 0)\n    }\n    m.size = 0\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, bucket := range tmpBuckets {\n        for _, p := range bucket {\n            m.put(p.key, p.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) print() {\n    var builder strings.Builder\n\n    for _, bucket := range m.buckets {\n        builder.WriteString(\"[\")\n        for _, p := range bucket {\n            builder.WriteString(strconv.Itoa(p.key) + \" -> \" + p.val + \" \")\n        }\n        builder.WriteString(\"]\")\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    hash_map_chaining.swift
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [[Pair]] // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: [], count: capacity)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return pair.val\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de nil\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair(key: key, val: val)\n        buckets[index].append(pair)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pairIndex, pair) in bucket.enumerated() {\n            if pair.key == key {\n                buckets[index].remove(at: pairIndex)\n                size -= 1\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: [], count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in bucketsTmp {\n            for pair in bucket {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for bucket in buckets {\n            let res = bucket.map { \"\\($0.key) -> \\($0.val)\" }\n            Swift.print(res)\n        }\n    }\n}\n
    hash_map_chaining.js
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.ts
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    #buckets: Pair[][]; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key: number): number {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor(): number {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.dart
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  late int size; // \u952e\u503c\u5bf9\u6570\u91cf\n  late int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  late double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  late int extendRatio; // \u6269\u5bb9\u500d\u6570\n  late List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapChaining() {\n    size = 0;\n    capacity = 4;\n    loadThres = 2.0 / 3.0;\n    extendRatio = 2;\n    buckets = List.generate(capacity, (_) => []);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return size / capacity;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        return pair.val;\n      }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > loadThres) {\n      extend();\n    }\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        pair.val = val;\n        return;\n      }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    Pair pair = Pair(key, val);\n    bucket.add(pair);\n    size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        bucket.remove(pair);\n        size--;\n        break;\n      }\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<List<Pair>> bucketsTmp = buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    capacity *= extendRatio;\n    buckets = List.generate(capacity, (_) => []);\n    size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (List<Pair> bucket in bucketsTmp) {\n      for (Pair pair in bucket) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (List<Pair> bucket in buckets) {\n      List<String> res = [];\n      for (Pair pair in bucket) {\n        res.add(\"${pair.key} -> ${pair.val}\");\n      }\n      print(res);\n    }\n  }\n}\n
    hash_map_chaining.rs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapChaining {\n    size: i32,\n    capacity: i32,\n    load_thres: f32,\n    extend_ratio: i32,\n    buckets: Vec<Vec<Pair>>,\n}\n\nimpl HashMapChaining {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![vec![]; 4],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % self.capacity as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f32 {\n        self.size as f32 / self.capacity as f32\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) -> Option<String> {\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for i in 0..bucket.len() {\n            if bucket[i].key == key {\n                let pair = bucket.remove(i);\n                self.size -= 1;\n                return Some(pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = std::mem::replace(&mut self.buckets, vec![]);\n\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![Vec::new(); self.capacity as usize];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets_tmp {\n            for pair in bucket {\n                self.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for bucket in &self.buckets {\n            let mut res = Vec::new();\n            for pair in bucket {\n                res.push(format!(\"{} -> {}\", pair.key, pair.val));\n            }\n            println!(\"{:?}\", res);\n        }\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val;\n                return;\n            }\n        }\n        let bucket = &mut self.buckets[index];\n\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair { key, val };\n        bucket.push(pair);\n        self.size += 1;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&self, key: i32) -> Option<&str> {\n        let index = self.hash_func(key);\n        let bucket = &self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return Some(&pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n}\n
    hash_map_chaining.c
    /* \u94fe\u8868\u8282\u70b9 */\ntypedef struct Node {\n    Pair *pair;\n    struct Node *next;\n} Node;\n\n/* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Node **buckets;   // \u6876\u6570\u7ec4\n} HashMapChaining;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapChaining *newHashMapChaining() {\n    HashMapChaining *hashMap = (HashMapChaining *)malloc(sizeof(HashMapChaining));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapChaining(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        while (cur) {\n            Node *tmp = cur;\n            cur = cur->next;\n            free(tmp->pair);\n            free(tmp);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapChaining *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapChaining *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            return cur->pair->val;\n        }\n        cur = cur->next;\n    }\n    return \"\"; // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapChaining *hashMap, int key, const char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            strcpy(cur->pair->val, val); // \u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n            return;\n        }\n        cur = cur->next;\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n    Pair *newPair = (Pair *)malloc(sizeof(Pair));\n    newPair->key = key;\n    strcpy(newPair->val, val);\n    Node *newNode = (Node *)malloc(sizeof(Node));\n    newNode->pair = newPair;\n    newNode->next = hashMap->buckets[index];\n    hashMap->buckets[index] = newNode;\n    hashMap->size++;\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapChaining *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    int oldCapacity = hashMap->capacity;\n    Node **oldBuckets = hashMap->buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Node *cur = oldBuckets[i];\n        while (cur) {\n            put(hashMap, cur->pair->key, cur->pair->val);\n            Node *temp = cur;\n            cur = cur->next;\n            // \u91ca\u653e\u5185\u5b58\n            free(temp->pair);\n            free(temp);\n        }\n    }\n\n    free(oldBuckets);\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    Node *cur = hashMap->buckets[index];\n    Node *pre = NULL;\n    while (cur) {\n        if (cur->pair->key == key) {\n            // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n            if (pre) {\n                pre->next = cur->next;\n            } else {\n                hashMap->buckets[index] = cur->next;\n            }\n            // \u91ca\u653e\u5185\u5b58\n            free(cur->pair);\n            free(cur);\n            hashMap->size--;\n            return;\n        }\n        pre = cur;\n        cur = cur->next;\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        printf(\"[\");\n        while (cur) {\n            printf(\"%d -> %s, \", cur->pair->key, cur->pair->val);\n            cur = cur->next;\n        }\n        printf(\"]\\n\");\n    }\n}\n
    hash_map_chaining.kt
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    val loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    val extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: MutableList<MutableList<Pair>> // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (pair in bucket) {\n            if (pair.key == key) return pair._val\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (pair in bucket) {\n            if (pair.key == key) {\n                pair._val = _val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        val pair = Pair(key, _val)\n        bucket.add(pair)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pair in bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair)\n                size--\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        // mutablelist \u65e0\u56fa\u5b9a\u5927\u5c0f\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (bucket in bucketsTmp) {\n            for (pair in bucket) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (bucket in buckets) {\n            val res = mutableListOf<String>()\n            for (pair in bucket) {\n                val k = pair.key\n                val v = pair._val\n                res.add(\"$k -> $v\")\n            }\n            println(res)\n        }\n    }\n}\n
    hash_map_chaining.rb
    ### \u952e\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapChaining\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) { [] } # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for pair in bucket\n      return pair.val if pair.key == key\n    end\n    # \u82e5\u672a\u627e\u5230 key , \u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for pair in bucket\n      if pair.key == key\n        pair.val = val\n        return\n      end\n    end\n    # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    pair = Pair.new(key, val)\n    bucket << pair\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for pair in bucket\n      if pair.key == key\n        bucket.delete(pair)\n        @size -= 1\n        break\n      end\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u66ab\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity) { [] }\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for bucket in buckets\n      for pair in bucket\n        put(pair.key, pair.val)\n      end\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for bucket in @buckets\n      res = []\n      for pair in bucket\n        res << \"#{pair.key} -> #{pair.val}\"\n      end\n      pp res\n    end\n  end\nend\n
    hash_map_chaining.zig
    [class]{HashMapChaining}-[func]{}\n
    Code Visualization

    Full Screen >

    It's worth noting that when the list is very long, the query efficiency \\(O(n)\\) is poor. At this point, the list can be converted to an \"AVL tree\" or \"Red-Black tree\" to optimize the time complexity of the query operation to \\(O(\\log n)\\).

    "},{"location":"chapter_hashing/hash_collision/#622-open-addressing","title":"6.2.2 \u00a0 Open addressing","text":"

    \"Open addressing\" does not introduce additional data structures but uses \"multiple probes\" to handle hash collisions. The probing methods mainly include linear probing, quadratic probing, and double hashing.

    Let's use linear probing as an example to introduce the mechanism of open addressing hash tables.

    "},{"location":"chapter_hashing/hash_collision/#1-linear-probing","title":"1. \u00a0 Linear probing","text":"

    Linear probing uses a fixed-step linear search for probing, differing from ordinary hash tables.

    • Inserting elements: Calculate the bucket index using the hash function. If the bucket already contains an element, linearly traverse forward from the conflict position (usually with a step size of \\(1\\)) until an empty bucket is found, then insert the element.
    • Searching for elements: If a hash collision is found, use the same step size to linearly traverse forward until the corresponding element is found and return value; if an empty bucket is encountered, it means the target element is not in the hash table, so return None.

    The Figure 6-6 shows the distribution of key-value pairs in an open addressing (linear probing) hash table. According to this hash function, keys with the same last two digits will be mapped to the same bucket. Through linear probing, they are stored consecutively in that bucket and the buckets below it.

    Figure 6-6 \u00a0 Distribution of key-value pairs in open addressing (linear probing) hash table

    However, linear probing tends to create \"clustering\". Specifically, the longer a continuous position in the array is occupied, the more likely these positions are to encounter hash collisions, further promoting the growth of these clusters and eventually leading to deterioration in the efficiency of operations.

    It's important to note that we cannot directly delete elements in an open addressing hash table. Deleting an element creates an empty bucket None in the array. When searching for elements, if linear probing encounters this empty bucket, it will return, making the elements below this bucket inaccessible. The program may incorrectly assume these elements do not exist, as shown in the Figure 6-7 .

    Figure 6-7 \u00a0 Query issues caused by deletion in open addressing

    To solve this problem, we can use a \"lazy deletion\" mechanism: instead of directly removing elements from the hash table, use a constant TOMBSTONE to mark the bucket. In this mechanism, both None and TOMBSTONE represent empty buckets and can hold key-value pairs. However, when linear probing encounters TOMBSTONE, it should continue traversing since there may still be key-value pairs below it.

    However, lazy deletion may accelerate the degradation of hash table performance. Every deletion operation produces a delete mark, and as TOMBSTONE increases, so does the search time, as linear probing may have to skip multiple TOMBSTONE to find the target element.

    Therefore, consider recording the index of the first TOMBSTONE encountered during linear probing and swapping the target element found with this TOMBSTONE. The advantage of this is that each time a query or addition is performed, the element is moved to a bucket closer to the ideal position (starting point of probing), thereby optimizing the query efficiency.

    The code below implements an open addressing (linear probing) hash table with lazy deletion. To make fuller use of the hash table space, we treat the hash table as a \"circular array,\" continuing to traverse from the beginning when the end of the array is passed.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_open_addressing.py
    class HashMapOpenAddressing:\n    \"\"\"\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets: list[Pair | None] = [None] * self.capacity  # \u6876\u6570\u7ec4\n        self.TOMBSTONE = Pair(-1, \"-1\")  # \u5220\u9664\u6807\u8bb0\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def find_bucket(self, key: int) -> int:\n        \"\"\"\u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\"\"\"\n        index = self.hash_func(key)\n        first_tombstone = -1\n        # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index] is not None:\n            # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].key == key:\n                # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if first_tombstone != -1:\n                    self.buckets[first_tombstone] = self.buckets[index]\n                    self.buckets[index] = self.TOMBSTONE\n                    return first_tombstone  # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                return index  # \u8fd4\u56de\u6876\u7d22\u5f15\n            # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 and self.buckets[index] is self.TOMBSTONE:\n                first_tombstone = index\n            # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity\n        # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return index if first_tombstone == -1 else first_tombstone\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            return self.buckets[index].val\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index].val = val\n            return\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Pair(key, val)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index] = self.TOMBSTONE\n            self.size -= 1\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets_tmp = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [None] * self.capacity\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp:\n            if pair not in [None, self.TOMBSTONE]:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is None:\n                print(\"None\")\n            elif pair is self.TOMBSTONE:\n                print(\"TOMBSTONE\")\n            else:\n                print(pair.key, \"->\", pair.val)\n
    hash_map_open_addressing.cpp
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  private:\n    int size;                             // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4;                     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    const double loadThres = 2.0 / 3.0;     // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    const int extendRatio = 2;            // \u6269\u5bb9\u500d\u6570\n    vector<Pair *> buckets;               // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapOpenAddressing() : size(0), buckets(capacity, nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapOpenAddressing() {\n        for (Pair *pair : buckets) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                delete pair;\n            }\n        }\n        delete TOMBSTONE;\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != nullptr) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]->key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            return buckets[index]->val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            buckets[index]->val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            delete buckets[index];\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<Pair *> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = vector<Pair *>(capacity, nullptr);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair *pair : bucketsTmp) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                put(pair->key, pair->val);\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *pair : buckets) {\n            if (pair == nullptr) {\n                cout << \"nullptr\" << endl;\n            } else if (pair == TOMBSTONE) {\n                cout << \"TOMBSTONE\" << endl;\n            } else {\n                cout << pair->key << \" -> \" << pair->val << endl;\n            }\n        }\n    }\n};\n
    hash_map_open_addressing.java
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    private int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private final double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private final int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    private Pair[] buckets; // \u6876\u6570\u7ec4\n    private final Pair TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair pair : bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair pair : buckets) {\n            if (pair == null) {\n                System.out.println(\"null\");\n            } else if (pair == TOMBSTONE) {\n                System.out.println(\"TOMBSTONE\");\n            } else {\n                System.out.println(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.cs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    Pair[] buckets; // \u6876\u6570\u7ec4\n    Pair TOMBSTONE = new(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int FindBucket(int key) {\n        int index = HashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (Pair pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair pair in buckets) {\n            if (pair == null) {\n                Console.WriteLine(\"null\");\n            } else if (pair == TOMBSTONE) {\n                Console.WriteLine(\"TOMBSTONE\");\n            } else {\n                Console.WriteLine(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.go
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntype hashMapOpenAddressing struct {\n    size        int     // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64 // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int     // \u6269\u5bb9\u500d\u6570\n    buckets     []*pair // \u6876\u6570\u7ec4\n    TOMBSTONE   *pair   // \u5220\u9664\u6807\u8bb0\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapOpenAddressing() *hashMapOpenAddressing {\n    return &hashMapOpenAddressing{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     make([]*pair, 4),\n        TOMBSTONE:   &pair{-1, \"-1\"},\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (h *hashMapOpenAddressing) hashFunc(key int) int {\n    return key % h.capacity // \u6839\u636e\u952e\u8ba1\u7b97\u54c8\u5e0c\u503c\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (h *hashMapOpenAddressing) loadFactor() float64 {\n    return float64(h.size) / float64(h.capacity) // \u8ba1\u7b97\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nfunc (h *hashMapOpenAddressing) findBucket(key int) int {\n    index := h.hashFunc(key) // \u83b7\u53d6\u521d\u59cb\u7d22\u5f15\n    firstTombstone := -1     // \u8bb0\u5f55\u9047\u5230\u7684\u7b2c\u4e00\u4e2aTOMBSTONE\u7684\u4f4d\u7f6e\n    for h.buckets[index] != nil {\n        if h.buckets[index].key == key {\n            if firstTombstone != -1 {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                h.buckets[firstTombstone] = h.buckets[index]\n                h.buckets[index] = h.TOMBSTONE\n                return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index // \u8fd4\u56de\u627e\u5230\u7684\u7d22\u5f15\n        }\n        if firstTombstone == -1 && h.buckets[index] == h.TOMBSTONE {\n            firstTombstone = index // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\u7684\u4f4d\u7f6e\n        }\n        index = (index + 1) % h.capacity // \u7ebf\u6027\u63a2\u6d4b\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    if firstTombstone != -1 {\n        return firstTombstone\n    }\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) get(key int) string {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        return h.buckets[index].val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    }\n    return \"\" // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) put(key int, val string) {\n    if h.loadFactor() > h.loadThres {\n        h.extend() // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    }\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] == nil || h.buckets[index] == h.TOMBSTONE {\n        h.buckets[index] = &pair{key, val} // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        h.size++\n    } else {\n        h.buckets[index].val = val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val\n    }\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) remove(key int) {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        h.buckets[index] = h.TOMBSTONE // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        h.size--\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) extend() {\n    oldBuckets := h.buckets               // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    h.capacity *= h.extendRatio           // \u66f4\u65b0\u5bb9\u91cf\n    h.buckets = make([]*pair, h.capacity) // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    h.size = 0                            // \u91cd\u7f6e\u5927\u5c0f\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, pair := range oldBuckets {\n        if pair != nil && pair != h.TOMBSTONE {\n            h.put(pair.key, pair.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) print() {\n    for _, pair := range h.buckets {\n        if pair == nil {\n            fmt.Println(\"nil\")\n        } else if pair == h.TOMBSTONE {\n            fmt.Println(\"TOMBSTONE\")\n        } else {\n            fmt.Printf(\"%d -> %s\\n\", pair.key, pair.val)\n        }\n    }\n}\n
    hash_map_open_addressing.swift
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [Pair?] // \u6876\u6570\u7ec4\n    var TOMBSTONE: Pair // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: nil, count: capacity)\n        TOMBSTONE = Pair(key: -1, val: \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    func findBucket(key: Int) -> Int {\n        var index = hashFunc(key: key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while buckets[index] != nil {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if buckets[index]!.key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if firstTombstone != -1 {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if firstTombstone == -1 && buckets[index] == TOMBSTONE {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            return buckets[index]!.val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index]!.val = val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key: key, val: val)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index] = TOMBSTONE\n            size -= 1\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: nil, count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in bucketsTmp {\n            if let pair, pair != TOMBSTONE {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in buckets {\n            if pair == nil {\n                Swift.print(\"null\")\n            } else if pair == TOMBSTONE {\n                Swift.print(\"TOMBSTONE\")\n            } else {\n                Swift.print(\"\\(pair!.key) -> \\(pair!.val)\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.js
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n    #TOMBSTONE; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.#capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.#loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.#extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.#buckets = Array(this.#capacity).fill(null); // \u6876\u6570\u7ec4\n        this.#TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    #findBucket(key) {\n        let index = this.#hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.#buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.#buckets[index].key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.#buckets[firstTombstone] = this.#buckets[index];\n                    this.#buckets[index] = this.#TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.#buckets[index] === this.#TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.#capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            return this.#buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.#buckets[index] = new Pair(key, val);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index] = this.#TOMBSTONE;\n            this.#size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = Array(this.#capacity).fill(null);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.#TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const pair of this.#buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.#TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.ts
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    private capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    private buckets: Array<Pair | null>; // \u6876\u6570\u7ec4\n    private TOMBSTONE: Pair; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.buckets = Array(this.capacity).fill(null); // \u6876\u6570\u7ec4\n        this.TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % this.capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private loadFactor(): number {\n        return this.size / this.capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private findBucket(key: number): number {\n        let index = this.hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.buckets[index]!.key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.buckets[firstTombstone] = this.buckets[index];\n                    this.buckets[index] = this.TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.buckets[index] === this.TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            return this.buckets[index]!.val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.loadFactor() > this.loadThres) {\n            this.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index]!.val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.buckets[index] = new Pair(key, val);\n        this.size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index] = this.TOMBSTONE;\n            this.size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.capacity *= this.extendRatio;\n        this.buckets = Array(this.capacity).fill(null);\n        this.size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const pair of this.buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.dart
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  late int _size; // \u952e\u503c\u5bf9\u6570\u91cf\n  int _capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  double _loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  int _extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n  late List<Pair?> _buckets; // \u6876\u6570\u7ec4\n  Pair _TOMBSTONE = Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapOpenAddressing() {\n    _size = 0;\n    _buckets = List.generate(_capacity, (index) => null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % _capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return _size / _capacity;\n  }\n\n  /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n  int findBucket(int key) {\n    int index = hashFunc(key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (_buckets[index] != null) {\n      // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if (_buckets[index]!.key == key) {\n        // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if (firstTombstone != -1) {\n          _buckets[firstTombstone] = _buckets[index];\n          _buckets[index] = _TOMBSTONE;\n          return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        }\n        return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n      }\n      // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      if (firstTombstone == -1 && _buckets[index] == _TOMBSTONE) {\n        firstTombstone = index;\n      }\n      // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % _capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      return _buckets[index]!.val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > _loadThres) {\n      extend();\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index]!.val = val;\n      return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    _buckets[index] = new Pair(key, val);\n    _size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index] = _TOMBSTONE;\n      _size--;\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<Pair?> bucketsTmp = _buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    _capacity *= _extendRatio;\n    _buckets = List.generate(_capacity, (index) => null);\n    _size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (Pair? pair in bucketsTmp) {\n      if (pair != null && pair != _TOMBSTONE) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (Pair? pair in _buckets) {\n      if (pair == null) {\n        print(\"null\");\n      } else if (pair == _TOMBSTONE) {\n        print(\"TOMBSTONE\");\n      } else {\n        print(\"${pair.key} -> ${pair.val}\");\n      }\n    }\n  }\n}\n
    hash_map_open_addressing.rs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapOpenAddressing {\n    size: usize,                // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity: usize,            // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    load_thres: f64,            // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extend_ratio: usize,        // \u6269\u5bb9\u500d\u6570\n    buckets: Vec<Option<Pair>>, // \u6876\u6570\u7ec4\n    TOMBSTONE: Option<Pair>,    // \u5220\u9664\u6807\u8bb0\n}\n\nimpl HashMapOpenAddressing {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![None; 4],\n            TOMBSTONE: Some(Pair {\n                key: -1,\n                val: \"-1\".to_string(),\n            }),\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        (key % self.capacity as i32) as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f64 {\n        self.size as f64 / self.capacity as f64\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fn find_bucket(&mut self, key: i32) -> usize {\n        let mut index = self.hash_func(key);\n        let mut first_tombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index].is_some() {\n            // \u82e5\u9047\u5230 key\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].as_ref().unwrap().key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u5efa\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\n                if first_tombstone != -1 {\n                    self.buckets[first_tombstone as usize] = self.buckets[index].take();\n                    self.buckets[index] = self.TOMBSTONE.clone();\n                    return first_tombstone as usize; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 && self.buckets[index] == self.TOMBSTONE {\n                first_tombstone = index as i32;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        if first_tombstone == -1 {\n            index\n        } else {\n            first_tombstone as usize\n        }\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&mut self, key: i32) -> Option<&str> {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            return self.buckets[index].as_ref().map(|pair| &pair.val as &str);\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        None\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index].as_mut().unwrap().val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Some(Pair { key, val });\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index] = self.TOMBSTONE.clone();\n            self.size -= 1;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = self.buckets.clone();\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![None; self.capacity];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp {\n            if pair.is_none() || pair == self.TOMBSTONE {\n                continue;\n            }\n            let pair = pair.unwrap();\n\n            self.put(pair.key, pair.val);\n        }\n    }\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for pair in &self.buckets {\n            if pair.is_none() {\n                println!(\"null\");\n            } else if pair == &self.TOMBSTONE {\n                println!(\"TOMBSTONE\");\n            } else {\n                let pair = pair.as_ref().unwrap();\n                println!(\"{} -> {}\", pair.key, pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.c
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Pair **buckets;   // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE;  // \u5220\u9664\u6807\u8bb0\n} HashMapOpenAddressing;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapOpenAddressing *newHashMapOpenAddressing() {\n    HashMapOpenAddressing *hashMap = (HashMapOpenAddressing *)malloc(sizeof(HashMapOpenAddressing));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->TOMBSTONE = (Pair *)malloc(sizeof(Pair));\n    hashMap->TOMBSTONE->key = -1;\n    hashMap->TOMBSTONE->val = \"-1\";\n\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapOpenAddressing(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap->TOMBSTONE);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapOpenAddressing *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapOpenAddressing *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nint findBucket(HashMapOpenAddressing *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (hashMap->buckets[index] != NULL) {\n        // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        if (hashMap->buckets[index]->key == key) {\n            // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n            if (firstTombstone != -1) {\n                hashMap->buckets[firstTombstone] = hashMap->buckets[index];\n                hashMap->buckets[index] = hashMap->TOMBSTONE;\n                return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n        }\n        // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n        if (firstTombstone == -1 && hashMap->buckets[index] == hashMap->TOMBSTONE) {\n            firstTombstone = index;\n        }\n        // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n        index = (index + 1) % hashMap->capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        return hashMap->buckets[index]->val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\";\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapOpenAddressing *hashMap, int key, char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        free(hashMap->buckets[index]->val);\n        hashMap->buckets[index]->val = (char *)malloc(sizeof(strlen(val) + 1));\n        strcpy(hashMap->buckets[index]->val, val);\n        hashMap->buckets[index]->val[strlen(val)] = '\\0';\n        return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    Pair *pair = (Pair *)malloc(sizeof(Pair));\n    pair->key = key;\n    pair->val = (char *)malloc(sizeof(strlen(val) + 1));\n    strcpy(pair->val, val);\n    pair->val[strlen(val)] = '\\0';\n\n    hashMap->buckets[index] = pair;\n    hashMap->size++;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        Pair *pair = hashMap->buckets[index];\n        free(pair->val);\n        free(pair);\n        hashMap->buckets[index] = hashMap->TOMBSTONE;\n        hashMap->size--;\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapOpenAddressing *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    Pair **bucketsTmp = hashMap->buckets;\n    int oldCapacity = hashMap->capacity;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Pair *pair = bucketsTmp[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            put(hashMap, pair->key, pair->val);\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(bucketsTmp);\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair == NULL) {\n            printf(\"NULL\\n\");\n        } else if (pair == hashMap->TOMBSTONE) {\n            printf(\"TOMBSTONE\\n\");\n        } else {\n            printf(\"%d -> %s\\n\", pair->key, pair->val);\n        }\n    }\n}\n
    hash_map_open_addressing.kt
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private var size: Int               // \u952e\u503c\u5bf9\u6570\u91cf\n    private var capacity: Int           // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private val loadThres: Double       // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private val extendRatio: Int        // \u6269\u5bb9\u500d\u6570\n    private var buckets: Array<Pair?>   // \u6876\u6570\u7ec4\n    private val TOMBSTONE: Pair         // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = arrayOfNulls(capacity)\n        TOMBSTONE = Pair(-1, \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fun findBucket(key: Int): Int {\n        var index = hashFunc(key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]?.key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return if (firstTombstone == -1) index else firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index]?._val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index]!!._val = _val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key, _val)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE\n            size--\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = arrayOfNulls(capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (pair in buckets) {\n            if (pair == null) {\n                println(\"null\")\n            } else if (pair == TOMBSTONE) {\n                println(\"TOMESTOME\")\n            } else {\n                println(\"${pair.key} -> ${pair._val}\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.rb
    ### \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapOpenAddressing\n  TOMBSTONE = Pair.new(-1, '-1') # \u5220\u9664\u6807\u8bb0\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 ###\n  def find_bucket(key)\n    index = hash_func(key)\n    first_tombstone = -1\n    # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while !@buckets[index].nil?\n      # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if @buckets[index].key == key\n        # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if first_tombstone != -1\n          @buckets[first_tombstone] = @buckets[index]\n          @buckets[index] = TOMBSTONE\n          return first_tombstone # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        end\n        return index # \u8fd4\u56de\u6876\u7d22\u5f15\n      end\n      # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      first_tombstone = index if first_tombstone == -1 && @buckets[index] == TOMBSTONE\n      # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % @capacity\n    end\n    # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    first_tombstone == -1 ? index : first_tombstone\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    return @buckets[index].val unless [nil, TOMBSTONE].include?(@buckets[index])\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5f00\u8fd4\u56de\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index].val = val\n      return\n    end\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    @buckets[index] = Pair.new(key, val)\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index] = TOMBSTONE\n      @size -= 1\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets_tmp = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity)\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for pair in buckets_tmp\n      put(pair.key, pair.val) unless [nil, TOMBSTONE].include?(pair)\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for pair in @buckets\n      if pair.nil?\n        puts \"Nil\"\n      elsif pair == TOMBSTONE\n        puts \"TOMBSTONE\"\n      else\n        puts \"#{pair.key} -> #{pair.val}\"\n      end\n    end\n  end\nend\n
    hash_map_open_addressing.zig
    [class]{HashMapOpenAddressing}-[func]{}\n
    "},{"location":"chapter_hashing/hash_collision/#2-quadratic-probing","title":"2. \u00a0 Quadratic probing","text":"

    Quadratic probing is similar to linear probing and is one of the common strategies of open addressing. When a collision occurs, quadratic probing does not simply skip a fixed number of steps but skips \"the square of the number of probes,\" i.e., \\(1, 4, 9, \\dots\\) steps.

    Quadratic probing has the following advantages:

    • Quadratic probing attempts to alleviate the clustering effect of linear probing by skipping the distance of the square of the number of probes.
    • Quadratic probing skips larger distances to find empty positions, helping to distribute data more evenly.

    However, quadratic probing is not perfect:

    • Clustering still exists, i.e., some positions are more likely to be occupied than others.
    • Due to the growth of squares, quadratic probing may not probe the entire hash table, meaning it might not access empty buckets even if they exist in the hash table.
    "},{"location":"chapter_hashing/hash_collision/#3-double-hashing","title":"3. \u00a0 Double hashing","text":"

    As the name suggests, the double hashing method uses multiple hash functions \\(f_1(x)\\), \\(f_2(x)\\), \\(f_3(x)\\), \\(\\dots\\) for probing.

    • Inserting elements: If hash function \\(f_1(x)\\) encounters a conflict, try \\(f_2(x)\\), and so on, until an empty position is found and the element is inserted.
    • Searching for elements: Search in the same order of hash functions until the target element is found and returned; if an empty position is encountered or all hash functions have been tried, it indicates the element is not in the hash table, then return None.

    Compared to linear probing, double hashing is less prone to clustering but involves additional computation for multiple hash functions.

    Tip

    Please note that open addressing (linear probing, quadratic probing, and double hashing) hash tables all have the issue of \"not being able to directly delete elements.\"

    "},{"location":"chapter_hashing/hash_collision/#623-choice-of-programming-languages","title":"6.2.3 \u00a0 Choice of programming languages","text":"

    Various programming languages have adopted different hash table implementation strategies, here are a few examples:

    • Python uses open addressing. The dict dictionary uses pseudo-random numbers for probing.
    • Java uses separate chaining. Since JDK 1.8, when the array length in HashMap reaches 64 and the length of a linked list reaches 8, the linked list is converted to a red-black tree to improve search performance.
    • Go uses separate chaining. Go stipulates that each bucket can store up to 8 key-value pairs, and if the capacity is exceeded, an overflow bucket is connected; when there are too many overflow buckets, a special equal-size expansion operation is performed to ensure performance.
    "},{"location":"chapter_hashing/hash_map/","title":"6.1 \u00a0 Hash table","text":"

    A \"hash table\", also known as a \"hash map\", achieves efficient element querying by establishing a mapping between keys and values. Specifically, when we input a key into the hash table, we can retrieve the corresponding value in \\(O(1)\\) time.

    As shown in the Figure 6-1 , given \\(n\\) students, each with two pieces of data: \"name\" and \"student number\". If we want to implement a query feature that returns the corresponding name when given a student number, we can use the hash table shown in the Figure 6-1 .

    Figure 6-1 \u00a0 Abstract representation of a hash table

    Apart from hash tables, arrays and linked lists can also be used to implement querying functions. Their efficiency is compared in the Table 6-1 .

    • Adding elements: Simply add the element to the end of the array (or linked list), using \\(O(1)\\) time.
    • Querying elements: Since the array (or linked list) is unordered, it requires traversing all the elements, using \\(O(n)\\) time.
    • Deleting elements: First, locate the element, then delete it from the array (or linked list), using \\(O(n)\\) time.

    Table 6-1 \u00a0 Comparison of element query efficiency

    Array Linked List Hash Table Find Element \\(O(n)\\) \\(O(n)\\) \\(O(1)\\) Add Element \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) Delete Element \\(O(n)\\) \\(O(n)\\) \\(O(1)\\)

    Observations reveal that the time complexity for adding, deleting, and querying in a hash table is \\(O(1)\\), which is highly efficient.

    "},{"location":"chapter_hashing/hash_map/#611-common-operations-of-hash-table","title":"6.1.1 \u00a0 Common operations of hash table","text":"

    Common operations of a hash table include initialization, querying, adding key-value pairs, and deleting key-value pairs, etc. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig hash_map.py
    # Initialize hash table\nhmap: dict = {}\n\n# Add operation\n# Add key-value pair (key, value) to the hash table\nhmap[12836] = \"Xiao Ha\"\nhmap[15937] = \"Xiao Luo\"\nhmap[16750] = \"Xiao Suan\"\nhmap[13276] = \"Xiao Fa\"\nhmap[10583] = \"Xiao Ya\"\n\n# Query operation\n# Input key into hash table, get value\nname: str = hmap[15937]\n\n# Delete operation\n# Delete key-value pair (key, value) from hash table\nhmap.pop(10583)\n
    hash_map.cpp
    /* Initialize hash table */\nunordered_map<int, string> map;\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap[12836] = \"Xiao Ha\";\nmap[15937] = \"Xiao Luo\";\nmap[16750] = \"Xiao Suan\";\nmap[13276] = \"Xiao Fa\";\nmap[10583] = \"Xiao Ya\";\n\n/* Query operation */\n// Input key into hash table, get value\nstring name = map[15937];\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.erase(10583);\n
    hash_map.java
    /* Initialize hash table */\nMap<Integer, String> map = new HashMap<>();\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.put(12836, \"Xiao Ha\");   \nmap.put(15937, \"Xiao Luo\");   \nmap.put(16750, \"Xiao Suan\");   \nmap.put(13276, \"Xiao Fa\");\nmap.put(10583, \"Xiao Ya\");\n\n/* Query operation */\n// Input key into hash table, get value\nString name = map.get(15937);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.remove(10583);\n
    hash_map.cs
    /* Initialize hash table */\nDictionary<int, string> map = new() {\n    /* Add operation */\n    // Add key-value pair (key, value) to the hash table\n    { 12836, \"Xiao Ha\" },\n    { 15937, \"Xiao Luo\" },\n    { 16750, \"Xiao Suan\" },\n    { 13276, \"Xiao Fa\" },\n    { 10583, \"Xiao Ya\" }\n};\n\n/* Query operation */\n// Input key into hash table, get value\nstring name = map[15937];\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.Remove(10583);\n
    hash_map_test.go
    /* Initialize hash table */\nhmap := make(map[int]string)\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nhmap[12836] = \"Xiao Ha\"\nhmap[15937] = \"Xiao Luo\"\nhmap[16750] = \"Xiao Suan\"\nhmap[13276] = \"Xiao Fa\"\nhmap[10583] = \"Xiao Ya\"\n\n/* Query operation */\n// Input key into hash table, get value\nname := hmap[15937]\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\ndelete(hmap, 10583)\n
    hash_map.swift
    /* Initialize hash table */\nvar map: [Int: String] = [:]\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap[12836] = \"Xiao Ha\"\nmap[15937] = \"Xiao Luo\"\nmap[16750] = \"Xiao Suan\"\nmap[13276] = \"Xiao Fa\"\nmap[10583] = \"Xiao Ya\"\n\n/* Query operation */\n// Input key into hash table, get value\nlet name = map[15937]!\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.removeValue(forKey: 10583)\n
    hash_map.js
    /* Initialize hash table */\nconst map = new Map();\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.set(12836, 'Xiao Ha');\nmap.set(15937, 'Xiao Luo');\nmap.set(16750, 'Xiao Suan');\nmap.set(13276, 'Xiao Fa');\nmap.set(10583, 'Xiao Ya');\n\n/* Query operation */\n// Input key into hash table, get value\nlet name = map.get(15937);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.delete(10583);\n
    hash_map.ts
    /* Initialize hash table */\nconst map = new Map<number, string>();\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.set(12836, 'Xiao Ha');\nmap.set(15937, 'Xiao Luo');\nmap.set(16750, 'Xiao Suan');\nmap.set(13276, 'Xiao Fa');\nmap.set(10583, 'Xiao Ya');\nconsole.info('\\nAfter adding, the hash table is\\nKey -> Value');\nconsole.info(map);\n\n/* Query operation */\n// Input key into hash table, get value\nlet name = map.get(15937);\nconsole.info('\\nInput student number 15937, query name ' + name);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.delete(10583);\nconsole.info('\\nAfter deleting 10583, the hash table is\\nKey -> Value');\nconsole.info(map);\n
    hash_map.dart
    /* Initialize hash table */\nMap<int, String> map = {};\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap[12836] = \"Xiao Ha\";\nmap[15937] = \"Xiao Luo\";\nmap[16750] = \"Xiao Suan\";\nmap[13276] = \"Xiao Fa\";\nmap[10583] = \"Xiao Ya\";\n\n/* Query operation */\n// Input key into hash table, get value\nString name = map[15937];\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nmap.remove(10583);\n
    hash_map.rs
    use std::collections::HashMap;\n\n/* Initialize hash table */\nlet mut map: HashMap<i32, String> = HashMap::new();\n\n/* Add operation */\n// Add key-value pair (key, value) to the hash table\nmap.insert(12836, \"Xiao Ha\".to_string());\nmap.insert(15937, \"Xiao Luo\".to_string());\nmap.insert(16750, \"Xiao Suan\".to_string());\nmap.insert(13279, \"Xiao Fa\".to_string());\nmap.insert(10583, \"Xiao Ya\".to_string());\n\n/* Query operation */\n// Input key into hash table, get value\nlet _name: Option<&String> = map.get(&15937);\n\n/* Delete operation */\n// Delete key-value pair (key, value) from hash table\nlet _removed_value: Option<String> = map.remove(&10583);\n
    hash_map.c
    // C does not provide a built-in hash table\n
    hash_map.kt
    \n
    hash_map.zig
    \n
    Code Visualization

    Full Screen >

    There are three common ways to traverse a hash table: traversing key-value pairs, keys, and values. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig hash_map.py
    # Traverse hash table\n# Traverse key-value pairs key->value\nfor key, value in hmap.items():\n    print(key, \"->\", value)\n# Traverse keys only\nfor key in hmap.keys():\n    print(key)\n# Traverse values only\nfor value in hmap.values():\n    print(value)\n
    hash_map.cpp
    /* Traverse hash table */\n// Traverse key-value pairs key->value\nfor (auto kv: map) {\n    cout << kv.first << \" -> \" << kv.second << endl;\n}\n// Traverse using iterator key->value\nfor (auto iter = map.begin(); iter != map.end(); iter++) {\n    cout << iter->first << \"->\" << iter->second << endl;\n}\n
    hash_map.java
    /* Traverse hash table */\n// Traverse key-value pairs key->value\nfor (Map.Entry<Integer, String> kv: map.entrySet()) {\n    System.out.println(kv.getKey() + \" -> \" + kv.getValue());\n}\n// Traverse keys only\nfor (int key: map.keySet()) {\n    System.out.println(key);\n}\n// Traverse values only\nfor (String val: map.values()) {\n    System.out.println(val);\n}\n
    hash_map.cs
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nforeach (var kv in map) {\n    Console.WriteLine(kv.Key + \" -> \" + kv.Value);\n}\n// Traverse keys only\nforeach (int key in map.Keys) {\n    Console.WriteLine(key);\n}\n// Traverse values only\nforeach (string val in map.Values) {\n    Console.WriteLine(val);\n}\n
    hash_map_test.go
    /* Traverse hash table */\n// Traverse key-value pairs key->value\nfor key, value := range hmap {\n    fmt.Println(key, \"->\", value)\n}\n// Traverse keys only\nfor key := range hmap {\n    fmt.Println(key)\n}\n// Traverse values only\nfor _, value := range hmap {\n    fmt.Println(value)\n}\n
    hash_map.swift
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nfor (key, value) in map {\n    print(\"\\(key) -> \\(value)\")\n}\n// Traverse keys only\nfor key in map.keys {\n    print(key)\n}\n// Traverse values only\nfor value in map.values {\n    print(value)\n}\n
    hash_map.js
    /* Traverse hash table */\nconsole.info('\\nTraverse key-value pairs Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\nTraverse keys only Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\nTraverse values only Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.ts
    /* Traverse hash table */\nconsole.info('\\nTraverse key-value pairs Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\nTraverse keys only Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\nTraverse values only Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.dart
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nmap.forEach((key, value) {\nprint('$key -> $value');\n});\n\n// Traverse keys only Key\nmap.keys.forEach((key) {\nprint(key);\n});\n\n// Traverse values only Value\nmap.values.forEach((value) {\nprint(value);\n});\n
    hash_map.rs
    /* Traverse hash table */\n// Traverse key-value pairs Key->Value\nfor (key, value) in &map {\n    println!(\"{key} -> {value}\");\n}\n\n// Traverse keys only Key\nfor key in map.keys() {\n    println!(\"{key}\"); \n}\n\n// Traverse values only Value\nfor value in map.values() {\n    println!(\"{value}\");\n}\n
    hash_map.c
    // C does not provide a built-in hash table\n
    hash_map.kt
    \n
    hash_map.zig
    // Zig example is not provided\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_hashing/hash_map/#612-simple-implementation-of-hash-table","title":"6.1.2 \u00a0 Simple implementation of hash table","text":"

    First, let's consider the simplest case: implementing a hash table using just an array. In the hash table, each empty slot in the array is called a \"bucket\", and each bucket can store one key-value pair. Therefore, the query operation involves finding the bucket corresponding to the key and retrieving the value from it.

    So, how do we locate the appropriate bucket based on the key? This is achieved through a \"hash function\". The role of the hash function is to map a larger input space to a smaller output space. In a hash table, the input space is all possible keys, and the output space is all buckets (array indices). In other words, input a key, and we can use the hash function to determine the storage location of the corresponding key-value pair in the array.

    The calculation process of the hash function for a given key is divided into the following two steps:

    1. Calculate the hash value using a certain hash algorithm hash().
    2. Take the modulus of the hash value with the number of buckets (array length) capacity to obtain the array index index.
    index = hash(key) % capacity\n

    Afterward, we can use index to access the corresponding bucket in the hash table and thereby retrieve the value.

    Assuming array length capacity = 100 and hash algorithm hash(key) = key, the hash function is key % 100. The Figure 6-2 uses key as the student number and value as the name to demonstrate the working principle of the hash function.

    Figure 6-2 \u00a0 Working principle of hash function

    The following code implements a simple hash table. Here, we encapsulate key and value into a class Pair to represent the key-value pair.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_hash_map.py
    class Pair:\n    \"\"\"\u952e\u503c\u5bf9\"\"\"\n\n    def __init__(self, key: int, val: str):\n        self.key = key\n        self.val = val\n\nclass ArrayHashMap:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        self.buckets: list[Pair | None] = [None] * 100\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        index = key % 100\n        return index\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        pair: Pair = self.buckets[index]\n        if pair is None:\n            return None\n        return pair.val\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        pair = Pair(key, val)\n        index: int = self.hash_func(key)\n        self.buckets[index] = pair\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        # \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None\n\n    def entry_set(self) -> list[Pair]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\"\"\"\n        result: list[Pair] = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair)\n        return result\n\n    def key_set(self) -> list[int]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.key)\n        return result\n\n    def value_set(self) -> list[str]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u503c\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.val)\n        return result\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is not None:\n                print(pair.key, \"->\", pair.val)\n
    array_hash_map.cpp
    /* \u952e\u503c\u5bf9 */\nstruct Pair {\n  public:\n    int key;\n    string val;\n    Pair(int key, string val) {\n        this->key = key;\n        this->val = val;\n    }\n};\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  private:\n    vector<Pair *> buckets;\n\n  public:\n    ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = vector<Pair *>(100);\n    }\n\n    ~ArrayHashMap() {\n        // \u91ca\u653e\u5185\u5b58\n        for (const auto &bucket : buckets) {\n            delete bucket;\n        }\n        buckets.clear();\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        Pair *pair = buckets[index];\n        if (pair == nullptr)\n            return \"\";\n        return pair->val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        Pair *pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        // \u91ca\u653e\u5185\u5b58\u5e76\u7f6e\u4e3a nullptr\n        delete buckets[index];\n        buckets[index] = nullptr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    vector<Pair *> pairSet() {\n        vector<Pair *> pairSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                pairSet.push_back(pair);\n            }\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    vector<int> keySet() {\n        vector<int> keySet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                keySet.push_back(pair->key);\n            }\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    vector<string> valueSet() {\n        vector<string> valueSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                valueSet.push_back(pair->val);\n            }\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *kv : pairSet()) {\n            cout << kv->key << \" -> \" << kv->val << endl;\n        }\n    }\n};\n
    array_hash_map.java
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n    public int key;\n    public String val;\n\n    public Pair(int key, String val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private List<Pair> buckets;\n\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = new ArrayList<>();\n        for (int i = 0; i < 100; i++) {\n            buckets.add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        int index = hashFunc(key);\n        Pair pair = buckets.get(index);\n        if (pair == null)\n            return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        Pair pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets.set(index, pair);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        int index = hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets.set(index, null);\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> pairSet() {\n        List<Pair> pairSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                pairSet.add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<Integer> keySet() {\n        List<Integer> keySet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                keySet.add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<String> valueSet() {\n        List<String> valueSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                valueSet.add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair kv : pairSet()) {\n            System.out.println(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.cs
    /* \u952e\u503c\u5bf9 int->string */\nclass Pair(int key, string val) {\n    public int key = key;\n    public string val = val;\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    List<Pair?> buckets;\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = [];\n        for (int i = 0; i < 100; i++) {\n            buckets.Add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        Pair? pair = buckets[index];\n        if (pair == null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        Pair pair = new(key, val);\n        int index = HashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> PairSet() {\n        List<Pair> pairSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                pairSet.Add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<int> KeySet() {\n        List<int> keySet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                keySet.Add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<string> ValueSet() {\n        List<string> valueSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                valueSet.Add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair kv in PairSet()) {\n            Console.WriteLine(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.go
    /* \u952e\u503c\u5bf9 */\ntype pair struct {\n    key int\n    val string\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntype arrayHashMap struct {\n    buckets []*pair\n}\n\n/* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nfunc newArrayHashMap() *arrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    buckets := make([]*pair, 100)\n    return &arrayHashMap{buckets: buckets}\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (a *arrayHashMap) hashFunc(key int) int {\n    index := key % 100\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (a *arrayHashMap) get(key int) string {\n    index := a.hashFunc(key)\n    pair := a.buckets[index]\n    if pair == nil {\n        return \"Not Found\"\n    }\n    return pair.val\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (a *arrayHashMap) put(key int, val string) {\n    pair := &pair{key: key, val: val}\n    index := a.hashFunc(key)\n    a.buckets[index] = pair\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (a *arrayHashMap) remove(key int) {\n    index := a.hashFunc(key)\n    // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    a.buckets[index] = nil\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u5bf9 */\nfunc (a *arrayHashMap) pairSet() []*pair {\n    var pairs []*pair\n    for _, pair := range a.buckets {\n        if pair != nil {\n            pairs = append(pairs, pair)\n        }\n    }\n    return pairs\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nfunc (a *arrayHashMap) keySet() []int {\n    var keys []int\n    for _, pair := range a.buckets {\n        if pair != nil {\n            keys = append(keys, pair.key)\n        }\n    }\n    return keys\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nfunc (a *arrayHashMap) valueSet() []string {\n    var values []string\n    for _, pair := range a.buckets {\n        if pair != nil {\n            values = append(values, pair.val)\n        }\n    }\n    return values\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (a *arrayHashMap) print() {\n    for _, pair := range a.buckets {\n        if pair != nil {\n            fmt.Println(pair.key, \"->\", pair.val)\n        }\n    }\n}\n
    array_hash_map.swift
    /* \u952e\u503c\u5bf9 */\nclass Pair: Equatable {\n    public var key: Int\n    public var val: String\n\n    public init(key: Int, val: String) {\n        self.key = key\n        self.val = val\n    }\n\n    public static func == (lhs: Pair, rhs: Pair) -> Bool {\n        lhs.key == rhs.key && lhs.val == rhs.val\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private var buckets: [Pair?]\n\n    init() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = Array(repeating: nil, count: 100)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private func hashFunc(key: Int) -> Int {\n        let index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let pair = buckets[index]\n        return pair?.val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        let pair = Pair(key: key, val: val)\n        let index = hashFunc(key: key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = nil\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    func pairSet() -> [Pair] {\n        buckets.compactMap { $0 }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    func keySet() -> [Int] {\n        buckets.compactMap { $0?.key }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    func valueSet() -> [String] {\n        buckets.compactMap { $0?.val }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in pairSet() {\n            Swift.print(\"\\(pair.key) -> \\(pair.val)\")\n        }\n    }\n}\n
    array_hash_map.js
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    constructor(key, val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    #buckets;\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.#buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        let index = this.#hashFunc(key);\n        let pair = this.#buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    set(key, val) {\n        let index = this.#hashFunc(key);\n        this.#buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    delete(key) {\n        let index = this.#hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.#buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    entries() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    keys() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    values() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.ts
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    public key: number;\n    public val: string;\n\n    constructor(key: number, val: string) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private readonly buckets: (Pair | null)[];\n\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public get(key: number): string | null {\n        let index = this.hashFunc(key);\n        let pair = this.buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public set(key: number, val: string) {\n        let index = this.hashFunc(key);\n        this.buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public delete(key: number) {\n        let index = this.hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public entries(): (Pair | null)[] {\n        let arr: (Pair | null)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public keys(): (number | undefined)[] {\n        let arr: (number | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public values(): (string | undefined)[] {\n        let arr: (string | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.dart
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n  int key;\n  String val;\n  Pair(this.key, this.val);\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  late List<Pair?> _buckets;\n\n  ArrayHashMap() {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    _buckets = List.filled(100, null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int _hashFunc(int key) {\n    final int index = key % 100;\n    return index;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    final int index = _hashFunc(key);\n    final Pair? pair = _buckets[index];\n    if (pair == null) {\n      return null;\n    }\n    return pair.val;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    final Pair pair = Pair(key, val);\n    final int index = _hashFunc(key);\n    _buckets[index] = pair;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    final int index = _hashFunc(key);\n    _buckets[index] = null;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n  List<Pair> pairSet() {\n    List<Pair> pairSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        pairSet.add(pair);\n      }\n    }\n    return pairSet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e */\n  List<int> keySet() {\n    List<int> keySet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        keySet.add(pair.key);\n      }\n    }\n    return keySet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u503c */\n  List<String> values() {\n    List<String> valueSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        valueSet.add(pair.val);\n      }\n    }\n    return valueSet;\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (final Pair kv in pairSet()) {\n      print(\"${kv.key} -> ${kv.val}\");\n    }\n  }\n}\n
    array_hash_map.rs
    /* \u952e\u503c\u5bf9 */\n#[derive(Debug, Clone, PartialEq)]\npub struct Pair {\n    pub key: i32,\n    pub val: String,\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\npub struct ArrayHashMap {\n    buckets: Vec<Option<Pair>>,\n}\n\nimpl ArrayHashMap {\n    pub fn new() -> ArrayHashMap {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        Self {\n            buckets: vec![None; 100],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % 100\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    pub fn get(&self, key: i32) -> Option<&String> {\n        let index = self.hash_func(key);\n        self.buckets[index].as_ref().map(|pair| &pair.val)\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    pub fn put(&mut self, key: i32, val: &str) {\n        let index = self.hash_func(key);\n        self.buckets[index] = Some(Pair {\n            key,\n            val: val.to_string(),\n        });\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    pub fn remove(&mut self, key: i32) {\n        let index = self.hash_func(key);\n        // \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    pub fn entry_set(&self) -> Vec<&Pair> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref())\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    pub fn key_set(&self) -> Vec<&i32> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.key))\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    pub fn value_set(&self) -> Vec<&String> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.val))\n            .collect()\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    pub fn print(&self) {\n        for pair in self.entry_set() {\n            println!(\"{} -> {}\", pair.key, pair.val);\n        }\n    }\n}\n
    array_hash_map.c
    /* \u952e\u503c\u5bf9 int->string */\ntypedef struct {\n    int key;\n    char *val;\n} Pair;\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntypedef struct {\n    Pair *buckets[MAX_SIZE];\n} ArrayHashMap;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayHashMap *newArrayHashMap() {\n    ArrayHashMap *hmap = malloc(sizeof(ArrayHashMap));\n    for (int i=0; i < MAX_SIZE; i++) {\n        hmap->buckets[i] = NULL;\n    }\n    return hmap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayHashMap(ArrayHashMap *hmap) {\n    for (int i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            free(hmap->buckets[i]->val);\n            free(hmap->buckets[i]);\n        }\n    }\n    free(hmap);\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(ArrayHashMap *hmap, const int key, const char *val) {\n    Pair *Pair = malloc(sizeof(Pair));\n    Pair->key = key;\n    Pair->val = malloc(strlen(val) + 1);\n    strcpy(Pair->val, val);\n\n    int index = hashFunc(key);\n    hmap->buckets[index] = Pair;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(ArrayHashMap *hmap, const int key) {\n    int index = hashFunc(key);\n    free(hmap->buckets[index]->val);\n    free(hmap->buckets[index]);\n    hmap->buckets[index] = NULL;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\nvoid pairSet(ArrayHashMap *hmap, MapSet *set) {\n    Pair *entries;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    entries = malloc(sizeof(Pair) * total);\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            entries[index].key = hmap->buckets[i]->key;\n            entries[index].val = malloc(strlen(hmap->buckets[i]->val) + 1);\n            strcpy(entries[index].val, hmap->buckets[i]->val);\n            index++;\n        }\n    }\n    set->set = entries;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nvoid keySet(ArrayHashMap *hmap, MapSet *set) {\n    int *keys;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    keys = malloc(total * sizeof(int));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            keys[index] = hmap->buckets[i]->key;\n            index++;\n        }\n    }\n    set->set = keys;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nvoid valueSet(ArrayHashMap *hmap, MapSet *set) {\n    char **vals;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    vals = malloc(total * sizeof(char *));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            vals[index] = hmap->buckets[i]->val;\n            index++;\n        }\n    }\n    set->set = vals;\n    set->len = total;\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(ArrayHashMap *hmap) {\n    int i;\n    MapSet set;\n    pairSet(hmap, &set);\n    Pair *entries = (Pair *)set.set;\n    for (i = 0; i < set.len; i++) {\n        printf(\"%d -> %s\\n\", entries[i].key, entries[i].val);\n    }\n    free(set.set);\n}\n
    array_hash_map.kt
    /* \u952e\u503c\u5bf9 */\nclass Pair(\n    var key: Int,\n    var _val: String\n)\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    private val buckets = arrayOfNulls<Pair>(100)\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        val index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val pair = buckets[index] ?: return null\n        return pair._val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        val pair = Pair(key, _val)\n        val index = hashFunc(key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    fun pairSet(): MutableList<Pair> {\n        val pairSet = mutableListOf<Pair>()\n        for (pair in buckets) {\n            if (pair != null)\n                pairSet.add(pair)\n        }\n        return pairSet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    fun keySet(): MutableList<Int> {\n        val keySet = mutableListOf<Int>()\n        for (pair in buckets) {\n            if (pair != null)\n                keySet.add(pair.key)\n        }\n        return keySet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    fun valueSet(): MutableList<String> {\n        val valueSet = mutableListOf<String>()\n        for (pair in buckets) {\n            if (pair != null)\n                valueSet.add(pair._val)\n        }\n        return valueSet\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (kv in pairSet()) {\n            val key = kv.key\n            val _val = kv._val\n            println(\"$key -> $_val\")\n        }\n    }\n}\n
    array_hash_map.rb
    ### \u952e\u503c\u5bf9 ###\nclass Pair\n  attr_accessor :key, :val\n\n  def initialize(key, val)\n    @key = key\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 ###\nclass ArrayHashMap\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    @buckets = Array.new(100)\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    index = key % 100\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    pair = @buckets[index]\n\n    return if pair.nil?\n    pair.val\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    pair = Pair.new(key, val)\n    index = hash_func(key)\n    @buckets[index] = pair\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    # \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    @buckets[index] = nil\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 ###\n  def entry_set\n    result = []\n    @buckets.each { |pair| result << pair unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e ###\n  def key_set\n    result = []\n    @buckets.each { |pair| result << pair.key unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u503c ###\n  def value_set\n    result = []\n    @buckets.each { |pair| result << pair.val unless pair.nil? }\n    result\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    @buckets.each { |pair| puts \"#{pair.key} -> #{pair.val}\" unless pair.nil? }\n  end\nend\n
    array_hash_map.zig
    // \u952e\u503c\u5bf9\nconst Pair = struct {\n    key: usize = undefined,\n    val: []const u8 = undefined,\n\n   pub fn init(key: usize, val: []const u8) Pair {\n        return Pair {\n            .key = key,\n            .val = val,\n        };\n    }\n};\n\n// \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\nfn ArrayHashMap(comptime T: type) type {\n    return struct {\n        bucket: ?std.ArrayList(?T) = null,\n        mem_allocator: std.mem.Allocator = undefined,\n\n        const Self = @This();\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            self.mem_allocator = allocator;\n            // \u521d\u59cb\u5316\u4e00\u4e2a\u957f\u5ea6\u4e3a 100 \u7684\u6876\uff08\u6570\u7ec4\uff09\n            self.bucket = std.ArrayList(?T).init(self.mem_allocator);\n            var i: i32 = 0;\n            while (i < 100) : (i += 1) {\n                try self.bucket.?.append(null);\n            }\n        }\n\n        // \u6790\u6784\u51fd\u6570\n        pub fn deinit(self: *Self) void {\n            if (self.bucket != null) self.bucket.?.deinit();\n        }\n\n        // \u54c8\u5e0c\u51fd\u6570\n        fn hashFunc(key: usize) usize {\n            var index = key % 100;\n            return index;\n        }\n\n        // \u67e5\u8be2\u64cd\u4f5c\n        pub fn get(self: *Self, key: usize) []const u8 {\n            var index = hashFunc(key);\n            var pair = self.bucket.?.items[index];\n            return pair.?.val;\n        }\n\n        // \u6dfb\u52a0\u64cd\u4f5c\n        pub fn put(self: *Self, key: usize, val: []const u8) !void {\n            var pair = Pair.init(key, val);\n            var index = hashFunc(key);\n            self.bucket.?.items[index] = pair;\n        }\n\n        // \u5220\u9664\u64cd\u4f5c\n        pub fn remove(self: *Self, key: usize) !void {\n            var index = hashFunc(key);\n            // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n            self.bucket.?.items[index] = null;\n        }       \n\n        // \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\n        pub fn pairSet(self: *Self) !std.ArrayList(T) {\n            var entry_set = std.ArrayList(T).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try entry_set.append(item.?);\n            }\n            return entry_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u952e\n        pub fn keySet(self: *Self) !std.ArrayList(usize) {\n            var key_set = std.ArrayList(usize).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try key_set.append(item.?.key);\n            }\n            return key_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u503c\n        pub fn valueSet(self: *Self) !std.ArrayList([]const u8) {\n            var value_set = std.ArrayList([]const u8).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try value_set.append(item.?.val);\n            }\n            return value_set;\n        }\n\n        // \u6253\u5370\u54c8\u5e0c\u8868\n        pub fn print(self: *Self) !void {\n            var entry_set = try self.pairSet();\n            defer entry_set.deinit();\n            for (entry_set.items) |item| {\n                std.debug.print(\"{} -> {s}\\n\", .{item.key, item.val});\n            }\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_hashing/hash_map/#613-hash-collision-and-resizing","title":"6.1.3 \u00a0 Hash collision and resizing","text":"

    Fundamentally, the role of the hash function is to map the entire input space of all keys to the output space of all array indices. However, the input space is often much larger than the output space. Therefore, theoretically, there must be situations where \"multiple inputs correspond to the same output\".

    For the hash function in the above example, if the last two digits of the input key are the same, the output of the hash function will also be the same. For example, when querying for students with student numbers 12836 and 20336, we find:

    12836 % 100 = 36\n20336 % 100 = 36\n

    As shown in the Figure 6-3 , both student numbers point to the same name, which is obviously incorrect. This situation where multiple inputs correspond to the same output is known as \"hash collision\".

    Figure 6-3 \u00a0 Example of hash collision

    It is easy to understand that the larger the capacity \\(n\\) of the hash table, the lower the probability of multiple keys being allocated to the same bucket, and the fewer the collisions. Therefore, expanding the capacity of the hash table can reduce hash collisions.

    As shown in the Figure 6-4 , before expansion, key-value pairs (136, A) and (236, D) collided; after expansion, the collision is resolved.

    Figure 6-4 \u00a0 Hash table expansion

    Similar to array expansion, resizing a hash table requires migrating all key-value pairs from the original hash table to the new one, which is time-consuming. Furthermore, since the capacity capacity of the hash table changes, we need to recalculate the storage positions of all key-value pairs using the hash function, which adds to the computational overhead of the resizing process. Therefore, programming languages often reserve a sufficiently large capacity for the hash table to prevent frequent resizing.

    The \"load factor\" is an important concept for hash tables. It is defined as the ratio of the number of elements in the hash table to the number of buckets. It is used to measure the severity of hash collisions and is often used as a trigger for resizing the hash table. For example, in Java, when the load factor exceeds \\(0.75\\), the system will resize the hash table to twice its original size.

    "},{"location":"chapter_hashing/summary/","title":"6.4 \u00a0 Summary","text":""},{"location":"chapter_hashing/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Given an input key, a hash table can retrieve the corresponding value in \\(O(1)\\) time, which is highly efficient.
    • Common hash table operations include querying, adding key-value pairs, deleting key-value pairs, and traversing the hash table.
    • The hash function maps a key to an array index, allowing access to the corresponding bucket and retrieval of the value.
    • Two different keys may end up with the same array index after hashing, leading to erroneous query results. This phenomenon is known as hash collision.
    • The larger the capacity of the hash table, the lower the probability of hash collisions. Therefore, hash table resizing can mitigate hash collisions. Similar to array resizing, hash table resizing is costly.
    • The load factor, defined as the number of elements divided by the number of buckets, reflects the severity of hash collisions and is often used as a condition to trigger hash table resizing.
    • Chaining addresses hash collisions by converting each element into a linked list, storing all colliding elements in the same list. However, excessively long lists can reduce query efficiency, which can be improved by converting the lists into red-black trees.
    • Open addressing handles hash collisions through multiple probes. Linear probing uses a fixed step size but it cannot delete elements and is prone to clustering. Multiple hashing uses several hash functions for probing which reduces clustering compared to linear probing but increases computational overhead.
    • Different programming languages adopt various hash table implementations. For example, Java's HashMap uses chaining, while Python's dict employs open addressing.
    • In hash tables, we desire hash algorithms with determinism, high efficiency, and uniform distribution. In cryptography, hash algorithms should also possess collision resistance and the avalanche effect.
    • Hash algorithms typically use large prime numbers as moduli to ensure uniform distribution of hash values and reduce hash collisions.
    • Common hash algorithms include MD5, SHA-1, SHA-2, and SHA-3. MD5 is often used for file integrity checks, while SHA-2 is commonly used in secure applications and protocols.
    • Programming languages usually provide built-in hash algorithms for data types to calculate bucket indices in hash tables. Generally, only immutable objects are hashable.
    "},{"location":"chapter_hashing/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: When does the time complexity of a hash table degrade to \\(O(n)\\)?

    The time complexity of a hash table can degrade to \\(O(n)\\) when hash collisions are severe. When the hash function is well-designed, the capacity is set appropriately, and collisions are evenly distributed, the time complexity is \\(O(1)\\). We usually consider the time complexity to be \\(O(1)\\) when using built-in hash tables in programming languages.

    Q: Why not use the hash function \\(f(x) = x\\)? This would eliminate collisions.

    Under the hash function \\(f(x) = x\\), each element corresponds to a unique bucket index, which is equivalent to an array. However, the input space is usually much larger than the output space (array length), so the last step of a hash function is often to take the modulo of the array length. In other words, the goal of a hash table is to map a larger state space to a smaller one while providing \\(O(1)\\) query efficiency.

    Q: Why can hash tables be more efficient than arrays, linked lists, or binary trees, even though hash tables are implemented using these structures?

    Firstly, hash tables have higher time efficiency but lower space efficiency. A significant portion of memory in hash tables remains unused.

    Secondly, hash tables are only more time-efficient in specific use cases. If a feature can be implemented with the same time complexity using an array or a linked list, it's usually faster than using a hash table. This is because the computation of the hash function incurs overhead, making the constant factor in the time complexity larger.

    Lastly, the time complexity of hash tables can degrade. For example, in chaining, we perform search operations in a linked list or red-black tree, which still risks degrading to \\(O(n)\\) time.

    Q: Does multiple hashing also have the flaw of not being able to delete elements directly? Can space marked as deleted be reused?

    Multiple hashing is a form of open addressing, and all open addressing methods have the drawback of not being able to delete elements directly; they require marking elements as deleted. Marked spaces can be reused. When inserting new elements into the hash table, and the hash function points to a position marked as deleted, that position can be used by the new element. This maintains the probing sequence of the hash table while ensuring efficient use of space.

    Q: Why do hash collisions occur during the search process in linear probing?

    During the search process, the hash function points to the corresponding bucket and key-value pair. If the key doesn't match, it indicates a hash collision. Therefore, linear probing will search downwards at a predetermined step size until the correct key-value pair is found or the search fails.

    Q: Why can resizing a hash table alleviate hash collisions?

    The last step of a hash function often involves taking the modulo of the array length \\(n\\), to keep the output within the array index range. When resizing, the array length \\(n\\) changes, and the indices corresponding to the keys may also change. Keys that were previously mapped to the same bucket might be distributed across multiple buckets after resizing, thereby mitigating hash collisions.

    "},{"location":"chapter_heap/","title":"Chapter 8. \u00a0 Heap","text":"

    Abstract

    The heap is like mountain peaks, stacked and undulating, each with its unique shape.

    Among these peaks, the highest one always catches the eye first.

    "},{"location":"chapter_heap/#chapter-contents","title":"Chapter contents","text":"
    • 8.1 \u00a0 Heap
    • 8.2 \u00a0 Building a heap
    • 8.3 \u00a0 Top-k problem
    • 8.4 \u00a0 Summary
    "},{"location":"chapter_heap/build_heap/","title":"8.2 \u00a0 Heap construction operation","text":"

    In some cases, we want to build a heap using all elements of a list, and this process is known as \"heap construction operation.\"

    "},{"location":"chapter_heap/build_heap/#821-implementing-with-heap-insertion-operation","title":"8.2.1 \u00a0 Implementing with heap insertion operation","text":"

    First, we create an empty heap and then iterate through the list, performing the \"heap insertion operation\" on each element in turn. This means adding the element to the end of the heap and then \"heapifying\" it from bottom to top.

    Each time an element is added to the heap, the length of the heap increases by one. Since nodes are added to the binary tree from top to bottom, the heap is constructed \"from top to bottom.\"

    Let the number of elements be \\(n\\), and each element's insertion operation takes \\(O(\\log{n})\\) time, thus the time complexity of this heap construction method is \\(O(n \\log n)\\).

    "},{"location":"chapter_heap/build_heap/#822-implementing-by-heapifying-through-traversal","title":"8.2.2 \u00a0 Implementing by heapifying through traversal","text":"

    In fact, we can implement a more efficient method of heap construction in two steps.

    1. Add all elements of the list as they are into the heap, at this point the properties of the heap are not yet satisfied.
    2. Traverse the heap in reverse order (reverse of level-order traversal), and perform \"top to bottom heapify\" on each non-leaf node.

    After heapifying a node, the subtree with that node as the root becomes a valid sub-heap. Since the traversal is in reverse order, the heap is built \"from bottom to top.\"

    The reason for choosing reverse traversal is that it ensures the subtree below the current node is already a valid sub-heap, making the heapification of the current node effective.

    It's worth mentioning that since leaf nodes have no children, they naturally form valid sub-heaps and do not need to be heapified. As shown in the following code, the last non-leaf node is the parent of the last node; we start from it and traverse in reverse order to perform heapification:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def __init__(self, nums: list[int]):\n    \"\"\"\u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\"\"\"\n    # \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    self.max_heap = nums\n    # \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(self.parent(self.size() - 1), -1, -1):\n        self.sift_down(i)\n
    my_heap.cpp
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(vector<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums;\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.java
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<Integer> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new ArrayList<>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.cs
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(IEnumerable<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new List<int>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var size = Parent(this.Size() - 1);\n    for (int i = size; i >= 0; i--) {\n        SiftDown(i);\n    }\n}\n
    my_heap.go
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nfunc newMaxHeap(nums []any) *maxHeap {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    h := &maxHeap{data: nums}\n    for i := h.parent(len(h.data) - 1); i >= 0; i-- {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        h.siftDown(i)\n    }\n    return h\n}\n
    my_heap.swift
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\ninit(nums: [Int]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0 ... parent(i: size() - 1)).reversed() {\n        siftDown(i: i)\n    }\n}\n
    my_heap.js
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.#maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.#parent(this.size() - 1); i >= 0; i--) {\n        this.#siftDown(i);\n    }\n}\n
    my_heap.ts
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums?: number[]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.parent(this.size() - 1); i >= 0; i--) {\n        this.siftDown(i);\n    }\n}\n
    my_heap.dart
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<int> nums) {\n  // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n  _maxHeap = nums;\n  // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = _parent(size() - 1); i >= 0; i--) {\n    siftDown(i);\n  }\n}\n
    my_heap.rs
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nfn new(nums: Vec<i32>) -> Self {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    let mut heap = MaxHeap { max_heap: nums };\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=Self::parent(heap.size() - 1)).rev() {\n        heap.sift_down(i);\n    }\n    heap\n}\n
    my_heap.c
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nMaxHeap *newMaxHeap(int nums[], int size) {\n    // \u6240\u6709\u5143\u7d20\u5165\u5806\n    MaxHeap *maxHeap = (MaxHeap *)malloc(sizeof(MaxHeap));\n    maxHeap->size = size;\n    memcpy(maxHeap->data, nums, size * sizeof(int));\n    for (int i = parent(maxHeap, size - 1); i >= 0; i--) {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        siftDown(maxHeap, i);\n    }\n    return maxHeap;\n}\n
    my_heap.kt
    /* \u5927\u9876\u5806 */\nclass MaxHeap(nums: MutableList<Int>?) {\n    // \u4f7f\u7528\u5217\u8868\u800c\u975e\u6570\u7ec4\uff0c\u8fd9\u6837\u65e0\u987b\u8003\u8651\u6269\u5bb9\u95ee\u9898\n    private val maxHeap = mutableListOf<Int>()\n\n    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\n    init {\n        // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n        maxHeap.addAll(nums!!)\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        for (i in parent(size() - 1) downTo 0) {\n            siftDown(i)\n        }\n    }\n\n    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun parent(i: Int): Int {\n        return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u4ea4\u6362\u5143\u7d20 */\n    private fun swap(i: Int, j: Int) {\n        val temp = maxHeap[i]\n        maxHeap[i] = maxHeap[j]\n        maxHeap[j] = temp\n    }\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    fun size(): Int {\n        return maxHeap.size\n    }\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n        return size() == 0\n    }\n\n    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        return maxHeap[0]\n    }\n\n    /* \u5143\u7d20\u5165\u5806 */\n    fun push(_val: Int) {\n        // \u6dfb\u52a0\u8282\u70b9\n        maxHeap.add(_val)\n        // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n        siftUp(size() - 1)\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n    private fun siftUp(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n            val p = parent(i)\n            // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n            if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, p)\n            // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n            i = p\n        }\n    }\n\n    /* \u5143\u7d20\u51fa\u5806 */\n    fun pop(): Int {\n        // \u5224\u7a7a\u5904\u7406\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(0, size() - 1)\n        // \u5220\u9664\u8282\u70b9\n        val _val = maxHeap.removeAt(size() - 1)\n        // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n        siftDown(0)\n        // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n        return _val\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n    private fun siftDown(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n            val l = left(i)\n            val r = right(i)\n            var ma = i\n            if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n            if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n            // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n            if (ma == i) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, ma)\n            // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n            i = ma\n        }\n    }\n\n    /* \u6253\u5370\u5806\uff08\u4e8c\u53c9\u6811\uff09 */\n    fun print() {\n        val queue = PriorityQueue { a: Int, b: Int -> b - a }\n        queue.addAll(maxHeap)\n        printHeap(queue)\n    }\n}\n
    my_heap.rb
    [class]{MaxHeap}-[func]{__init__}\n
    my_heap.zig
    // \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\nfn init(self: *Self, allocator: std.mem.Allocator, nums: []const T) !void {\n    if (self.max_heap != null) return;\n    self.max_heap = std.ArrayList(T).init(allocator);\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    try self.max_heap.?.appendSlice(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var i: usize = parent(self.size() - 1) + 1;\n    while (i > 0) : (i -= 1) {\n        try self.siftDown(i - 1);\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/build_heap/#823-complexity-analysis","title":"8.2.3 \u00a0 Complexity analysis","text":"

    Next, let's attempt to calculate the time complexity of this second method of heap construction.

    • Assuming the number of nodes in the complete binary tree is \\(n\\), then the number of leaf nodes is \\((n + 1) / 2\\), where \\(/\\) is integer division. Therefore, the number of nodes that need to be heapified is \\((n - 1) / 2\\).
    • In the process of \"top to bottom heapification,\" each node is heapified to the leaf nodes at most, so the maximum number of iterations is the height of the binary tree \\(\\log n\\).

    Multiplying the two, we get the time complexity of the heap construction process as \\(O(n \\log n)\\). But this estimate is not accurate, because it does not take into account the nature of the binary tree having far more nodes at the lower levels than at the top.

    Let's perform a more accurate calculation. To simplify the calculation, assume a \"perfect binary tree\" with \\(n\\) nodes and height \\(h\\); this assumption does not affect the correctness of the result.

    Figure 8-5 \u00a0 Node counts at each level of a perfect binary tree

    As shown in the Figure 8-5 , the maximum number of iterations for a node \"to be heapified from top to bottom\" is equal to the distance from that node to the leaf nodes, which is precisely \"node height.\" Therefore, we can sum the \"number of nodes \\(\\times\\) node height\" at each level, to get the total number of heapification iterations for all nodes.

    \\[ T(h) = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{(h-1)}\\times1 \\]

    To simplify the above equation, we need to use knowledge of sequences from high school, first multiply \\(T(h)\\) by \\(2\\), to get:

    \\[ \\begin{aligned} T(h) & = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{h-1}\\times1 \\newline 2T(h) & = 2^1h + 2^2(h-1) + 2^3(h-2) + \\dots + 2^h\\times1 \\newline \\end{aligned} \\]

    By subtracting \\(T(h)\\) from \\(2T(h)\\) using the method of displacement, we get:

    \\[ 2T(h) - T(h) = T(h) = -2^0h + 2^1 + 2^2 + \\dots + 2^{h-1} + 2^h \\]

    Observing the equation, \\(T(h)\\) is an geometric series, which can be directly calculated using the sum formula, resulting in a time complexity of:

    \\[ \\begin{aligned} T(h) & = 2 \\frac{1 - 2^h}{1 - 2} - h \\newline & = 2^{h+1} - h - 2 \\newline & = O(2^h) \\end{aligned} \\]

    Further, a perfect binary tree with height \\(h\\) has \\(n = 2^{h+1} - 1\\) nodes, thus the complexity is \\(O(2^h) = O(n)\\). This calculation shows that the time complexity of inputting a list and constructing a heap is \\(O(n)\\), which is very efficient.

    "},{"location":"chapter_heap/heap/","title":"8.1 \u00a0 Heap","text":"

    A \"heap\" is a complete binary tree that satisfies specific conditions and can be mainly divided into two types, as shown in the Figure 8-1 .

    • \"Min heap\": The value of any node \\(\\leq\\) the values of its child nodes.
    • \"Max heap\": The value of any node \\(\\geq\\) the values of its child nodes.

    Figure 8-1 \u00a0 Min heap and max heap

    As a special case of a complete binary tree, heaps have the following characteristics:

    • The bottom layer nodes are filled from left to right, and nodes in other layers are fully filled.
    • The root node of the binary tree is called the \"heap top,\" and the bottom-rightmost node is called the \"heap bottom.\"
    • For max heaps (min heaps), the value of the heap top element (root node) is the largest (smallest).
    "},{"location":"chapter_heap/heap/#811-common-operations-on-heaps","title":"8.1.1 \u00a0 Common operations on heaps","text":"

    It should be noted that many programming languages provide a \"priority queue,\" which is an abstract data structure defined as a queue with priority sorting.

    In fact, heaps are often used to implement priority queues, with max heaps equivalent to priority queues where elements are dequeued in descending order. From a usage perspective, we can consider \"priority queue\" and \"heap\" as equivalent data structures. Therefore, this book does not make a special distinction between the two, uniformly referring to them as \"heap.\"

    Common operations on heaps are shown in the Table 8-1 , and the method names depend on the programming language.

    Table 8-1 \u00a0 Efficiency of Heap Operations

    Method name Description Time complexity push() Add an element to the heap \\(O(\\log n)\\) pop() Remove the top element from the heap \\(O(\\log n)\\) peek() Access the top element (for max/min heap, the max/min value) \\(O(1)\\) size() Get the number of elements in the heap \\(O(1)\\) isEmpty() Check if the heap is empty \\(O(1)\\)

    In practice, we can directly use the heap class (or priority queue class) provided by programming languages.

    Similar to sorting algorithms where we have \"ascending order\" and \"descending order,\" we can switch between \"min heap\" and \"max heap\" by setting a flag or modifying the Comparator. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap.py
    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\nmin_heap, flag = [], 1\n# \u521d\u59cb\u5316\u5927\u9876\u5806\nmax_heap, flag = [], -1\n\n# Python \u7684 heapq \u6a21\u5757\u9ed8\u8ba4\u5b9e\u73b0\u5c0f\u9876\u5806\n# \u8003\u8651\u5c06\u201c\u5143\u7d20\u53d6\u8d1f\u201d\u540e\u518d\u5165\u5806\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u5927\u5c0f\u5173\u7cfb\u98a0\u5012\uff0c\u4ece\u800c\u5b9e\u73b0\u5927\u9876\u5806\n# \u5728\u672c\u793a\u4f8b\u4e2d\uff0cflag = 1 \u65f6\u5bf9\u5e94\u5c0f\u9876\u5806\uff0cflag = -1 \u65f6\u5bf9\u5e94\u5927\u9876\u5806\n\n# \u5143\u7d20\u5165\u5806\nheapq.heappush(max_heap, flag * 1)\nheapq.heappush(max_heap, flag * 3)\nheapq.heappush(max_heap, flag * 2)\nheapq.heappush(max_heap, flag * 5)\nheapq.heappush(max_heap, flag * 4)\n\n# \u83b7\u53d6\u5806\u9876\u5143\u7d20\npeek: int = flag * max_heap[0] # 5\n\n# \u5806\u9876\u5143\u7d20\u51fa\u5806\n# \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nval = flag * heapq.heappop(max_heap) # 5\nval = flag * heapq.heappop(max_heap) # 4\nval = flag * heapq.heappop(max_heap) # 3\nval = flag * heapq.heappop(max_heap) # 2\nval = flag * heapq.heappop(max_heap) # 1\n\n# \u83b7\u53d6\u5806\u5927\u5c0f\nsize: int = len(max_heap)\n\n# \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = not max_heap\n\n# \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806\nmin_heap: list[int] = [1, 3, 2, 5, 4]\nheapq.heapify(min_heap)\n
    heap.cpp
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\npriority_queue<int, vector<int>, greater<int>> minHeap;\n// \u521d\u59cb\u5316\u5927\u9876\u5806\npriority_queue<int, vector<int>, less<int>> maxHeap;\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.push(1);\nmaxHeap.push(3);\nmaxHeap.push(2);\nmaxHeap.push(5);\nmaxHeap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.top(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nmaxHeap.pop(); // 5\nmaxHeap.pop(); // 4\nmaxHeap.pop(); // 3\nmaxHeap.pop(); // 2\nmaxHeap.pop(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nvector<int> input{1, 3, 2, 5, 4};\npriority_queue<int, vector<int>, greater<int>> minHeap(input.begin(), input.end());\n
    heap.java
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nQueue<Integer> minHeap = new PriorityQueue<>();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1);\nmaxHeap.offer(3);\nmaxHeap.offer(2);\nmaxHeap.offer(5);\nmaxHeap.offer(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.peek(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll(); // 5\npeek = maxHeap.poll(); // 4\npeek = maxHeap.poll(); // 3\npeek = maxHeap.poll(); // 2\npeek = maxHeap.poll(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = maxHeap.isEmpty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<>(Arrays.asList(1, 3, 2, 5, 4));\n
    heap.cs
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nPriorityQueue<int, int> minHeap = new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nPriorityQueue<int, int> maxHeap = new(Comparer<int>.Create((x, y) => y - x));\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.Enqueue(1, 1);\nmaxHeap.Enqueue(3, 3);\nmaxHeap.Enqueue(2, 2);\nmaxHeap.Enqueue(5, 5);\nmaxHeap.Enqueue(4, 4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.Peek();//5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.Dequeue();  // 5\npeek = maxHeap.Dequeue();  // 4\npeek = maxHeap.Dequeue();  // 3\npeek = maxHeap.Dequeue();  // 2\npeek = maxHeap.Dequeue();  // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.Count;\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.Count == 0;\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<int, int>([(1, 1), (3, 3), (2, 2), (5, 5), (4, 4)]);\n
    heap.go
    // Go \u8bed\u8a00\u4e2d\u53ef\u4ee5\u901a\u8fc7\u5b9e\u73b0 heap.Interface \u6765\u6784\u5efa\u6574\u6570\u5927\u9876\u5806\n// \u5b9e\u73b0 heap.Interface \u9700\u8981\u540c\u65f6\u5b9e\u73b0 sort.Interface\ntype intHeap []any\n\n// Push heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u63a8\u5165\u5143\u7d20\u5230\u5806\nfunc (h *intHeap) Push(x any) {\n    // Push \u548c Pop \u4f7f\u7528 pointer receiver \u4f5c\u4e3a\u53c2\u6570\n    // \u56e0\u4e3a\u5b83\u4eec\u4e0d\u4ec5\u4f1a\u5bf9\u5207\u7247\u7684\u5185\u5bb9\u8fdb\u884c\u8c03\u6574\uff0c\u8fd8\u4f1a\u4fee\u6539\u5207\u7247\u7684\u957f\u5ea6\u3002\n    *h = append(*h, x.(int))\n}\n\n// Pop heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u5f39\u51fa\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Pop() any {\n    // \u5f85\u51fa\u5806\u5143\u7d20\u5b58\u653e\u5728\u6700\u540e\n    last := (*h)[len(*h)-1]\n    *h = (*h)[:len(*h)-1]\n    return last\n}\n\n// Len sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Len() int {\n    return len(*h)\n}\n\n// Less sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Less(i, j int) bool {\n    // \u5982\u679c\u5b9e\u73b0\u5c0f\u9876\u5806\uff0c\u5219\u9700\u8981\u8c03\u6574\u4e3a\u5c0f\u4e8e\u53f7\n    return (*h)[i].(int) > (*h)[j].(int)\n}\n\n// Swap sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Swap(i, j int) {\n    (*h)[i], (*h)[j] = (*h)[j], (*h)[i]\n}\n\n// Top \u83b7\u53d6\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Top() any {\n    return (*h)[0]\n}\n\n/* Driver Code */\nfunc TestHeap(t *testing.T) {\n    /* \u521d\u59cb\u5316\u5806 */\n    // \u521d\u59cb\u5316\u5927\u9876\u5806\n    maxHeap := &intHeap{}\n    heap.Init(maxHeap)\n    /* \u5143\u7d20\u5165\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u6dfb\u52a0\u5143\u7d20\n    heap.Push(maxHeap, 1)\n    heap.Push(maxHeap, 3)\n    heap.Push(maxHeap, 2)\n    heap.Push(maxHeap, 4)\n    heap.Push(maxHeap, 5)\n\n    /* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\n    top := maxHeap.Top()\n    fmt.Printf(\"\u5806\u9876\u5143\u7d20\u4e3a %d\\n\", top)\n\n    /* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u79fb\u9664\u5143\u7d20\n    heap.Pop(maxHeap) // 5\n    heap.Pop(maxHeap) // 4\n    heap.Pop(maxHeap) // 3\n    heap.Pop(maxHeap) // 2\n    heap.Pop(maxHeap) // 1\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    size := len(*maxHeap)\n    fmt.Printf(\"\u5806\u5143\u7d20\u6570\u91cf\u4e3a %d\\n\", size)\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    isEmpty := len(*maxHeap) == 0\n    fmt.Printf(\"\u5806\u662f\u5426\u4e3a\u7a7a %t\\n\", isEmpty)\n}\n
    heap.swift
    /* \u521d\u59cb\u5316\u5806 */\n// Swift \u7684 Heap \u7c7b\u578b\u540c\u65f6\u652f\u6301\u6700\u5927\u5806\u548c\u6700\u5c0f\u5806\uff0c\u4e14\u9700\u8981\u5f15\u5165 swift-collections\nvar heap = Heap<Int>()\n\n/* \u5143\u7d20\u5165\u5806 */\nheap.insert(1)\nheap.insert(3)\nheap.insert(2)\nheap.insert(5)\nheap.insert(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = heap.max()!\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\npeek = heap.removeMax() // 5\npeek = heap.removeMax() // 4\npeek = heap.removeMax() // 3\npeek = heap.removeMax() // 2\npeek = heap.removeMax() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = heap.count\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = heap.isEmpty\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet heap2 = Heap([1, 3, 2, 5, 4])\n
    heap.js
    // JavaScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.ts
    // TypeScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.dart
    // Dart \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.rs
    use std::collections::BinaryHeap;\nuse std::cmp::Reverse;\n\n/* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nlet mut min_heap = BinaryHeap::<Reverse<i32>>::new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\nlet mut max_heap = BinaryHeap::new();\n\n/* \u5143\u7d20\u5165\u5806 */\nmax_heap.push(1);\nmax_heap.push(3);\nmax_heap.push(2);\nmax_heap.push(5);\nmax_heap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nlet peek = max_heap.peek().unwrap();  // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nlet peek = max_heap.pop().unwrap();   // 5\nlet peek = max_heap.pop().unwrap();   // 4\nlet peek = max_heap.pop().unwrap();   // 3\nlet peek = max_heap.pop().unwrap();   // 2\nlet peek = max_heap.pop().unwrap();   // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = max_heap.len();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = max_heap.is_empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet min_heap = BinaryHeap::from(vec![Reverse(1), Reverse(3), Reverse(2), Reverse(5), Reverse(4)]);\n
    heap.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.kt
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nvar minHeap = PriorityQueue<Int>()\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nval maxHeap = PriorityQueue { a: Int, b: Int -> b - a }\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1)\nmaxHeap.offer(3)\nmaxHeap.offer(2)\nmaxHeap.offer(5)\nmaxHeap.offer(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = maxHeap.peek() // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll() // 5\npeek = maxHeap.poll() // 4\npeek = maxHeap.poll() // 3\npeek = maxHeap.poll() // 2\npeek = maxHeap.poll() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nval size = maxHeap.size\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = maxHeap.isEmpty()\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = PriorityQueue(mutableListOf(1, 3, 2, 5, 4))\n
    heap.rb
    \n
    heap.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    https://pythontutor.com/render.html#code=import%20heapq%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B0%8F%E9%A1%B6%E5%A0%86%0A%20%20%20%20min_heap,%20flag%20%3D%20%5B%5D,%201%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%A4%A7%E9%A1%B6%E5%A0%86%0A%20%20%20%20max_heap,%20flag%20%3D%20%5B%5D,%20-1%0A%20%20%20%20%0A%20%20%20%20%23%20Python%20%E7%9A%84%20heapq%20%E6%A8%A1%E5%9D%97%E9%BB%98%E8%AE%A4%E5%AE%9E%E7%8E%B0%E5%B0%8F%E9%A1%B6%E5%A0%86%0A%20%20%20%20%23%20%E8%80%83%E8%99%91%E5%B0%86%E2%80%9C%E5%85%83%E7%B4%A0%E5%8F%96%E8%B4%9F%E2%80%9D%E5%90%8E%E5%86%8D%E5%85%A5%E5%A0%86%EF%BC%8C%E8%BF%99%E6%A0%B7%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%B0%86%E5%A4%A7%E5%B0%8F%E5%85%B3%E7%B3%BB%E9%A2%A0%E5%80%92%EF%BC%8C%E4%BB%8E%E8%80%8C%E5%AE%9E%E7%8E%B0%E5%A4%A7%E9%A1%B6%E5%A0%86%0A%20%20%20%20%23%20%E5%9C%A8%E6%9C%AC%E7%A4%BA%E4%BE%8B%E4%B8%AD%EF%BC%8Cflag%20%3D%201%20%E6%97%B6%E5%AF%B9%E5%BA%94%E5%B0%8F%E9%A1%B6%E5%A0%86%EF%BC%8Cflag%20%3D%20-1%20%E6%97%B6%E5%AF%B9%E5%BA%94%E5%A4%A7%E9%A1%B6%E5%A0%86%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%85%A5%E5%A0%86%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%201%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%203%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%202%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%205%29%0A%20%20%20%20heapq.heappush%28max_heap,%20flag%20*%204%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E5%A0%86%E9%A1%B6%E5%85%83%E7%B4%A0%0A%20%20%20%20peek%20%3D%20flag%20*%20max_heap%5B0%5D%20%23%205%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%A0%86%E9%A1%B6%E5%85%83%E7%B4%A0%E5%87%BA%E5%A0%86%0A%20%20%20%20%23%20%E5%87%BA%E5%A0%86%E5%85%83%E7%B4%A0%E4%BC%9A%E5%BD%A2%E6%88%90%E4%B8%80%E4%B8%AA%E4%BB%8E%E5%A4%A7%E5%88%B0%E5%B0%8F%E7%9A%84%E5%BA%8F%E5%88%97%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%205%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%204%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%203%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%202%0A%20%20%20%20val%20%3D%20flag%20*%20heapq.heappop%28max_heap%29%20%23%201%0A%20%20%20%20%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E5%A0%86%E5%A4%A7%E5%B0%8F%0A%20%20%20%20size%20%3D%20len%28max_heap%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%88%A4%E6%96%AD%E5%A0%86%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%0A%20%20%20%20is_empty%20%3D%20not%20max_heap%0A%20%20%20%20%0A%20%20%20%20%23%20%E8%BE%93%E5%85%A5%E5%88%97%E8%A1%A8%E5%B9%B6%E5%BB%BA%E5%A0%86%0A%20%20%20%20min_heap%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%20%20%20%20heapq.heapify%28min_heap%29&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    "},{"location":"chapter_heap/heap/#812-implementation-of-heaps","title":"8.1.2 \u00a0 Implementation of heaps","text":"

    The following implementation is of a max heap. To convert it into a min heap, simply invert all size logic comparisons (for example, replace \\(\\geq\\) with \\(\\leq\\)). Interested readers are encouraged to implement it on their own.

    "},{"location":"chapter_heap/heap/#1-storage-and-representation-of-heaps","title":"1. \u00a0 Storage and representation of heaps","text":"

    As mentioned in the \"Binary Trees\" section, complete binary trees are well-suited for array representation. Since heaps are a type of complete binary tree, we will use arrays to store heaps.

    When using an array to represent a binary tree, elements represent node values, and indexes represent node positions in the binary tree. Node pointers are implemented through an index mapping formula.

    As shown in the Figure 8-2 , given an index \\(i\\), the index of its left child is \\(2i + 1\\), the index of its right child is \\(2i + 2\\), and the index of its parent is \\((i - 1) / 2\\) (floor division). When the index is out of bounds, it signifies a null node or the node does not exist.

    Figure 8-2 \u00a0 Representation and storage of heaps

    We can encapsulate the index mapping formula into functions for convenient later use:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def left(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 1\n\ndef right(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 2\n\ndef parent(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return (i - 1) // 2  # \u5411\u4e0b\u6574\u9664\n
    my_heap.cpp
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.java
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.cs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint Parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.go
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) parent(i int) int {\n    // \u5411\u4e0b\u6574\u9664\n    return (i - 1) / 2\n}\n
    my_heap.swift
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc left(i: Int) -> Int {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc right(i: Int) -> Int {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc parent(i: Int) -> Int {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.js
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#left(i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#right(i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n#parent(i) {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.ts
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nleft(i: number): number {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nright(i: number): number {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nparent(i: number): number {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.dart
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _left(int i) {\n  return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _right(int i) {\n  return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint _parent(int i) {\n  return (i - 1) ~/ 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn left(i: usize) -> usize {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn right(i: usize) -> usize {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfn parent(i: usize) -> usize {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.c
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(MaxHeap *maxHeap, int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(MaxHeap *maxHeap, int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(MaxHeap *maxHeap, int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u53d6\u6574\n}\n
    my_heap.kt
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun left(i: Int): Int {\n    return 2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun right(i: Int): Int {\n    return 2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfun parent(i: Int): Int {\n    return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rb
    ### \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef left(i)\n  2 * i + 1\nend\n\n### \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef right(i)\n  2 * i + 2\nend\n\n### \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef parent(i)\n  (i - 1) / 2     # \u5411\u4e0b\u6574\u9664\nend\n
    my_heap.zig
    // \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn left(i: usize) usize {\n    return 2 * i + 1;\n}\n\n// \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn right(i: usize) usize {\n    return 2 * i + 2;\n}\n\n// \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\nfn parent(i: usize) usize {\n    // return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n    return @divFloor(i - 1, 2);\n}\n
    "},{"location":"chapter_heap/heap/#2-accessing-the-top-element-of-the-heap","title":"2. \u00a0 Accessing the top element of the heap","text":"

    The top element of the heap is the root node of the binary tree, which is also the first element of the list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def peek(self) -> int:\n    \"\"\"\u8bbf\u95ee\u5806\u9876\u5143\u7d20\"\"\"\n    return self.max_heap[0]\n
    my_heap.cpp
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap[0];\n}\n
    my_heap.java
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap.get(0);\n}\n
    my_heap.cs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint Peek() {\n    return maxHeap[0];\n}\n
    my_heap.go
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc (h *maxHeap) peek() any {\n    return h.data[0]\n}\n
    my_heap.swift
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc peek() -> Int {\n    maxHeap[0]\n}\n
    my_heap.js
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek() {\n    return this.#maxHeap[0];\n}\n
    my_heap.ts
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek(): number {\n    return this.maxHeap[0];\n}\n
    my_heap.dart
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n  return _maxHeap[0];\n}\n
    my_heap.rs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfn peek(&self) -> Option<i32> {\n    self.max_heap.first().copied()\n}\n
    my_heap.c
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek(MaxHeap *maxHeap) {\n    return maxHeap->data[0];\n}\n
    my_heap.kt
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfun peek(): Int {\n    return maxHeap[0]\n}\n
    my_heap.rb
    ### \u8bbf\u95ee\u5806\u9876\u5143\u7d20 ###\ndef peek\n  @max_heap[0]\nend\n
    my_heap.zig
    // \u8bbf\u95ee\u5806\u9876\u5143\u7d20\nfn peek(self: *Self) T {\n    return self.max_heap.?.items[0];\n}  \n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/heap/#3-inserting-an-element-into-the-heap","title":"3. \u00a0 Inserting an element into the heap","text":"

    Given an element val, we first add it to the bottom of the heap. After addition, since val may be larger than other elements in the heap, the heap's integrity might be compromised, thus it's necessary to repair the path from the inserted node to the root node. This operation is called \"heapifying\".

    Considering starting from the node inserted, perform heapify from bottom to top. As shown in the Figure 8-3 , we compare the value of the inserted node with its parent node, and if the inserted node is larger, we swap them. Then continue this operation, repairing each node in the heap from bottom to top until passing the root node or encountering a node that does not need to be swapped.

    <1><2><3><4><5><6><7><8><9>

    Figure 8-3 \u00a0 Steps of element insertion into the heap

    Given a total of \\(n\\) nodes, the height of the tree is \\(O(\\log n)\\). Hence, the loop iterations for the heapify operation are at most \\(O(\\log n)\\), making the time complexity of the element insertion operation \\(O(\\log n)\\). The code is as shown:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def push(self, val: int):\n    \"\"\"\u5143\u7d20\u5165\u5806\"\"\"\n    # \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.append(val)\n    # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1)\n\ndef sift_up(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\"\"\"\n    while True:\n        # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p = self.parent(i)\n        # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 or self.max_heap[i] <= self.max_heap[p]:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p)\n        # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n
    my_heap.cpp
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.push_back(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap[i], maxHeap[p]);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap.get(i) <= maxHeap.get(p))\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u5165\u5806 */\nvoid Push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.Add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    SiftUp(Size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid SiftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = Parent(i);\n        // \u82e5\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u5165\u5806 */\nfunc (h *maxHeap) push(val any) {\n    // \u6dfb\u52a0\u8282\u70b9\n    h.data = append(h.data, val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    h.siftUp(len(h.data) - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc (h *maxHeap) siftUp(i int) {\n    for true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p := h.parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || h.data[i].(int) <= h.data[p].(int) {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u5165\u5806 */\nfunc push(val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.append(val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(i: size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc siftUp(i: Int) {\n    var i = i\n    while true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = parent(i: i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || maxHeap[i] <= maxHeap[p] {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u5165\u5806 */\npush(val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.#maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.#siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n#siftUp(i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.#parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.#maxHeap[i] <= this.#maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u5165\u5806 */\npush(val: number): void {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nsiftUp(i: number): void {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n  // \u6dfb\u52a0\u8282\u70b9\n  _maxHeap.add(val);\n  // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n  while (true) {\n    // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    int p = _parent(i);\n    // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    if (p < 0 || _maxHeap[i] <= _maxHeap[p]) {\n      break;\n    }\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, p);\n    // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u5165\u5806 */\nfn push(&mut self, val: i32) {\n    // \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfn sift_up(&mut self, mut i: usize) {\n    loop {\n        // \u8282\u70b9 i \u5df2\u7ecf\u662f\u5806\u9876\u8282\u70b9\u4e86\uff0c\u7ed3\u675f\u5806\u5316\n        if i == 0 {\n            break;\n        }\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = Self::parent(i);\n        // \u5f53\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if self.max_heap[i] <= self.max_heap[p] {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(MaxHeap *maxHeap, int val) {\n    // \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u4e0d\u5e94\u8be5\u6dfb\u52a0\u8fd9\u4e48\u591a\u8282\u70b9\n    if (maxHeap->size == MAX_SIZE) {\n        printf(\"heap is full!\");\n        return;\n    }\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap->data[maxHeap->size] = val;\n    maxHeap->size++;\n\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(maxHeap, maxHeap->size - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(maxHeap, i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap->data[i] <= maxHeap->data[p]) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u5165\u5806 */\nfun push(_val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(_val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfun siftUp(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        val p = parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u5165\u5806 ###\ndef push(val)\n  # \u6dfb\u52a0\u8282\u70b9\n  @max_heap << val\n  # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  sift_up(size - 1)\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 ###\ndef sift_up(i)\n  loop do\n    # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    p = parent(i)\n    # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    break if p < 0 || @max_heap[i] <= @max_heap[p]\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, p)\n    # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u5165\u5806\nfn push(self: *Self, val: T) !void {\n    // \u6dfb\u52a0\u8282\u70b9\n    try self.max_heap.?.append(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    try self.siftUp(self.size() - 1);\n}  \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\nfn siftUp(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        var p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 or self.max_heap.?.items[i] <= self.max_heap.?.items[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/heap/#4-removing-the-top-element-from-the-heap","title":"4. \u00a0 Removing the top element from the heap","text":"

    The top element of the heap is the root node of the binary tree, that is, the first element of the list. If we directly remove the first element from the list, all node indexes in the binary tree would change, making it difficult to use heapify for repairs subsequently. To minimize changes in element indexes, we use the following steps.

    1. Swap the top element with the bottom element of the heap (swap the root node with the rightmost leaf node).
    2. After swapping, remove the bottom of the heap from the list (note, since it has been swapped, what is actually being removed is the original top element).
    3. Starting from the root node, perform heapify from top to bottom.

    As shown in the Figure 8-4 , the direction of \"heapify from top to bottom\" is opposite to \"heapify from bottom to top\". We compare the value of the root node with its two children and swap it with the largest child. Then repeat this operation until passing the leaf node or encountering a node that does not need to be swapped.

    <1><2><3><4><5><6><7><8><9><10>

    Figure 8-4 \u00a0 Steps of removing the top element from the heap

    Similar to the element insertion operation, the time complexity of the top element removal operation is also \\(O(\\log n)\\). The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def pop(self) -> int:\n    \"\"\"\u5143\u7d20\u51fa\u5806\"\"\"\n    # \u5224\u7a7a\u5904\u7406\n    if self.is_empty():\n        raise IndexError(\"\u5806\u4e3a\u7a7a\")\n    # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1)\n    # \u5220\u9664\u8282\u70b9\n    val = self.max_heap.pop()\n    # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0)\n    # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n\ndef sift_down(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l, r, ma = self.left(i), self.right(i), i\n        if l < self.size() and self.max_heap[l] > self.max_heap[ma]:\n            ma = l\n        if r < self.size() and self.max_heap[r] > self.max_heap[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma)\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n
    my_heap.cpp
    /* \u5143\u7d20\u51fa\u5806 */\nvoid pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) {\n        throw out_of_range(\"\u5806\u4e3a\u7a7a\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap[0], maxHeap[size() - 1]);\n    // \u5220\u9664\u8282\u70b9\n    maxHeap.pop_back();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        swap(maxHeap[i], maxHeap[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty())\n        throw new IndexOutOfBoundsException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.remove(size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap.get(l) > maxHeap.get(ma))\n            ma = l;\n        if (r < size() && maxHeap.get(r) > maxHeap.get(ma))\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u51fa\u5806 */\nint Pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (IsEmpty())\n        throw new IndexOutOfRangeException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    Swap(0, Size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.Last();\n    maxHeap.RemoveAt(Size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    SiftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = Left(i), r = Right(i), ma = i;\n        if (l < Size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < Size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u201c\u8282\u70b9 i \u6700\u5927\u201d\u6216\u201c\u8d8a\u8fc7\u53f6\u8282\u70b9\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u51fa\u5806 */\nfunc (h *maxHeap) pop() any {\n    // \u5224\u7a7a\u5904\u7406\n    if h.isEmpty() {\n        fmt.Println(\"error\")\n        return nil\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    h.swap(0, h.size()-1)\n    // \u5220\u9664\u8282\u70b9\n    val := h.data[len(h.data)-1]\n    h.data = h.data[:len(h.data)-1]\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    h.siftDown(0)\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc (h *maxHeap) siftDown(i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        l, r, max := h.left(i), h.right(i), i\n        if l < h.size() && h.data[l].(int) > h.data[max].(int) {\n            max = l\n        }\n        if r < h.size() && h.data[r].(int) > h.data[max].(int) {\n            max = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if max == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, max)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u51fa\u5806 */\nfunc pop() -> Int {\n    // \u5224\u7a7a\u5904\u7406\n    if isEmpty() {\n        fatalError(\"\u5806\u4e3a\u7a7a\")\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(i: 0, j: size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    let val = maxHeap.remove(at: size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(i: 0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = left(i: i)\n        let r = right(i: i)\n        var ma = i\n        if l < size(), maxHeap[l] > maxHeap[ma] {\n            ma = l\n        }\n        if r < size(), maxHeap[r] > maxHeap[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u51fa\u5806 */\npop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new Error('\u5806\u4e3a\u7a7a');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.#swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.#maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.#siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n#siftDown(i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.#left(i),\n            r = this.#right(i);\n        let ma = i;\n        if (l < this.size() && this.#maxHeap[l] > this.#maxHeap[ma]) ma = l;\n        if (r < this.size() && this.#maxHeap[r] > this.#maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u51fa\u5806 */\npop(): number {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new RangeError('Heap is empty.');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nsiftDown(i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.left(i),\n            r = this.right(i);\n        let ma = i;\n        if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;\n        if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n  // \u5224\u7a7a\u5904\u7406\n  if (isEmpty()) throw Exception('\u5806\u4e3a\u7a7a');\n  // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  _swap(0, size() - 1);\n  // \u5220\u9664\u8282\u70b9\n  int val = _maxHeap.removeLast();\n  // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  siftDown(0);\n  // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = _left(i);\n    int r = _right(i);\n    int ma = i;\n    if (l < size() && _maxHeap[l] > _maxHeap[ma]) ma = l;\n    if (r < size() && _maxHeap[r] > _maxHeap[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, ma);\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u51fa\u5806 */\nfn pop(&mut self) -> i32 {\n    // \u5224\u7a7a\u5904\u7406\n    if self.is_empty() {\n        panic!(\"index out of bounds\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    let val = self.max_heap.pop().unwrap();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(&mut self, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let (l, r, mut ma) = (Self::left(i), Self::right(i), i);\n        if l < self.size() && self.max_heap[l] > self.max_heap[ma] {\n            ma = l;\n        }\n        if r < self.size() && self.max_heap[r] > self.max_heap[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u51fa\u5806 */\nint pop(MaxHeap *maxHeap) {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty(maxHeap)) {\n        printf(\"heap is empty!\");\n        return INT_MAX;\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap, 0, size(maxHeap) - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap->data[maxHeap->size - 1];\n    maxHeap->size--;\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(maxHeap, 0);\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        int l = left(maxHeap, i);\n        int r = right(maxHeap, i);\n        int max = i;\n        if (l < size(maxHeap) && maxHeap->data[l] > maxHeap->data[max]) {\n            max = l;\n        }\n        if (r < size(maxHeap) && maxHeap->data[r] > maxHeap->data[max]) {\n            max = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (max == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, max);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u51fa\u5806 */\nfun pop(): Int {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) throw IndexOutOfBoundsException()\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    val _val = maxHeap.removeAt(size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return _val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = left(i)\n        val r = right(i)\n        var ma = i\n        if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n        if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u51fa\u5806 ###\ndef pop\n  # \u5224\u7a7a\u5904\u7406\n  raise IndexError, \"\u5806\u4e3a\u7a7a\" if is_empty?\n  # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  swap(0, size - 1)\n  # \u5220\u9664\u8282\u70b9\n  val = @max_heap.pop\n  # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  sift_down(0)\n  # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  val\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 ###\ndef sift_down(i)\n  loop do\n    # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    l, r, ma = left(i), right(i), i\n    ma = l if l < size && @max_heap[l] > @max_heap[ma]\n    ma = r if r < size && @max_heap[r] > @max_heap[ma]\n\n    # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    break if ma == i\n\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, ma)\n    # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u51fa\u5806\nfn pop(self: *Self) !T {\n    // \u5224\u65ad\u5904\u7406\n    if (self.isEmpty()) unreachable;\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    try self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    var val = self.max_heap.?.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    try self.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n} \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\nfn siftDown(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        var l = left(i);\n        var r = right(i);\n        var ma = i;\n        if (l < self.size() and self.max_heap.?.items[l] > self.max_heap.?.items[ma]) ma = l;\n        if (r < self.size() and self.max_heap.?.items[r] > self.max_heap.?.items[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_heap/heap/#813-common-applications-of-heaps","title":"8.1.3 \u00a0 Common applications of heaps","text":"
    • Priority Queue: Heaps are often the preferred data structure for implementing priority queues, with both enqueue and dequeue operations having a time complexity of \\(O(\\log n)\\), and building a queue having a time complexity of \\(O(n)\\), all of which are very efficient.
    • Heap Sort: Given a set of data, we can create a heap from them and then continually perform element removal operations to obtain ordered data. However, we usually use a more elegant method to implement heap sort, as detailed in the \"Heap Sort\" section.
    • Finding the Largest \\(k\\) Elements: This is a classic algorithm problem and also a typical application, such as selecting the top 10 hot news for Weibo hot search, picking the top 10 selling products, etc.
    "},{"location":"chapter_heap/summary/","title":"8.4 \u00a0 Summary","text":""},{"location":"chapter_heap/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • A heap is a complete binary tree, which can be divided into a max heap and a min heap based on its property. The top element of a max (min) heap is the largest (smallest).
    • A priority queue is defined as a queue with dequeue priority, usually implemented using a heap.
    • Common operations of a heap and their corresponding time complexities include: element insertion into the heap \\(O(\\log n)\\), removing the top element from the heap \\(O(\\log n)\\), and accessing the top element of the heap \\(O(1)\\).
    • A complete binary tree is well-suited to be represented by an array, thus heaps are commonly stored using arrays.
    • Heapify operations are used to maintain the properties of the heap and are used in both heap insertion and removal operations.
    • The time complexity of inserting \\(n\\) elements into a heap and building the heap can be optimized to \\(O(n)\\), which is highly efficient.
    • Top-k is a classic algorithm problem that can be efficiently solved using the heap data structure, with a time complexity of \\(O(n \\log k)\\).
    "},{"location":"chapter_heap/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is the \"heap\" in data structures the same concept as the \"heap\" in memory management?

    The two are not the same concept, even though they are both referred to as \"heap\". The heap in computer system memory is part of dynamic memory allocation, where the program can use it to store data during execution. The program can request a certain amount of heap memory to store complex structures like objects and arrays. When these data are no longer needed, the program needs to release this memory to prevent memory leaks. Compared to stack memory, the management and usage of heap memory need to be more cautious, as improper use may lead to memory leaks and dangling pointers.

    "},{"location":"chapter_heap/top_k/","title":"8.3 \u00a0 Top-k problem","text":"

    Question

    Given an unordered array nums of length \\(n\\), return the largest \\(k\\) elements in the array.

    For this problem, we will first introduce two straightforward solutions, then explain a more efficient heap-based method.

    "},{"location":"chapter_heap/top_k/#831-method-1-iterative-selection","title":"8.3.1 \u00a0 Method 1: Iterative selection","text":"

    We can perform \\(k\\) rounds of iterations as shown in the Figure 8-6 , extracting the \\(1^{st}\\), \\(2^{nd}\\), \\(\\dots\\), \\(k^{th}\\) largest elements in each round, with a time complexity of \\(O(nk)\\).

    This method is only suitable when \\(k \\ll n\\), as the time complexity approaches \\(O(n^2)\\) when \\(k\\) is close to \\(n\\), which is very time-consuming.

    Figure 8-6 \u00a0 Iteratively finding the largest k elements

    Tip

    When \\(k = n\\), we can obtain a complete ordered sequence, which is equivalent to the \"selection sort\" algorithm.

    "},{"location":"chapter_heap/top_k/#832-method-2-sorting","title":"8.3.2 \u00a0 Method 2: Sorting","text":"

    As shown in the Figure 8-7 , we can first sort the array nums and then return the last \\(k\\) elements, with a time complexity of \\(O(n \\log n)\\).

    Clearly, this method \"overachieves\" the task, as we only need to find the largest \\(k\\) elements, without the need to sort the other elements.

    Figure 8-7 \u00a0 Sorting to find the largest k elements

    "},{"location":"chapter_heap/top_k/#833-method-3-heap","title":"8.3.3 \u00a0 Method 3: Heap","text":"

    We can solve the Top-k problem more efficiently based on heaps, as shown in the following process.

    1. Initialize a min heap, where the top element is the smallest.
    2. First, insert the first \\(k\\) elements of the array into the heap.
    3. Starting from the \\(k + 1^{th}\\) element, if the current element is greater than the top element of the heap, remove the top element of the heap and insert the current element into the heap.
    4. After completing the traversal, the heap contains the largest \\(k\\) elements.
    <1><2><3><4><5><6><7><8><9>

    Figure 8-8 \u00a0 Find the largest k elements based on heap

    Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig top_k.py
    def top_k_heap(nums: list[int], k: int) -> list[int]:\n    \"\"\"\u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\"\"\"\n    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    heap = []\n    # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i in range(k):\n        heapq.heappush(heap, nums[i])\n    # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in range(k, len(nums)):\n        # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap[0]:\n            heapq.heappop(heap)\n            heapq.heappush(heap, nums[i])\n    return heap\n
    top_k.cpp
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\npriority_queue<int, vector<int>, greater<int>> topKHeap(vector<int> &nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    priority_queue<int, vector<int>, greater<int>> heap;\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.push(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.size(); i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.top()) {\n            heap.pop();\n            heap.push(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.java
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nQueue<Integer> topKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    Queue<Integer> heap = new PriorityQueue<Integer>();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.offer(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll();\n            heap.offer(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.cs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nPriorityQueue<int, int> TopKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    PriorityQueue<int, int> heap = new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.Enqueue(nums[i], nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.Length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.Peek()) {\n            heap.Dequeue();\n            heap.Enqueue(nums[i], nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.go
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums []int, k int) *minHeap {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    h := &minHeap{}\n    heap.Init(h)\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i := 0; i < k; i++ {\n        heap.Push(h, nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i := k; i < len(nums); i++ {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > h.Top().(int) {\n            heap.Pop(h)\n            heap.Push(h, nums[i])\n        }\n    }\n    return h\n}\n
    top_k.swift
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums: [Int], k: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5c0f\u9876\u5806\uff0c\u5e76\u5c06\u524d k \u4e2a\u5143\u7d20\u5efa\u5806\n    var heap = Heap(nums.prefix(k))\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in nums.indices.dropFirst(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap.min()! {\n            _ = heap.removeMin()\n            heap.insert(nums[i])\n        }\n    }\n    return heap.unordered\n}\n
    top_k.js
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap, val) {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums, k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.ts
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap: MaxHeap, val: number): void {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap: MaxHeap): number[] {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num: number) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums: number[], k: number): number[] {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.dart
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nMinHeap topKHeap(List<int> nums, int k) {\n  // \u521d\u59cb\u5316\u5c0f\u9876\u5806\uff0c\u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  MinHeap heap = MinHeap(nums.sublist(0, k));\n  // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for (int i = k; i < nums.length; i++) {\n    // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if (nums[i] > heap.peek()) {\n      heap.pop();\n      heap.push(nums[i]);\n    }\n  }\n  return heap;\n}\n
    top_k.rs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfn top_k_heap(nums: Vec<i32>, k: usize) -> BinaryHeap<Reverse<i32>> {\n    // BinaryHeap \u662f\u5927\u9876\u5806\uff0c\u4f7f\u7528 Reverse \u5c06\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u5b9e\u73b0\u5c0f\u9876\u5806\n    let mut heap = BinaryHeap::<Reverse<i32>>::new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for &num in nums.iter().take(k) {\n        heap.push(Reverse(num));\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for &num in nums.iter().skip(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if num > heap.peek().unwrap().0 {\n            heap.pop();\n            heap.push(Reverse(num));\n        }\n    }\n    heap\n}\n
    top_k.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid pushMinHeap(MaxHeap *maxHeap, int val) {\n    // \u5143\u7d20\u53d6\u53cd\n    push(maxHeap, -val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nint popMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -pop(maxHeap);\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peekMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -peek(maxHeap);\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n// \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\u7684\u51fd\u6570\nint *topKHeap(int *nums, int sizeNums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    int *empty = (int *)malloc(0);\n    MaxHeap *maxHeap = newMaxHeap(empty, 0);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < sizeNums; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    int *res = getMinHeap(maxHeap);\n    // \u91ca\u653e\u5185\u5b58\n    delMaxHeap(maxHeap);\n    return res;\n}\n
    top_k.kt
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfun topKHeap(nums: IntArray, k: Int): Queue<Int> {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    val heap = PriorityQueue<Int>()\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (i in 0..<k) {\n        heap.offer(nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (i in k..<nums.size) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll()\n            heap.offer(nums[i])\n        }\n    }\n    return heap\n}\n
    top_k.rb
    ### \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 ###\ndef top_k_heap(nums, k)\n  # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n  # \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n  max_heap = MaxHeap.new([])\n\n  # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  for i in 0...k\n    push_min_heap(max_heap, nums[i])\n  end\n\n  # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for i in k...nums.length\n    # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if nums[i] > peek_min_heap(max_heap)\n      pop_min_heap(max_heap)\n      push_min_heap(max_heap, nums[i])\n    end\n  end\n\n  get_min_heap(max_heap)\nend\n
    top_k.zig
    [class]{}-[func]{topKHeap}\n
    Code Visualization

    Full Screen >

    A total of \\(n\\) rounds of heap insertions and deletions are performed, with the maximum heap size being \\(k\\), hence the time complexity is \\(O(n \\log k)\\). This method is very efficient; when \\(k\\) is small, the time complexity tends towards \\(O(n)\\); when \\(k\\) is large, the time complexity will not exceed \\(O(n \\log n)\\).

    Additionally, this method is suitable for scenarios with dynamic data streams. By continuously adding data, we can maintain the elements within the heap, thereby achieving dynamic updates of the largest \\(k\\) elements.

    "},{"location":"chapter_hello_algo/","title":"Before starting","text":"

    A few years ago, I shared the \"Sword for Offer\" problem solutions on LeetCode, receiving encouragement and support from many readers. During interactions with readers, the most common question I encountered was \"how to get started with algorithms.\" Gradually, I developed a keen interest in this question.

    Directly solving problems seems to be the most popular method \u2014 it's simple, direct, and effective. However, problem-solving is like playing a game of Minesweeper: those with strong self-study abilities can defuse the mines one by one, but those with insufficient basics might end up metaphorically bruised from explosions, retreating step by step in frustration. Going through textbooks is also common, but for those aiming for job applications, the energy spent on thesis writing, resume submissions, and preparation for written tests and interviews leaves little for tackling thick books, turning it into a daunting challenge.

    If you're facing similar troubles, then this book is lucky to have found you. This book is my answer to the question. While it may not be the best solution, it is at least a positive attempt. This book may not directly land you an offer, but it will guide you through the \"knowledge map\" in data structures and algorithms, help you understand the shapes, sizes, and locations of different \"mines,\" and enable you to master various \"demining methods.\" With these skills, I believe you can solve problems and read literature more comfortably, gradually building a knowledge system.

    I deeply agree with Professor Feynman's statement: \"Knowledge isn't free. You have to pay attention.\" In this sense, this book is not entirely \"free.\" To not disappoint the precious \"attention\" you pay for this book, I will do my best, dedicating my utmost \"attention\" to this book.

    Knowing my limitations, although the content of this book has been refined over time, there are surely many errors remaining. I sincerely request critiques and corrections from all teachers and students.

    Hello, Algo!

    The advent of computers has brought significant changes to the world. With their high-speed computing power and excellent programmability, they have become the ideal medium for executing algorithms and processing data. Whether it's the realistic graphics of video games, the intelligent decisions in autonomous driving, the brilliant Go games of AlphaGo, or the natural interactions of ChatGPT, these applications are all exquisite demonstrations of algorithms at work on computers.

    In fact, before the advent of computers, algorithms and data structures already existed in every corner of the world. Early algorithms were relatively simple, such as ancient counting methods and tool-making procedures. As civilization progressed, algorithms became more refined and complex. From the exquisite craftsmanship of artisans, to industrial products that liberate productive forces, to the scientific laws governing the universe, almost every ordinary or astonishing thing has behind it the ingenious thought of algorithms.

    Similarly, data structures are everywhere: from social networks to subway lines, many systems can be modeled as \"graphs\"; from a country to a family, the main forms of social organization exhibit characteristics of \"trees\"; winter clothes are like a \"stack\", where the first item worn is the last to be taken off; a badminton shuttle tube resembles a \"queue\", with one end for insertion and the other for retrieval; a dictionary is like a \"hash table\", enabling quick search for target entries.

    This book aims to help readers understand the core concepts of algorithms and data structures through clear, easy-to-understand animated illustrations and runnable code examples, and to be able to implement them through programming. On this basis, this book strives to reveal the vivid manifestations of algorithms in the complex world, showcasing the beauty of algorithms. I hope this book can help you!

    "},{"location":"chapter_introduction/","title":"Chapter 1. \u00a0 Encounter with algorithms","text":"

    Abstract

    A graceful maiden dances, intertwined with the data, her skirt swaying to the melody of algorithms.

    She invites you to a dance, follow her steps, and enter the world of algorithms full of logic and beauty.

    "},{"location":"chapter_introduction/#chapter-contents","title":"Chapter contents","text":"
    • 1.1 \u00a0 Algorithms are everywhere
    • 1.2 \u00a0 What is an algorithm
    • 1.3 \u00a0 Summary
    "},{"location":"chapter_introduction/algorithms_are_everywhere/","title":"1.1 \u00a0 Algorithms are everywhere","text":"

    When we hear the word \"algorithm,\" we naturally think of mathematics. However, many algorithms do not involve complex mathematics but rely more on basic logic, which can be seen everywhere in our daily lives.

    Before formally discussing algorithms, there's an interesting fact worth sharing: you have already unconsciously learned many algorithms and have become accustomed to applying them in your daily life. Here, I will give a few specific examples to prove this point.

    Example 1: Looking Up a Dictionary. In an English dictionary, words are listed alphabetically. Suppose we're searching for a word that starts with the letter \\(r\\). This is typically done in the following way:

    1. Open the dictionary to about halfway and check the first letter on the page, let's say the letter is \\(m\\).
    2. Since \\(r\\) comes after \\(m\\) in the alphabet, we can ignore the first half of the dictionary and focus on the latter half.
    3. Repeat steps 1. and 2. until you find the page where the word starts with \\(r\\).
    <1><2><3><4><5>

    Figure 1-1 \u00a0 Process of Looking Up a Dictionary

    This essential skill for elementary students, looking up a dictionary, is actually the famous \"Binary Search\" algorithm. From a data structure perspective, we can consider the dictionary as a sorted \"array\"; from an algorithmic perspective, the series of actions taken to look up a word in the dictionary can be viewed as \"Binary Search.\"

    Example 2: Organizing Playing Cards. When playing cards, we need to arrange the cards in our hand in ascending order, as shown in the following process.

    1. Divide the playing cards into \"ordered\" and \"unordered\" sections, assuming initially the leftmost card is already in order.
    2. Take out a card from the unordered section and insert it into the correct position in the ordered section; after this, the leftmost two cards are in order.
    3. Continue to repeat step 2. until all cards are in order.

    Figure 1-2 \u00a0 Playing cards sorting process

    The above method of organizing playing cards is essentially the \"Insertion Sort\" algorithm, which is very efficient for small datasets. Many programming languages' sorting functions include the insertion sort.

    Example 3: Making Change. Suppose we buy goods worth \\(69\\) yuan at a supermarket and give the cashier \\(100\\) yuan, then the cashier needs to give us \\(31\\) yuan in change. They would naturally complete the thought process as shown below.

    1. The options are currencies smaller than \\(31\\), including \\(1\\), \\(5\\), \\(10\\), and \\(20\\).
    2. Take out the largest \\(20\\) from the options, leaving \\(31 - 20 = 11\\).
    3. Take out the largest \\(10\\) from the remaining options, leaving \\(11 - 10 = 1\\).
    4. Take out the largest \\(1\\) from the remaining options, leaving \\(1 - 1 = 0\\).
    5. Complete the change-making, with the solution being \\(20 + 10 + 1 = 31\\).

    Figure 1-3 \u00a0 Change making process

    In the above steps, we make the best choice at each step (using the largest denomination possible), ultimately resulting in a feasible change-making plan. From the perspective of data structures and algorithms, this method is essentially a \"Greedy\" algorithm.

    From cooking a meal to interstellar travel, almost all problem-solving involves algorithms. The advent of computers allows us to store data structures in memory and write code to call the CPU and GPU to execute algorithms. In this way, we can transfer real-life problems to computers, solving various complex issues more efficiently.

    Tip

    If concepts such as data structures, algorithms, arrays, and binary search still seem somewhat obsecure, I encourage you to continue reading. This book will gently guide you into the realm of understanding data structures and algorithms.

    "},{"location":"chapter_introduction/summary/","title":"1.3 \u00a0 Summary","text":"
    • Algorithms are ubiquitous in daily life and are not as inaccessible and complex as they might seem. In fact, we have already unconsciously learned many algorithms to solve various problems in life.
    • The principle of looking up a word in a dictionary is consistent with the binary search algorithm. The binary search algorithm embodies the important algorithmic concept of divide and conquer.
    • The process of organizing playing cards is very similar to the insertion sort algorithm. The insertion sort algorithm is suitable for sorting small datasets.
    • The steps of making change in currency essentially follow the greedy algorithm, where each step involves making the best possible choice at the moment.
    • An algorithm is a set of instructions or steps used to solve a specific problem within a finite amount of time, while a data structure is the way data is organized and stored in a computer.
    • Data structures and algorithms are closely linked. Data structures are the foundation of algorithms, and algorithms are the stage to utilize the functions of data structures.
    • We can liken data structures and algorithms to building blocks. The blocks represent data, the shape and connection method of the blocks represent data structures, and the steps of assembling the blocks correspond to algorithms.
    "},{"location":"chapter_introduction/what_is_dsa/","title":"1.2 \u00a0 What is an algorithm","text":""},{"location":"chapter_introduction/what_is_dsa/#121-definition-of-an-algorithm","title":"1.2.1 \u00a0 Definition of an algorithm","text":"

    An \"algorithm\" is a set of instructions or steps to solve a specific problem within a finite amount of time. It has the following characteristics:

    • The problem is clearly defined, including unambiguous definitions of input and output.
    • The algorithm is feasible, meaning it can be completed within a finite number of steps, time, and memory space.
    • Each step has a definitive meaning. The output is consistently the same under the same inputs and conditions.
    "},{"location":"chapter_introduction/what_is_dsa/#122-definition-of-a-data-structure","title":"1.2.2 \u00a0 Definition of a data structure","text":"

    A \"data structure\" is a way of organizing and storing data in a computer, with the following design goals:

    • Minimize space occupancy to save computer memory.
    • Make data operations as fast as possible, covering data access, addition, deletion, updating, etc.
    • Provide concise data representation and logical information to enable efficient algorithm execution.

    Designing data structures is a balancing act, often requiring trade-offs. If you want to improve in one aspect, you often need to compromise in another. Here are two examples:

    • Compared to arrays, linked lists offer more convenience in data addition and deletion but sacrifice data access speed.
    • Graphs, compared to linked lists, provide richer logical information but require more memory space.
    "},{"location":"chapter_introduction/what_is_dsa/#123-relationship-between-data-structures-and-algorithms","title":"1.2.3 \u00a0 Relationship between data structures and algorithms","text":"

    As shown in the Figure 1-4 , data structures and algorithms are highly related and closely integrated, specifically in the following three aspects:

    • Data structures are the foundation of algorithms. They provide structured data storage and methods for manipulating data for algorithms.
    • Algorithms are the stage where data structures come into play. The data structure alone only stores data information; it is through the application of algorithms that specific problems can be solved.
    • Algorithms can often be implemented based on different data structures, but their execution efficiency can vary greatly. Choosing the right data structure is key.

    Figure 1-4 \u00a0 Relationship between data structures and algorithms

    Data structures and algorithms can be likened to a set of building blocks, as illustrated in the Figure 1-5 . A building block set includes numerous pieces, accompanied by detailed assembly instructions. Following these instructions step by step allows us to construct an intricate block model.

    Figure 1-5 \u00a0 Assembling blocks

    The detailed correspondence between the two is shown in the Table 1-1 .

    Table 1-1 \u00a0 Comparing data structures and algorithms to building blocks

    Data Structures and Algorithms Building Blocks Input data Unassembled blocks Data structure Organization of blocks, including shape, size, connections, etc Algorithm A series of steps to assemble the blocks into the desired shape Output data Completed Block model

    It's worth noting that data structures and algorithms are independent of programming languages. For this reason, this book is able to provide implementations in multiple programming languages.

    Conventional Abbreviation

    In real-life discussions, we often refer to \"Data Structures and Algorithms\" simply as \"Algorithms\". For example, the well-known LeetCode algorithm problems actually test both data structure and algorithm knowledge.

    "},{"location":"chapter_preface/","title":"Chapter 0. \u00a0 Preface","text":"

    Abstract

    Algorithms are like a beautiful symphony, with each line of code flowing like a rhythm.

    May this book ring softly in your mind, leaving a unique and profound melody.

    "},{"location":"chapter_preface/#chapter-contents","title":"Chapter contents","text":"
    • 0.1 \u00a0 About this book
    • 0.2 \u00a0 How to read
    • 0.3 \u00a0 Summary
    "},{"location":"chapter_preface/about_the_book/","title":"0.1 \u00a0 About this book","text":"

    This open-source project aims to create a free, and beginner-friendly crash course on data structures and algorithms.

    • Using animated illustrations, it delivers structured insights into data structures and algorithmic concepts, ensuring comprehensibility and a smooth learning curve.
    • Run code with just one click, supporting Java, C++, Python, Go, JS, TS, C#, Swift, Rust, Dart, Zig and other languages.
    • Readers are encouraged to engage with each other in the discussion area for each section, questions and comments are usually answered within two days.
    "},{"location":"chapter_preface/about_the_book/#011-target-audience","title":"0.1.1 \u00a0 Target audience","text":"

    If you are new to algorithms with limited exposure, or you have accumulated some experience in algorithms, but you only have a vague understanding of data structures and algorithms, and you are constantly jumping between \"yep\" and \"hmm\", then this book is for you!

    If you have already accumulated a certain amount of problem-solving experience, and are familiar with most types of problems, then this book can help you review and organize your algorithm knowledge system. The repository's source code can be used as a \"problem-solving toolkit\" or an \"algorithm cheat sheet\".

    If you are an algorithm expert, we look forward to receiving your valuable suggestions, or join us and collaborate.

    Prerequisites

    You should know how to write and read simple code in at least one programming language.

    "},{"location":"chapter_preface/about_the_book/#012-content-structure","title":"0.1.2 \u00a0 Content structure","text":"

    The main content of the book is shown in the following figure.

    • Complexity analysis: explores aspects and methods for evaluating data structures and algorithms. Covers methods of deriving time complexity and space complexity, along with common types and examples.
    • Data structures: focuses on fundamental data types, classification methods, definitions, pros and cons, common operations, types, applications, and implementation methods of data structures such as array, linked list, stack, queue, hash table, tree, heap, graph, etc.
    • Algorithms: defines algorithms, discusses their pros and cons, efficiency, application scenarios, problem-solving steps, and includes sample questions for various algorithms such as search, sorting, divide and conquer, backtracking, dynamic programming, greedy algorithms, and more.

    Figure 0-1 \u00a0 Main content of the book

    "},{"location":"chapter_preface/about_the_book/#013-acknowledgements","title":"0.1.3 \u00a0 Acknowledgements","text":"

    This book is continuously improved with the joint efforts of many contributors from the open-source community. Thanks to each writer who invested their time and energy, listed in the order generated by GitHub: krahets, codingonion, nuomi1, Gonglja, Reanon, justin-tse, danielsss, hpstory, S-N-O-R-L-A-X, night-cruise, msk397, gvenusleo, RiverTwilight, gyt95, zhuoqinyue, Zuoxun, Xia-Sang, mingXta, FangYuan33, GN-Yu, IsChristina, xBLACKICEx, guowei-gong, Cathay-Chen, mgisr, JoseHung, qualifier1024, pengchzn, Guanngxu, longsizhuo, L-Super, what-is-me, yuan0221, lhxsm, Slone123c, WSL0809, longranger2, theNefelibatas, xiongsp, JeffersonHuang, hongyun-robot, K3v123, yuelinxin, a16su, gaofer, malone6, Wonderdch, xjr7670, DullSword, Horbin-Magician, NI-SW, reeswell, XC-Zero, XiaChuerwu, yd-j, iron-irax, huawuque404, MolDuM, Nigh, KorsChen, foursevenlove, 52coder, bubble9um, youshaoXG, curly210102, gltianwen, fanchenggang, Transmigration-zhou, FloranceYeh, FreddieLi, ShiMaRing, lipusheng, Javesun99, JackYang-hellobobo, shanghai-Jerry, 0130w, Keynman, psychelzh, logan-qiu, ZnYang2018, MwumLi, 1ch0, Phoenix0415, qingpeng9802, Richard-Zhang1019, QiLOL, Suremotoo, Turing-1024-Lee, Evilrabbit520, GaochaoZhu, ZJKung, linzeyan, hezhizhen, ZongYangL, beintentional, czruby, coderlef, dshlstarr, szu17dmy, fbigm, gledfish, hts0000, boloboloda, iStig, jiaxianhua, wenjianmin, keshida, kilikilikid, lclc6, lwbaptx, liuxjerry, lucaswangdev, lyl625760, chadyi, noobcodemaker, selear, siqyka, syd168, 4yDX3906, tao363, wangwang105, weibk, yabo083, yi427, yishangzhang, zhouLion, baagod, ElaBosak233, xb534, luluxia, yanedie, thomasq0, YangXuanyi and th1nk3r-ing.

    The code review work for this book was completed by codingonion, Gonglja, gvenusleo, hpstory, justin\u2010tse, krahets, night-cruise, nuomi1, and Reanon (listed in alphabetical order). Thanks to them for their time and effort, ensuring the standardization and uniformity of the code in various languages.

    Throughout the creation of this book, numerous individuals provided invaluable assistance, including but not limited to:

    • Thanks to my mentor at the company, Dr. Xi Li, who encouraged me in a conversation to \"get moving fast,\" which solidified my determination to write this book;
    • Thanks to my girlfriend Bubble, as the first reader of this book, for offering many valuable suggestions from the perspective of a beginner in algorithms, making this book more suitable for newbies;
    • Thanks to Tengbao, Qibao, and Feibao for coming up with a creative name for this book, evoking everyone's fond memories of writing their first line of code \"Hello World!\";
    • Thanks to Xiaoquan for providing professional help in intellectual property, which has played a significant role in the development of this open-source book;
    • Thanks to Sutong for designing a beautiful cover and logo for this book, and for patiently making multiple revisions under my insistence;
    • Thanks to @squidfunk for providing writing and typesetting suggestions, as well as his developed open-source documentation theme Material-for-MkDocs.

    Throughout the writing journey, I delved into numerous textbooks and articles on data structures and algorithms. These works served as exemplary models, ensuring the accuracy and quality of this book's content. I extend my gratitude to all who preceded me for their invaluable contributions!

    This book advocates a combination of hands-on and minds-on learning, inspired in this regard by \"Dive into Deep Learning\". I highly recommend this excellent book to all readers.

    Heartfelt thanks to my parents, whose ongoing support and encouragement have allowed me to do this interesting work.

    "},{"location":"chapter_preface/suggestions/","title":"0.2 \u00a0 How to read","text":"

    Tip

    For the best reading experience, it is recommended that you read through this section.

    "},{"location":"chapter_preface/suggestions/#021-writing-conventions","title":"0.2.1 \u00a0 Writing conventions","text":"
    • Chapters marked with '*' after the title are optional and contain relatively challenging content. If you are short on time, it is advisable to skip them.
    • Technical terms will be in boldface (in the print and PDF versions) or underlined (in the web version), for instance, array. It's advisable to familiarize yourself with these for better comprehension of technical texts.
    • Bolded text indicates key content or summary statements, which deserve special attention.
    • Words and phrases with specific meanings are indicated with \u201cquotation marks\u201d to avoid ambiguity.
    • When it comes to terms that are inconsistent between programming languages, this book follows Python, for example using None to mean null.
    • This book partially ignores the comment conventions for programming languages in exchange for a more compact layout of the content. The comments primarily consist of three types: title comments, content comments, and multi-line comments.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig
    \"\"\"Header comments for labeling functions, classes, test samples, etc\"\"\"\n\n# Comments for explaining details\n\n\"\"\"\nMultiline\ncomments\n\"\"\"\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    /* Header comments for labeling functions, classes, test samples, etc */\n\n// Comments for explaining details.\n\n/**\n * Multiline\n * comments\n */\n
    // Header comments for labeling functions, classes, test samples, etc\n\n// Comments for explaining details.\n\n// Multiline\n// comments\n
    "},{"location":"chapter_preface/suggestions/#022-efficient-learning-via-animated-illustrations","title":"0.2.2 \u00a0 Efficient learning via animated illustrations","text":"

    Compared with text, videos and pictures have a higher density of information and are more structured, making them easier to understand. In this book, key and difficult concepts are mainly presented through animations and illustrations, with text serving as explanations and supplements.

    When encountering content with animations or illustrations as shown in the Figure 0-2 , prioritize understanding the figure, with text as supplementary, integrating both for a comprehensive understanding.

    Figure 0-2 \u00a0 Animated illustration example

    "},{"location":"chapter_preface/suggestions/#023-deepen-understanding-through-coding-practice","title":"0.2.3 \u00a0 Deepen understanding through coding practice","text":"

    The source code of this book is hosted on the GitHub Repository. As shown in the Figure 0-3 , the source code comes with test examples and can be executed with just a single click.

    If time permits, it's recommended to type out the code yourself. If pressed for time, at least read and run all the codes.

    Compared to just reading code, writing code often yields more learning. Learning by doing is the real way to learn.

    Figure 0-3 \u00a0 Running code example

    Setting up to run the code involves three main steps.

    Step 1: Install a local programming environment. Follow the tutorial in the appendix for installation, or skip this step if already installed.

    Step 2: Clone or download the code repository. Visit the GitHub Repository.

    If Git is installed, use the following command to clone the repository:

    git clone https://github.com/krahets/hello-algo.git\n

    Alternatively, you can also click the \"Download ZIP\" button at the location shown in the Figure 0-4 to directly download the code as a compressed ZIP file. Then, you can simply extract it locally.

    Figure 0-4 \u00a0 Cloning repository and downloading code

    Step 3: Run the source code. As shown in the Figure 0-5 , for the code block labeled with the file name at the top, we can find the corresponding source code file in the codes folder of the repository. These files can be executed with a single click, which will help you save unnecessary debugging time and allow you to focus on learning.

    Figure 0-5 \u00a0 Code block and corresponding source code file

    "},{"location":"chapter_preface/suggestions/#024-learning-together-in-discussion","title":"0.2.4 \u00a0 Learning together in discussion","text":"

    While reading this book, please don't skip over the points that you didn't learn. Feel free to post your questions in the comment section. We will be happy to answer them and can usually respond within two days.

    As illustrated in the Figure 0-6 , each chapter features a comment section at the bottom. I encourage you to pay attention to these comments. They not only expose you to others' encountered problems, aiding in identifying knowledge gaps and sparking deeper contemplation, but also invite you to generously contribute by answering fellow readers' inquiries, sharing insights, and fostering mutual improvement.

    Figure 0-6 \u00a0 Comment section example

    "},{"location":"chapter_preface/suggestions/#025-algorithm-learning-path","title":"0.2.5 \u00a0 Algorithm learning path","text":"

    Overall, the journey of mastering data structures and algorithms can be divided into three stages:

    1. Stage 1: Introduction to algorithms. We need to familiarize ourselves with the characteristics and usage of various data structures and learn about the principles, processes, uses, and efficiency of different algorithms.
    2. Stage 2: Practicing algorithm problems. It is recommended to start from popular problems, such as Sword for Offer and LeetCode Hot 100, and accumulate at least 100 questions to familiarize yourself with mainstream algorithmic problems. Forgetfulness can be a challenge when you start practicing, but rest assured that this is normal. We can follow the \"Ebbinghaus Forgetting Curve\" to review the questions, and usually after 3~5 rounds of repetitions, we will be able to memorize them.
    3. Stage 3: Building the knowledge system. In terms of learning, we can read algorithm column articles, solution frameworks, and algorithm textbooks to continuously enrich the knowledge system. In terms of practicing, we can try advanced strategies, such as categorizing by topic, multiple solutions for a single problem, and one solution for multiple problems, etc. Insights on these strategies can be found in various communities.

    As shown in the Figure 0-7 , this book mainly covers \u201cStage 1,\u201d aiming to help you more efficiently embark on Stages 2 and 3.

    Figure 0-7 \u00a0 Algorithm learning path

    "},{"location":"chapter_preface/summary/","title":"0.3 \u00a0 Summary","text":"
    • The main audience of this book is beginners in algorithm. If you already have some basic knowledge, this book can help you systematically review your algorithm knowledge, and the source code in this book can also be used as a \"Coding Toolkit\".
    • The book consists of three main sections, Complexity Analysis, Data Structures, and Algorithms, covering most of the topics in the field.
    • For newcomers to algorithms, it is crucial to read an introductory book in the beginning stages to avoid many detours or common pitfalls.
    • Animations and figures within the book are usually used to introduce key points and difficult knowledge. These should be given more attention when reading the book.
    • Practice is the best way to learn programming. It is highly recommended that you run the source code and type in the code yourself.
    • Each chapter in the web version of this book features a discussion section, and you are welcome to share your questions and insights at any time.
    "},{"location":"chapter_reference/","title":"References","text":"

    [1] Thomas H. Cormen, et al. Introduction to Algorithms (3rd Edition).

    [2] Aditya Bhargava. Grokking Algorithms: An Illustrated Guide for Programmers and Other Curious People (1st Edition).

    [3] Robert Sedgewick, et al. Algorithms (4th Edition).

    [4] Yan Weimin. Data Structures (C Language Version).

    [5] Deng Junhui. Data Structures (C++ Language Version, Third Edition).

    [6] Mark Allen Weiss, translated by Chen Yue. Data Structures and Algorithm Analysis in Java (Third Edition).

    [7] Cheng Jie. Speaking of Data Structures.

    [8] Wang Zheng. The Beauty of Data Structures and Algorithms.

    [9] Gayle Laakmann McDowell. Cracking the Coding Interview: 189 Programming Questions and Solutions (6th Edition).

    [10] Aston Zhang, et al. Dive into Deep Learning.

    "},{"location":"chapter_searching/","title":"Chapter 10. \u00a0 Searching","text":"

    Abstract

    Searching is an unknown adventure, where we may need to traverse every corner of a mysterious space, or perhaps quickly pinpoint our target.

    In this journey of discovery, each exploration may yield an unexpected answer.

    "},{"location":"chapter_searching/#chapter-contents","title":"Chapter contents","text":"
    • 10.1 \u00a0 Binary search
    • 10.2 \u00a0 Binary search insertion
    • 10.3 \u00a0 Binary search boundaries
    • 10.4 \u00a0 Hashing optimization strategies
    • 10.5 \u00a0 Search algorithms revisited
    • 10.6 \u00a0 Summary
    "},{"location":"chapter_searching/binary_search/","title":"10.1 \u00a0 Binary search","text":"

    Binary search is an efficient search algorithm based on the divide-and-conquer strategy. It utilizes the orderliness of data, reducing the search range by half each round until the target element is found or the search interval is empty.

    Question

    Given an array nums of length \\(n\\), with elements arranged in ascending order and non-repeating. Please find and return the index of element target in this array. If the array does not contain the element, return \\(-1\\). An example is shown below.

    Figure 10-1 \u00a0 Binary search example data

    As shown in the Figure 10-2 , we first initialize pointers \\(i = 0\\) and \\(j = n - 1\\), pointing to the first and last elements of the array, representing the search interval \\([0, n - 1]\\). Please note that square brackets indicate a closed interval, which includes the boundary values themselves.

    Next, perform the following two steps in a loop.

    1. Calculate the midpoint index \\(m = \\lfloor {(i + j) / 2} \\rfloor\\), where \\(\\lfloor \\: \\rfloor\\) denotes the floor operation.
    2. Compare the size of nums[m] and target, divided into the following three scenarios.
      1. If nums[m] < target, it indicates that target is in the interval \\([m + 1, j]\\), thus set \\(i = m + 1\\).
      2. If nums[m] > target, it indicates that target is in the interval \\([i, m - 1]\\), thus set \\(j = m - 1\\).
      3. If nums[m] = target, it indicates that target is found, thus return index \\(m\\).

    If the array does not contain the target element, the search interval will eventually reduce to empty. In this case, return \\(-1\\).

    <1><2><3><4><5><6><7>

    Figure 10-2 \u00a0 Binary search process

    It's worth noting that since \\(i\\) and \\(j\\) are both of type int, \\(i + j\\) might exceed the range of int type. To avoid large number overflow, we usually use the formula \\(m = \\lfloor {i + (j - i) / 2} \\rfloor\\) to calculate the midpoint.

    The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search.py
    def binary_search(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09\"\"\"\n    # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    i, j = 0, len(nums) - 1\n    # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j:\n        # \u7406\u8bba\u4e0a Python \u7684\u6570\u5b57\u53ef\u4ee5\u65e0\u9650\u5927\uff08\u53d6\u51b3\u4e8e\u5185\u5b58\u5927\u5c0f\uff09\uff0c\u65e0\u987b\u8003\u8651\u5927\u6570\u8d8a\u754c\u95ee\u9898\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n
    binary_search.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(vector<int> &nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.size() - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.java
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.cs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint BinarySearch(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.Length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2;   // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else                       // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.go
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunc binarySearch(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    i, j := 0, len(nums)-1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    for i <= j {\n        m := i + (j-i)/2      // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.swift
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunc binarySearch(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.js
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunction binarySearch(nums, target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let i = 0,\n        j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m \uff0c\u4f7f\u7528 parseInt() \u5411\u4e0b\u53d6\u6574\n        const m = parseInt(i + (j - i) / 2);\n        if (nums[m] < target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else return m; // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.ts
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunction binarySearch(nums: number[], target: number): number {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let i = 0,\n        j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        const m = Math.floor(i + (j - i) / 2);\n        if (nums[m] < target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if (nums[m] > target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    return -1; // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n}\n
    binary_search.dart
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(List<int> nums, int target) {\n  // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n  int i = 0, j = nums.length - 1;\n  // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n      i = m + 1;\n    } else if (nums[m] > target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n      j = m - 1;\n    } else {\n      // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n      return m;\n    }\n  }\n  // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n  return -1;\n}\n
    binary_search.rs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfn binary_search(nums: &[i32], target: i32) -> i32 {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let mut i = 0;\n    let mut j = nums.len() as i32 - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if nums[m as usize] > target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.c
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(int *nums, int len, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = len - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.kt
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfun binarySearch(nums: IntArray, target: Int): Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i = 0\n    var j = nums.size - 1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        else  // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.rb
    ### \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 ###\ndef binary_search(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n  i, j = 0, nums.length - 1\n\n  # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n  while i <= j\n    # \u7406\u8bba\u4e0a Ruby \u7684\u6570\u5b57\u53ef\u4ee5\u65e0\u9650\u5927\uff08\u53d6\u51b3\u4e8e\u5185\u5b58\u5927\u5c0f\uff09\uff0c\u65e0\u987b\u8003\u8651\u5927\u6570\u8d8a\u754c\u95ee\u9898\n    m = (i + j) / 2   # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n\n    if nums[m] < target\n      i = m + 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    end\n  end\n\n  -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\nend\n
    binary_search.zig
    // \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09\nfn binarySearch(comptime T: type, nums: std.ArrayList(T), target: T) T {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i: usize = 0;\n    var j: usize = nums.items.len - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        var m = i + (j - i) / 2;                // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums.items[m] < target) {           // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if (nums.items[m] > target) {    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {                                // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return @intCast(m);\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    Time complexity is \\(O(\\log n)\\) : In the binary loop, the interval reduces by half each round, hence the number of iterations is \\(\\log_2 n\\).

    Space complexity is \\(O(1)\\) : Pointers \\(i\\) and \\(j\\) use constant size space.

    "},{"location":"chapter_searching/binary_search/#1011-interval-representation-methods","title":"10.1.1 \u00a0 Interval representation methods","text":"

    Besides the aforementioned closed interval, a common interval representation is the \"left-closed right-open\" interval, defined as \\([0, n)\\), where the left boundary includes itself, and the right boundary does not include itself. In this representation, the interval \\([i, j)\\) is empty when \\(i = j\\).

    We can implement a binary search algorithm with the same functionality based on this representation:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search.py
    def binary_search_lcro(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09\"\"\"\n    # \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    i, j = 0, len(nums)\n    # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n        elif nums[m] > target:\n            j = m  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n        else:\n            return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n
    binary_search.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(vector<int> &nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.size();\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.java
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.cs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint BinarySearchLCRO(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.Length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2;   // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else                       // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.go
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunc binarySearchLCRO(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    i, j := 0, len(nums)\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    for i < j {\n        m := i + (j-i)/2      // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.swift
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunc binarySearchLCRO(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i = nums.startIndex\n    var j = nums.endIndex\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.js
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunction binarySearchLCRO(nums, target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let i = 0,\n        j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m \uff0c\u4f7f\u7528 parseInt() \u5411\u4e0b\u53d6\u6574\n        const m = parseInt(i + (j - i) / 2);\n        if (nums[m] < target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        else return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.ts
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunction binarySearchLCRO(nums: number[], target: number): number {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let i = 0,\n        j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        const m = Math.floor(i + (j - i) / 2);\n        if (nums[m] < target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if (nums[m] > target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    return -1; // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n}\n
    binary_search.dart
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(List<int> nums, int target) {\n  // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n  int i = 0, j = nums.length;\n  // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n  while (i < j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n      i = m + 1;\n    } else if (nums[m] > target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n      j = m;\n    } else {\n      // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n      return m;\n    }\n  }\n  // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n  return -1;\n}\n
    binary_search.rs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfn binary_search_lcro(nums: &[i32], target: i32) -> i32 {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let mut i = 0;\n    let mut j = nums.len() as i32;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if nums[m as usize] > target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.c
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(int *nums, int len, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = len;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.kt
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfun binarySearchLCRO(nums: IntArray, target: Int): Int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i = 0\n    var j = nums.size\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        else  // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.rb
    ### \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 ###\ndef binary_search_lcro(nums, target)\n  # \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n  i, j = 0, nums.length\n\n  # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n  while i < j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n    else\n      return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    end\n  end\n\n  -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\nend\n
    binary_search.zig
    // \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09\nfn binarySearchLCRO(comptime T: type, nums: std.ArrayList(T), target: T) T {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i: usize = 0;\n    var j: usize = nums.items.len;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        var m = i + (j - i) / 2;                // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums.items[m] < target) {           // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if (nums.items[m] > target) {    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {                                // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return @intCast(m);\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    Code Visualization

    Full Screen >

    As shown in the Figure 10-3 , in the two types of interval representations, the initialization of the binary search algorithm, the loop condition, and the narrowing interval operation are different.

    Since both boundaries in the \"closed interval\" representation are defined as closed, the operations to narrow the interval through pointers \\(i\\) and \\(j\\) are also symmetrical. This makes it less prone to errors, therefore, it is generally recommended to use the \"closed interval\" approach.

    Figure 10-3 \u00a0 Two types of interval definitions

    "},{"location":"chapter_searching/binary_search/#1012-advantages-and-limitations","title":"10.1.2 \u00a0 Advantages and limitations","text":"

    Binary search performs well in both time and space aspects.

    • Binary search is time-efficient. With large data volumes, the logarithmic time complexity has a significant advantage. For instance, when the data size \\(n = 2^{20}\\), linear search requires \\(2^{20} = 1048576\\) iterations, while binary search only requires \\(\\log_2 2^{20} = 20\\) iterations.
    • Binary search does not require extra space. Compared to search algorithms that rely on additional space (like hash search), binary search is more space-efficient.

    However, binary search is not suitable for all situations, mainly for the following reasons.

    • Binary search is only applicable to ordered data. If the input data is unordered, it is not worth sorting it just to use binary search, as sorting algorithms typically have a time complexity of \\(O(n \\log n)\\), which is higher than both linear and binary search. For scenarios with frequent element insertion to maintain array order, inserting elements into specific positions has a time complexity of \\(O(n)\\), which is also quite costly.
    • Binary search is only applicable to arrays. Binary search requires non-continuous (jumping) element access, which is inefficient in linked lists, thus not suitable for use in linked lists or data structures based on linked lists.
    • With small data volumes, linear search performs better. In linear search, each round only requires 1 decision operation; whereas in binary search, it involves 1 addition, 1 division, 1 to 3 decision operations, 1 addition (subtraction), totaling 4 to 6 operations; therefore, when data volume \\(n\\) is small, linear search can be faster than binary search.
    "},{"location":"chapter_searching/binary_search_edge/","title":"10.3 \u00a0 Binary search boundaries","text":""},{"location":"chapter_searching/binary_search_edge/#1031-find-the-left-boundary","title":"10.3.1 \u00a0 Find the left boundary","text":"

    Question

    Given a sorted array nums of length \\(n\\), which may contain duplicate elements, return the index of the leftmost element target. If the element is not present in the array, return \\(-1\\).

    Recall the method of binary search for an insertion point, after the search is completed, \\(i\\) points to the leftmost target, thus searching for the insertion point is essentially searching for the index of the leftmost target.

    Consider implementing the search for the left boundary using the function for finding an insertion point. Note that the array might not contain target, which could lead to the following two results:

    • The index \\(i\\) of the insertion point is out of bounds.
    • The element nums[i] is not equal to target.

    In these cases, simply return \\(-1\\). The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_edge.py
    def binary_search_left_edge(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target\"\"\"\n    # \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    i = binary_search_insertion(nums, target)\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == len(nums) or nums[i] != target:\n        return -1\n    # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n
    binary_search_edge.cpp
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(vector<int> &nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.size() || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.java
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(int[] nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binary_search_insertion.binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.length || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.cs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint BinarySearchLeftEdge(int[] nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binary_search_insertion.BinarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.Length || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.go
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunc binarySearchLeftEdge(nums []int, target int) int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    i := binarySearchInsertion(nums, target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == len(nums) || nums[i] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.swift
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunc binarySearchLeftEdge(nums: [Int], target: Int) -> Int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    let i = binarySearchInsertion(nums: nums, target: target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == nums.endIndex || nums[i] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.js
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunction binarySearchLeftEdge(nums, target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    const i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i === nums.length || nums[i] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.ts
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunction binarySearchLeftEdge(nums: Array<number>, target: number): number {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    const i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i === nums.length || nums[i] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.dart
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(List<int> nums, int target) {\n  // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n  int i = binarySearchInsertion(nums, target);\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  if (i == nums.length || nums[i] != target) {\n    return -1;\n  }\n  // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n  return i;\n}\n
    binary_search_edge.rs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfn binary_search_left_edge(nums: &[i32], target: i32) -> i32 {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    let i = binary_search_insertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == nums.len() as i32 || nums[i as usize] != target {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    i\n}\n
    binary_search_edge.c
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(int *nums, int numSize, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binarySearchInsertion(nums, numSize, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == numSize || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.kt
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfun binarySearchLeftEdge(nums: IntArray, target: Int): Int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    val i = binarySearchInsertion(nums, target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.size || nums[i] != target) {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.rb
    ### \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target ###\ndef binary_search_left_edge(nums, target)\n  # \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n  i = binary_search_insertion(nums, target)\n\n  # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  return -1 if i == nums.length || nums[i] != target\n\n  i # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\nend\n
    binary_search_edge.zig
    [class]{}-[func]{binarySearchLeftEdge}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_searching/binary_search_edge/#1032-find-the-right-boundary","title":"10.3.2 \u00a0 Find the right boundary","text":"

    So how do we find the rightmost target? The most straightforward way is to modify the code, replacing the pointer contraction operation in the case of nums[m] == target. The code is omitted here, but interested readers can implement it on their own.

    Below we introduce two more cunning methods.

    "},{"location":"chapter_searching/binary_search_edge/#1-reusing-the-search-for-the-left-boundary","title":"1. \u00a0 Reusing the search for the left boundary","text":"

    In fact, we can use the function for finding the leftmost element to find the rightmost element, specifically by transforming the search for the rightmost target into a search for the leftmost target + 1.

    As shown in the Figure 10-7 , after the search is completed, the pointer \\(i\\) points to the leftmost target + 1 (if it exists), while \\(j\\) points to the rightmost target, thus returning \\(j\\) is sufficient.

    Figure 10-7 \u00a0 Transforming the search for the right boundary into the search for the left boundary

    Please note, the insertion point returned is \\(i\\), therefore, it should be subtracted by \\(1\\) to obtain \\(j\\):

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_edge.py
    def binary_search_right_edge(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target\"\"\"\n    # \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    i = binary_search_insertion(nums, target + 1)\n    # j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    j = i - 1\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 or nums[j] != target:\n        return -1\n    # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n
    binary_search_edge.cpp
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(vector<int> &nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.java
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(int[] nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binary_search_insertion.binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.cs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint BinarySearchRightEdge(int[] nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binary_search_insertion.BinarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.go
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunc binarySearchRightEdge(nums []int, target int) int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    i := binarySearchInsertion(nums, target+1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    j := i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.swift
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunc binarySearchRightEdge(nums: [Int], target: Int) -> Int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    let i = binarySearchInsertion(nums: nums, target: target + 1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    let j = i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.js
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunction binarySearchRightEdge(nums, target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    const i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    const j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j === -1 || nums[j] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.ts
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunction binarySearchRightEdge(nums: Array<number>, target: number): number {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    const i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    const j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j === -1 || nums[j] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.dart
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(List<int> nums, int target) {\n  // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n  int i = binarySearchInsertion(nums, target + 1);\n  // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n  int j = i - 1;\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  if (j == -1 || nums[j] != target) {\n    return -1;\n  }\n  // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n  return j;\n}\n
    binary_search_edge.rs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfn binary_search_right_edge(nums: &[i32], target: i32) -> i32 {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    let i = binary_search_insertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    let j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j as usize] != target {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    j\n}\n
    binary_search_edge.c
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(int *nums, int numSize, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binarySearchInsertion(nums, numSize, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.kt
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfun binarySearchRightEdge(nums: IntArray, target: Int): Int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    val i = binarySearchInsertion(nums, target + 1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    val j = i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.rb
    ### \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target ###\ndef binary_search_right_edge(nums, target)\n  # \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n  i = binary_search_insertion(nums, target + 1)\n\n  # j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n  j = i - 1\n\n  # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  return -1 if j == -1 || nums[j] != target\n\n  j # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\nend\n
    binary_search_edge.zig
    [class]{}-[func]{binarySearchRightEdge}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_searching/binary_search_edge/#2-transforming-into-an-element-search","title":"2. \u00a0 Transforming into an element search","text":"

    We know that when the array does not contain target, \\(i\\) and \\(j\\) will eventually point to the first element greater and smaller than target respectively.

    Thus, as shown in the Figure 10-8 , we can construct an element that does not exist in the array, to search for the left and right boundaries.

    • To find the leftmost target: it can be transformed into searching for target - 0.5, and return the pointer \\(i\\).
    • To find the rightmost target: it can be transformed into searching for target + 0.5, and return the pointer \\(j\\).

    Figure 10-8 \u00a0 Transforming the search for boundaries into the search for an element

    The code is omitted here, but two points are worth noting.

    • The given array does not contain decimals, meaning we do not need to worry about how to handle equal situations.
    • Since this method introduces decimals, the variable target in the function needs to be changed to a floating point type (no change needed in Python).
    "},{"location":"chapter_searching/binary_search_insertion/","title":"10.2 \u00a0 Binary search insertion","text":"

    Binary search is not only used to search for target elements but also to solve many variant problems, such as searching for the insertion position of target elements.

    "},{"location":"chapter_searching/binary_search_insertion/#1021-case-with-no-duplicate-elements","title":"10.2.1 \u00a0 Case with no duplicate elements","text":"

    Question

    Given an ordered array nums of length \\(n\\) and an element target, where the array has no duplicate elements. Now insert target into the array nums while maintaining its order. If the element target already exists in the array, insert it to its left side. Please return the index of target in the array after insertion. See the example shown in the Figure 10-4 .

    Figure 10-4 \u00a0 Example data for binary search insertion point

    If you want to reuse the binary search code from the previous section, you need to answer the following two questions.

    Question one: When the array contains target, is the insertion point index the index of that element?

    The requirement to insert target to the left of equal elements means that the newly inserted target replaces the original target position. Thus, when the array contains target, the insertion point index is the index of that target.

    Question two: When the array does not contain target, what is the index of the insertion point?

    Further consider the binary search process: when nums[m] < target, pointer \\(i\\) moves, meaning that pointer \\(i\\) is approaching an element greater than or equal to target. Similarly, pointer \\(j\\) is always approaching an element less than or equal to target.

    Therefore, at the end of the binary, it is certain that: \\(i\\) points to the first element greater than target, and \\(j\\) points to the first element less than target. It is easy to see that when the array does not contain target, the insertion index is \\(i\\). The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_insertion.py
    def binary_search_insertion_simple(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09\"\"\"\n    i, j = 0, len(nums) - 1  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            return m  # \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n
    binary_search_insertion.cpp
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(vector<int> &nums, int target) {\n    int i = 0, j = nums.size() - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.java
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(int[] nums, int target) {\n    int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.cs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint BinarySearchInsertionSimple(int[] nums, int target) {\n    int i = 0, j = nums.Length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.go
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertionSimple(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    i, j := 0, len(nums)-1\n    for i <= j {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        m := i + (j-i)/2\n        if nums[m] < target {\n            // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target {\n            // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else {\n            // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n            return m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.swift
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertionSimple(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m] > target {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.js
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertionSimple(nums, target) {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.ts
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertionSimple(\n    nums: Array<number>,\n    target: number\n): number {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.dart
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(List<int> nums, int target) {\n  int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    } else if (nums[m] > target) {\n      j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    } else {\n      return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    }\n  }\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n  return i;\n}\n
    binary_search_insertion.rs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfn binary_search_insertion_simple(nums: &[i32], target: i32) -> i32 {\n    let (mut i, mut j) = (0, nums.len() as i32 - 1); // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m as usize] > target {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    i\n}\n
    binary_search_insertion.c
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(int *nums, int numSize, int target) {\n    int i = 0, j = numSize - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.kt
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfun binarySearchInsertionSimple(nums: IntArray, target: Int): Int {\n    var i = 0\n    var j = nums.size - 1 // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.rb
    ### \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 ###\ndef binary_search_insertion_simple(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  i, j = 0, nums.length - 1\n\n  while i <= j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      return m  # \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    end\n  end\n\n  i # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\nend\n
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertionSimple}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_searching/binary_search_insertion/#1022-case-with-duplicate-elements","title":"10.2.2 \u00a0 Case with duplicate elements","text":"

    Question

    Based on the previous question, assume the array may contain duplicate elements, all else remains the same.

    Suppose there are multiple targets in the array, ordinary binary search can only return the index of one of the targets, and it cannot determine how many targets are to the left and right of that element.

    The task requires inserting the target element to the very left, so we need to find the index of the leftmost target in the array. Initially consider implementing this through the steps shown in the Figure 10-5 .

    1. Perform a binary search, get an arbitrary index of target, denoted as \\(k\\).
    2. Start from index \\(k\\), and perform a linear search to the left until the leftmost target is found and return.

    Figure 10-5 \u00a0 Linear search for the insertion point of duplicate elements

    Although this method is feasible, it includes linear search, so its time complexity is \\(O(n)\\). This method is inefficient when the array contains many duplicate targets.

    Now consider extending the binary search code. As shown in the Figure 10-6 , the overall process remains the same, each round first calculates the midpoint index \\(m\\), then judges the size relationship between target and nums[m], divided into the following cases.

    • When nums[m] < target or nums[m] > target, it means target has not been found yet, thus use the normal binary search interval reduction operation, thus making pointers \\(i\\) and \\(j\\) approach target.
    • When nums[m] == target, it indicates that the elements less than target are in the interval \\([i, m - 1]\\), therefore use \\(j = m - 1\\) to narrow the interval, thus making pointer \\(j\\) approach elements less than target.

    After the loop, \\(i\\) points to the leftmost target, and \\(j\\) points to the first element less than target, therefore index \\(i\\) is the insertion point.

    <1><2><3><4><5><6><7><8>

    Figure 10-6 \u00a0 Steps for binary search insertion point of duplicate elements

    Observe the code, the operations of the branch nums[m] > target and nums[m] == target are the same, so the two can be combined.

    Even so, we can still keep the conditions expanded, as their logic is clearer and more readable.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_insertion.py
    def binary_search_insertion(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09\"\"\"\n    i, j = 0, len(nums) - 1  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            j = m - 1  # \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    # \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n
    binary_search_insertion.cpp
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(vector<int> &nums, int target) {\n    int i = 0, j = nums.size() - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.java
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(int[] nums, int target) {\n    int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.cs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint BinarySearchInsertion(int[] nums, int target) {\n    int i = 0, j = nums.Length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.go
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertion(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    i, j := 0, len(nums)-1\n    for i <= j {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        m := i + (j-i)/2\n        if nums[m] < target {\n            // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target {\n            // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else {\n            // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.swift
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertion(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m] > target {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1 // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.js
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertion(nums, target) {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.ts
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertion(nums: Array<number>, target: number): number {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.dart
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(List<int> nums, int target) {\n  int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    } else if (nums[m] > target) {\n      j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    } else {\n      j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    }\n  }\n  // \u8fd4\u56de\u63d2\u5165\u70b9 i\n  return i;\n}\n
    binary_search_insertion.rs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\npub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 {\n    let (mut i, mut j) = (0, nums.len() as i32 - 1); // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m as usize] > target {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    i\n}\n
    binary_search_insertion.c
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(int *nums, int numSize, int target) {\n    int i = 0, j = numSize - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.kt
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfun binarySearchInsertion(nums: IntArray, target: Int): Int {\n    var i = 0\n    var j = nums.size - 1 // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1 // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.rb
    ### \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 ###\ndef binary_search_insertion(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  i, j = 0, nums.length - 1\n\n  while i <= j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      j = m - 1 # \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    end\n  end\n\n  i # \u8fd4\u56de\u63d2\u5165\u70b9 i\nend\n
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertion}\n
    Code Visualization

    Full Screen >

    Tip

    The code in this section uses \"closed intervals\". Readers interested can implement the \"left-closed right-open\" method themselves.

    In summary, binary search is merely about setting search targets for pointers \\(i\\) and \\(j\\), which might be a specific element (like target) or a range of elements (like elements less than target).

    In the continuous loop of binary search, pointers \\(i\\) and \\(j\\) gradually approach the predefined target. Ultimately, they either find the answer or stop after crossing the boundary.

    "},{"location":"chapter_searching/replace_linear_by_hashing/","title":"10.4 \u00a0 Hash optimization strategies","text":"

    In algorithm problems, we often reduce the time complexity of algorithms by replacing linear search with hash search. Let's use an algorithm problem to deepen understanding.

    Question

    Given an integer array nums and a target element target, please search for two elements in the array whose \"sum\" equals target, and return their array indices. Any solution is acceptable.

    "},{"location":"chapter_searching/replace_linear_by_hashing/#1041-linear-search-trading-time-for-space","title":"10.4.1 \u00a0 Linear search: trading time for space","text":"

    Consider traversing all possible combinations directly. As shown in the Figure 10-9 , we initiate a two-layer loop, and in each round, we determine whether the sum of the two integers equals target. If so, we return their indices.

    Figure 10-9 \u00a0 Linear search solution for two-sum problem

    The code is shown below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig two_sum.py
    def two_sum_brute_force(nums: list[int], target: int) -> list[int]:\n    \"\"\"\u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e\"\"\"\n    # \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in range(len(nums) - 1):\n        for j in range(i + 1, len(nums)):\n            if nums[i] + nums[j] == target:\n                return [i, j]\n    return []\n
    two_sum.cpp
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nvector<int> twoSumBruteForce(vector<int> &nums, int target) {\n    int size = nums.size();\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return {i, j};\n        }\n    }\n    return {};\n}\n
    two_sum.java
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint[] twoSumBruteForce(int[] nums, int target) {\n    int size = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return new int[] { i, j };\n        }\n    }\n    return new int[0];\n}\n
    two_sum.cs
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint[] TwoSumBruteForce(int[] nums, int target) {\n    int size = nums.Length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return [i, j];\n        }\n    }\n    return [];\n}\n
    two_sum.go
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunc twoSumBruteForce(nums []int, target int) []int {\n    size := len(nums)\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i := 0; i < size-1; i++ {\n        for j := i + 1; j < size; j++ {\n            if nums[i]+nums[j] == target {\n                return []int{i, j}\n            }\n        }\n    }\n    return nil\n}\n
    two_sum.swift
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunc twoSumBruteForce(nums: [Int], target: Int) -> [Int] {\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in nums.indices.dropLast() {\n        for j in nums.indices.dropFirst(i + 1) {\n            if nums[i] + nums[j] == target {\n                return [i, j]\n            }\n        }\n    }\n    return [0]\n}\n
    two_sum.js
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunction twoSumBruteForce(nums, target) {\n    const n = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (let i = 0; i < n; i++) {\n        for (let j = i + 1; j < n; j++) {\n            if (nums[i] + nums[j] === target) {\n                return [i, j];\n            }\n        }\n    }\n    return [];\n}\n
    two_sum.ts
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunction twoSumBruteForce(nums: number[], target: number): number[] {\n    const n = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (let i = 0; i < n; i++) {\n        for (let j = i + 1; j < n; j++) {\n            if (nums[i] + nums[j] === target) {\n                return [i, j];\n            }\n        }\n    }\n    return [];\n}\n
    two_sum.dart
    /* \u65b9\u6cd5\u4e00\uff1a \u66b4\u529b\u679a\u4e3e */\nList<int> twoSumBruteForce(List<int> nums, int target) {\n  int size = nums.length;\n  // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n  for (var i = 0; i < size - 1; i++) {\n    for (var j = i + 1; j < size; j++) {\n      if (nums[i] + nums[j] == target) return [i, j];\n    }\n  }\n  return [0];\n}\n
    two_sum.rs
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\npub fn two_sum_brute_force(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {\n    let size = nums.len();\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in 0..size - 1 {\n        for j in i + 1..size {\n            if nums[i] + nums[j] == target {\n                return Some(vec![i as i32, j as i32]);\n            }\n        }\n    }\n    None\n}\n
    two_sum.c
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint *twoSumBruteForce(int *nums, int numsSize, int target, int *returnSize) {\n    for (int i = 0; i < numsSize; ++i) {\n        for (int j = i + 1; j < numsSize; ++j) {\n            if (nums[i] + nums[j] == target) {\n                int *res = malloc(sizeof(int) * 2);\n                res[0] = i, res[1] = j;\n                *returnSize = 2;\n                return res;\n            }\n        }\n    }\n    *returnSize = 0;\n    return NULL;\n}\n
    two_sum.kt
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfun twoSumBruteForce(nums: IntArray, target: Int): IntArray {\n    val size = nums.size\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (i in 0..<size - 1) {\n        for (j in i + 1..<size) {\n            if (nums[i] + nums[j] == target) return intArrayOf(i, j)\n        }\n    }\n    return IntArray(0)\n}\n
    two_sum.rb
    ### \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e ###\ndef two_sum_brute_force(nums, target)\n  # \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n  for i in 0...(nums.length - 1)\n    for j in (i + 1)...nums.length\n      return [i, j] if nums[i] + nums[j] == target\n    end\n  end\n\n  []\nend\n
    two_sum.zig
    // \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e\nfn twoSumBruteForce(nums: []i32, target: i32) ?[2]i32 {\n    var size: usize = nums.len;\n    var i: usize = 0;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    while (i < size - 1) : (i += 1) {\n        var j = i + 1;\n        while (j < size) : (j += 1) {\n            if (nums[i] + nums[j] == target) {\n                return [_]i32{@intCast(i), @intCast(j)};\n            }\n        }\n    }\n    return null;\n}\n
    Code Visualization

    Full Screen >

    This method has a time complexity of \\(O(n^2)\\) and a space complexity of \\(O(1)\\), which is very time-consuming with large data volumes.

    "},{"location":"chapter_searching/replace_linear_by_hashing/#1042-hash-search-trading-space-for-time","title":"10.4.2 \u00a0 Hash search: trading space for time","text":"

    Consider using a hash table, with key-value pairs being the array elements and their indices, respectively. Loop through the array, performing the steps shown in the figures below each round.

    1. Check if the number target - nums[i] is in the hash table. If so, directly return the indices of these two elements.
    2. Add the key-value pair nums[i] and index i to the hash table.
    <1><2><3>

    Figure 10-10 \u00a0 Help hash table solve two-sum

    The implementation code is shown below, requiring only a single loop:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig two_sum.py
    def two_sum_hash_table(nums: list[int], target: int) -> list[int]:\n    \"\"\"\u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868\"\"\"\n    # \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    dic = {}\n    # \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for i in range(len(nums)):\n        if target - nums[i] in dic:\n            return [dic[target - nums[i]], i]\n        dic[nums[i]] = i\n    return []\n
    two_sum.cpp
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nvector<int> twoSumHashTable(vector<int> &nums, int target) {\n    int size = nums.size();\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    unordered_map<int, int> dic;\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.find(target - nums[i]) != dic.end()) {\n            return {dic[target - nums[i]], i};\n        }\n        dic.emplace(nums[i], i);\n    }\n    return {};\n}\n
    two_sum.java
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint[] twoSumHashTable(int[] nums, int target) {\n    int size = nums.length;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    Map<Integer, Integer> dic = new HashMap<>();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.containsKey(target - nums[i])) {\n            return new int[] { dic.get(target - nums[i]), i };\n        }\n        dic.put(nums[i], i);\n    }\n    return new int[0];\n}\n
    two_sum.cs
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint[] TwoSumHashTable(int[] nums, int target) {\n    int size = nums.Length;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    Dictionary<int, int> dic = [];\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.ContainsKey(target - nums[i])) {\n            return [dic[target - nums[i]], i];\n        }\n        dic.Add(nums[i], i);\n    }\n    return [];\n}\n
    two_sum.go
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunc twoSumHashTable(nums []int, target int) []int {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    hashTable := map[int]int{}\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for idx, val := range nums {\n        if preIdx, ok := hashTable[target-val]; ok {\n            return []int{preIdx, idx}\n        }\n        hashTable[val] = idx\n    }\n    return nil\n}\n
    two_sum.swift
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunc twoSumHashTable(nums: [Int], target: Int) -> [Int] {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    var dic: [Int: Int] = [:]\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for i in nums.indices {\n        if let j = dic[target - nums[i]] {\n            return [j, i]\n        }\n        dic[nums[i]] = i\n    }\n    return [0]\n}\n
    two_sum.js
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunction twoSumHashTable(nums, target) {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let m = {};\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (let i = 0; i < nums.length; i++) {\n        if (m[target - nums[i]] !== undefined) {\n            return [m[target - nums[i]], i];\n        } else {\n            m[nums[i]] = i;\n        }\n    }\n    return [];\n}\n
    two_sum.ts
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunction twoSumHashTable(nums: number[], target: number): number[] {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let m: Map<number, number> = new Map();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (let i = 0; i < nums.length; i++) {\n        let index = m.get(target - nums[i]);\n        if (index !== undefined) {\n            return [index, i];\n        } else {\n            m.set(nums[i], i);\n        }\n    }\n    return [];\n}\n
    two_sum.dart
    /* \u65b9\u6cd5\u4e8c\uff1a \u8f85\u52a9\u54c8\u5e0c\u8868 */\nList<int> twoSumHashTable(List<int> nums, int target) {\n  int size = nums.length;\n  // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  Map<int, int> dic = HashMap();\n  // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  for (var i = 0; i < size; i++) {\n    if (dic.containsKey(target - nums[i])) {\n      return [dic[target - nums[i]]!, i];\n    }\n    dic.putIfAbsent(nums[i], () => i);\n  }\n  return [0];\n}\n
    two_sum.rs
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\npub fn two_sum_hash_table(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let mut dic = HashMap::new();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (i, num) in nums.iter().enumerate() {\n        match dic.get(&(target - num)) {\n            Some(v) => return Some(vec![*v as i32, i as i32]),\n            None => dic.insert(num, i as i32),\n        };\n    }\n    None\n}\n
    two_sum.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u54c8\u5e0c\u8868\u67e5\u8be2 */\nHashTable *find(HashTable *h, int key) {\n    HashTable *tmp;\n    HASH_FIND_INT(h, &key, tmp);\n    return tmp;\n}\n\n/* \u54c8\u5e0c\u8868\u5143\u7d20\u63d2\u5165 */\nvoid insert(HashTable *h, int key, int val) {\n    HashTable *t = find(h, key);\n    if (t == NULL) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = key, tmp->val = val;\n        HASH_ADD_INT(h, key, tmp);\n    } else {\n        t->val = val;\n    }\n}\n\n/* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint *twoSumHashTable(int *nums, int numsSize, int target, int *returnSize) {\n    HashTable *hashtable = NULL;\n    for (int i = 0; i < numsSize; i++) {\n        HashTable *t = find(hashtable, target - nums[i]);\n        if (t != NULL) {\n            int *res = malloc(sizeof(int) * 2);\n            res[0] = t->val, res[1] = i;\n            *returnSize = 2;\n            return res;\n        }\n        insert(hashtable, nums[i], i);\n    }\n    *returnSize = 0;\n    return NULL;\n}\n
    two_sum.kt
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfun twoSumHashTable(nums: IntArray, target: Int): IntArray {\n    val size = nums.size\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    val dic = HashMap<Int, Int>()\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (i in 0..<size) {\n        if (dic.containsKey(target - nums[i])) {\n            return intArrayOf(dic[target - nums[i]]!!, i)\n        }\n        dic[nums[i]] = i\n    }\n    return IntArray(0)\n}\n
    two_sum.rb
    ### \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 ###\ndef two_sum_hash_table(nums, target)\n  # \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  dic = {}\n  # \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  for i in 0...nums.length\n    return [dic[target - nums[i]], i] if dic.has_key?(target - nums[i])\n\n    dic[nums[i]] = i\n  end\n\n  []\nend\n
    two_sum.zig
    // \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868\nfn twoSumHashTable(nums: []i32, target: i32) !?[2]i32 {\n    var size: usize = nums.len;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    var dic = std.AutoHashMap(i32, i32).init(std.heap.page_allocator);\n    defer dic.deinit();\n    var i: usize = 0;\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    while (i < size) : (i += 1) {\n        if (dic.contains(target - nums[i])) {\n            return [_]i32{dic.get(target - nums[i]).?, @intCast(i)};\n        }\n        try dic.put(nums[i], @intCast(i));\n    }\n    return null;\n}\n
    Code Visualization

    Full Screen >

    This method reduces the time complexity from \\(O(n^2)\\) to \\(O(n)\\) by using hash search, greatly improving the running efficiency.

    As it requires maintaining an additional hash table, the space complexity is \\(O(n)\\). Nevertheless, this method has a more balanced time-space efficiency overall, making it the optimal solution for this problem.

    "},{"location":"chapter_searching/searching_algorithm_revisited/","title":"10.5 \u00a0 Search algorithms revisited","text":"

    Searching algorithms (searching algorithm) are used to search for one or several elements that meet specific criteria in data structures such as arrays, linked lists, trees, or graphs.

    Searching algorithms can be divided into the following two categories based on their implementation approaches.

    • Locating the target element by traversing the data structure, such as traversals of arrays, linked lists, trees, and graphs, etc.
    • Using the organizational structure of the data or the prior information contained in the data to achieve efficient element search, such as binary search, hash search, and binary search tree search, etc.

    It is not difficult to notice that these topics have been introduced in previous chapters, so searching algorithms are not unfamiliar to us. In this section, we will revisit searching algorithms from a more systematic perspective.

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1051-brute-force-search","title":"10.5.1 \u00a0 Brute-force search","text":"

    Brute-force search locates the target element by traversing every element of the data structure.

    • \"Linear search\" is suitable for linear data structures such as arrays and linked lists. It starts from one end of the data structure, accesses each element one by one, until the target element is found or the other end is reached without finding the target element.
    • \"Breadth-first search\" and \"Depth-first search\" are two traversal strategies for graphs and trees. Breadth-first search starts from the initial node and searches layer by layer, accessing nodes from near to far. Depth-first search starts from the initial node, follows a path until the end, then backtracks and tries other paths until the entire data structure is traversed.

    The advantage of brute-force search is its simplicity and versatility, no need for data preprocessing and the help of additional data structures.

    However, the time complexity of this type of algorithm is \\(O(n)\\), where \\(n\\) is the number of elements, so the performance is poor in cases of large data volumes.

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1052-adaptive-search","title":"10.5.2 \u00a0 Adaptive search","text":"

    Adaptive search uses the unique properties of data (such as order) to optimize the search process, thereby locating the target element more efficiently.

    • \"Binary search\" uses the orderliness of data to achieve efficient searching, only suitable for arrays.
    • \"Hash search\" uses a hash table to establish a key-value mapping between search data and target data, thus implementing the query operation.
    • \"Tree search\" in a specific tree structure (such as a binary search tree), quickly eliminates nodes based on node value comparisons, thus locating the target element.

    The advantage of these algorithms is high efficiency, with time complexities reaching \\(O(\\log n)\\) or even \\(O(1)\\).

    However, using these algorithms often requires data preprocessing. For example, binary search requires sorting the array in advance, and hash search and tree search both require the help of additional data structures, maintaining these structures also requires extra time and space overhead.

    Tip

    Adaptive search algorithms are often referred to as search algorithms, mainly used for quickly retrieving target elements in specific data structures.

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1053-choosing-a-search-method","title":"10.5.3 \u00a0 Choosing a search method","text":"

    Given a set of data of size \\(n\\), we can use linear search, binary search, tree search, hash search, and other methods to search for the target element from it. The working principles of these methods are shown in the following figure.

    Figure 10-11 \u00a0 Various search strategies

    The operation efficiency and characteristics of the aforementioned methods are shown in the following table.

    Table 10-1 \u00a0 Comparison of search algorithm efficiency

    Linear search Binary search Tree search Hash search Search element \\(O(n)\\) \\(O(\\log n)\\) \\(O(\\log n)\\) \\(O(1)\\) Insert element \\(O(1)\\) \\(O(n)\\) \\(O(\\log n)\\) \\(O(1)\\) Delete element \\(O(n)\\) \\(O(n)\\) \\(O(\\log n)\\) \\(O(1)\\) Extra space \\(O(1)\\) \\(O(1)\\) \\(O(n)\\) \\(O(n)\\) Data preprocessing / Sorting \\(O(n \\log n)\\) Building tree \\(O(n \\log n)\\) Building hash table \\(O(n)\\) Data orderliness Unordered Ordered Ordered Unordered

    The choice of search algorithm also depends on the volume of data, search performance requirements, data query and update frequency, etc.

    Linear search

    • Good versatility, no need for any data preprocessing operations. If we only need to query the data once, then the time for data preprocessing in the other three methods would be longer than the time for linear search.
    • Suitable for small volumes of data, where time complexity has a smaller impact on efficiency.
    • Suitable for scenarios with high data update frequency, because this method does not require any additional maintenance of the data.

    Binary search

    • Suitable for large data volumes, with stable efficiency performance, the worst time complexity being \\(O(\\log n)\\).
    • The data volume cannot be too large, because storing arrays requires contiguous memory space.
    • Not suitable for scenarios with frequent additions and deletions, because maintaining an ordered array incurs high overhead.

    Hash search

    • Suitable for scenarios with high query performance requirements, with an average time complexity of \\(O(1)\\).
    • Not suitable for scenarios needing ordered data or range searches, because hash tables cannot maintain data orderliness.
    • High dependency on hash functions and hash collision handling strategies, with significant performance degradation risks.
    • Not suitable for overly large data volumes, because hash tables need extra space to minimize collisions and provide good query performance.

    Tree search

    • Suitable for massive data, because tree nodes are stored scattered in memory.
    • Suitable for maintaining ordered data or range searches.
    • In the continuous addition and deletion of nodes, the binary search tree may become skewed, degrading the time complexity to \\(O(n)\\).
    • If using AVL trees or red-black trees, operations can run stably at \\(O(\\log n)\\) efficiency, but the operation to maintain tree balance adds extra overhead.
    "},{"location":"chapter_searching/summary/","title":"10.6 \u00a0 Summary","text":"
    • Binary search depends on the order of data and performs the search by iteratively halving the search interval. It requires the input data to be sorted and is only applicable to arrays or array-based data structures.
    • Brute force search locates data by traversing the data structure. Linear search is suitable for arrays and linked lists, while breadth-first search and depth-first search are suitable for graphs and trees. These algorithms are highly versatile, requiring no preprocessing of data, but have a higher time complexity of \\(O(n)\\).
    • Hash search, tree search, and binary search are efficient searching methods, capable of quickly locating target elements in specific data structures. These algorithms are highly efficient, with time complexities reaching \\(O(\\log n)\\) or even \\(O(1)\\), but they usually require additional data structures.
    • In practice, we need to analyze factors such as data volume, search performance requirements, data query and update frequencies, etc., to choose the appropriate search method.
    • Linear search is suitable for small or frequently updated data; binary search is suitable for large, sorted data; hash search is suitable for scenarios requiring high query efficiency without the need for range queries; tree search is appropriate for large dynamic data that needs to maintain order and support range queries.
    • Replacing linear search with hash search is a common strategy to optimize runtime, reducing the time complexity from \\(O(n)\\) to \\(O(1)\\).
    "},{"location":"chapter_sorting/","title":"Chapter 11. \u00a0 Sorting","text":"

    Abstract

    Sorting is like a magical key that turns chaos into order, enabling us to understand and handle data in a more efficient manner.

    Whether it's simple ascending order or complex categorical arrangements, sorting reveals the harmonious beauty of data.

    "},{"location":"chapter_sorting/#chapter-contents","title":"Chapter contents","text":"
    • 11.1 \u00a0 Sorting algorithms
    • 11.2 \u00a0 Selection sort
    • 11.3 \u00a0 Bubble sort
    • 11.4 \u00a0 Insertion sort
    • 11.5 \u00a0 Quick sort
    • 11.6 \u00a0 Merge sort
    • 11.7 \u00a0 Heap sort
    • 11.8 \u00a0 Bucket sort
    • 11.9 \u00a0 Counting sort
    • 11.10 \u00a0 Radix sort
    • 11.11 \u00a0 Summary
    "},{"location":"chapter_sorting/bubble_sort/","title":"11.3 \u00a0 Bubble sort","text":"

    Bubble sort achieves sorting by continuously comparing and swapping adjacent elements. This process resembles bubbles rising from the bottom to the top, hence the name bubble sort.

    As shown in the following figures, the bubbling process can be simulated using element swap operations: starting from the leftmost end of the array and moving right, sequentially compare the size of adjacent elements. If \"left element > right element,\" then swap them. After the traversal, the largest element will be moved to the far right end of the array.

    <1><2><3><4><5><6><7>

    Figure 11-4 \u00a0 Simulating bubble process using element swap

    "},{"location":"chapter_sorting/bubble_sort/#1131-algorithm-process","title":"11.3.1 \u00a0 Algorithm process","text":"

    Assuming the length of the array is \\(n\\), the steps of bubble sort are shown below.

    1. First, perform a \"bubble\" on \\(n\\) elements, swapping the largest element to its correct position.
    2. Next, perform a \"bubble\" on the remaining \\(n - 1\\) elements, swapping the second largest element to its correct position.
    3. Similarly, after \\(n - 1\\) rounds of \"bubbling,\" the top \\(n - 1\\) largest elements will be swapped to their correct positions.
    4. The only remaining element is necessarily the smallest and does not require sorting, thus the array sorting is complete.

    Figure 11-5 \u00a0 Bubble sort process

    Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bubble_sort.py
    def bubble_sort(nums: list[int]):\n    \"\"\"\u5192\u6ce1\u6392\u5e8f\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(n - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j + 1] = nums[j + 1], nums[j]\n
    bubble_sort.cpp
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                // \u8fd9\u91cc\u4f7f\u7528\u4e86 std::swap() \u51fd\u6570\n                swap(nums[j], nums[j + 1]);\n            }\n        }\n    }\n}\n
    bubble_sort.java
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.cs
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid BubbleSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n            }\n        }\n    }\n}\n
    bubble_sort.go
    /* \u5192\u6ce1\u6392\u5e8f */\nfunc bubbleSort(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j+1] = nums[j+1], nums[j]\n            }\n        }\n    }\n}\n
    bubble_sort.swift
    /* \u5192\u6ce1\u6392\u5e8f */\nfunc bubbleSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums.swapAt(j, j + 1)\n            }\n        }\n    }\n}\n
    bubble_sort.js
    /* \u5192\u6ce1\u6392\u5e8f */\nfunction bubbleSort(nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.ts
    /* \u5192\u6ce1\u6392\u5e8f */\nfunction bubbleSort(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.dart
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (int i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (int j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n      }\n    }\n  }\n}\n
    bubble_sort.rs
    /* \u5192\u6ce1\u6392\u5e8f */\nfn bubble_sort(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.c
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = size - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                int temp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = temp;\n            }\n        }\n    }\n}\n
    bubble_sort.kt
    /* \u5192\u6ce1\u6392\u5e8f */\nfun bubbleSort(nums: IntArray) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n            }\n        }\n    }\n}\n
    bubble_sort.rb
    [class]{}-[func]{bubble_sort}\n
    bubble_sort.zig
    // \u5192\u6ce1\u6392\u5e8f\nfn bubbleSort(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: usize = nums.len - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/bubble_sort/#1132-efficiency-optimization","title":"11.3.2 \u00a0 Efficiency optimization","text":"

    We find that if no swaps are performed in a round of \"bubbling,\" the array is already sorted, and we can return the result immediately. Thus, we can add a flag flag to monitor this situation and return immediately when it occurs.

    Even after optimization, the worst-case time complexity and average time complexity of bubble sort remain at \\(O(n^2)\\); however, when the input array is completely ordered, it can achieve the best time complexity of \\(O(n)\\).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bubble_sort.py
    def bubble_sort_with_flag(nums: list[int]):\n    \"\"\"\u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(n - 1, 0, -1):\n        flag = False  # \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j + 1] = nums[j + 1], nums[j]\n                flag = True  # \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n        if not flag:\n            break  # \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n
    bubble_sort.cpp
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                // \u8fd9\u91cc\u4f7f\u7528\u4e86 std::swap() \u51fd\u6570\n                swap(nums[j], nums[j + 1]);\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag)\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.java
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nvoid bubbleSortWithFlag(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        boolean flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag)\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.cs
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid BubbleSortWithFlag(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                flag = true;  // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break;     // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.go
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunc bubbleSortWithFlag(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        flag := false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j+1] = nums[j+1], nums[j]\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if flag == false { // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n            break\n        }\n    }\n}\n
    bubble_sort.swift
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunc bubbleSortWithFlag(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        var flag = false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums.swapAt(j, j + 1)\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if !flag { // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n            break\n        }\n    }\n}\n
    bubble_sort.js
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunction bubbleSortWithFlag(nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        let flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.ts
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunction bubbleSortWithFlag(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        let flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.dart
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (int i = nums.length - 1; i > 0; i--) {\n    bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (int j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n      }\n    }\n    if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n  }\n}\n
    bubble_sort.rs
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nfn bubble_sort_with_flag(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        let mut flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if !flag {\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n        };\n    }\n}\n
    bubble_sort.c
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = size - 1; i > 0; i--) {\n        bool flag = false;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                int temp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = temp;\n                flag = true;\n            }\n        }\n        if (!flag)\n            break;\n    }\n}\n
    bubble_sort.kt
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nfun bubbleSortWithFlag(nums: IntArray) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        var flag = false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.rb
    [class]{}-[func]{bubble_sort_with_flag}\n
    bubble_sort.zig
    // \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09\nfn bubbleSortWithFlag(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: usize = nums.len - 1;\n    while (i > 0) : (i -= 1) {\n        var flag = false;   // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true;\n            }\n        }\n        if (!flag) break;   // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/bubble_sort/#1133-algorithm-characteristics","title":"11.3.3 \u00a0 Algorithm characteristics","text":"
    • Time complexity of \\(O(n^2)\\), adaptive sorting: The length of the array traversed in each round of \"bubbling\" decreases sequentially from \\(n - 1\\), \\(n - 2\\), \\(\\dots\\), \\(2\\), \\(1\\), totaling \\((n - 1) n / 2\\). With the introduction of flag optimization, the best time complexity can reach \\(O(n)\\).
    • Space complexity of \\(O(1)\\), in-place sorting: Only a constant amount of extra space is used by pointers \\(i\\) and \\(j\\).
    • Stable sorting: As equal elements are not swapped during the \"bubbling\".
    "},{"location":"chapter_sorting/bucket_sort/","title":"11.8 \u00a0 Bucket sort","text":"

    The previously mentioned sorting algorithms are all \"comparison-based sorting algorithms,\" which sort by comparing the size of elements. Such sorting algorithms cannot surpass a time complexity of \\(O(n \\log n)\\). Next, we will discuss several \"non-comparison sorting algorithms\" that can achieve linear time complexity.

    Bucket sort is a typical application of the divide-and-conquer strategy. It involves setting up a series of ordered buckets, each corresponding to a range of data, and then distributing the data evenly among these buckets; each bucket is then sorted individually; finally, all the data are merged in the order of the buckets.

    "},{"location":"chapter_sorting/bucket_sort/#1181-algorithm-process","title":"11.8.1 \u00a0 Algorithm process","text":"

    Consider an array of length \\(n\\), with elements in the range \\([0, 1)\\). The bucket sort process is illustrated in the Figure 11-13 .

    1. Initialize \\(k\\) buckets and distribute \\(n\\) elements into these \\(k\\) buckets.
    2. Sort each bucket individually (using the built-in sorting function of the programming language).
    3. Merge the results in the order from the smallest to the largest bucket.

    Figure 11-13 \u00a0 Bucket sort algorithm process

    The code is shown as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bucket_sort.py
    def bucket_sort(nums: list[float]):\n    \"\"\"\u6876\u6392\u5e8f\"\"\"\n    # \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    k = len(nums) // 2\n    buckets = [[] for _ in range(k)]\n    # 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for num in nums:\n        # \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        i = int(num * k)\n        # \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].append(num)\n    # 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for bucket in buckets:\n        # \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort()\n    # 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    i = 0\n    for bucket in buckets:\n        for num in bucket:\n            nums[i] = num\n            i += 1\n
    bucket_sort.cpp
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(vector<float> &nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.size() / 2;\n    vector<vector<float>> buckets(k);\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (float num : nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = num * k;\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 bucket_idx\n        buckets[i].push_back(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (vector<float> &bucket : buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        sort(bucket.begin(), bucket.end());\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int i = 0;\n    for (vector<float> &bucket : buckets) {\n        for (float num : bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.java
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(float[] nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.length / 2;\n    List<List<Float>> buckets = new ArrayList<>();\n    for (int i = 0; i < k; i++) {\n        buckets.add(new ArrayList<>());\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (float num : nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = (int) (num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets.get(i).add(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (List<Float> bucket : buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        Collections.sort(bucket);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int i = 0;\n    for (List<Float> bucket : buckets) {\n        for (float num : bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.cs
    /* \u6876\u6392\u5e8f */\nvoid BucketSort(float[] nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.Length / 2;\n    List<List<float>> buckets = [];\n    for (int i = 0; i < k; i++) {\n        buckets.Add([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    foreach (float num in nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = (int)(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].Add(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    foreach (List<float> bucket in buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.Sort();\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int j = 0;\n    foreach (List<float> bucket in buckets) {\n        foreach (float num in bucket) {\n            nums[j++] = num;\n        }\n    }\n}\n
    bucket_sort.go
    /* \u6876\u6392\u5e8f */\nfunc bucketSort(nums []float64) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    k := len(nums) / 2\n    buckets := make([][]float64, k)\n    for i := 0; i < k; i++ {\n        buckets[i] = make([]float64, 0)\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for _, num := range nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        i := int(num * float64(k))\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i] = append(buckets[i], num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for i := 0; i < k; i++ {\n        // \u4f7f\u7528\u5185\u7f6e\u5207\u7247\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        sort.Float64s(buckets[i])\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    i := 0\n    for _, bucket := range buckets {\n        for _, num := range bucket {\n            nums[i] = num\n            i++\n        }\n    }\n}\n
    bucket_sort.swift
    /* \u6876\u6392\u5e8f */\nfunc bucketSort(nums: inout [Double]) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    let k = nums.count / 2\n    var buckets = (0 ..< k).map { _ in [Double]() }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for num in nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        let i = Int(num * Double(k))\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].append(num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for i in buckets.indices {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        buckets[i].sort()\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    var i = nums.startIndex\n    for bucket in buckets {\n        for num in bucket {\n            nums[i] = num\n            i += 1\n        }\n    }\n}\n
    bucket_sort.js
    /* \u6876\u6392\u5e8f */\nfunction bucketSort(nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    const k = nums.length / 2;\n    const buckets = [];\n    for (let i = 0; i < k; i++) {\n        buckets.push([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (const num of nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        const i = Math.floor(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (const bucket of buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort((a, b) => a - b);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let i = 0;\n    for (const bucket of buckets) {\n        for (const num of bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.ts
    /* \u6876\u6392\u5e8f */\nfunction bucketSort(nums: number[]): void {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    const k = nums.length / 2;\n    const buckets: number[][] = [];\n    for (let i = 0; i < k; i++) {\n        buckets.push([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (const num of nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        const i = Math.floor(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (const bucket of buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort((a, b) => a - b);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let i = 0;\n    for (const bucket of buckets) {\n        for (const num of bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.dart
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(List<double> nums) {\n  // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n  int k = nums.length ~/ 2;\n  List<List<double>> buckets = List.generate(k, (index) => []);\n\n  // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n  for (double _num in nums) {\n    // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 _num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n    int i = (_num * k).toInt();\n    // \u5c06 _num \u6dfb\u52a0\u8fdb\u6876 bucket_idx\n    buckets[i].add(_num);\n  }\n  // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n  for (List<double> bucket in buckets) {\n    bucket.sort();\n  }\n  // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n  int i = 0;\n  for (List<double> bucket in buckets) {\n    for (double _num in bucket) {\n      nums[i++] = _num;\n    }\n  }\n}\n
    bucket_sort.rs
    /* \u6876\u6392\u5e8f */\nfn bucket_sort(nums: &mut [f64]) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    let k = nums.len() / 2;\n    let mut buckets = vec![vec![]; k];\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for &mut num in &mut *nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        let i = (num * k as f64) as usize;\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for bucket in &mut buckets {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort_by(|a, b| a.partial_cmp(b).unwrap());\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let mut i = 0;\n    for bucket in &mut buckets {\n        for &mut num in bucket {\n            nums[i] = num;\n            i += 1;\n        }\n    }\n}\n
    bucket_sort.c
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(float nums[], int n) {\n    int k = n / 2;                                 // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\n    int *sizes = malloc(k * sizeof(int));          // \u8bb0\u5f55\u6bcf\u4e2a\u6876\u7684\u5927\u5c0f\n    float **buckets = malloc(k * sizeof(float *)); // \u52a8\u6001\u6570\u7ec4\u7684\u6570\u7ec4\uff08\u6876\uff09\n    // \u4e3a\u6bcf\u4e2a\u6876\u9884\u5206\u914d\u8db3\u591f\u7684\u7a7a\u95f4\n    for (int i = 0; i < k; ++i) {\n        buckets[i] = (float *)malloc(n * sizeof(float));\n        sizes[i] = 0;\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (int i = 0; i < n; ++i) {\n        int idx = (int)(nums[i] * k);\n        buckets[idx][sizes[idx]++] = nums[i];\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (int i = 0; i < k; ++i) {\n        qsort(buckets[i], sizes[i], sizeof(float), compare);\n    }\n    // 3. \u5408\u5e76\u6392\u5e8f\u540e\u7684\u6876\n    int idx = 0;\n    for (int i = 0; i < k; ++i) {\n        for (int j = 0; j < sizes[i]; ++j) {\n            nums[idx++] = buckets[i][j];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(buckets[i]);\n    }\n}\n
    bucket_sort.kt
    /* \u6876\u6392\u5e8f */\nfun bucketSort(nums: FloatArray) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    val k = nums.size / 2\n    val buckets = mutableListOf<MutableList<Float>>()\n    for (i in 0..<k) {\n        buckets.add(mutableListOf())\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (num in nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        val i = (num * k).toInt()\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].add(num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (bucket in buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort()\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    var i = 0\n    for (bucket in buckets) {\n        for (num in bucket) {\n            nums[i++] = num\n        }\n    }\n}\n
    bucket_sort.rb
    ### \u6876\u6392\u5e8f ###\ndef bucket_sort(nums)\n  # \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n  k = nums.length / 2\n  buckets = Array.new(k) { [] }\n\n  # 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n  nums.each do |num|\n    # \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n    i = (num * k).to_i\n    # \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n    buckets[i] << num\n  end\n\n  # 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n  buckets.each do |bucket|\n    # \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n    bucket.sort!\n  end\n\n  # 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n  i = 0\n  buckets.each do |bucket|\n    bucket.each do |num|\n      nums[i] = num\n      i += 1\n    end\n  end\nend\n
    bucket_sort.zig
    [class]{}-[func]{bucketSort}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/bucket_sort/#1182-algorithm-characteristics","title":"11.8.2 \u00a0 Algorithm characteristics","text":"

    Bucket sort is suitable for handling very large data sets. For example, if the input data includes 1 million elements, and system memory limitations prevent loading all the data at once, you can divide the data into 1,000 buckets and sort each bucket separately before merging the results.

    • Time complexity is \\(O(n + k)\\): Assuming the elements are evenly distributed across the buckets, the number of elements in each bucket is \\(n/k\\). Assuming sorting a single bucket takes \\(O(n/k \\log(n/k))\\) time, sorting all buckets takes \\(O(n \\log(n/k))\\) time. When the number of buckets \\(k\\) is relatively large, the time complexity tends towards \\(O(n)\\). Merging the results requires traversing all buckets and elements, taking \\(O(n + k)\\) time.
    • Adaptive sorting: In the worst case, all data is distributed into a single bucket, and sorting that bucket takes \\(O(n^2)\\) time.
    • Space complexity is \\(O(n + k)\\), non-in-place sorting: It requires additional space for \\(k\\) buckets and a total of \\(n\\) elements.
    • Whether bucket sort is stable depends on whether the algorithm used to sort elements within the buckets is stable.
    "},{"location":"chapter_sorting/bucket_sort/#1183-how-to-achieve-even-distribution","title":"11.8.3 \u00a0 How to achieve even distribution","text":"

    The theoretical time complexity of bucket sort can reach \\(O(n)\\), the key is to evenly distribute the elements across all buckets, as real data is often not uniformly distributed. For example, if we want to evenly distribute all products on Taobao by price range into 10 buckets, but the distribution of product prices is uneven, with many under 100 yuan and few over 1000 yuan. If the price range is evenly divided into 10, the difference in the number of products in each bucket will be very large.

    To achieve even distribution, we can initially set a rough dividing line, roughly dividing the data into 3 buckets. After the distribution is complete, the buckets with more products can be further divided into 3 buckets, until the number of elements in all buckets is roughly equal.

    As shown in the Figure 11-14 , this method essentially creates a recursive tree, aiming to make the leaf node values as even as possible. Of course, you don't have to divide the data into 3 buckets each round; the specific division method can be flexibly chosen based on data characteristics.

    Figure 11-14 \u00a0 Recursive division of buckets

    If we know the probability distribution of product prices in advance, we can set the price dividing line for each bucket based on the data probability distribution. It is worth noting that it is not necessarily required to specifically calculate the data distribution; it can also be approximated based on data characteristics using some probability model.

    As shown in the Figure 11-15 , we assume that product prices follow a normal distribution, allowing us to reasonably set the price intervals, thereby evenly distributing the products into the respective buckets.

    Figure 11-15 \u00a0 Dividing buckets based on probability distribution

    "},{"location":"chapter_sorting/counting_sort/","title":"11.9 \u00a0 Counting sort","text":"

    Counting sort achieves sorting by counting the number of elements, typically applied to arrays of integers.

    "},{"location":"chapter_sorting/counting_sort/#1191-simple-implementation","title":"11.9.1 \u00a0 Simple implementation","text":"

    Let's start with a simple example. Given an array nums of length \\(n\\), where all elements are \"non-negative integers\", the overall process of counting sort is illustrated in the following diagram.

    1. Traverse the array to find the maximum number, denoted as \\(m\\), then create an auxiliary array counter of length \\(m + 1\\).
    2. Use counter to count the occurrence of each number in nums, where counter[num] corresponds to the occurrence of the number num. The counting method is simple, just traverse nums (suppose the current number is num), and increase counter[num] by \\(1\\) each round.
    3. Since the indices of counter are naturally ordered, all numbers are essentially sorted already. Next, we traverse counter, filling nums in ascending order of occurrence.

    Figure 11-16 \u00a0 Counting sort process

    The code is shown below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig counting_sort.py
    def counting_sort_naive(nums: list[int]):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\"\"\"\n    # \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\n    # 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m = 0\n    for num in nums:\n        m = max(m, num)\n    # 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    # counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter = [0] * (m + 1)\n    for num in nums:\n        counter[num] += 1\n    # 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    i = 0\n    for num in range(m + 1):\n        for _ in range(counter[num]):\n            nums[i] = num\n            i += 1\n
    counting_sort.cpp
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(vector<int> &nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    vector<int> counter(m + 1, 0);\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.java
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.cs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid CountingSortNaive(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    foreach (int num in nums) {\n        m = Math.Max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    foreach (int num in nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.go
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunc countingSortNaive(nums []int) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m := 0\n    for _, num := range nums {\n        if num > m {\n            m = num\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter := make([]int, m+1)\n    for _, num := range nums {\n        counter[num]++\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    for i, num := 0, 0; num < m+1; num++ {\n        for j := 0; j < counter[num]; j++ {\n            nums[i] = num\n            i++\n        }\n    }\n}\n
    counting_sort.swift
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunc countingSortNaive(nums: inout [Int]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = nums.max()!\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    var counter = Array(repeating: 0, count: m + 1)\n    for num in nums {\n        counter[num] += 1\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    var i = 0\n    for num in 0 ..< m + 1 {\n        for _ in 0 ..< counter[num] {\n            nums[i] = num\n            i += 1\n        }\n    }\n}\n
    counting_sort.js
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunction countingSortNaive(nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter = new Array(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let i = 0;\n    for (let num = 0; num < m + 1; num++) {\n        for (let j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.ts
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunction countingSortNaive(nums: number[]): void {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter: number[] = new Array<number>(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let i = 0;\n    for (let num = 0; num < m + 1; num++) {\n        for (let j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.dart
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(List<int> nums) {\n  // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n  int m = 0;\n  for (int _num in nums) {\n    m = max(m, _num);\n  }\n  // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  // counter[_num] \u4ee3\u8868 _num \u7684\u51fa\u73b0\u6b21\u6570\n  List<int> counter = List.filled(m + 1, 0);\n  for (int _num in nums) {\n    counter[_num]++;\n  }\n  // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n  int i = 0;\n  for (int _num = 0; _num < m + 1; _num++) {\n    for (int j = 0; j < counter[_num]; j++, i++) {\n      nums[i] = _num;\n    }\n  }\n}\n
    counting_sort.rs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfn counting_sort_naive(nums: &mut [i32]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = *nums.into_iter().max().unwrap();\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    let mut counter = vec![0; m as usize + 1];\n    for &num in &*nums {\n        counter[num as usize] += 1;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let mut i = 0;\n    for num in 0..m + 1 {\n        for _ in 0..counter[num as usize] {\n            nums[i] = num;\n            i += 1;\n        }\n    }\n}\n
    counting_sort.c
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(int nums[], int size) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int i = 0; i < size; i++) {\n        if (nums[i] > m) {\n            m = nums[i];\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int *counter = calloc(m + 1, sizeof(int));\n    for (int i = 0; i < size; i++) {\n        counter[nums[i]]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n    // 4. \u91ca\u653e\u5185\u5b58\n    free(counter);\n}\n
    counting_sort.kt
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfun countingSortNaive(nums: IntArray) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    var m = 0\n    for (num in nums) {\n        m = max(m, num)\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    val counter = IntArray(m + 1)\n    for (num in nums) {\n        counter[num]++\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    var i = 0\n    for (num in 0..<m + 1) {\n        var j = 0\n        while (j < counter[num]) {\n            nums[i] = num\n            j++\n            i++\n        }\n    }\n}\n
    counting_sort.rb
    [class]{}-[func]{counting_sort_naive}\n
    counting_sort.zig
    [class]{}-[func]{countingSortNaive}\n
    Code Visualization

    Full Screen >

    Connection between counting sort and bucket sort

    From the perspective of bucket sort, we can consider each index of the counting array counter in counting sort as a bucket, and the process of counting as distributing elements into the corresponding buckets. Essentially, counting sort is a special case of bucket sort for integer data.

    "},{"location":"chapter_sorting/counting_sort/#1192-complete-implementation","title":"11.9.2 \u00a0 Complete implementation","text":"

    Astute readers might have noticed, if the input data is an object, the above step 3. becomes ineffective. Suppose the input data is a product object, we want to sort the products by their price (a class member variable), but the above algorithm can only provide the sorting result for the price.

    So how can we get the sorting result for the original data? First, we calculate the \"prefix sum\" of counter. As the name suggests, the prefix sum at index i, prefix[i], equals the sum of the first i elements of the array:

    \\[ \\text{prefix}[i] = \\sum_{j=0}^i \\text{counter[j]} \\]

    The prefix sum has a clear meaning, prefix[num] - 1 represents the last occurrence index of element num in the result array res. This information is crucial, as it tells us where each element should appear in the result array. Next, we traverse the original array nums for each element num in reverse order, performing the following two steps in each iteration.

    1. Fill num into the array res at the index prefix[num] - 1.
    2. Reduce the prefix sum prefix[num] by \\(1\\), thus obtaining the next index to place num.

    After the traversal, the array res contains the sorted result, and finally, res replaces the original array nums. The complete counting sort process is shown in the figures below.

    <1><2><3><4><5><6><7><8>

    Figure 11-17 \u00a0 Counting sort process

    The implementation code of counting sort is shown below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig counting_sort.py
    def counting_sort(nums: list[int]):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\"\"\"\n    # \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\n    # 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m = max(nums)\n    # 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    # counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter = [0] * (m + 1)\n    for num in nums:\n        counter[num] += 1\n    # 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    # \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in range(m):\n        counter[i + 1] += counter[i]\n    # 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    # \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    n = len(nums)\n    res = [0] * n\n    for i in range(n - 1, -1, -1):\n        num = nums[i]\n        res[counter[num] - 1] = num  # \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num] -= 1  # \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    # \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in range(n):\n        nums[i] = res[i]\n
    counting_sort.cpp
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(vector<int> &nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    vector<int> counter(m + 1, 0);\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.size();\n    vector<int> res(n);\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--;              // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    nums = res;\n}\n
    counting_sort.java
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.length;\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.cs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid CountingSort(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    foreach (int num in nums) {\n        m = Math.Max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    foreach (int num in nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.Length;\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.go
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunc countingSort(nums []int) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m := 0\n    for _, num := range nums {\n        if num > m {\n            m = num\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter := make([]int, m+1)\n    for _, num := range nums {\n        counter[num]++\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i := 0; i < m; i++ {\n        counter[i+1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    n := len(nums)\n    res := make([]int, n)\n    for i := n - 1; i >= 0; i-- {\n        num := nums[i]\n        // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        res[counter[num]-1] = num\n        // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n        counter[num]--\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    copy(nums, res)\n}\n
    counting_sort.swift
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunc countingSort(nums: inout [Int]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = nums.max()!\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    var counter = Array(repeating: 0, count: m + 1)\n    for num in nums {\n        counter[num] += 1\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in 0 ..< m {\n        counter[i + 1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    var res = Array(repeating: 0, count: nums.count)\n    for i in nums.indices.reversed() {\n        let num = nums[i]\n        res[counter[num] - 1] = num // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num] -= 1 // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in nums.indices {\n        nums[i] = res[i]\n    }\n}\n
    counting_sort.js
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunction countingSort(nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter = new Array(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (let i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    const n = nums.length;\n    const res = new Array(n);\n    for (let i = n - 1; i >= 0; i--) {\n        const num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.ts
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunction countingSort(nums: number[]): void {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter: number[] = new Array<number>(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (let i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    const n = nums.length;\n    const res: number[] = new Array<number>(n);\n    for (let i = n - 1; i >= 0; i--) {\n        const num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.dart
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(List<int> nums) {\n  // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n  int m = 0;\n  for (int _num in nums) {\n    m = max(m, _num);\n  }\n  // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  // counter[_num] \u4ee3\u8868 _num \u7684\u51fa\u73b0\u6b21\u6570\n  List<int> counter = List.filled(m + 1, 0);\n  for (int _num in nums) {\n    counter[_num]++;\n  }\n  // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n  // \u5373 counter[_num]-1 \u662f _num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n  for (int i = 0; i < m; i++) {\n    counter[i + 1] += counter[i];\n  }\n  // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n  // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n  int n = nums.length;\n  List<int> res = List.filled(n, 0);\n  for (int i = n - 1; i >= 0; i--) {\n    int _num = nums[i];\n    res[counter[_num] - 1] = _num; // \u5c06 _num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n    counter[_num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e _num \u7684\u7d22\u5f15\n  }\n  // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n  nums.setAll(0, res);\n}\n
    counting_sort.rs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfn counting_sort(nums: &mut [i32]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = *nums.into_iter().max().unwrap();\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    let mut counter = vec![0; m as usize + 1];\n    for &num in &*nums {\n        counter[num as usize] += 1;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in 0..m as usize {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    let n = nums.len();\n    let mut res = vec![0; n];\n    for i in (0..n).rev() {\n        let num = nums[i];\n        res[counter[num as usize] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num as usize] -= 1; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in 0..n {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.c
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(int nums[], int size) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int i = 0; i < size; i++) {\n        if (nums[i] > m) {\n            m = nums[i];\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int *counter = calloc(m, sizeof(int));\n    for (int i = 0; i < size; i++) {\n        counter[nums[i]]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int *res = malloc(sizeof(int) * size);\n    for (int i = size - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--;              // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    memcpy(nums, res, size * sizeof(int));\n    // 5. \u91ca\u653e\u5185\u5b58\n    free(counter);\n}\n
    counting_sort.kt
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfun countingSort(nums: IntArray) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    var m = 0\n    for (num in nums) {\n        m = max(m, num)\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    val counter = IntArray(m + 1)\n    for (num in nums) {\n        counter[num]++\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (i in 0..<m) {\n        counter[i + 1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    val n = nums.size\n    val res = IntArray(n)\n    for (i in n - 1 downTo 0) {\n        val num = nums[i]\n        res[counter[num] - 1] = num // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]-- // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (i in 0..<n) {\n        nums[i] = res[i]\n    }\n}\n
    counting_sort.rb
    [class]{}-[func]{counting_sort}\n
    counting_sort.zig
    [class]{}-[func]{countingSort}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/counting_sort/#1193-algorithm-characteristics","title":"11.9.3 \u00a0 Algorithm characteristics","text":"
    • Time complexity is \\(O(n + m)\\), non-adaptive sort: Involves traversing nums and counter, both using linear time. Generally, \\(n \\gg m\\), and the time complexity tends towards \\(O(n)\\).
    • Space complexity is \\(O(n + m)\\), non-in-place sort: Utilizes arrays res and counter of lengths \\(n\\) and \\(m\\) respectively.
    • Stable sort: Since elements are filled into res in a \"right-to-left\" order, reversing the traversal of nums can prevent changing the relative position between equal elements, thereby achieving a stable sort. Actually, traversing nums in order can also produce the correct sorting result, but the outcome is unstable.
    "},{"location":"chapter_sorting/counting_sort/#1194-limitations","title":"11.9.4 \u00a0 Limitations","text":"

    By now, you might find counting sort very clever, as it can achieve efficient sorting merely by counting quantities. However, the prerequisites for using counting sort are relatively strict.

    Counting sort is only suitable for non-negative integers. If you want to apply it to other types of data, you need to ensure that these data can be converted to non-negative integers without changing the relative sizes of the elements. For example, for an array containing negative integers, you can first add a constant to all numbers, converting them all to positive numbers, and then convert them back after sorting is complete.

    Counting sort is suitable for large data volumes but small data ranges. For example, in the above example, \\(m\\) should not be too large, otherwise, it will occupy too much space. And when \\(n \\ll m\\), counting sort uses \\(O(m)\\) time, which may be slower than \\(O(n \\log n)\\) sorting algorithms.

    "},{"location":"chapter_sorting/heap_sort/","title":"11.7 \u00a0 Heap sort","text":"

    Tip

    Before reading this section, please make sure you have completed the \"Heap\" chapter.

    Heap sort is an efficient sorting algorithm based on the heap data structure. We can implement heap sort using the \"heap creation\" and \"element extraction\" operations we have already learned.

    1. Input the array and establish a min-heap, where the smallest element is at the heap's top.
    2. Continuously perform the extraction operation, recording the extracted elements in sequence to obtain a sorted list from smallest to largest.

    Although the above method is feasible, it requires an additional array to save the popped elements, which is somewhat space-consuming. In practice, we usually use a more elegant implementation.

    "},{"location":"chapter_sorting/heap_sort/#1171-algorithm-flow","title":"11.7.1 \u00a0 Algorithm flow","text":"

    Suppose the array length is \\(n\\), the heap sort process is as follows.

    1. Input the array and establish a max-heap. After completion, the largest element is at the heap's top.
    2. Swap the top element of the heap (the first element) with the heap's bottom element (the last element). After the swap, reduce the heap's length by \\(1\\) and increase the sorted elements count by \\(1\\).
    3. Starting from the heap top, perform the sift-down operation from top to bottom. After the sift-down, the heap's property is restored.
    4. Repeat steps 2. and 3. Loop for \\(n - 1\\) rounds to complete the sorting of the array.

    Tip

    In fact, the element extraction operation also includes steps 2. and 3., with the addition of a popping element step.

    <1><2><3><4><5><6><7><8><9><10><11><12>

    Figure 11-12 \u00a0 Heap sort process

    In the code implementation, we used the sift-down function sift_down() from the \"Heap\" chapter. It is important to note that since the heap's length decreases as the maximum element is extracted, we need to add a length parameter \\(n\\) to the sift_down() function to specify the current effective length of the heap. The code is shown below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap_sort.py
    def sift_down(nums: list[int], n: int, i: int):\n    \"\"\"\u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l = 2 * i + 1\n        r = 2 * i + 2\n        ma = i\n        if l < n and nums[l] > nums[ma]:\n            ma = l\n        if r < n and nums[r] > nums[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        nums[i], nums[ma] = nums[ma], nums[i]\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n\ndef heap_sort(nums: list[int]):\n    \"\"\"\u5806\u6392\u5e8f\"\"\"\n    # \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(len(nums) // 2 - 1, -1, -1):\n        sift_down(nums, len(nums), i)\n    # \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in range(len(nums) - 1, 0, -1):\n        # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        nums[0], nums[i] = nums[i], nums[0]\n        # \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        sift_down(nums, i, 0)\n
    heap_sort.cpp
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(vector<int> &nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(nums[i], nums[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(vector<int> &nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.size() / 2 - 1; i >= 0; --i) {\n        siftDown(nums, nums.size(), i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.size() - 1; i > 0; --i) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(nums[0], nums[i]);\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.java
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int[] nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        int temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(int[] nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.length / 2 - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        int tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.cs
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int[] nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        (nums[ma], nums[i]) = (nums[i], nums[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid HeapSort(int[] nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.Length / 2 - 1; i >= 0; i--) {\n        SiftDown(nums, nums.Length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        (nums[i], nums[0]) = (nums[0], nums[i]);\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        SiftDown(nums, i, 0);\n    }\n}\n
    heap_sort.go
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(nums *[]int, n, i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l := 2*i + 1\n        r := 2*i + 2\n        ma := i\n        if l < n && (*nums)[l] > (*nums)[ma] {\n            ma = l\n        }\n        if r < n && (*nums)[r] > (*nums)[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        (*nums)[i], (*nums)[ma] = (*nums)[ma], (*nums)[i]\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunc heapSort(nums *[]int) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i := len(*nums)/2 - 1; i >= 0; i-- {\n        siftDown(nums, len(*nums), i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i := len(*nums) - 1; i > 0; i-- {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        (*nums)[0], (*nums)[i] = (*nums)[i], (*nums)[0]\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0)\n    }\n}\n
    heap_sort.swift
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(nums: inout [Int], n: Int, i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1\n        let r = 2 * i + 2\n        var ma = i\n        if l < n, nums[l] > nums[ma] {\n            ma = l\n        }\n        if r < n, nums[r] > nums[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        nums.swapAt(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunc heapSort(nums: inout [Int]) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in stride(from: nums.count / 2 - 1, through: 0, by: -1) {\n        siftDown(nums: &nums, n: nums.count, i: i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in nums.indices.dropFirst().reversed() {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        nums.swapAt(0, i)\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums: &nums, n: i, i: 0)\n    }\n}\n
    heap_sort.js
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunction siftDown(nums, n, i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let ma = i;\n        if (l < n && nums[l] > nums[ma]) {\n            ma = l;\n        }\n        if (r < n && nums[r] > nums[ma]) {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        [nums[i], nums[ma]] = [nums[ma], nums[i]];\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunction heapSort(nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        [nums[0], nums[i]] = [nums[i], nums[0]];\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.ts
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunction siftDown(nums: number[], n: number, i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let ma = i;\n        if (l < n && nums[l] > nums[ma]) {\n            ma = l;\n        }\n        if (r < n && nums[r] > nums[ma]) {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        [nums[i], nums[ma]] = [nums[ma], nums[i]];\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunction heapSort(nums: number[]): void {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        [nums[0], nums[i]] = [nums[i], nums[0]];\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.dart
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(List<int> nums, int n, int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = 2 * i + 1;\n    int r = 2 * i + 2;\n    int ma = i;\n    if (l < n && nums[l] > nums[ma]) ma = l;\n    if (r < n && nums[r] > nums[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    int temp = nums[i];\n    nums[i] = nums[ma];\n    nums[ma] = temp;\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(List<int> nums) {\n  // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = nums.length ~/ 2 - 1; i >= 0; i--) {\n    siftDown(nums, nums.length, i);\n  }\n  // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n  for (int i = nums.length - 1; i > 0; i--) {\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    int tmp = nums[0];\n    nums[0] = nums[i];\n    nums[i] = tmp;\n    // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n    siftDown(nums, i, 0);\n  }\n}\n
    heap_sort.rs
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(nums: &mut [i32], n: usize, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let mut ma = i;\n        if l < n && nums[l] > nums[ma] {\n            ma = l;\n        }\n        if r < n && nums[r] > nums[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        let temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfn heap_sort(nums: &mut [i32]) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=nums.len() / 2 - 1).rev() {\n        sift_down(nums, nums.len(), i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in (1..=nums.len() - 1).rev() {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        let tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        sift_down(nums, i, 0);\n    }\n}\n
    heap_sort.c
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int nums[], int n, int i) {\n    while (1) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        int temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(int nums[], int n) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = n / 2 - 1; i >= 0; --i) {\n        siftDown(nums, n, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = n - 1; i > 0; --i) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        int tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.kt
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(nums: IntArray, n: Int, li: Int) {\n    var i = li\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = 2 * i + 1\n        val r = 2 * i + 2\n        var ma = i\n        if (l < n && nums[l] > nums[ma]) \n            ma = l\n        if (r < n && nums[r] > nums[ma]) \n            ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) \n            break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        val temp = nums[i]\n        nums[i] = nums[ma]\n        nums[ma] = temp\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfun heapSort(nums: IntArray) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (i in nums.size / 2 - 1 downTo 0) {\n        siftDown(nums, nums.size, i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (i in nums.size - 1 downTo 1) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        val temp = nums[0]\n        nums[0] = nums[i]\n        nums[i] = temp\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0)\n    }\n}\n
    heap_sort.rb
    ### \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 ###\ndef sift_down(nums, n, i)\n  while true\n    # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    l = 2 * i + 1\n    r = 2 * i + 2\n    ma = i\n    ma = l if l < n && nums[l] > nums[ma]\n    ma = r if r < n && nums[r] > nums[ma]\n    # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    break if ma == i\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    nums[i], nums[ma] = nums[ma], nums[i]\n    # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma\n  end\nend\n\n### \u5806\u6392\u5e8f ###\ndef heap_sort(nums)\n  # \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  (nums.length / 2 - 1).downto(0) do |i|\n    sift_down(nums, nums.length, i)\n  end\n  # \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n  (nums.length - 1).downto(1) do |i|\n    # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    nums[0], nums[i] = nums[i], nums[0]\n    # \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n    sift_down(nums, i, 0)\n  end\nend\n
    heap_sort.zig
    [class]{}-[func]{siftDown}\n\n[class]{}-[func]{heapSort}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/heap_sort/#1172-algorithm-characteristics","title":"11.7.2 \u00a0 Algorithm characteristics","text":"
    • Time complexity is \\(O(n \\log n)\\), non-adaptive sort: The heap creation uses \\(O(n)\\) time. Extracting the largest element from the heap takes \\(O(\\log n)\\) time, looping for \\(n - 1\\) rounds.
    • Space complexity is \\(O(1)\\), in-place sort: A few pointer variables use \\(O(1)\\) space. The element swapping and heapifying operations are performed on the original array.
    • Non-stable sort: The relative positions of equal elements may change during the swapping of the heap's top and bottom elements.
    "},{"location":"chapter_sorting/insertion_sort/","title":"11.4 \u00a0 Insertion sort","text":"

    Insertion sort is a simple sorting algorithm that works very much like the process of manually sorting a deck of cards.

    Specifically, we select a pivot element from the unsorted interval, compare it with the elements in the sorted interval to its left, and insert the element into the correct position.

    The Figure 11-6 shows the process of inserting an element into an array. Assuming the pivot element is base, we need to move all elements between the target index and base one position to the right, then assign base to the target index.

    Figure 11-6 \u00a0 Single insertion operation

    "},{"location":"chapter_sorting/insertion_sort/#1141-algorithm-process","title":"11.4.1 \u00a0 Algorithm process","text":"

    The overall process of insertion sort is shown in the following figure.

    1. Initially, the first element of the array is sorted.
    2. The second element of the array is taken as base, and after inserting it into the correct position, the first two elements of the array are sorted.
    3. The third element is taken as base, and after inserting it into the correct position, the first three elements of the array are sorted.
    4. And so on, in the last round, the last element is taken as base, and after inserting it into the correct position, all elements are sorted.

    Figure 11-7 \u00a0 Insertion sort process

    Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig insertion_sort.py
    def insertion_sort(nums: list[int]):\n    \"\"\"\u63d2\u5165\u6392\u5e8f\"\"\"\n    # \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in range(1, len(nums)):\n        base = nums[i]\n        j = i - 1\n        # \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0 and nums[j] > base:\n            nums[j + 1] = nums[j]  # \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1\n        nums[j + 1] = base  # \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n
    insertion_sort.cpp
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.size(); i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.java
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.length; i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base;        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.cs
    /* \u63d2\u5165\u6392\u5e8f */\nvoid InsertionSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.Length; i++) {\n        int bas = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > bas) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = bas;         // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.go
    /* \u63d2\u5165\u6392\u5e8f */\nfunc insertionSort(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i := 1; i < len(nums); i++ {\n        base := nums[i]\n        j := i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        for j >= 0 && nums[j] > base {\n            nums[j+1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--\n        }\n        nums[j+1] = base // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.swift
    /* \u63d2\u5165\u6392\u5e8f */\nfunc insertionSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in nums.indices.dropFirst() {\n        let base = nums[i]\n        var j = i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0, nums[j] > base {\n            nums[j + 1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1\n        }\n        nums[j + 1] = base // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.js
    /* \u63d2\u5165\u6392\u5e8f */\nfunction insertionSort(nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (let i = 1; i < nums.length; i++) {\n        let base = nums[i],\n            j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.ts
    /* \u63d2\u5165\u6392\u5e8f */\nfunction insertionSort(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (let i = 1; i < nums.length; i++) {\n        const base = nums[i];\n        let j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.dart
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n  for (int i = 1; i < nums.length; i++) {\n    int base = nums[i], j = i - 1;\n    // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n    while (j >= 0 && nums[j] > base) {\n      nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n      j--;\n    }\n    nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n  }\n}\n
    insertion_sort.rs
    /* \u63d2\u5165\u6392\u5e8f */\nfn insertion_sort(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in 1..nums.len() {\n        let (base, mut j) = (nums[i], (i - 1) as i32);\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0 && nums[j as usize] > base {\n            nums[(j + 1) as usize] = nums[j as usize]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1;\n        }\n        nums[(j + 1) as usize] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.c
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < size; i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            nums[j + 1] = nums[j];\n            j--;\n        }\n        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n        nums[j + 1] = base;\n    }\n}\n
    insertion_sort.kt
    /* \u63d2\u5165\u6392\u5e8f */\nfun insertionSort(nums: IntArray) {\n    //\u5916\u5faa\u73af: \u5df2\u6392\u5e8f\u5143\u7d20\u4e3a 1, 2, ..., n\n    for (i in nums.indices) {\n        val base = nums[i]\n        var j = i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--\n        }\n        nums[j + 1] = base        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.rb
    ### \u63d2\u5165\u6392\u5e8f ###\ndef insertion_sort(nums)\n  n = nums.length\n  # \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n  for i in 1...n\n    base = nums[i]\n    j = i - 1\n    # \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n    while j >= 0 && nums[j] > base\n      nums[j + 1] = nums[j] # \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n      j -= 1\n    end\n    nums[j + 1] = base # \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n  end\nend\n
    insertion_sort.zig
    // \u63d2\u5165\u6392\u5e8f\nfn insertionSort(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    var i: usize = 1;\n    while (i < nums.len) : (i += 1) {\n        var base = nums[i];\n        var j: usize = i;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 1 and nums[j - 1] > base) : (j -= 1) {\n            nums[j] = nums[j - 1];  // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n        }\n        nums[j] = base;             // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/insertion_sort/#1142-algorithm-characteristics","title":"11.4.2 \u00a0 Algorithm characteristics","text":"
    • Time complexity is \\(O(n^2)\\), adaptive sorting: In the worst case, each insertion operation requires \\(n - 1\\), \\(n-2\\), ..., \\(2\\), \\(1\\) loops, summing up to \\((n - 1) n / 2\\), thus the time complexity is \\(O(n^2)\\). In the case of ordered data, the insertion operation will terminate early. When the input array is completely ordered, insertion sort achieves the best time complexity of \\(O(n)\\).
    • Space complexity is \\(O(1)\\), in-place sorting: Pointers \\(i\\) and \\(j\\) use a constant amount of extra space.
    • Stable sorting: During the insertion operation, we insert elements to the right of equal elements, not changing their order.
    "},{"location":"chapter_sorting/insertion_sort/#1143-advantages-of-insertion-sort","title":"11.4.3 \u00a0 Advantages of insertion sort","text":"

    The time complexity of insertion sort is \\(O(n^2)\\), while the time complexity of quicksort, which we will study next, is \\(O(n \\log n)\\). Although insertion sort has a higher time complexity, it is usually faster in cases of small data volumes.

    This conclusion is similar to that for linear and binary search. Algorithms like quicksort that have a time complexity of \\(O(n \\log n)\\) and are based on the divide-and-conquer strategy often involve more unit operations. In cases of small data volumes, the numerical values of \\(n^2\\) and \\(n \\log n\\) are close, and complexity does not dominate, with the number of unit operations per round playing a decisive role.

    In fact, many programming languages (such as Java) use insertion sort in their built-in sorting functions. The general approach is: for long arrays, use sorting algorithms based on divide-and-conquer strategies, such as quicksort; for short arrays, use insertion sort directly.

    Although bubble sort, selection sort, and insertion sort all have a time complexity of \\(O(n^2)\\), in practice, insertion sort is used significantly more frequently than bubble sort and selection sort, mainly for the following reasons.

    • Bubble sort is based on element swapping, which requires the use of a temporary variable, involving 3 unit operations; insertion sort is based on element assignment, requiring only 1 unit operation. Therefore, the computational overhead of bubble sort is generally higher than that of insertion sort.
    • The time complexity of selection sort is always \\(O(n^2)\\). Given a set of partially ordered data, insertion sort is usually more efficient than selection sort.
    • Selection sort is unstable and cannot be applied to multi-level sorting.
    "},{"location":"chapter_sorting/merge_sort/","title":"11.6 \u00a0 Merge sort","text":"

    Merge sort is a sorting algorithm based on the divide-and-conquer strategy, involving the \"divide\" and \"merge\" phases shown in the following figure.

    1. Divide phase: Recursively split the array from the midpoint, transforming the sorting problem of a long array into that of shorter arrays.
    2. Merge phase: Stop dividing when the length of the sub-array is 1, start merging, and continuously combine two shorter ordered arrays into one longer ordered array until the process is complete.

    Figure 11-10 \u00a0 The divide and merge phases of merge sort

    "},{"location":"chapter_sorting/merge_sort/#1161-algorithm-workflow","title":"11.6.1 \u00a0 Algorithm workflow","text":"

    As shown in the Figure 11-11 , the \"divide phase\" recursively splits the array from the midpoint into two sub-arrays from top to bottom.

    1. Calculate the midpoint mid, recursively divide the left sub-array (interval [left, mid]) and the right sub-array (interval [mid + 1, right]).
    2. Continue with step 1. recursively until the sub-array interval length is 1 to stop.

    The \"merge phase\" combines the left and right sub-arrays into a single ordered array from bottom to top. Note that merging starts with sub-arrays of length 1, and each sub-array is ordered during the merge phase.

    <1><2><3><4><5><6><7><8><9><10>

    Figure 11-11 \u00a0 Merge sort process

    It is observed that the order of recursion in merge sort is consistent with the post-order traversal of a binary tree.

    • Post-order traversal: First recursively traverse the left subtree, then the right subtree, and finally handle the root node.
    • Merge sort: First recursively handle the left sub-array, then the right sub-array, and finally perform the merge.

    The implementation of merge sort is shown in the following code. Note that the interval to be merged in nums is [left, right], while the corresponding interval in tmp is [0, right - left].

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig merge_sort.py
    def merge(nums: list[int], left: int, mid: int, right: int):\n    \"\"\"\u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\"\"\"\n    # \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    # \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    tmp = [0] * (right - left + 1)\n    # \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    i, j, k = left, mid + 1, 0\n    # \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid and j <= right:\n        if nums[i] <= nums[j]:\n            tmp[k] = nums[i]\n            i += 1\n        else:\n            tmp[k] = nums[j]\n            j += 1\n        k += 1\n    # \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid:\n        tmp[k] = nums[i]\n        i += 1\n        k += 1\n    while j <= right:\n        tmp[k] = nums[j]\n        j += 1\n        k += 1\n    # \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in range(0, len(tmp)):\n        nums[left + k] = tmp[k]\n\ndef merge_sort(nums: list[int], left: int, right: int):\n    \"\"\"\u5f52\u5e76\u6392\u5e8f\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if left >= right:\n        return  # \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    # \u5212\u5206\u9636\u6bb5\n    mid = (left + right) // 2  # \u8ba1\u7b97\u4e2d\u70b9\n    merge_sort(nums, left, mid)  # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    merge_sort(nums, mid + 1, right)  # \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    # \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n
    merge_sort.cpp
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(vector<int> &nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    vector<int> tmp(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.size(); k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(vector<int> &nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.java
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(int[] nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int[] tmp = new int[right - left + 1];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(int[] nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2; // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.cs
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid Merge(int[] nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int[] tmp = new int[right - left + 1];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.Length; ++k) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid MergeSort(int[] nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return;       // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    MergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    MergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    Merge(nums, left, mid, right);\n}\n
    merge_sort.go
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunc merge(nums []int, left, mid, right int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    tmp := make([]int, right-left+1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    i, j, k := left, mid+1, 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    for i <= mid && j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i]\n            i++\n        } else {\n            tmp[k] = nums[j]\n            j++\n        }\n        k++\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    for i <= mid {\n        tmp[k] = nums[i]\n        i++\n        k++\n    }\n    for j <= right {\n        tmp[k] = nums[j]\n        j++\n        k++\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k := 0; k < len(tmp); k++ {\n        nums[left+k] = tmp[k]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunc mergeSort(nums []int, left, right int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right {\n        return\n    }\n    // \u5212\u5206\u9636\u6bb5\n    mid := (left + right) / 2\n    mergeSort(nums, left, mid)\n    mergeSort(nums, mid+1, right)\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n}\n
    merge_sort.swift
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunc merge(nums: inout [Int], left: Int, mid: Int, right: Int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    var tmp = Array(repeating: 0, count: right - left + 1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    var i = left, j = mid + 1, k = 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid, j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i]\n            i += 1\n        } else {\n            tmp[k] = nums[j]\n            j += 1\n        }\n        k += 1\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid {\n        tmp[k] = nums[i]\n        i += 1\n        k += 1\n    }\n    while j <= right {\n        tmp[k] = nums[j]\n        j += 1\n        k += 1\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in tmp.indices {\n        nums[left + k] = tmp[k]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunc mergeSort(nums: inout [Int], left: Int, right: Int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right { // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n        return\n    }\n    // \u5212\u5206\u9636\u6bb5\n    let mid = (left + right) / 2 // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums: &nums, left: left, right: mid) // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums: &nums, left: mid + 1, right: right) // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums: &nums, left: left, mid: mid, right: right)\n}\n
    merge_sort.js
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunction merge(nums, left, mid, right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    const tmp = new Array(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let i = left,\n        j = mid + 1,\n        k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunction mergeSort(nums, left, right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    let mid = Math.floor((left + right) / 2); // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.ts
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunction merge(nums: number[], left: number, mid: number, right: number): void {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    const tmp = new Array(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let i = left,\n        j = mid + 1,\n        k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunction mergeSort(nums: number[], left: number, right: number): void {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    let mid = Math.floor((left + right) / 2); // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.dart
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(List<int> nums, int left, int mid, int right) {\n  // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n  // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n  List<int> tmp = List.filled(right - left + 1, 0);\n  // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n  int i = left, j = mid + 1, k = 0;\n  // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while (i <= mid && j <= right) {\n    if (nums[i] <= nums[j])\n      tmp[k++] = nums[i++];\n    else\n      tmp[k++] = nums[j++];\n  }\n  // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while (i <= mid) {\n    tmp[k++] = nums[i++];\n  }\n  while (j <= right) {\n    tmp[k++] = nums[j++];\n  }\n  // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n  for (k = 0; k < tmp.length; k++) {\n    nums[left + k] = tmp[k];\n  }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(List<int> nums, int left, int right) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  // \u5212\u5206\u9636\u6bb5\n  int mid = (left + right) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\n  mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n  mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n  // \u5408\u5e76\u9636\u6bb5\n  merge(nums, left, mid, right);\n}\n
    merge_sort.rs
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfn merge(nums: &mut [i32], left: usize, mid: usize, right: usize) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    let tmp_size = right - left + 1;\n    let mut tmp = vec![0; tmp_size];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let (mut i, mut j, mut k) = (left, mid + 1, 0);\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid && j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i];\n            i += 1;\n        } else {\n            tmp[k] = nums[j];\n            j += 1;\n        }\n        k += 1;\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid {\n        tmp[k] = nums[i];\n        k += 1;\n        i += 1;\n    }\n    while j <= right {\n        tmp[k] = nums[j];\n        k += 1;\n        j += 1;\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in 0..tmp_size {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfn merge_sort(nums: &mut [i32], left: usize, right: usize) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right {\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    }\n\n    // \u5212\u5206\u9636\u6bb5\n    let mid = (left + right) / 2; // \u8ba1\u7b97\u4e2d\u70b9\n    merge_sort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    merge_sort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.c
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(int *nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int tmpSize = right - left + 1;\n    int *tmp = (int *)malloc(tmpSize * sizeof(int));\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmpSize; ++k) {\n        nums[left + k] = tmp[k];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(int *nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.kt
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfun merge(nums: IntArray, left: Int, mid: Int, right: Int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    val tmp = IntArray(right - left + 1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    var i = left\n    var j = mid + 1\n    var k = 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++]\n        else \n            tmp[k++] = nums[j++]\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++]\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++]\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (l in tmp.indices) {\n        nums[left + l] = tmp[l]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfun mergeSort(nums: IntArray, left: Int, right: Int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return  // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    val mid = (left + right) / 2 // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid) // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right) // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n}\n
    merge_sort.rb
    ### \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 ###\ndef merge(nums, left, mid, right)\n  # \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n  # \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp\uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n  tmp = Array.new(right - left + 1, 0)\n  # \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n  i, j, k = left, mid + 1, 0\n  # \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while i <= mid && j <= right\n    if nums[i] <= nums[j]\n      tmp[k] = nums[i]\n      i += 1\n    else\n      tmp[k] = nums[j]\n      j += 1\n    end\n    k += 1\n  end\n  # \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while i <= mid\n    tmp[k] = nums[i]\n    i += 1\n    k += 1\n  end\n  while j <= right\n    tmp[k] = nums[j]\n    j += 1\n    k += 1\n  end\n  # \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n  (0...tmp.length).each do |k|\n    nums[left + k] = tmp[k]\n  end\nend\n\n### \u5f52\u5e76\u6392\u5e8f ###\ndef merge_sort(nums, left, right)\n  # \u7ec8\u6b62\u6761\u4ef6\n  # \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  return if left >= right\n  # \u5212\u5206\u9636\u6bb5\n  mid = (left + right) / 2 # \u8ba1\u7b97\u4e2d\u70b9\n  merge_sort(nums, left, mid) # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n  merge_sort(nums, mid + 1, right) # \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n  # \u5408\u5e76\u9636\u6bb5\n  merge(nums, left, mid, right)\nend\n
    merge_sort.zig
    // \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\n// \u5de6\u5b50\u6570\u7ec4\u533a\u95f4 [left, mid]\n// \u53f3\u5b50\u6570\u7ec4\u533a\u95f4 [mid + 1, right]\nfn merge(nums: []i32, left: usize, mid: usize, right: usize) !void {\n    // \u521d\u59cb\u5316\u8f85\u52a9\u6570\u7ec4\n    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);\n    defer mem_arena.deinit();\n    const mem_allocator = mem_arena.allocator();\n    var tmp = try mem_allocator.alloc(i32, right + 1 - left);\n    std.mem.copy(i32, tmp, nums[left..right+1]);\n    // \u5de6\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\u548c\u7ed3\u675f\u7d22\u5f15  \n    var leftStart = left - left;\n    var leftEnd = mid - left;\n    // \u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\u548c\u7ed3\u675f\u7d22\u5f15       \n    var rightStart = mid + 1 - left;\n    var rightEnd = right - left;\n    // i, j \u5206\u522b\u6307\u5411\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\u7684\u9996\u5143\u7d20\n    var i = leftStart;\n    var j = rightStart;\n    // \u901a\u8fc7\u8986\u76d6\u539f\u6570\u7ec4 nums \u6765\u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\n    var k = left;\n    while (k <= right) : (k += 1) {\n        // \u82e5\u201c\u5de6\u5b50\u6570\u7ec4\u5df2\u5168\u90e8\u5408\u5e76\u5b8c\u201d\uff0c\u5219\u9009\u53d6\u53f3\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 j++\n        if (i > leftEnd) {\n            nums[k] = tmp[j];\n            j += 1;\n        // \u5426\u5219\uff0c\u82e5\u201c\u53f3\u5b50\u6570\u7ec4\u5df2\u5168\u90e8\u5408\u5e76\u5b8c\u201d\u6216\u201c\u5de6\u5b50\u6570\u7ec4\u5143\u7d20 <= \u53f3\u5b50\u6570\u7ec4\u5143\u7d20\u201d\uff0c\u5219\u9009\u53d6\u5de6\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 i++\n        } else if  (j > rightEnd or tmp[i] <= tmp[j]) {\n            nums[k] = tmp[i];\n            i += 1;\n        // \u5426\u5219\uff0c\u82e5\u201c\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u672a\u5168\u90e8\u5408\u5e76\u5b8c\u201d\u4e14\u201c\u5de6\u5b50\u6570\u7ec4\u5143\u7d20 > \u53f3\u5b50\u6570\u7ec4\u5143\u7d20\u201d\uff0c\u5219\u9009\u53d6\u53f3\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 j++\n        } else {\n            nums[k] = tmp[j];\n            j += 1;\n        }\n    }\n}\n\n// \u5f52\u5e76\u6392\u5e8f\nfn mergeSort(nums: []i32, left: usize, right: usize) !void {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return;              // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    var mid = (left + right) / 2;           // \u8ba1\u7b97\u4e2d\u70b9\n    try mergeSort(nums, left, mid);         // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    try mergeSort(nums, mid + 1, right);    // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    try merge(nums, left, mid, right);\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/merge_sort/#1162-algorithm-characteristics","title":"11.6.2 \u00a0 Algorithm characteristics","text":"
    • Time complexity of \\(O(n \\log n)\\), non-adaptive sort: The division creates a recursion tree of height \\(\\log n\\), with each layer merging a total of \\(n\\) operations, resulting in an overall time complexity of \\(O(n \\log n)\\).
    • Space complexity of \\(O(n)\\), non-in-place sort: The recursion depth is \\(\\log n\\), using \\(O(\\log n)\\) stack frame space. The merging operation requires auxiliary arrays, using an additional space of \\(O(n)\\).
    • Stable sort: During the merging process, the order of equal elements remains unchanged.
    "},{"location":"chapter_sorting/merge_sort/#1163-linked-list-sorting","title":"11.6.3 \u00a0 Linked List sorting","text":"

    For linked lists, merge sort has significant advantages over other sorting algorithms, optimizing the space complexity of the linked list sorting task to \\(O(1)\\).

    • Divide phase: \"Iteration\" can be used instead of \"recursion\" to perform the linked list division work, thus saving the stack frame space used by recursion.
    • Merge phase: In linked lists, node addition and deletion operations can be achieved by changing references (pointers), so no extra lists need to be created during the merge phase (combining two short ordered lists into one long ordered list).

    Detailed implementation details are complex, and interested readers can consult related materials for learning.

    "},{"location":"chapter_sorting/quick_sort/","title":"11.5 \u00a0 Quick sort","text":"

    Quick sort is a sorting algorithm based on the divide and conquer strategy, known for its efficiency and wide application.

    The core operation of quick sort is \"pivot partitioning,\" aiming to: select an element from the array as the \"pivot,\" move all elements smaller than the pivot to its left, and move elements greater than the pivot to its right. Specifically, the pivot partitioning process is illustrated as follows.

    1. Select the leftmost element of the array as the pivot, and initialize two pointers i and j at both ends of the array.
    2. Set up a loop where each round uses i (j) to find the first element larger (smaller) than the pivot, then swap these two elements.
    3. Repeat step 2. until i and j meet, finally swap the pivot to the boundary between the two sub-arrays.
    <1><2><3><4><5><6><7><8><9>

    Figure 11-8 \u00a0 Pivot division process

    After the pivot partitioning, the original array is divided into three parts: left sub-array, pivot, and right sub-array, satisfying \"any element in the left sub-array \\(\\leq\\) pivot \\(\\leq\\) any element in the right sub-array.\" Therefore, we only need to sort these two sub-arrays next.

    Quick sort's divide and conquer strategy

    The essence of pivot partitioning is to simplify a longer array's sorting problem into two shorter arrays' sorting problems.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def partition(self, nums: list[int], left: int, right: int) -> int:\n    \"\"\"\u54e8\u5175\u5212\u5206\"\"\"\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j = left, right\n    while i < j:\n        while i < j and nums[j] >= nums[left]:\n            j -= 1  # \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while i < j and nums[i] <= nums[left]:\n            i += 1  # \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        # \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    # \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i  # \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n
    quick_sort.cpp
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(vector<int> &nums, int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(vector<int> &nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.java
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(int[] nums, int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(int[] nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.cs
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid Swap(int[] nums, int i, int j) {\n    (nums[j], nums[i]) = (nums[i], nums[j]);\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint Partition(int[] nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        Swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    Swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.go
    /* \u54e8\u5175\u5212\u5206 */\nfunc (q *quickSort) partition(nums []int, left, right int) int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j := left, right\n    for i < j {\n        for i < j && nums[j] >= nums[left] {\n            j-- // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        for i < j && nums[i] <= nums[left] {\n            i++ // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    }\n    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.swift
    /* \u54e8\u5175\u5212\u5206 */\nfunc partition(nums: inout [Int], left: Int, right: Int) -> Int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while i < j {\n        while i < j, nums[j] >= nums[left] {\n            j -= 1 // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j, nums[i] <= nums[left] {\n            i += 1 // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swapAt(i, j) // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swapAt(i, left) // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.js
    /* \u5143\u7d20\u4ea4\u6362 */\nswap(nums, i, j) {\n    let tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\npartition(nums, left, right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.ts
    /* \u5143\u7d20\u4ea4\u6362 */\nswap(nums: number[], i: number, j: number): void {\n    let tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\npartition(nums: number[], left: number, right: number): number {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.dart
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid _swap(List<int> nums, int i, int j) {\n  int tmp = nums[i];\n  nums[i] = nums[j];\n  nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint _partition(List<int> nums, int left, int right) {\n  // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n  int i = left, j = right;\n  while (i < j) {\n    while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    _swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n  }\n  _swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n  return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rs
    /* \u54e8\u5175\u5212\u5206 */\nfn partition(nums: &mut [i32], left: usize, right: usize) -> usize {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let (mut i, mut j) = (left, right);\n    while i < j {\n        while i < j && nums[j] >= nums[left] {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j && nums[i] <= nums[left] {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swap(i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swap(i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.c
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(int nums[], int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(int nums[], int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n        swap(nums, i, j);\n    }\n    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    swap(nums, i, left);\n    // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n    return i;\n}\n
    quick_sort.kt
    /* \u5143\u7d20\u4ea4\u6362 */\nfun swap(nums: IntArray, i: Int, j: Int) {\n    val temp = nums[i]\n    nums[i] = nums[j]\n    nums[j] = temp\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nfun partition(nums: IntArray, left: Int, right: Int): Int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--           // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++           // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j)  // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left)   // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i              // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rb
    [class]{QuickSort}-[func]{partition}\n
    quick_sort.zig
    // \u5143\u7d20\u4ea4\u6362\nfn swap(nums: []i32, i: usize, j: usize) void {\n    var tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n// \u54e8\u5175\u5212\u5206\nfn partition(nums: []i32, left: usize, right: usize) usize {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left;\n    var j = right;\n    while (i < j) {\n        while (i < j and nums[j] >= nums[left]) j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j and nums[i] <= nums[left]) i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j);   // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;               // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/quick_sort/#1151-algorithm-process","title":"11.5.1 \u00a0 Algorithm process","text":"

    The overall process of quick sort is shown in the following figure.

    1. First, perform a \"pivot partitioning\" on the original array to obtain the unsorted left and right sub-arrays.
    2. Then, recursively perform \"pivot partitioning\" on both the left and right sub-arrays.
    3. Continue recursively until the sub-array length reaches 1, thus completing the sorting of the entire array.

    Figure 11-9 \u00a0 Quick sort process

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):\n    \"\"\"\u5feb\u901f\u6392\u5e8f\"\"\"\n    # \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right:\n        return\n    # \u54e8\u5175\u5212\u5206\n    pivot = self.partition(nums, left, right)\n    # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    self.quick_sort(nums, left, pivot - 1)\n    self.quick_sort(nums, pivot + 1, right)\n
    quick_sort.cpp
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(vector<int> &nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.java
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.cs
    /* \u5feb\u901f\u6392\u5e8f */\nvoid QuickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = Partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    QuickSort(nums, left, pivot - 1);\n    QuickSort(nums, pivot + 1, right);\n}\n
    quick_sort.go
    /* \u5feb\u901f\u6392\u5e8f */\nfunc (q *quickSort) quickSort(nums []int, left, right int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return\n    }\n    // \u54e8\u5175\u5212\u5206\n    pivot := q.partition(nums, left, right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    q.quickSort(nums, left, pivot-1)\n    q.quickSort(nums, pivot+1, right)\n}\n
    quick_sort.swift
    /* \u5feb\u901f\u6392\u5e8f */\nfunc quickSort(nums: inout [Int], left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return\n    }\n    // \u54e8\u5175\u5212\u5206\n    let pivot = partition(nums: &nums, left: left, right: right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums: &nums, left: left, right: pivot - 1)\n    quickSort(nums: &nums, left: pivot + 1, right: right)\n}\n
    quick_sort.js
    /* \u5feb\u901f\u6392\u5e8f */\nquickSort(nums, left, right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return;\n    // \u54e8\u5175\u5212\u5206\n    const pivot = this.partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    this.quickSort(nums, left, pivot - 1);\n    this.quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.ts
    /* \u5feb\u901f\u6392\u5e8f */\nquickSort(nums: number[], left: number, right: number): void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    const pivot = this.partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    this.quickSort(nums, left, pivot - 1);\n    this.quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.dart
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(List<int> nums, int left, int right) {\n  // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  if (left >= right) return;\n  // \u54e8\u5175\u5212\u5206\n  int pivot = _partition(nums, left, right);\n  // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n  quickSort(nums, left, pivot - 1);\n  quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.rs
    /* \u5feb\u901f\u6392\u5e8f */\npub fn quick_sort(left: i32, right: i32, nums: &mut [i32]) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    let pivot = Self::partition(nums, left as usize, right as usize) as i32;\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    Self::quick_sort(left, pivot - 1, nums);\n    Self::quick_sort(pivot + 1, right, nums);\n}\n
    quick_sort.c
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(int nums[], int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.kt
    /* \u5feb\u901f\u6392\u5e8f */\nfun quickSort(nums: IntArray, left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return\n    // \u54e8\u5175\u5212\u5206\n    val pivot = partition(nums, left, right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1)\n    quickSort(nums, pivot + 1, right)\n}\n
    quick_sort.rb
    [class]{QuickSort}-[func]{quick_sort}\n
    quick_sort.zig
    // \u5feb\u901f\u6392\u5e8f\nfn quickSort(nums: []i32, left: usize, right: usize) void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return;\n    // \u54e8\u5175\u5212\u5206\n    var pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/quick_sort/#1152-algorithm-features","title":"11.5.2 \u00a0 Algorithm features","text":"
    • Time complexity of \\(O(n \\log n)\\), adaptive sorting: In average cases, the recursive levels of pivot partitioning are \\(\\log n\\), and the total number of loops per level is \\(n\\), using \\(O(n \\log n)\\) time overall. In the worst case, each round of pivot partitioning divides an array of length \\(n\\) into two sub-arrays of lengths \\(0\\) and \\(n - 1\\), reaching \\(n\\) recursive levels, and using \\(O(n^2)\\) time overall.
    • Space complexity of \\(O(n)\\), in-place sorting: In completely reversed input arrays, reaching the worst recursion depth of \\(n\\), using \\(O(n)\\) stack frame space. The sorting operation is performed on the original array without the aid of additional arrays.
    • Non-stable sorting: In the final step of pivot partitioning, the pivot may be swapped to the right of equal elements.
    "},{"location":"chapter_sorting/quick_sort/#1153-why-is-quick-sort-fast","title":"11.5.3 \u00a0 Why is quick sort fast","text":"

    From its name, it is apparent that quick sort should have certain efficiency advantages. Although the average time complexity of quick sort is the same as \"merge sort\" and \"heap sort,\" quick sort is generally more efficient, mainly for the following reasons.

    • Low probability of worst-case scenarios: Although the worst time complexity of quick sort is \\(O(n^2)\\), less stable than merge sort, in most cases, quick sort can operate under a time complexity of \\(O(n \\log n)\\).
    • High cache usage efficiency: During the pivot partitioning operation, the system can load the entire sub-array into the cache, thus accessing elements more efficiently. In contrast, algorithms like \"heap sort\" need to access elements in a jumping manner, lacking this feature.
    • Small constant coefficient of complexity: Among the mentioned algorithms, quick sort has the fewest total number of comparisons, assignments, and swaps. This is similar to why \"insertion sort\" is faster than \"bubble sort.\"
    "},{"location":"chapter_sorting/quick_sort/#1154-pivot-optimization","title":"11.5.4 \u00a0 Pivot optimization","text":"

    Quick sort's time efficiency may decrease under certain inputs. For example, if the input array is completely reversed, since we select the leftmost element as the pivot, after the pivot partitioning, the pivot is swapped to the array's right end, causing the left sub-array length to be \\(n - 1\\) and the right sub-array length to be \\(0\\). If this recursion continues, each round of pivot partitioning will have a sub-array length of \\(0\\), and the divide and conquer strategy fails, degrading quick sort to a form similar to \"bubble sort.\"

    To avoid this situation, we can optimize the strategy for selecting the pivot in the pivot partitioning. For instance, we can randomly select an element as the pivot. However, if luck is not on our side, and we keep selecting suboptimal pivots, the efficiency is still not satisfactory.

    It's important to note that programming languages usually generate \"pseudo-random numbers\". If we construct a specific test case for a pseudo-random number sequence, the efficiency of quick sort may still degrade.

    For further improvement, we can select three candidate elements (usually the first, last, and midpoint elements of the array), and use the median of these three candidate elements as the pivot. This significantly increases the probability that the pivot is \"neither too small nor too large\". Of course, we can also select more candidate elements to further enhance the algorithm's robustness. Using this method significantly reduces the probability of time complexity degradation to \\(O(n^2)\\).

    Sample code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:\n    \"\"\"\u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\"\"\"\n    l, m, r = nums[left], nums[mid], nums[right]\n    if (l <= m <= r) or (r <= m <= l):\n        return mid  # m \u5728 l \u548c r \u4e4b\u95f4\n    if (m <= l <= r) or (r <= l <= m):\n        return left  # l \u5728 m \u548c r \u4e4b\u95f4\n    return right\n\ndef partition(self, nums: list[int], left: int, right: int) -> int:\n    \"\"\"\u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09\"\"\"\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    med = self.median_three(nums, left, (left + right) // 2, right)\n    # \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums[left], nums[med] = nums[med], nums[left]\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j = left, right\n    while i < j:\n        while i < j and nums[j] >= nums[left]:\n            j -= 1  # \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while i < j and nums[i] <= nums[left]:\n            i += 1  # \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        # \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    # \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i  # \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n
    quick_sort.cpp
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(vector<int> &nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partition(vector<int> &nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.java
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(int[] nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partition(int[] nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.cs
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint MedianThree(int[] nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint Partition(int[] nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = MedianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    Swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        Swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    Swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.go
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfunc (q *quickSortMedian) medianThree(nums []int, left, mid, right int) int {\n    l, m, r := nums[left], nums[mid], nums[right]\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09*/\nfunc (q *quickSortMedian) partition(nums []int, left, right int) int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    med := q.medianThree(nums, left, (left+right)/2, right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums[left], nums[med] = nums[med], nums[left]\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j := left, right\n    for i < j {\n        for i < j && nums[j] >= nums[left] {\n            j-- //\u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        for i < j && nums[i] <= nums[left] {\n            i++ //\u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        //\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    }\n    //\u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i //\u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.swift
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfunc medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {\n    let l = nums[left]\n    let m = nums[mid]\n    let r = nums[right]\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfunc partitionMedian(nums: inout [Int], left: Int, right: Int) -> Int {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums.swapAt(left, med)\n    return partition(nums: &nums, left: left, right: right)\n}\n
    quick_sort.js
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nmedianThree(nums, left, mid, right) {\n    let l = nums[left],\n        m = nums[mid],\n        r = nums[right];\n    // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;\n    // l \u5728 m \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\npartition(nums, left, right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = this.medianThree(\n        nums,\n        left,\n        Math.floor((left + right) / 2),\n        right\n    );\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    this.swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.ts
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nmedianThree(\n    nums: number[],\n    left: number,\n    mid: number,\n    right: number\n): number {\n    let l = nums[left],\n        m = nums[mid],\n        r = nums[right];\n    // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;\n    // l \u5728 m \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\npartition(nums: number[], left: number, right: number): number {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = this.medianThree(\n        nums,\n        left,\n        Math.floor((left + right) / 2),\n        right\n    );\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    this.swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.dart
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint _medianThree(List<int> nums, int left, int mid, int right) {\n  int l = nums[left], m = nums[mid], r = nums[right];\n  if ((l <= m && m <= r) || (r <= m && m <= l))\n    return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n  if ((m <= l && l <= r) || (r <= l && l <= m))\n    return left; // l \u5728 m \u548c r \u4e4b\u95f4\n  return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint _partition(List<int> nums, int left, int right) {\n  // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n  int med = _medianThree(nums, left, (left + right) ~/ 2, right);\n  // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n  _swap(nums, left, med);\n  // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n  int i = left, j = right;\n  while (i < j) {\n    while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    _swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n  }\n  _swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n  return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rs
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfn median_three(nums: &mut [i32], left: usize, mid: usize, right: usize) -> usize {\n    let (l, m, r) = (nums[left], nums[mid], nums[right]);\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfn partition(nums: &mut [i32], left: usize, right: usize) -> usize {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = Self::median_three(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums.swap(left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let (mut i, mut j) = (left, right);\n    while i < j {\n        while i < j && nums[j] >= nums[left] {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j && nums[i] <= nums[left] {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swap(i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swap(i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.c
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(int nums[], int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partitionMedian(int nums[], int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.kt
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfun medianThree(nums: IntArray, left: Int, mid: Int, right: Int): Int {\n    val l = nums[left]\n    val m = nums[mid]\n    val r = nums[right]\n    if ((m in l..r) || (m in r..l))\n        return mid  // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l in m..r) || (l in r..m))\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfun partitionMedian(nums: IntArray, left: Int, right: Int): Int {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    val med = medianThree(nums, left, (left + right) / 2, right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med)\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--                      // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++                      // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j)             // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left)              // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i                         // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rb
    [class]{QuickSortMedian}-[func]{median_three}\n\n[class]{QuickSortMedian}-[func]{partition}\n
    quick_sort.zig
    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\nfn medianThree(nums: []i32, left: usize, mid: usize, right: usize) usize {\n    var l = nums[left];\n    var m = nums[mid];\n    var r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n// \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09\nfn partition(nums: []i32, left: usize, right: usize) usize {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    var med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left;\n    var j = right;\n    while (i < j) {\n        while (i < j and nums[j] >= nums[left]) j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j and nums[i] <= nums[left]) i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j);   // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;               // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/quick_sort/#1155-tail-recursion-optimization","title":"11.5.5 \u00a0 Tail recursion optimization","text":"

    Under certain inputs, quick sort may occupy more space. For a completely ordered input array, assume the sub-array length in recursion is \\(m\\), each round of pivot partitioning produces a left sub-array of length \\(0\\) and a right sub-array of length \\(m - 1\\), meaning the problem size reduced per recursive call is very small (only one element), and the height of the recursion tree can reach \\(n - 1\\), requiring \\(O(n)\\) stack frame space.

    To prevent the accumulation of stack frame space, we can compare the lengths of the two sub-arrays after each round of pivot sorting, and only recursively sort the shorter sub-array. Since the length of the shorter sub-array will not exceed \\(n / 2\\), this method ensures that the recursion depth does not exceed \\(\\log n\\), thus optimizing the worst space complexity to \\(O(\\log n)\\). The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):\n    \"\"\"\u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09\"\"\"\n    # \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right:\n        # \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        pivot = self.partition(nums, left, right)\n        # \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot - left < right - pivot:\n            self.quick_sort(nums, left, pivot - 1)  # \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1  # \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        else:\n            self.quick_sort(nums, pivot + 1, right)  # \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1  # \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n
    quick_sort.cpp
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(vector<int> &nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1;                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.java
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.cs
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid QuickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = Partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            QuickSort(nums, left, pivot - 1);  // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;  // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            QuickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.go
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09*/\nfunc (q *quickSortTailCall) quickSort(nums []int, left, right int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    for left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        pivot := q.partition(nums, left, right)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot-left < right-pivot {\n            q.quickSort(nums, left, pivot-1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            q.quickSort(nums, pivot+1, right) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.swift
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nfunc quickSortTailCall(nums: inout [Int], left: Int, right: Int) {\n    var left = left\n    var right = right\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = partition(nums: &nums, left: left, right: right)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left) < (right - pivot) {\n            quickSortTailCall(nums: &nums, left: left, right: pivot - 1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSortTailCall(nums: &nums, left: pivot + 1, right: right) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.js
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nquickSort(nums, left, right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = this.partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            this.quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            this.quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.ts
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nquickSort(nums: number[], left: number, right: number): void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = this.partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            this.quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            this.quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.dart
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(List<int> nums, int left, int right) {\n  // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n  while (left < right) {\n    // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n    int pivot = _partition(nums, left, right);\n    // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n    if (pivot - left < right - pivot) {\n      quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n      left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n    } else {\n      quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n      right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n    }\n  }\n}\n
    quick_sort.rs
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\npub fn quick_sort(mut left: i32, mut right: i32, nums: &mut [i32]) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = Self::partition(nums, left as usize, right as usize) as i32;\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot - left < right - pivot {\n            Self::quick_sort(left, pivot - 1, nums); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            Self::quick_sort(pivot + 1, right, nums); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.c
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSortTailCall(int nums[], int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            quickSortTailCall(nums, left, pivot - 1);\n            // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n            left = pivot + 1;\n        } else {\n            // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            quickSortTailCall(nums, pivot + 1, right);\n            // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n            right = pivot - 1;\n        }\n    }\n}\n
    quick_sort.kt
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nfun quickSortTailCall(nums: IntArray, left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    var l = left\n    var r = right\n    while (l < r) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        val pivot = partition(nums, l, r)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - l < r - pivot) {\n            quickSort(nums, l, pivot - 1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            l = pivot + 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, r) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            r = pivot - 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.rb
    [class]{QuickSortTailCall}-[func]{quick_sort}\n
    quick_sort.zig
    // \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09\nfn quickSort(nums: []i32, left_: usize, right_: usize) void {\n    var left = left_;\n    var right = right_;\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        var pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1);   // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;                   // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right);  // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1;                  // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/radix_sort/","title":"11.10 \u00a0 Radix sort","text":"

    The previous section introduced counting sort, which is suitable for scenarios where the data volume \\(n\\) is large but the data range \\(m\\) is small. Suppose we need to sort \\(n = 10^6\\) student IDs, where each ID is an \\(8\\)-digit number. This means the data range \\(m = 10^8\\) is very large, requiring a significant amount of memory space for counting sort, while radix sort can avoid this situation.

    Radix sort shares the core idea with counting sort, which also sorts by counting the frequency of elements. Building on this, radix sort utilizes the progressive relationship between the digits of numbers, sorting each digit in turn to achieve the final sorted order.

    "},{"location":"chapter_sorting/radix_sort/#11101-algorithm-process","title":"11.10.1 \u00a0 Algorithm process","text":"

    Taking the student ID data as an example, assuming the least significant digit is the \\(1^{st}\\) and the most significant is the \\(8^{th}\\), the radix sort process is illustrated in the following diagram.

    1. Initialize digit \\(k = 1\\).
    2. Perform \"counting sort\" on the \\(k^{th}\\) digit of the student IDs. After completion, the data will be sorted from smallest to largest based on the \\(k^{th}\\) digit.
    3. Increment \\(k\\) by \\(1\\), then return to step 2. and continue iterating until all digits have been sorted, then the process ends.

    Figure 11-18 \u00a0 Radix sort algorithm process

    Below we dissect the code implementation. For a number \\(x\\) in base \\(d\\), to obtain its \\(k^{th}\\) digit \\(x_k\\), the following calculation formula can be used:

    \\[ x_k = \\lfloor\\frac{x}{d^{k-1}}\\rfloor \\bmod d \\]

    Where \\(\\lfloor a \\rfloor\\) denotes rounding down the floating point number \\(a\\), and \\(\\bmod \\: d\\) denotes taking the modulus of \\(d\\). For student ID data, \\(d = 10\\) and \\(k \\in [1, 8]\\).

    Additionally, we need to slightly modify the counting sort code to allow sorting based on the \\(k^{th}\\) digit:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig radix_sort.py
    def digit(num: int, exp: int) -> int:\n    \"\"\"\u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1)\"\"\"\n    # \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num // exp) % 10\n\ndef counting_sort_digit(nums: list[int], exp: int):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09\"\"\"\n    # \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    counter = [0] * 10\n    n = len(nums)\n    # \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in range(n):\n        d = digit(nums[i], exp)  # \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1  # \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    # \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in range(1, 10):\n        counter[i] += counter[i - 1]\n    # \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    res = [0] * n\n    for i in range(n - 1, -1, -1):\n        d = digit(nums[i], exp)\n        j = counter[d] - 1  # \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]  # \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1  # \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    # \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in range(n):\n        nums[i] = res[i]\n\ndef radix_sort(nums: list[int]):\n    \"\"\"\u57fa\u6570\u6392\u5e8f\"\"\"\n    # \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    m = max(nums)\n    # \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    exp = 1\n    while exp <= m:\n        # \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        # k = 1 -> exp = 1\n        # k = 2 -> exp = 10\n        # \u5373 exp = 10^(k-1)\n        counting_sort_digit(nums, exp)\n        exp *= 10\n
    radix_sort.cpp
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(vector<int> &nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    vector<int> counter(10, 0);\n    int n = nums.size();\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    vector<int> res(n, 0);\n    for (int i = n - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++)\n        nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(vector<int> &nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = *max_element(nums.begin(), nums.end());\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10)\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n}\n
    radix_sort.java
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(int[] nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int[] counter = new int[10];\n    int n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++)\n        nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(int[] nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = Integer.MIN_VALUE;\n    for (int num : nums)\n        if (num > m)\n            m = num;\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.cs
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint Digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid CountingSortDigit(int[] nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int[] counter = new int[10];\n    int n = nums.Length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = Digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int d = Digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid RadixSort(int[] nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = int.MinValue;\n    foreach (int num in nums) {\n        if (num > m) m = num;\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        CountingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.go
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunc digit(num, exp int) int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunc countingSortDigit(nums []int, exp int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    counter := make([]int, 10)\n    n := len(nums)\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i := 0; i < n; i++ {\n        d := digit(nums[i], exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++             // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i := 1; i < 10; i++ {\n        counter[i] += counter[i-1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    res := make([]int, n)\n    for i := n - 1; i >= 0; i-- {\n        d := digit(nums[i], exp)\n        j := counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]    // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--        // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i := 0; i < n; i++ {\n        nums[i] = res[i]\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunc radixSort(nums []int) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    max := math.MinInt\n    for _, num := range nums {\n        if num > max {\n            max = num\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for exp := 1; max >= exp; exp *= 10 {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp)\n    }\n}\n
    radix_sort.swift
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunc digit(num: Int, exp: Int) -> Int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunc countingSortDigit(nums: inout [Int], exp: Int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    var counter = Array(repeating: 0, count: 10)\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in nums.indices {\n        let d = digit(num: nums[i], exp: exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1 // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in 1 ..< 10 {\n        counter[i] += counter[i - 1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    var res = Array(repeating: 0, count: nums.count)\n    for i in nums.indices.reversed() {\n        let d = digit(num: nums[i], exp: exp)\n        let j = counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i] // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1 // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in nums.indices {\n        nums[i] = res[i]\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunc radixSort(nums: inout [Int]) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m = Int.min\n    for num in nums {\n        if num > m {\n            m = num\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for exp in sequence(first: 1, next: { m >= ($0 * 10) ? $0 * 10 : nil }) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums: &nums, exp: exp)\n    }\n}\n
    radix_sort.js
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunction digit(num, exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return Math.floor(num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunction countingSortDigit(nums, exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    const counter = new Array(10).fill(0);\n    const n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (let i = 0; i < n; i++) {\n        const d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (let i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    const res = new Array(n).fill(0);\n    for (let i = n - 1; i >= 0; i--) {\n        const d = digit(nums[i], exp);\n        const j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunction radixSort(nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = Number.MIN_VALUE;\n    for (const num of nums) {\n        if (num > m) {\n            m = num;\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (let exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.ts
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunction digit(num: number, exp: number): number {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return Math.floor(num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunction countingSortDigit(nums: number[], exp: number): void {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    const counter = new Array(10).fill(0);\n    const n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (let i = 0; i < n; i++) {\n        const d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (let i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    const res = new Array(n).fill(0);\n    for (let i = n - 1; i >= 0; i--) {\n        const d = digit(nums[i], exp);\n        const j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunction radixSort(nums: number[]): void {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = Number.MIN_VALUE;\n    for (const num of nums) {\n        if (num > m) {\n            m = num;\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (let exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.dart
    /* \u83b7\u53d6\u5143\u7d20 _num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int _num, int exp) {\n  // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n  return (_num ~/ exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(List<int> nums, int exp) {\n  // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n  List<int> counter = List<int>.filled(10, 0);\n  int n = nums.length;\n  // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  for (int i = 0; i < n; i++) {\n    int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n    counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n  }\n  // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n  for (int i = 1; i < 10; i++) {\n    counter[i] += counter[i - 1];\n  }\n  // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n  List<int> res = List<int>.filled(n, 0);\n  for (int i = n - 1; i >= 0; i--) {\n    int d = digit(nums[i], exp);\n    int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n    res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n    counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n  }\n  // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n  for (int i = 0; i < n; i++) nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(List<int> nums) {\n  // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n  // dart \u4e2d int \u7684\u957f\u5ea6\u662f 64 \u4f4d\u7684\n  int m = -1 << 63;\n  for (int _num in nums) if (_num > m) m = _num;\n  // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n  for (int exp = 1; exp <= m; exp *= 10)\n    // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n    // k = 1 -> exp = 1\n    // k = 2 -> exp = 10\n    // \u5373 exp = 10^(k-1)\n    countingSortDigit(nums, exp);\n}\n
    radix_sort.rs
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfn digit(num: i32, exp: i32) -> usize {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return ((num / exp) % 10) as usize;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfn counting_sort_digit(nums: &mut [i32], exp: i32) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    let mut counter = [0; 10];\n    let n = nums.len();\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in 0..n {\n        let d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in 1..10 {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    let mut res = vec![0; n];\n    for i in (0..n).rev() {\n        let d = digit(nums[i], exp);\n        let j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in 0..n {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfn radix_sort(nums: &mut [i32]) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = *nums.into_iter().max().unwrap();\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    let mut exp = 1;\n    while exp <= m {\n        counting_sort_digit(nums, exp);\n        exp *= 10;\n    }\n}\n
    radix_sort.c
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(int nums[], int size, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int *counter = (int *)malloc((sizeof(int) * 10));\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < size; i++) {\n        // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        int d = digit(nums[i], exp);\n        // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n        counter[d]++;\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int *res = (int *)malloc(sizeof(int) * size);\n    for (int i = size - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < size; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(int nums[], int size) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int max = INT32_MIN;\n    for (size_t i = 0; i < size - 1; i++) {\n        if (nums[i] > max) {\n            max = nums[i];\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; max >= exp; exp *= 10)\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, size, exp);\n}\n
    radix_sort.kt
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfun digit(num: Int, exp: Int): Int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfun countingSortDigit(nums: IntArray, exp: Int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    val counter = IntArray(10)\n    val n = nums.size\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (i in 0..<n) {\n        val d = digit(nums[i], exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (i in 1..9) {\n        counter[i] += counter[i - 1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    val res = IntArray(n)\n    for (i in n - 1 downTo 0) {\n        val d = digit(nums[i], exp)\n        val j = counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (i in 0..<n)\n        nums[i] = res[i]\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfun radixSort(nums: IntArray) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m = Int.MIN_VALUE\n    for (num in nums) if (num > m) m = num\n    var exp = 1\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    while (exp <= m) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp)\n        exp *= 10\n    }\n}\n
    radix_sort.rb
    [class]{}-[func]{digit}\n\n[class]{}-[func]{counting_sort_digit}\n\n[class]{}-[func]{radix_sort}\n
    radix_sort.zig
    // \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1)\nfn digit(num: i32, exp: i32) i32 {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return @mod(@divFloor(num, exp), 10);\n}\n\n// \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09\nfn countingSortDigit(nums: []i32, exp: i32) !void {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);\n    // defer mem_arena.deinit();\n    const mem_allocator = mem_arena.allocator();\n    var counter = try mem_allocator.alloc(usize, 10);\n    @memset(counter, 0);\n    var n = nums.len;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (nums) |num| {\n        var d: u32 = @bitCast(digit(num, exp)); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    var i: usize = 1;\n    while (i < 10) : (i += 1) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    var res = try mem_allocator.alloc(i32, n);\n    i = n - 1;\n    while (i >= 0) : (i -= 1) {\n        var d: u32 = @bitCast(digit(nums[i], exp));\n        var j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1;        // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n        if (i == 0) break;\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    i = 0;\n    while (i < n) : (i += 1) {\n        nums[i] = res[i];\n    }\n}\n\n// \u57fa\u6570\u6392\u5e8f\nfn radixSort(nums: []i32) !void {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m: i32 = std.math.minInt(i32);\n    for (nums) |num| {\n        if (num > m) m = num;\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    var exp: i32 = 1;\n    while (exp <= m) : (exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        try countingSortDigit(nums, exp);    \n    }\n} \n
    Code Visualization

    Full Screen >

    Why start sorting from the least significant digit?

    In consecutive sorting rounds, the result of a later round will override the result of an earlier round. For example, if the result of the first round is \\(a < b\\) and the result of the second round is \\(a > b\\), the result of the second round will replace the first round's result. Since the significance of higher digits is greater than that of lower digits, it makes sense to sort lower digits before higher digits.

    "},{"location":"chapter_sorting/radix_sort/#11102-algorithm-characteristics","title":"11.10.2 \u00a0 Algorithm characteristics","text":"

    Compared to counting sort, radix sort is suitable for larger numerical ranges, but it assumes that the data can be represented in a fixed number of digits, and the number of digits should not be too large. For example, floating-point numbers are not suitable for radix sort, as their digit count \\(k\\) may be large, potentially leading to a time complexity \\(O(nk) \\gg O(n^2)\\).

    • Time complexity is \\(O(nk)\\), non-adaptive sorting: Assuming the data size is \\(n\\), the data is in base \\(d\\), and the maximum number of digits is \\(k\\), then sorting a single digit takes \\(O(n + d)\\) time, and sorting all \\(k\\) digits takes \\(O((n + d)k)\\) time. Generally, both \\(d\\) and \\(k\\) are relatively small, leading to a time complexity approaching \\(O(n)\\).
    • Space complexity is \\(O(n + d)\\), non-in-place sorting: Like counting sort, radix sort relies on arrays res and counter of lengths \\(n\\) and \\(d\\) respectively.
    • Stable sorting: When counting sort is stable, radix sort is also stable; if counting sort is unstable, radix sort cannot guarantee a correct sorting outcome.
    "},{"location":"chapter_sorting/selection_sort/","title":"11.2 \u00a0 Selection sort","text":"

    Selection sort works on a very simple principle: it starts a loop where each iteration selects the smallest element from the unsorted interval and moves it to the end of the sorted interval.

    Suppose the length of the array is \\(n\\), the algorithm flow of selection sort is as shown below.

    1. Initially, all elements are unsorted, i.e., the unsorted (index) interval is \\([0, n-1]\\).
    2. Select the smallest element in the interval \\([0, n-1]\\) and swap it with the element at index \\(0\\). After this, the first element of the array is sorted.
    3. Select the smallest element in the interval \\([1, n-1]\\) and swap it with the element at index \\(1\\). After this, the first two elements of the array are sorted.
    4. Continue in this manner. After \\(n - 1\\) rounds of selection and swapping, the first \\(n - 1\\) elements are sorted.
    5. The only remaining element is necessarily the largest element and does not need sorting, thus the array is sorted.
    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 11-2 \u00a0 Selection sort process

    In the code, we use \\(k\\) to record the smallest element within the unsorted interval:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig selection_sort.py
    def selection_sort(nums: list[int]):\n    \"\"\"\u9009\u62e9\u6392\u5e8f\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in range(n - 1):\n        # \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        k = i\n        for j in range(i + 1, n):\n            if nums[j] < nums[k]:\n                k = j  # \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        # \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[k] = nums[k], nums[i]\n
    selection_sort.cpp
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(vector<int> &nums) {\n    int n = nums.size();\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        swap(nums[i], nums[k]);\n    }\n}\n
    selection_sort.java
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(int[] nums) {\n    int n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        int temp = nums[i];\n        nums[i] = nums[k];\n        nums[k] = temp;\n    }\n}\n
    selection_sort.cs
    /* \u9009\u62e9\u6392\u5e8f */\nvoid SelectionSort(int[] nums) {\n    int n = nums.Length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        (nums[k], nums[i]) = (nums[i], nums[k]);\n    }\n}\n
    selection_sort.go
    /* \u9009\u62e9\u6392\u5e8f */\nfunc selectionSort(nums []int) {\n    n := len(nums)\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i := 0; i < n-1; i++ {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        k := i\n        for j := i + 1; j < n; j++ {\n            if nums[j] < nums[k] {\n                // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n                k = j\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[k] = nums[k], nums[i]\n\n    }\n}\n
    selection_sort.swift
    /* \u9009\u62e9\u6392\u5e8f */\nfunc selectionSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in nums.indices.dropLast() {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        var k = i\n        for j in nums.indices.dropFirst(i + 1) {\n            if nums[j] < nums[k] {\n                k = j // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums.swapAt(i, k)\n    }\n}\n
    selection_sort.js
    /* \u9009\u62e9\u6392\u5e8f */\nfunction selectionSort(nums) {\n    let n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (let i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let k = i;\n        for (let j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k]) {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        [nums[i], nums[k]] = [nums[k], nums[i]];\n    }\n}\n
    selection_sort.ts
    /* \u9009\u62e9\u6392\u5e8f */\nfunction selectionSort(nums: number[]): void {\n    let n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (let i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let k = i;\n        for (let j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k]) {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        [nums[i], nums[k]] = [nums[k], nums[i]];\n    }\n}\n
    selection_sort.dart
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(List<int> nums) {\n  int n = nums.length;\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n  for (int i = 0; i < n - 1; i++) {\n    // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n    int k = i;\n    for (int j = i + 1; j < n; j++) {\n      if (nums[j] < nums[k]) k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n    }\n    // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n    int temp = nums[i];\n    nums[i] = nums[k];\n    nums[k] = temp;\n  }\n}\n
    selection_sort.rs
    /* \u9009\u62e9\u6392\u5e8f */\nfn selection_sort(nums: &mut [i32]) {\n    if nums.is_empty() {\n        return;\n    }\n    let n = nums.len();\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in 0..n - 1 {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let mut k = i;\n        for j in i + 1..n {\n            if nums[j] < nums[k] {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums.swap(i, k);\n    }\n}\n
    selection_sort.c
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(int nums[], int n) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        int temp = nums[i];\n        nums[i] = nums[k];\n        nums[k] = temp;\n    }\n}\n
    selection_sort.kt
    /* \u9009\u62e9\u6392\u5e8f */\nfun selectionSort(nums: IntArray) {\n    val n = nums.size\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (i in 0..<n - 1) {\n        var k = i\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        for (j in i + 1..<n) {\n            if (nums[j] < nums[k])\n                k = j // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        val temp = nums[i]\n        nums[i] = nums[k]\n        nums[k] = temp\n    }\n}\n
    selection_sort.rb
    [class]{}-[func]{selection_sort}\n
    selection_sort.zig
    [class]{}-[func]{selectionSort}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_sorting/selection_sort/#1121-algorithm-characteristics","title":"11.2.1 \u00a0 Algorithm characteristics","text":"
    • Time complexity of \\(O(n^2)\\), non-adaptive sort: There are \\(n - 1\\) rounds in the outer loop, with the unsorted interval length starting at \\(n\\) in the first round and decreasing to \\(2\\) in the last round, i.e., the outer loops contain \\(n\\), \\(n - 1\\), \\(\\dots\\), \\(3\\), \\(2\\) inner loops respectively, summing up to \\(\\frac{(n - 1)(n + 2)}{2}\\).
    • Space complexity of \\(O(1)\\), in-place sort: Uses constant extra space with pointers \\(i\\) and \\(j\\).
    • Non-stable sort: As shown in the Figure 11-3 , an element nums[i] may be swapped to the right of an equal element, causing their relative order to change.

    Figure 11-3 \u00a0 Selection sort instability example

    "},{"location":"chapter_sorting/sorting_algorithm/","title":"11.1 \u00a0 Sorting algorithms","text":"

    Sorting algorithms (sorting algorithm) are used to arrange a set of data in a specific order. Sorting algorithms have a wide range of applications because ordered data can usually be searched, analyzed, and processed more efficiently.

    As shown in the following figure, the data types in sorting algorithms can be integers, floating point numbers, characters, or strings, etc. Sorting rules can be set according to needs, such as numerical size, character ASCII order, or custom rules.

    Figure 11-1 \u00a0 Data types and comparator examples

    "},{"location":"chapter_sorting/sorting_algorithm/#1111-evaluation-dimensions","title":"11.1.1 \u00a0 Evaluation dimensions","text":"

    Execution efficiency: We expect the time complexity of sorting algorithms to be as low as possible, with a lower number of overall operations (reduction in the constant factor of time complexity). For large data volumes, execution efficiency is particularly important.

    In-place property: As the name implies, in-place sorting is achieved by directly manipulating the original array, without the need for additional auxiliary arrays, thus saving memory. Generally, in-place sorting involves fewer data movement operations and is faster.

    Stability: Stable sorting ensures that the relative order of equal elements in the array does not change after sorting.

    Stable sorting is a necessary condition for multi-level sorting scenarios. Suppose we have a table storing student information, with the first and second columns being name and age, respectively. In this case, unstable sorting might lead to a loss of orderedness in the input data:

    # Input data is sorted by name\n# (name, age)\n  ('A', 19)\n  ('B', 18)\n  ('C', 21)\n  ('D', 19)\n  ('E', 23)\n\n# Assuming an unstable sorting algorithm is used to sort the list by age,\n# the result changes the relative position of ('D', 19) and ('A', 19),\n# and the property of the input data being sorted by name is lost\n  ('B', 18)\n  ('D', 19)\n  ('A', 19)\n  ('C', 21)\n  ('E', 23)\n

    Adaptability: Adaptive sorting has a time complexity that depends on the input data, i.e., the best time complexity, worst time complexity, and average time complexity are not exactly equal.

    Adaptability needs to be assessed according to the specific situation. If the worst time complexity is worse than the average, it suggests that the performance of the sorting algorithm might deteriorate under certain data, hence it is seen as a negative attribute; whereas, if the best time complexity is better than the average, it is considered a positive attribute.

    Comparison-based: Comparison-based sorting relies on comparison operators (\\(<\\), \\(=\\), \\(>\\)) to determine the relative order of elements and thus sort the entire array, with the theoretical optimal time complexity being \\(O(n \\log n)\\). Meanwhile, non-comparison sorting does not use comparison operators and can achieve a time complexity of \\(O(n)\\), but its versatility is relatively poor.

    "},{"location":"chapter_sorting/sorting_algorithm/#1112-ideal-sorting-algorithm","title":"11.1.2 \u00a0 Ideal sorting algorithm","text":"

    Fast execution, in-place, stable, positively adaptive, and versatile. Clearly, no sorting algorithm that combines all these features has been found to date. Therefore, when selecting a sorting algorithm, it is necessary to decide based on the specific characteristics of the data and the requirements of the problem.

    Next, we will learn about various sorting algorithms together and analyze the advantages and disadvantages of each based on the above evaluation dimensions.

    "},{"location":"chapter_sorting/summary/","title":"11.11 \u00a0 Summary","text":""},{"location":"chapter_sorting/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Bubble sort works by swapping adjacent elements. By adding a flag to enable early return, we can optimize the best-case time complexity of bubble sort to \\(O(n)\\).
    • Insertion sort sorts each round by inserting elements from the unsorted interval into the correct position in the sorted interval. Although the time complexity of insertion sort is \\(O(n^2)\\), it is very popular in sorting small amounts of data due to relatively fewer operations per unit.
    • Quick sort is based on sentinel partitioning operations. In sentinel partitioning, it's possible to always pick the worst pivot, leading to a time complexity degradation to \\(O(n^2)\\). Introducing median or random pivots can reduce the probability of such degradation. Tail recursion can effectively reduce the recursion depth, optimizing the space complexity to \\(O(\\log n)\\).
    • Merge sort includes dividing and merging two phases, typically embodying the divide-and-conquer strategy. In merge sort, sorting an array requires creating auxiliary arrays, resulting in a space complexity of \\(O(n)\\); however, the space complexity for sorting a list can be optimized to \\(O(1)\\).
    • Bucket sort consists of three steps: data bucketing, sorting within buckets, and merging results. It also embodies the divide-and-conquer strategy, suitable for very large datasets. The key to bucket sort is the even distribution of data.
    • Counting sort is a special case of bucket sort, which sorts by counting the occurrences of each data point. Counting sort is suitable for large datasets with a limited range of data and requires that data can be converted to positive integers.
    • Radix sort sorts data by sorting digit by digit, requiring data to be represented as fixed-length numbers.
    • Overall, we hope to find a sorting algorithm that has high efficiency, stability, in-place operation, and positive adaptability. However, like other data structures and algorithms, no sorting algorithm can meet all these conditions simultaneously. In practical applications, we need to choose the appropriate sorting algorithm based on the characteristics of the data.
    • The following figure compares mainstream sorting algorithms in terms of efficiency, stability, in-place nature, and adaptability.

    Figure 11-19 \u00a0 Sorting Algorithm Comparison

    "},{"location":"chapter_sorting/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: When is the stability of sorting algorithms necessary?

    In reality, we might sort based on one attribute of an object. For example, students have names and heights as attributes, and we aim to implement multi-level sorting: first by name to get (A, 180) (B, 185) (C, 170) (D, 170); then by height. Because the sorting algorithm is unstable, we might end up with (D, 170) (C, 170) (A, 180) (B, 185).

    It can be seen that the positions of students D and C have been swapped, disrupting the orderliness of the names, which is undesirable.

    Q: Can the order of \"searching from right to left\" and \"searching from left to right\" in sentinel partitioning be swapped?

    No, when using the leftmost element as the pivot, we must first \"search from right to left\" then \"search from left to right\". This conclusion is somewhat counterintuitive, so let's analyze the reason.

    The last step of the sentinel partition partition() is to swap nums[left] and nums[i]. After the swap, the elements to the left of the pivot are all <= the pivot, which requires that nums[left] >= nums[i] must hold before the last swap. Suppose we \"search from left to right\" first, then if no element larger than the pivot is found, we will exit the loop when i == j, possibly with nums[j] == nums[i] > nums[left]. In other words, the final swap operation will exchange an element larger than the pivot to the left end of the array, causing the sentinel partition to fail.

    For example, given the array [0, 0, 0, 0, 1], if we first \"search from left to right\", the array after the sentinel partition is [1, 0, 0, 0, 0], which is incorrect.

    Upon further consideration, if we choose nums[right] as the pivot, then exactly the opposite, we must first \"search from left to right\".

    Q: Regarding tail recursion optimization, why does choosing the shorter array ensure that the recursion depth does not exceed \\(\\log n\\)?

    The recursion depth is the number of currently unreturned recursive methods. Each round of sentinel partition divides the original array into two subarrays. With tail recursion optimization, the length of the subarray to be recursively followed is at most half of the original array length. Assuming the worst case always halves the length, the final recursion depth will be \\(\\log n\\).

    Reviewing the original quicksort, we might continuously recursively process larger arrays, in the worst case from \\(n\\), \\(n - 1\\), ..., \\(2\\), \\(1\\), with a recursion depth of \\(n\\). Tail recursion optimization can avoid this scenario.

    Q: When all elements in the array are equal, is the time complexity of quicksort \\(O(n^2)\\)? How should this degenerate case be handled?

    Yes. For this situation, consider using sentinel partitioning to divide the array into three parts: less than, equal to, and greater than the pivot. Only recursively proceed with the less than and greater than parts. In this method, an array where all input elements are equal can be sorted in just one round of sentinel partitioning.

    Q: Why is the worst-case time complexity of bucket sort \\(O(n^2)\\)?

    In the worst case, all elements are placed in the same bucket. If we use an \\(O(n^2)\\) algorithm to sort these elements, the time complexity will be \\(O(n^2)\\).

    "},{"location":"chapter_stack_and_queue/","title":"Chapter 5. \u00a0 Stack and queue","text":"

    Abstract

    A stack is like cats placed on top of each other, while a queue is like cats lined up one by one.

    They represent the logical relationships of Last-In-First-Out (LIFO) and First-In-First-Out (FIFO), respectively.

    "},{"location":"chapter_stack_and_queue/#chapter-contents","title":"Chapter contents","text":"
    • 5.1 \u00a0 Stack
    • 5.2 \u00a0 Queue
    • 5.3 \u00a0 Double-ended queue
    • 5.4 \u00a0 Summary
    "},{"location":"chapter_stack_and_queue/deque/","title":"5.3 \u00a0 Double-ended queue","text":"

    In a queue, we can only delete elements from the head or add elements to the tail. As shown in the following diagram, a \"double-ended queue (deque)\" offers more flexibility, allowing the addition or removal of elements at both the head and the tail.

    Figure 5-7 \u00a0 Operations in double-ended queue

    "},{"location":"chapter_stack_and_queue/deque/#531-common-operations-in-double-ended-queue","title":"5.3.1 \u00a0 Common operations in double-ended queue","text":"

    The common operations in a double-ended queue are listed below, and the names of specific methods depend on the programming language used.

    Table 5-3 \u00a0 Efficiency of double-ended queue operations

    Method Name Description Time Complexity pushFirst() Add an element to the head \\(O(1)\\) pushLast() Add an element to the tail \\(O(1)\\) popFirst() Remove the first element \\(O(1)\\) popLast() Remove the last element \\(O(1)\\) peekFirst() Access the first element \\(O(1)\\) peekLast() Access the last element \\(O(1)\\)

    Similarly, we can directly use the double-ended queue classes implemented in programming languages:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig deque.py
    from collections import deque\n\n# Initialize the deque\ndeq: deque[int] = deque()\n\n# Enqueue elements\ndeq.append(2)      # Add to the tail\ndeq.append(5)\ndeq.append(4)\ndeq.appendleft(3)  # Add to the head\ndeq.appendleft(1)\n\n# Access elements\nfront: int = deq[0]  # The first element\nrear: int = deq[-1]  # The last element\n\n# Dequeue elements\npop_front: int = deq.popleft()  # The first element dequeued\npop_rear: int = deq.pop()       # The last element dequeued\n\n# Get the length of the deque\nsize: int = len(deq)\n\n# Check if the deque is empty\nis_empty: bool = len(deq) == 0\n
    deque.cpp
    /* Initialize the deque */\ndeque<int> deque;\n\n/* Enqueue elements */\ndeque.push_back(2);   // Add to the tail\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3);  // Add to the head\ndeque.push_front(1);\n\n/* Access elements */\nint front = deque.front(); // The first element\nint back = deque.back();   // The last element\n\n/* Dequeue elements */\ndeque.pop_front();  // The first element dequeued\ndeque.pop_back();   // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.size();\n\n/* Check if the deque is empty */\nbool empty = deque.empty();\n
    deque.java
    /* Initialize the deque */\nDeque<Integer> deque = new LinkedList<>();\n\n/* Enqueue elements */\ndeque.offerLast(2);   // Add to the tail\ndeque.offerLast(5);\ndeque.offerLast(4);\ndeque.offerFirst(3);  // Add to the head\ndeque.offerFirst(1);\n\n/* Access elements */\nint peekFirst = deque.peekFirst();  // The first element\nint peekLast = deque.peekLast();    // The last element\n\n/* Dequeue elements */\nint popFirst = deque.pollFirst();  // The first element dequeued\nint popLast = deque.pollLast();    // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.size();\n\n/* Check if the deque is empty */\nboolean isEmpty = deque.isEmpty();\n
    deque.cs
    /* Initialize the deque */\n// In C#, LinkedList is used as a deque\nLinkedList<int> deque = new();\n\n/* Enqueue elements */\ndeque.AddLast(2);   // Add to the tail\ndeque.AddLast(5);\ndeque.AddLast(4);\ndeque.AddFirst(3);  // Add to the head\ndeque.AddFirst(1);\n\n/* Access elements */\nint peekFirst = deque.First.Value;  // The first element\nint peekLast = deque.Last.Value;    // The last element\n\n/* Dequeue elements */\ndeque.RemoveFirst();  // The first element dequeued\ndeque.RemoveLast();   // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.Count;\n\n/* Check if the deque is empty */\nbool isEmpty = deque.Count == 0;\n
    deque_test.go
    /* Initialize the deque */\n// In Go, use list as a deque\ndeque := list.New()\n\n/* Enqueue elements */\ndeque.PushBack(2)      // Add to the tail\ndeque.PushBack(5)\ndeque.PushBack(4)\ndeque.PushFront(3)     // Add to the head\ndeque.PushFront(1)\n\n/* Access elements */\nfront := deque.Front() // The first element\nrear := deque.Back()   // The last element\n\n/* Dequeue elements */\ndeque.Remove(front)    // The first element dequeued\ndeque.Remove(rear)     // The last element dequeued\n\n/* Get the length of the deque */\nsize := deque.Len()\n\n/* Check if the deque is empty */\nisEmpty := deque.Len() == 0\n
    deque.swift
    /* Initialize the deque */\n// Swift does not have a built-in deque class, so Array can be used as a deque\nvar deque: [Int] = []\n\n/* Enqueue elements */\ndeque.append(2) // Add to the tail\ndeque.append(5)\ndeque.append(4)\ndeque.insert(3, at: 0) // Add to the head\ndeque.insert(1, at: 0)\n\n/* Access elements */\nlet peekFirst = deque.first! // The first element\nlet peekLast = deque.last!   // The last element\n\n/* Dequeue elements */\n// Using Array, popFirst has a complexity of O(n)\nlet popFirst = deque.removeFirst() // The first element dequeued\nlet popLast = deque.removeLast()   // The last element dequeued\n\n/* Get the length of the deque */\nlet size = deque.count\n\n/* Check if the deque is empty */\nlet isEmpty = deque.isEmpty\n
    deque.js
    /* Initialize the deque */\n// JavaScript does not have a built-in deque, so Array is used as a deque\nconst deque = [];\n\n/* Enqueue elements */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// Note that unshift() has a time complexity of O(n) as it's an array\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* Access elements */\nconst peekFirst = deque[0]; // The first element\nconst peekLast = deque[deque.length - 1]; // The last element\n\n/* Dequeue elements */\n// Note that shift() has a time complexity of O(n) as it's an array\nconst popFront = deque.shift(); // The first element dequeued\nconst popBack = deque.pop();    // The last element dequeued\n\n/* Get the length of the deque */\nconst size = deque.length;\n\n/* Check if the deque is empty */\nconst isEmpty = size === 0;\n
    deque.ts
    /* Initialize the deque */\n// TypeScript does not have a built-in deque, so Array is used as a deque\nconst deque: number[] = [];\n\n/* Enqueue elements */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// Note that unshift() has a time complexity of O(n) as it's an array\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* Access elements */\nconst peekFirst: number = deque[0]; // The first element\nconst peekLast: number = deque[deque.length - 1]; // The last element\n\n/* Dequeue elements */\n// Note that shift() has a time complexity of O(n) as it's an array\nconst popFront: number = deque.shift() as number; // The first element dequeued\nconst popBack: number = deque.pop() as number;    // The last element dequeued\n\n/* Get the length of the deque */\nconst size: number = deque.length;\n\n/* Check if the deque is empty */\nconst isEmpty: boolean = size === 0;\n
    deque.dart
    /* Initialize the deque */\n// In Dart, Queue is defined as a deque\nQueue<int> deque = Queue<int>();\n\n/* Enqueue elements */\ndeque.addLast(2);  // Add to the tail\ndeque.addLast(5);\ndeque.addLast(4);\ndeque.addFirst(3); // Add to the head\ndeque.addFirst(1);\n\n/* Access elements */\nint peekFirst = deque.first; // The first element\nint peekLast = deque.last;   // The last element\n\n/* Dequeue elements */\nint popFirst = deque.removeFirst(); // The first element dequeued\nint popLast = deque.removeLast();   // The last element dequeued\n\n/* Get the length of the deque */\nint size = deque.length;\n\n/* Check if the deque is empty */\nbool isEmpty = deque.isEmpty;\n
    deque.rs
    /* Initialize the deque */\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* Enqueue elements */\ndeque.push_back(2);  // Add to the tail\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3); // Add to the head\ndeque.push_front(1);\n\n/* Access elements */\nif let Some(front) = deque.front() { // The first element\n}\nif let Some(rear) = deque.back() {   // The last element\n}\n\n/* Dequeue elements */\nif let Some(pop_front) = deque.pop_front() { // The first element dequeued\n}\nif let Some(pop_rear) = deque.pop_back() {   // The last element dequeued\n}\n\n/* Get the length of the deque */\nlet size = deque.len();\n\n/* Check if the deque is empty */\nlet is_empty = deque.is_empty();\n
    deque.c
    // C does not provide a built-in deque\n
    deque.kt
    \n
    deque.zig
    \n
    Visualizing Code

    https://pythontutor.com/render.html#code=from%20collections%20import%20deque%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%0A%20%20%20%20deq%20%3D%20deque%28%29%0A%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%85%A5%E9%98%9F%0A%20%20%20%20deq.append%282%29%20%20%23%20%E6%B7%BB%E5%8A%A0%E8%87%B3%E9%98%9F%E5%B0%BE%0A%20%20%20%20deq.append%285%29%0A%20%20%20%20deq.append%284%29%0A%20%20%20%20deq.appendleft%283%29%20%20%23%20%E6%B7%BB%E5%8A%A0%E8%87%B3%E9%98%9F%E9%A6%96%0A%20%20%20%20deq.appendleft%281%29%0A%20%20%20%20print%28%22%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%20deque%20%3D%22,%20deq%29%0A%0A%20%20%20%20%23%20%E8%AE%BF%E9%97%AE%E5%85%83%E7%B4%A0%0A%20%20%20%20front%20%3D%20deq%5B0%5D%20%20%23%20%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%20front%20%3D%22,%20front%29%0A%20%20%20%20rear%20%3D%20deq%5B-1%5D%20%20%23%20%E9%98%9F%E5%B0%BE%E5%85%83%E7%B4%A0%0A%20%20%20%20print%28%22%E9%98%9F%E5%B0%BE%E5%85%83%E7%B4%A0%20rear%20%3D%22,%20rear%29%0A%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20pop_front%20%3D%20deq.popleft%28%29%20%20%23%20%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%87%BA%E9%98%9F%E5%85%83%E7%B4%A0%20%20pop_front%20%3D%22,%20pop_front%29%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%87%BA%E9%98%9F%E5%90%8E%20deque%20%3D%22,%20deq%29%0A%20%20%20%20pop_rear%20%3D%20deq.pop%28%29%20%20%23%20%E9%98%9F%E5%B0%BE%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20print%28%22%E9%98%9F%E5%B0%BE%E5%87%BA%E9%98%9F%E5%85%83%E7%B4%A0%20%20pop_rear%20%3D%22,%20pop_rear%29%0A%20%20%20%20print%28%22%E9%98%9F%E5%B0%BE%E5%87%BA%E9%98%9F%E5%90%8E%20deque%20%3D%22,%20deq%29%0A%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E7%9A%84%E9%95%BF%E5%BA%A6%0A%20%20%20%20size%20%3D%20len%28deq%29%0A%20%20%20%20print%28%22%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E9%95%BF%E5%BA%A6%20size%20%3D%22,%20size%29%0A%0A%20%20%20%20%23%20%E5%88%A4%E6%96%AD%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%0A%20%20%20%20is_empty%20%3D%20len%28deq%29%20%3D%3D%200%0A%20%20%20%20print%28%22%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%20%3D%22,%20is_empty%29&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    "},{"location":"chapter_stack_and_queue/deque/#532-implementing-a-double-ended-queue","title":"5.3.2 \u00a0 Implementing a double-ended queue *","text":"

    The implementation of a double-ended queue is similar to that of a regular queue, it can be based on either a linked list or an array as the underlying data structure.

    "},{"location":"chapter_stack_and_queue/deque/#1-implementation-based-on-doubly-linked-list","title":"1. \u00a0 Implementation based on doubly linked list","text":"

    Recall from the previous section that we used a regular singly linked list to implement a queue, as it conveniently allows for deleting from the head (corresponding to the dequeue operation) and adding new elements after the tail (corresponding to the enqueue operation).

    For a double-ended queue, both the head and the tail can perform enqueue and dequeue operations. In other words, a double-ended queue needs to implement operations in the opposite direction as well. For this, we use a \"doubly linked list\" as the underlying data structure of the double-ended queue.

    As shown in the Figure 5-8 , we treat the head and tail nodes of the doubly linked list as the front and rear of the double-ended queue, respectively, and implement the functionality to add and remove nodes at both ends.

    LinkedListDequepushLast()pushFirst()popLast()popFirst()

    Figure 5-8 \u00a0 Implementing Double-Ended Queue with Doubly Linked List for Enqueue and Dequeue Operations

    The implementation code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_deque.py
    class ListNode:\n    \"\"\"\u53cc\u5411\u94fe\u8868\u8282\u70b9\"\"\"\n\n    def __init__(self, val: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.val: int = val\n        self.next: ListNode | None = None  # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n        self.prev: ListNode | None = None  # \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\nclass LinkedListDeque:\n    \"\"\"\u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0  # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int, is_front: bool):\n        \"\"\"\u5165\u961f\u64cd\u4f5c\"\"\"\n        node = ListNode(num)\n        # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if self.is_empty():\n            self._front = self._rear = node\n        # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        elif is_front:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            self._front.prev = node\n            node.next = self._front\n            self._front = node  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            self._rear.next = node\n            node.prev = self._rear\n            self._rear = node  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size += 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        self.push(num, True)\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        self.push(num, False)\n\n    def pop(self, is_front: bool) -> int:\n        \"\"\"\u51fa\u961f\u64cd\u4f5c\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front:\n            val: int = self._front.val  # \u6682\u5b58\u5934\u8282\u70b9\u503c\n            # \u5220\u9664\u5934\u8282\u70b9\n            fnext: ListNode | None = self._front.next\n            if fnext != None:\n                fnext.prev = None\n                self._front.next = None\n            self._front = fnext  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else:\n            val: int = self._rear.val  # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            # \u5220\u9664\u5c3e\u8282\u70b9\n            rprev: ListNode | None = self._rear.prev\n            if rprev != None:\n                rprev.next = None\n                self._rear.prev = None\n            self._rear = rprev  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size -= 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        return self.pop(True)\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        return self.pop(False)\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._rear.val\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        node = self._front\n        res = [0] * self.size()\n        for i in range(self.size()):\n            res[i] = node.val\n            node = node.next\n        return res\n
    linkedlist_deque.cpp
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nstruct DoublyListNode {\n    int val;              // \u8282\u70b9\u503c\n    DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\u6307\u9488\n    DoublyListNode(int val) : val(val), prev(nullptr), next(nullptr) {\n    }\n};\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n  private:\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize = 0;              // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    LinkedListDeque() : front(nullptr), rear(nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~LinkedListDeque() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        DoublyListNode *pre, *cur = front;\n        while (cur != nullptr) {\n            pre = cur;\n            cur = cur->next;\n            delete pre;\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void push(int num, bool isFront) {\n        DoublyListNode *node = new DoublyListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front->prev = node;\n            node->next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear->next = node;\n            node->prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int pop(bool isFront) {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front->val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            DoublyListNode *fNext = front->next;\n            if (fNext != nullptr) {\n                fNext->prev = nullptr;\n                front->next = nullptr;\n            }\n            delete front;\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear->val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            DoublyListNode *rPrev = rear->prev;\n            if (rPrev != nullptr) {\n                rPrev->next = nullptr;\n                rear->prev = nullptr;\n            }\n            delete rear;\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return rear->val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        DoublyListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_deque.java
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    int val; // \u8282\u70b9\u503c\n    ListNode next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    ListNode prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    ListNode(int val) {\n        this.val = val;\n        prev = next = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private void push(int num, boolean isFront) {\n        ListNode node = new ListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear.next = node;\n            node.prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private int pop(boolean isFront) {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode fNext = front.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front.next = null;\n            }\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode rPrev = rear.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear.prev = null;\n            }\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return rear.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_deque.cs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(int val) {\n    public int val = val;       // \u8282\u70b9\u503c\n    public ListNode? next = null; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    public ListNode? prev = null; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    ListNode? front, rear; // \u5934\u8282\u70b9 front, \u5c3e\u8282\u70b9 rear\n    int queSize = 0;      // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void Push(int num, bool isFront) {\n        ListNode node = new(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (IsEmpty()) {\n            front = node;\n            rear = node;\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front!.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9                           \n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear!.next = node;\n            node.prev = rear;\n            rear = node;  // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        Push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        Push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int? Pop(bool isFront) {\n        if (IsEmpty())\n            throw new Exception();\n        int? val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front?.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode? fNext = front?.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front!.next = null;\n            }\n            front = fNext;   // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear?.val;  // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode? rPrev = rear?.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear!.prev = null;\n            }\n            rear = rPrev;    // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int? PopFirst() {\n        return Pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int? PopLast() {\n        return Pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int? PeekFirst() {\n        if (IsEmpty())\n            throw new Exception();\n        return front?.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int? PeekLast() {\n        if (IsEmpty())\n            throw new Exception();\n        return rear?.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int?[] ToArray() {\n        ListNode? node = front;\n        int?[] res = new int?[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node?.val;\n            node = node?.next;\n        }\n\n        return res;\n    }\n}\n
    linkedlist_deque.go
    /* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype linkedListDeque struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u53cc\u7aef\u961f\u5217 */\nfunc newLinkedListDeque() *linkedListDeque {\n    return &linkedListDeque{\n        data: list.New(),\n    }\n}\n\n/* \u961f\u9996\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushFirst(value any) {\n    s.data.PushFront(value)\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushLast(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u961f\u9996\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListDeque) peekFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (s *linkedListDeque) peekLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListDeque) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListDeque) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListDeque) toList() *list.List {\n    return s.data\n}\n
    linkedlist_deque.swift
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    weak var prev: ListNode? // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    init(val: Int) {\n        self.val = val\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? // \u5934\u8282\u70b9 front\n    private var rear: ListNode? // \u5c3e\u8282\u70b9 rear\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private func push(num: Int, isFront: Bool) {\n        let node = ListNode(val: num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if isEmpty() {\n            front = node\n            rear = node\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if isFront {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size += 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        push(num: num, isFront: true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        push(num: num, isFront: false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private func pop(isFront: Bool) -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        let val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if isFront {\n            val = front!.val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            let fNext = front?.next\n            if fNext != nil {\n                fNext?.prev = nil\n                front?.next = nil\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear!.val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            let rPrev = rear?.prev\n            if rPrev != nil {\n                rPrev?.next = nil\n                rear?.prev = nil\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size -= 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        pop(isFront: true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        pop(isFront: false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return rear!.val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.js
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val; // \u8282\u70b9\u503c\n\n    constructor(val) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    #front; // \u5934\u8282\u70b9 front\n    #rear; // \u5c3e\u8282\u70b9 rear\n    #queSize; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n        this.#queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.#rear.next = node;\n            node.prev = this.#rear;\n            this.#rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.#front.prev = node;\n            node.next = this.#front;\n            this.#front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp = this.#rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.#rear.prev = null;\n        }\n        this.#rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp = this.#front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.#front.next = null;\n        }\n        this.#front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        return this.#queSize === 0 ? null : this.#rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        return this.#queSize === 0 ? null : this.#front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print() {\n        const arr = [];\n        let temp = this.#front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.ts
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev: ListNode; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next: ListNode; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val: number; // \u8282\u70b9\u503c\n\n    constructor(val: number) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private front: ListNode; // \u5934\u8282\u70b9 front\n    private rear: ListNode; // \u5c3e\u8282\u70b9 rear\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n        this.queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.rear.next = node;\n            node.prev = this.rear;\n            this.rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.front.prev = node;\n            node.next = this.front;\n            this.front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp: ListNode = this.rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.rear.prev = null;\n        }\n        this.rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp: ListNode = this.front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.front.next = null;\n        }\n        this.front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        return this.queSize === 0 ? null : this.rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        return this.queSize === 0 ? null : this.front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print(): void {\n        const arr: number[] = [];\n        let temp: ListNode = this.front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.dart
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n  int val; // \u8282\u70b9\u503c\n  ListNode? next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  ListNode? prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n  ListNode(this.val, {this.next, this.prev});\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u5bf9\u5217 */\nclass LinkedListDeque {\n  late ListNode? _front; // \u5934\u8282\u70b9 _front\n  late ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  LinkedListDeque() {\n    this._front = null;\n    this._rear = null;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u957f\u5ea6 */\n  int size() {\n    return this._queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return size() == 0;\n  }\n\n  /* \u5165\u961f\u64cd\u4f5c */\n  void push(int _num, bool isFront) {\n    final ListNode node = ListNode(_num);\n    if (isEmpty()) {\n      // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 _front \u548c _rear \u90fd\u6307\u5411 node\n      _front = _rear = node;\n    } else if (isFront) {\n      // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      _front!.prev = node;\n      node.next = _front;\n      _front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      _rear!.next = node;\n      node.prev = _rear;\n      _rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    push(_num, true);\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    push(_num, false);\n  }\n\n  /* \u51fa\u961f\u64cd\u4f5c */\n  int? pop(bool isFront) {\n    // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de null\n    if (isEmpty()) {\n      return null;\n    }\n    final int val;\n    if (isFront) {\n      // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n      val = _front!.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n      // \u5220\u9664\u5934\u8282\u70b9\n      ListNode? fNext = _front!.next;\n      if (fNext != null) {\n        fNext.prev = null;\n        _front!.next = null;\n      }\n      _front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n      val = _rear!.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      // \u5220\u9664\u5c3e\u8282\u70b9\n      ListNode? rPrev = _rear!.prev;\n      if (rPrev != null) {\n        rPrev.next = null;\n        _rear!.prev = null;\n      }\n      _rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int? popFirst() {\n    return pop(true);\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int? popLast() {\n    return pop(false);\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int? peekFirst() {\n    return _front?.val;\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int? peekLast() {\n    return _rear?.val;\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> res = [];\n    for (int i = 0; i < _queSize; i++) {\n      res.add(node!.val);\n      node = node.next;\n    }\n    return res;\n  }\n}\n
    linkedlist_deque.rs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\npub struct ListNode<T> {\n    pub val: T,                                 // \u8282\u70b9\u503c\n    pub next: Option<Rc<RefCell<ListNode<T>>>>, // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    pub prev: Option<Rc<RefCell<ListNode<T>>>>, // \u524d\u9a71\u8282\u70b9\u6307\u9488\n}\n\nimpl<T> ListNode<T> {\n    pub fn new(val: T) -> Rc<RefCell<ListNode<T>>> {\n        Rc::new(RefCell::new(ListNode {\n            val,\n            next: None,\n            prev: None,\n        }))\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListDeque<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListDeque<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    pub fn push(&mut self, num: T, is_front: bool) {\n        let node = ListNode::new(num);\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        if is_front {\n            match self.front.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.rear = Some(node.clone());\n                    self.front = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                Some(old_front) => {\n                    old_front.borrow_mut().prev = Some(node.clone());\n                    node.borrow_mut().next = Some(old_front);\n                    self.front = Some(node); // \u66f4\u65b0\u5934\u8282\u70b9\n                }\n            }\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            match self.rear.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.front = Some(node.clone());\n                    self.rear = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                Some(old_rear) => {\n                    old_rear.borrow_mut().next = Some(node.clone());\n                    node.borrow_mut().prev = Some(old_rear);\n                    self.rear = Some(node); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                }\n            }\n        }\n        self.que_size += 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: T) {\n        self.push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: T) {\n        self.push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    pub fn pop(&mut self, is_front: bool) -> Option<T> {\n        // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de None\n        if self.is_empty() {\n            return None;\n        };\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front {\n            self.front.take().map(|old_front| {\n                match old_front.borrow_mut().next.take() {\n                    Some(new_front) => {\n                        new_front.borrow_mut().prev.take();\n                        self.front = Some(new_front); // \u66f4\u65b0\u5934\u8282\u70b9\n                    }\n                    None => {\n                        self.rear.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n            })\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            self.rear.take().map(|old_rear| {\n                match old_rear.borrow_mut().prev.take() {\n                    Some(new_rear) => {\n                        new_rear.borrow_mut().next.take();\n                        self.rear = Some(new_rear); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                    }\n                    None => {\n                        self.front.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_rear).ok().unwrap().into_inner().val\n            })\n        }\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    pub fn pop_first(&mut self) -> Option<T> {\n        return self.pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    pub fn pop_last(&mut self) -> Option<T> {\n        return self.pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek_first(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    pub fn peek_last(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.rear.as_ref()\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_deque.c
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\ntypedef struct DoublyListNode {\n    int val;                     // \u8282\u70b9\u503c\n    struct DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\n    struct DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\n} DoublyListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nDoublyListNode *newDoublyListNode(int num) {\n    DoublyListNode *new = (DoublyListNode *)malloc(sizeof(DoublyListNode));\n    new->val = num;\n    new->next = NULL;\n    new->prev = NULL;\n    return new;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delDoublyListNode(DoublyListNode *node) {\n    free(node);\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;                  // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n} LinkedListDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListDeque *newLinkedListDeque() {\n    LinkedListDeque *deque = (LinkedListDeque *)malloc(sizeof(LinkedListDeque));\n    deque->front = NULL;\n    deque->rear = NULL;\n    deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListdeque(LinkedListDeque *deque) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    for (int i = 0; i < deque->queSize && deque->front != NULL; i++) {\n        DoublyListNode *tmp = deque->front;\n        deque->front = deque->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e deque \u7ed3\u6784\u4f53\n    free(deque);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListDeque *deque) {\n    return (size(deque) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListDeque *deque, int num, bool isFront) {\n    DoublyListNode *node = newDoublyListNode(num);\n    // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411node\n    if (empty(deque)) {\n        deque->front = deque->rear = node;\n    }\n    // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    else if (isFront) {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n        deque->front->prev = node;\n        node->next = deque->front;\n        deque->front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n        deque->rear->next = node;\n        node->prev = deque->rear;\n        deque->rear = node;\n    }\n    deque->queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(LinkedListDeque *deque, int num) {\n    push(deque, num, true);\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(LinkedListDeque *deque, int num) {\n    push(deque, num, false);\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(LinkedListDeque *deque) {\n    assert(size(deque) && deque->front);\n    return deque->front->val;\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(LinkedListDeque *deque) {\n    assert(size(deque) && deque->rear);\n    return deque->rear->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListDeque *deque, bool isFront) {\n    if (empty(deque))\n        return -1;\n    int val;\n    // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if (isFront) {\n        val = peekFirst(deque); // \u6682\u5b58\u5934\u8282\u70b9\u503c\n        DoublyListNode *fNext = deque->front->next;\n        if (fNext) {\n            fNext->prev = NULL;\n            deque->front->next = NULL;\n        }\n        delDoublyListNode(deque->front);\n        deque->front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else {\n        val = peekLast(deque); // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n        DoublyListNode *rPrev = deque->rear->prev;\n        if (rPrev) {\n            rPrev->next = NULL;\n            deque->rear->prev = NULL;\n        }\n        delDoublyListNode(deque->rear);\n        deque->rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    deque->queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(LinkedListDeque *deque) {\n    return pop(deque, true);\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(LinkedListDeque *deque) {\n    return pop(deque, false);\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListDeque(LinkedListDeque *deque) {\n    int *arr = malloc(sizeof(int) * deque->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    DoublyListNode *node;\n    for (i = 0, node = deque->front; i < deque->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, deque->queSize);\n    free(arr);\n}\n
    linkedlist_deque.kt
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(var _val: Int) {\n    // \u8282\u70b9\u503c\n    var next: ListNode? = null // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    var prev: ListNode? = null // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? = null // \u5934\u8282\u70b9 front\n    private var rear: ListNode? = null // \u5c3e\u8282\u70b9 rear\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    fun push(num: Int, isFront: Boolean) {\n        val node = ListNode(num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty()) {\n            rear = node\n            front = rear\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        } else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++ // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        push(num, true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        push(num, false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    fun pop(isFront: Boolean): Int {\n        if (isEmpty()) \n            throw IndexOutOfBoundsException()\n        val _val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            _val = front!!._val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            val fNext = front!!.next\n            if (fNext != null) {\n                fNext.prev = null\n                front!!.next = null\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            _val = rear!!._val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            val rPrev = rear!!.prev\n            if (rPrev != null) {\n                rPrev.next = null\n                rear!!.prev = null\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize-- // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return _val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        return pop(true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        return pop(false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return rear!!._val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.rb
    =begin\nFile: linkedlist_deque.rb\nCreated Time: 2024-04-06\nAuthor: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)\n=end\n\n### \u53cc\u5411\u94fe\u8868\u8282\u70b9\nclass ListNode\n  attr_accessor :val\n  attr_accessor :next # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  attr_accessor :prev # \u524d\u8eaf\u8282\u70b9\u5f15\u7528\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(val)\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass LinkedListDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0     # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f\u64cd\u4f5c ###\n  def push(num, is_front)\n    node = ListNode.new(num)\n    # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c \u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n    if is_empty?\n      @front = @rear = node\n    # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    elsif is_front\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      @front.prev = node\n      node.next = @front\n      @front = node # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      @rear.next = node\n      node.prev = @rear\n      @rear = node # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size += 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    push(num, true)\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    push(num, false)\n  end\n\n  ### \u51fa\u961f\u64cd\u4f5c ###\n  def pop(is_front)\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if is_front\n      val = @front.val # \u6682\u5b58\u5934\u8282\u70b9\u503c\n      # \u5220\u9664\u5934\u8282\u70b9\n      fnext = @front.next\n      unless fnext.nil?\n        fnext.prev = nil\n        @front.next = nil\n      end\n      @front = fnext # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else\n      val = @rear.val # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      # \u5220\u9664\u5c3e\u8282\u70b9\n      rprev = @rear.prev\n      unless rprev.nil?\n        rprev.next = nil\n        @rear.prev = nil\n      end\n      @rear = rprev # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size -= 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    val\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    pop(true)\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_last\n    pop(false)\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @rear.val\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    node = @front\n    res = Array.new(size, 0)\n    for i in 0...size\n      res[i] = node.val\n      node = node.next\n    end\n    res\n  end\nend\n
    linkedlist_deque.zig
    // \u53cc\u5411\u94fe\u8868\u8282\u70b9\nfn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = undefined,     // \u8282\u70b9\u503c\n        next: ?*Self = null,    // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n        prev: ?*Self = null,    // \u524d\u9a71\u8282\u70b9\u6307\u9488\n\n        // Initialize a list node with specific value\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n\n// \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\nfn LinkedListDeque(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*ListNode(T) = null,                    // \u5934\u8282\u70b9 front\n        rear: ?*ListNode(T) = null,                     // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                             // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u5165\u961f\u64cd\u4f5c\n        pub fn push(self: *Self, num: T, is_front: bool) !void {\n            var node = try self.mem_allocator.create(ListNode(T));\n            node.init(num);\n            // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n            if (self.isEmpty()) {\n                self.front = node;\n                self.rear = node;\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n            } else if (is_front) {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                self.front.?.prev = node;\n                node.next = self.front;\n                self.front = node;  // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n            } else {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                self.rear.?.next = node;\n                node.prev = self.rear;\n                self.rear = node;   // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size += 1;      // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        } \n\n        // \u961f\u9996\u5165\u961f\n        pub fn pushFirst(self: *Self, num: T) !void {\n            try self.push(num, true);\n        } \n\n        // \u961f\u5c3e\u5165\u961f\n        pub fn pushLast(self: *Self, num: T) !void {\n            try self.push(num, false);\n        } \n\n        // \u51fa\u961f\u64cd\u4f5c\n        pub fn pop(self: *Self, is_front: bool) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            var val: T = undefined;\n            // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n            if (is_front) {\n                val = self.front.?.val;     // \u6682\u5b58\u5934\u8282\u70b9\u503c\n                // \u5220\u9664\u5934\u8282\u70b9\n                var fNext = self.front.?.next;\n                if (fNext != null) {\n                    fNext.?.prev = null;\n                    self.front.?.next = null;\n                }\n                self.front = fNext;         // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n            } else {\n                val = self.rear.?.val;      // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n                // \u5220\u9664\u5c3e\u8282\u70b9\n                var rPrev = self.rear.?.prev;\n                if (rPrev != null) {\n                    rPrev.?.next = null;\n                    self.rear.?.prev = null;\n                }\n                self.rear = rPrev;          // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size -= 1;              // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n            return val;\n        } \n\n        // \u961f\u9996\u51fa\u961f\n        pub fn popFirst(self: *Self) T {\n            return self.pop(true);\n        } \n\n        // \u961f\u5c3e\u51fa\u961f\n        pub fn popLast(self: *Self) T {\n            return self.pop(false);\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peekFirst(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\n        pub fn peekLast(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.rear.?.val;\n        }\n\n        // \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    "},{"location":"chapter_stack_and_queue/deque/#2-implementation-based-on-array","title":"2. \u00a0 Implementation based on array","text":"

    As shown in the Figure 5-9 , similar to implementing a queue with an array, we can also use a circular array to implement a double-ended queue.

    ArrayDequepushLast()pushFirst()popLast()popFirst()

    Figure 5-9 \u00a0 Implementing Double-Ended Queue with Array for Enqueue and Dequeue Operations

    The implementation only needs to add methods for \"front enqueue\" and \"rear dequeue\":

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_deque.py
    class ArrayDeque:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self, capacity: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * capacity\n        self._front: int = 0\n        self._size: int = 0\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def index(self, i: int) -> int:\n        \"\"\"\u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15\"\"\"\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + self.capacity()) % self.capacity()\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self._front = self.index(self._front - 1)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self._nums[self._front] = num\n        self._size += 1\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        rear = self.index(self._front + self._size)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        num = self.peek_first()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self._front = self.index(self._front + 1)\n        self._size -= 1\n        return num\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        num = self.peek_last()\n        self._size -= 1\n        return num\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        last = self.index(self._front + self._size - 1)\n        return self._nums[last]\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        res = []\n        for i in range(self._size):\n            res.append(self._nums[self.index(self._front + i)])\n        return res\n
    array_deque.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  private:\n    vector<int> nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;      // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayDeque(int capacity) {\n        nums.resize(capacity);\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return nums.size();\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> res(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n};\n
    array_deque.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        this.nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int Index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + Capacity()) % Capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = Index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = Index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int PopFirst() {\n        int num = PeekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = Index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int PopLast() {\n        int num = PeekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int PeekFirst() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int PeekLast() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = Index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[Index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype arrayDeque struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayDeque(queCapacity int) *arrayDeque {\n    return &arrayDeque{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayDeque) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayDeque) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nfunc (q *arrayDeque) index(i int) int {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + q.queCapacity) % q.queCapacity\n}\n\n/* \u961f\u9996\u5165\u961f */\nfunc (q *arrayDeque) pushFirst(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    q.front = q.index(q.front - 1)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    q.nums[q.front] = num\n    q.queSize++\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nfunc (q *arrayDeque) pushLast(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear := q.index(q.front + q.queSize)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u961f\u9996\u51fa\u961f */\nfunc (q *arrayDeque) popFirst() any {\n    num := q.peekFirst()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    q.front = q.index(q.front + 1)\n    q.queSize--\n    return num\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nfunc (q *arrayDeque) popLast() any {\n    num := q.peekLast()\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayDeque) peekFirst() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (q *arrayDeque) peekLast() any {\n    if q.isEmpty() {\n        return nil\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last := q.index(q.front + q.queSize - 1)\n    return q.nums[last]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayDeque) toSlice() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res := make([]int, q.queSize)\n    for i, j := 0, q.front; i < q.queSize; i++ {\n        res[i] = q.nums[q.index(j)]\n        j++\n    }\n    return res\n}\n
    array_deque.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(capacity: Int) {\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private func index(i: Int) -> Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(i: front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        _size += 1\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = index(i: front + size())\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        let num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(i: front + 1)\n        _size -= 1\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        let num = peekLast()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = index(i: front + size() - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[index(i: $0)] }\n    }\n}\n
    array_deque.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n        this.#front = 0;\n        this.#queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.#front = this.index(this.#front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.#nums[this.#front] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear = this.index(this.#front + this.#queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst() {\n        const num = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.#front = this.index(this.#front + 1);\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast() {\n        const num = this.peekLast();\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.#front + this.#queSize - 1);\n        return this.#nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res = [];\n        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {\n            res[i] = this.#nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = 0;\n        this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i: number): number {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.front = this.index(this.front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.nums[this.front] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear: number = this.index(this.front + this.queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst(): number {\n        const num: number = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.front = this.index(this.front + 1);\n        this.queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast(): number {\n        const num: number = this.peekLast();\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.nums[this.front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.front + this.queSize - 1);\n        return this.nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res: number[] = [];\n        for (let i = 0, j = this.front; i < this.queSize; i++, j++) {\n            res[i] = this.nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  late List<int> _nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayDeque(int capacity) {\n    this._nums = List.filled(capacity, 0);\n    this._front = this._queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n  int capacity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n  int index(int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + capacity()) % capacity();\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 _front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    _front = index(_front - 1);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u9996\n    _nums[_front] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = index(_front + _queSize);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int popFirst() {\n    int _num = peekFirst();\n    // \u961f\u9996\u6307\u9488\u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n    _front = index(_front + 1);\n    _queSize--;\n    return _num;\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int popLast() {\n    int _num = peekLast();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peekFirst() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int peekLast() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    int last = index(_front + _queSize - 1);\n    return _nums[last];\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[index(j)];\n    }\n    return res;\n  }\n}\n
    array_deque.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nstruct ArrayDeque {\n    nums: Vec<i32>,  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: usize,    // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: usize, // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n}\n\nimpl ArrayDeque {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        Self {\n            nums: vec![0; capacity],\n            front: 0,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        self.nums.len()\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    fn index(&self, i: i32) -> usize {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return ((i + self.capacity() as i32) % self.capacity() as i32) as usize;\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self.front = self.index(self.front as i32 - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self.nums[self.front] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = self.index(self.front as i32 + self.que_size as i32);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fn pop_first(&mut self) -> i32 {\n        let num = self.peek_first();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self.front = self.index(self.front as i32 + 1);\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fn pop_last(&mut self) -> i32 {\n        let num = self.peek_last();\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek_first(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        self.nums[self.front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fn peek_last(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = self.index(self.front as i32 + self.que_size as i32 - 1);\n        self.nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fn to_array(&self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut res = vec![0; self.que_size];\n        let mut j = self.front;\n        for i in 0..self.que_size {\n            res[i] = self.nums[self.index(j as i32)];\n            j += 1;\n        }\n        res\n    }\n}\n
    array_deque.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayDeque *newArrayDeque(int capacity) {\n    ArrayDeque *deque = (ArrayDeque *)malloc(sizeof(ArrayDeque));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    deque->queCapacity = capacity;\n    deque->nums = (int *)malloc(sizeof(int) * deque->queCapacity);\n    deque->front = deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayDeque(ArrayDeque *deque) {\n    free(deque->nums);\n    free(deque);\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayDeque *deque) {\n    return deque->queCapacity;\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayDeque *deque) {\n    return deque->queSize == 0;\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nint dequeIndex(ArrayDeque *deque, int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return ((i + capacity(deque)) % capacity(deque));\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u56de\u5230\u5c3e\u90e8\n    deque->front = dequeIndex(deque, deque->front - 1);\n    // \u5c06 num \u6dfb\u52a0\u5230\u961f\u9996\n    deque->nums[deque->front] = num;\n    deque->queSize++;\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = dequeIndex(deque, deque->front + deque->queSize);\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    deque->nums[rear] = num;\n    deque->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    return deque->nums[deque->front];\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    int last = dequeIndex(deque, deque->front + deque->queSize - 1);\n    return deque->nums[last];\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(ArrayDeque *deque) {\n    int num = peekFirst(deque);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    deque->front = dequeIndex(deque, deque->front + 1);\n    deque->queSize--;\n    return num;\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(ArrayDeque *deque) {\n    int num = peekLast(deque);\n    deque->queSize--;\n    return num;\n}\n
    array_deque.kt
    /* \u6784\u9020\u65b9\u6cd5 */\nclass ArrayDeque(capacity: Int) {\n    private var nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private fun index(i: Int): Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        queSize++\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        val rear = index(front + queSize)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        val num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1)\n        queSize--\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        val num = peekLast()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        val last = index(front + queSize - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[index(j)]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_deque.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass ArrayDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(capacity)\n    @nums = Array.new(capacity, 0)\n    @front = 0\n    @size = 0\n  end\n\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    @front = index(@front - 1)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    @nums[@front] = num\n    @size += 1\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear = index(@front + size)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    num = peek_first\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    @front = index(@front + 1)\n    @size -= 1\n    num\n  end\n\n  ### \u961f\u5c3e\u51fa\u961f ###\n  def pop_last\n    num = peek_last\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last = index(@front + size - 1)\n    @nums[last]\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res = []\n    for i in 0...size\n      res << @nums[index(@front + i)]\n    end\n    res\n  end\n\n  private\n\n  ### \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 ###\n  def index(i)\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    (i + capacity) % capacity\n  end\nend\n
    array_deque.zig
    [class]{ArrayDeque}-[func]{}\n
    "},{"location":"chapter_stack_and_queue/deque/#533-applications-of-double-ended-queue","title":"5.3.3 \u00a0 Applications of double-ended queue","text":"

    The double-ended queue combines the logic of both stacks and queues, thus, it can implement all their respective use cases while offering greater flexibility.

    We know that software's \"undo\" feature is typically implemented using a stack: the system pushes each change operation onto the stack and then pops to implement undoing. However, considering the limitations of system resources, software often restricts the number of undo steps (for example, only allowing the last 50 steps). When the stack length exceeds 50, the software needs to perform a deletion operation at the bottom of the stack (the front of the queue). But a regular stack cannot perform this function, where a double-ended queue becomes necessary. Note that the core logic of \"undo\" still follows the Last-In-First-Out principle of a stack, but a double-ended queue can more flexibly implement some additional logic.

    "},{"location":"chapter_stack_and_queue/queue/","title":"5.2 \u00a0 Queue","text":"

    \"Queue\" is a linear data structure that follows the First-In-First-Out (FIFO) rule. As the name suggests, a queue simulates the phenomenon of lining up, where newcomers join the queue at the rear, and the person at the front leaves the queue first.

    As shown in the Figure 5-4 , we call the front of the queue the \"head\" and the back the \"tail.\" The operation of adding elements to the rear of the queue is termed \"enqueue,\" and the operation of removing elements from the front is termed \"dequeue.\"

    Figure 5-4 \u00a0 Queue's first-in-first-out rule

    "},{"location":"chapter_stack_and_queue/queue/#521-common-operations-on-queue","title":"5.2.1 \u00a0 Common operations on queue","text":"

    The common operations on a queue are shown in the Table 5-2 . Note that method names may vary across different programming languages. Here, we use the same naming convention as that used for stacks.

    Table 5-2 \u00a0 Efficiency of queue operations

    Method Name Description Time Complexity push() Enqueue an element, add it to the tail \\(O(1)\\) pop() Dequeue the head element \\(O(1)\\) peek() Access the head element \\(O(1)\\)

    We can directly use the ready-made queue classes in programming languages:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig queue.py
    from collections import deque\n\n# Initialize the queue\n# In Python, we generally use the deque class as a queue\n# Although queue.Queue() is a pure queue class, it's not very user-friendly, so it's not recommended\nque: deque[int] = deque()\n\n# Enqueue elements\nque.append(1)\nque.append(3)\nque.append(2)\nque.append(5)\nque.append(4)\n\n# Access the first element\nfront: int = que[0]\n\n# Dequeue an element\npop: int = que.popleft()\n\n# Get the length of the queue\nsize: int = len(que)\n\n# Check if the queue is empty\nis_empty: bool = len(que) == 0\n
    queue.cpp
    /* Initialize the queue */\nqueue<int> queue;\n\n/* Enqueue elements */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* Access the first element*/\nint front = queue.front();\n\n/* Dequeue an element */\nqueue.pop();\n\n/* Get the length of the queue */\nint size = queue.size();\n\n/* Check if the queue is empty */\nbool empty = queue.empty();\n
    queue.java
    /* Initialize the queue */\nQueue<Integer> queue = new LinkedList<>();\n\n/* Enqueue elements */\nqueue.offer(1);\nqueue.offer(3);\nqueue.offer(2);\nqueue.offer(5);\nqueue.offer(4);\n\n/* Access the first element */\nint peek = queue.peek();\n\n/* Dequeue an element */\nint pop = queue.poll();\n\n/* Get the length of the queue */\nint size = queue.size();\n\n/* Check if the queue is empty */\nboolean isEmpty = queue.isEmpty();\n
    queue.cs
    /* Initialize the queue */\nQueue<int> queue = new();\n\n/* Enqueue elements */\nqueue.Enqueue(1);\nqueue.Enqueue(3);\nqueue.Enqueue(2);\nqueue.Enqueue(5);\nqueue.Enqueue(4);\n\n/* Access the first element */\nint peek = queue.Peek();\n\n/* Dequeue an element */\nint pop = queue.Dequeue();\n\n/* Get the length of the queue */\nint size = queue.Count;\n\n/* Check if the queue is empty */\nbool isEmpty = queue.Count == 0;\n
    queue_test.go
    /* Initialize the queue */\n// In Go, use list as a queue\nqueue := list.New()\n\n/* Enqueue elements */\nqueue.PushBack(1)\nqueue.PushBack(3)\nqueue.PushBack(2)\nqueue.PushBack(5)\nqueue.PushBack(4)\n\n/* Access the first element */\npeek := queue.Front()\n\n/* Dequeue an element */\npop := queue.Front()\nqueue.Remove(pop)\n\n/* Get the length of the queue */\nsize := queue.Len()\n\n/* Check if the queue is empty */\nisEmpty := queue.Len() == 0\n
    queue.swift
    /* Initialize the queue */\n// Swift does not have a built-in queue class, so Array can be used as a queue\nvar queue: [Int] = []\n\n/* Enqueue elements */\nqueue.append(1)\nqueue.append(3)\nqueue.append(2)\nqueue.append(5)\nqueue.append(4)\n\n/* Access the first element */\nlet peek = queue.first!\n\n/* Dequeue an element */\n// Since it's an array, removeFirst has a complexity of O(n)\nlet pool = queue.removeFirst()\n\n/* Get the length of the queue */\nlet size = queue.count\n\n/* Check if the queue is empty */\nlet isEmpty = queue.isEmpty\n
    queue.js
    /* Initialize the queue */\n// JavaScript does not have a built-in queue, so Array can be used as a queue\nconst queue = [];\n\n/* Enqueue elements */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* Access the first element */\nconst peek = queue[0];\n\n/* Dequeue an element */\n// Since the underlying structure is an array, shift() method has a time complexity of O(n)\nconst pop = queue.shift();\n\n/* Get the length of the queue */\nconst size = queue.length;\n\n/* Check if the queue is empty */\nconst empty = queue.length === 0;\n
    queue.ts
    /* Initialize the queue */\n// TypeScript does not have a built-in queue, so Array can be used as a queue \nconst queue: number[] = [];\n\n/* Enqueue elements */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* Access the first element */\nconst peek = queue[0];\n\n/* Dequeue an element */\n// Since the underlying structure is an array, shift() method has a time complexity of O(n)\nconst pop = queue.shift();\n\n/* Get the length of the queue */\nconst size = queue.length;\n\n/* Check if the queue is empty */\nconst empty = queue.length === 0;\n
    queue.dart
    /* Initialize the queue */\n// In Dart, the Queue class is a double-ended queue but can be used as a queue\nQueue<int> queue = Queue();\n\n/* Enqueue elements */\nqueue.add(1);\nqueue.add(3);\nqueue.add(2);\nqueue.add(5);\nqueue.add(4);\n\n/* Access the first element */\nint peek = queue.first;\n\n/* Dequeue an element */\nint pop = queue.removeFirst();\n\n/* Get the length of the queue */\nint size = queue.length;\n\n/* Check if the queue is empty */\nbool isEmpty = queue.isEmpty;\n
    queue.rs
    /* Initialize the double-ended queue */\n// In Rust, use a double-ended queue as a regular queue\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* Enqueue elements */\ndeque.push_back(1);\ndeque.push_back(3);\ndeque.push_back(2);\ndeque.push_back(5);\ndeque.push_back(4);\n\n/* Access the first element */\nif let Some(front) = deque.front() {\n}\n\n/* Dequeue an element */\nif let Some(pop) = deque.pop_front() {\n}\n\n/* Get the length of the queue */\nlet size = deque.len();\n\n/* Check if the queue is empty */\nlet is_empty = deque.is_empty();\n
    queue.c
    // C does not provide a built-in queue\n
    queue.kt
    \n
    queue.zig
    \n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/queue/#522-implementing-a-queue","title":"5.2.2 \u00a0 Implementing a queue","text":"

    To implement a queue, we need a data structure that allows adding elements at one end and removing them at the other. Both linked lists and arrays meet this requirement.

    "},{"location":"chapter_stack_and_queue/queue/#1-implementation-based-on-a-linked-list","title":"1. \u00a0 Implementation based on a linked list","text":"

    As shown in the Figure 5-5 , we can consider the \"head node\" and \"tail node\" of a linked list as the \"front\" and \"rear\" of the queue, respectively. It is stipulated that nodes can only be added at the rear and removed at the front.

    LinkedListQueuepush()pop()

    Figure 5-5 \u00a0 Implementing Queue with Linked List for Enqueue and Dequeue Operations

    Below is the code for implementing a queue using a linked list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_queue.py
    class LinkedListQueue:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        node = ListNode(num)\n        # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if self._front is None:\n            self._front = node\n            self._rear = node\n        # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else:\n            self._rear.next = node\n            self._rear = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num = self.peek()\n        # \u5220\u9664\u5934\u8282\u70b9\n        self._front = self._front.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        queue = []\n        temp = self._front\n        while temp:\n            queue.append(temp.val)\n            temp = temp.next\n        return queue\n
    linkedlist_queue.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  private:\n    ListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;\n\n  public:\n    LinkedListQueue() {\n        front = nullptr;\n        rear = nullptr;\n        queSize = 0;\n    }\n\n    ~LinkedListQueue() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(front);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode *node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == nullptr) {\n            front = node;\n            rear = node;\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear->next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        ListNode *tmp = front;\n        front = front->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (size() == 0)\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_queue.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    ListNode? front, rear;  // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear \n    int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else if (rear != null) {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (front == null)\n            return [];\n\n        ListNode? node = front;\n        int[] res = new int[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntype linkedListQueue struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u961f\u5217\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newLinkedListQueue() *linkedListQueue {\n    return &linkedListQueue{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u961f */\nfunc (s *linkedListQueue) push(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u961f */\nfunc (s *linkedListQueue) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListQueue) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListQueue) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListQueue) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListQueue) toList() *list.List {\n    return s.data\n}\n
    linkedlist_queue.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private var front: ListNode? // \u5934\u8282\u70b9\n    private var rear: ListNode? // \u5c3e\u8282\u70b9\n    private var _size: Int\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let node = ListNode(x: num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if front == nil {\n            front = node\n            rear = node\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear?.next = node\n            rear = node\n        }\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    #front; // \u5934\u8282\u70b9 #front\n    #rear; // \u5c3e\u8282\u70b9 #rear\n    #queSize = 0;\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.#front) {\n            this.#front = node;\n            this.#rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.#rear.next = node;\n            this.#rear = node;\n        }\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.#front = this.#front.next;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#front;\n        const res = new Array(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private front: ListNode | null; // \u5934\u8282\u70b9 front\n    private rear: ListNode | null; // \u5c3e\u8282\u70b9 rear\n    private queSize: number = 0;\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.front) {\n            this.front = node;\n            this.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.rear!.next = node;\n            this.rear = node;\n        }\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        if (!this.front) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.front = this.front.next;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.front;\n        const res = new Array<number>(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.dart
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  ListNode? _front; // \u5934\u8282\u70b9 _front\n  ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n  LinkedListQueue() {\n    _front = null;\n    _rear = null;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 _num\n    final node = ListNode(_num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (_front == null) {\n      _front = node;\n      _rear = node;\n    } else {\n      // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n      _rear!.next = node;\n      _rear = node;\n    }\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    final int _num = peek();\n    // \u5220\u9664\u5934\u8282\u70b9\n    _front = _front!.next;\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (_queSize == 0) {\n      throw Exception('\u961f\u5217\u4e3a\u7a7a');\n    }\n    return _front!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> queue = [];\n    while (node != null) {\n      queue.add(node.val);\n      node = node.next;\n    }\n    return queue;\n  }\n}\n
    linkedlist_queue.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListQueue<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListQueue<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f */\n    pub fn push(&mut self, num: T) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let new_rear = ListNode::new(num);\n        match self.rear.take() {\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            Some(old_rear) => {\n                old_rear.borrow_mut().next = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            None => {\n                self.front = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n        }\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    pub fn pop(&mut self) -> Option<T> {\n        self.front.take().map(|old_front| {\n            match old_front.borrow_mut().next.take() {\n                Some(new_front) => {\n                    self.front = Some(new_front);\n                }\n                None => {\n                    self.rear.take();\n                }\n            }\n            self.que_size -= 1;\n            Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_queue.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    ListNode *front, *rear;\n    int queSize;\n} LinkedListQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListQueue *newLinkedListQueue() {\n    LinkedListQueue *queue = (LinkedListQueue *)malloc(sizeof(LinkedListQueue));\n    queue->front = NULL;\n    queue->rear = NULL;\n    queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListQueue(LinkedListQueue *queue) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    while (queue->front != NULL) {\n        ListNode *tmp = queue->front;\n        queue->front = queue->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e queue \u7ed3\u6784\u4f53\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListQueue *queue) {\n    return (size(queue) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListQueue *queue, int num) {\n    // \u5c3e\u8282\u70b9\u5904\u6dfb\u52a0 node\n    ListNode *node = newListNode(num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (queue->front == NULL) {\n        queue->front = node;\n        queue->rear = node;\n    }\n    // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else {\n        queue->rear->next = node;\n        queue->rear = node;\n    }\n    queue->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(LinkedListQueue *queue) {\n    assert(size(queue) && queue->front);\n    return queue->front->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListQueue *queue) {\n    int num = peek(queue);\n    ListNode *tmp = queue->front;\n    queue->front = queue->front->next;\n    free(tmp);\n    queue->queSize--;\n    return num;\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListQueue(LinkedListQueue *queue) {\n    int *arr = malloc(sizeof(int) * queue->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    ListNode *node;\n    for (i = 0, node = queue->front; i < queue->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, queue->queSize);\n    free(arr);\n}\n
    linkedlist_queue.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue(\n    // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private var front: ListNode? = null,\n    private var rear: ListNode? = null,\n    private var queSize: Int = 0\n) {\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        val node = ListNode(num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node\n            rear = node\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear?.next = node\n            rear = node\n        }\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5934\u73b0\u7684\u961f\u5217 ###\nclass LinkedListQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @front.nil?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n    node = ListNode.new(num)\n\n    # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\uff0c\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if @front.nil?\n      @front = node\n      @rear = node\n    # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u4ee4\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else\n      @rear.next = node\n      @rear = node\n    end\n\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u5220\u9664\u5934\u8282\u70b9\n    @front = @front.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u5c06\u94fe\u8868\u4e3a Array \u5e76\u8fd4\u56de ###\n  def to_array\n    queue = []\n    temp = @front\n    while temp\n      queue << temp.val\n      temp = temp.next\n    end\n    queue\n  end\nend\n
    linkedlist_queue.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\nfn LinkedListQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*inc.ListNode(T) = null,                // \u5934\u8282\u70b9 front\n        rear: ?*inc.ListNode(T) = null,                 // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                            // \u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            if (self.front == null) {\n                self.front = node;\n                self.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            } else {\n                self.rear.?.next = node;\n                self.rear = node;\n            }\n            self.que_size += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u5220\u9664\u5934\u8282\u70b9\n            self.front = self.front.?.next;\n            self.que_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/queue/#2-implementation-based-on-an-array","title":"2. \u00a0 Implementation based on an array","text":"

    Deleting the first element in an array has a time complexity of \\(O(n)\\), which would make the dequeue operation inefficient. However, this problem can be cleverly avoided as follows.

    We use a variable front to indicate the index of the front element and maintain a variable size to record the queue's length. Define rear = front + size, which points to the position immediately following the tail element.

    With this design, the effective interval of elements in the array is [front, rear - 1]. The implementation methods for various operations are shown in the Figure 5-6 .

    • Enqueue operation: Assign the input element to the rear index and increase size by 1.
    • Dequeue operation: Simply increase front by 1 and decrease size by 1.

    Both enqueue and dequeue operations only require a single operation, each with a time complexity of \\(O(1)\\).

    ArrayQueuepush()pop()

    Figure 5-6 \u00a0 Implementing Queue with Array for Enqueue and Dequeue Operations

    You might notice a problem: as enqueue and dequeue operations are continuously performed, both front and rear move to the right and will eventually reach the end of the array and can't move further. To resolve this, we can treat the array as a \"circular array\" where connecting the end of the array back to its beginning.

    In a circular array, front or rear needs to loop back to the start of the array upon reaching the end. This cyclical pattern can be achieved with a \"modulo operation\" as shown in the code below:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_queue.py
    class ArrayQueue:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self, size: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * size  # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n        self._front: int = 0  # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        self._size: int = 0  # \u961f\u5217\u957f\u5ea6\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            raise IndexError(\"\u961f\u5217\u5df2\u6ee1\")\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        rear: int = (self._front + self._size) % self.capacity()\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num: int = self.peek()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self._front = (self._front + 1) % self.capacity()\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        res = [0] * self.size()\n        j: int = self._front\n        for i in range(self.size()):\n            res[i] = self._nums[(j % self.capacity())]\n            j += 1\n        return res\n
    array_queue.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  private:\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u961f\u5217\u957f\u5ea6\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n\n  public:\n    ArrayQueue(int capacity) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = new int[capacity];\n        queCapacity = capacity;\n        front = queSize = 0;\n    }\n\n    ~ArrayQueue() {\n        delete[] nums;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return queCapacity;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        if (queSize == queCapacity) {\n            cout << \"\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % queCapacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % queCapacity;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u5c06\u6570\u7ec4\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> arr(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            arr[i] = nums[j % queCapacity];\n        }\n        return arr;\n    }\n};\n
    array_queue.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % Capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % Capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % this.Capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntype arrayQueue struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayQueue(queCapacity int) *arrayQueue {\n    return &arrayQueue{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayQueue) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayQueue) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u5165\u961f */\nfunc (q *arrayQueue) push(num int) {\n    // \u5f53 rear == queCapacity \u8868\u793a\u961f\u5217\u5df2\u6ee1\n    if q.queSize == q.queCapacity {\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear := (q.front + q.queSize) % q.queCapacity\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u51fa\u961f */\nfunc (q *arrayQueue) pop() any {\n    num := q.peek()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    q.front = (q.front + 1) % q.queCapacity\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayQueue) peek() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayQueue) toSlice() []int {\n    rear := (q.front + q.queSize)\n    if rear >= q.queCapacity {\n        rear %= q.queCapacity\n        return append(q.nums[q.front:], q.nums[:rear]...)\n    }\n    return q.nums[q.front:rear]\n}\n
    array_queue.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u961f\u5217\u957f\u5ea6\n\n    init(capacity: Int) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        if size() == capacity() {\n            print(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (front + size()) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[$0 % capacity()] }\n    }\n}\n
    array_queue.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front = 0; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.#front + this.size) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.#front = (this.#front + 1) % this.capacity;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.#front; i < this.size; i++, j++) {\n            arr[i] = this.#nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.front + this.queSize) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.front = (this.front + 1) % this.capacity;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.nums[this.front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.front; i < this.size; i++, j++) {\n            arr[i] = this.nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  late List<int> _nums; // \u7528\u4e8e\u50a8\u5b58\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u961f\u5217\u957f\u5ea6\n\n  ArrayQueue(int capacity) {\n    _nums = List.filled(capacity, 0);\n    _front = _queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n  int capaCity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    if (_queSize == capaCity()) {\n      throw Exception(\"\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (_front + _queSize) % capaCity();\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    int _num = peek();\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    _front = (_front + 1) % capaCity();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8fd4\u56de Array */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    final List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[j % capaCity()];\n    }\n    return res;\n  }\n}\n
    array_queue.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nstruct ArrayQueue {\n    nums: Vec<i32>,    // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: i32,        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: i32,     // \u961f\u5217\u957f\u5ea6\n    que_capacity: i32, // \u961f\u5217\u5bb9\u91cf\n}\n\nimpl ArrayQueue {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(capacity: i32) -> ArrayQueue {\n        ArrayQueue {\n            nums: vec![0; capacity as usize],\n            front: 0,\n            que_size: 0,\n            que_capacity: capacity,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fn capacity(&self) -> i32 {\n        self.que_capacity\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fn size(&self) -> i32 {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u5165\u961f */\n    fn push(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (self.front + self.que_size) % self.que_capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear as usize] = num;\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    fn pop(&mut self) -> i32 {\n        let num = self.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self.front = (self.front + 1) % self.que_capacity;\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"index out of bounds\");\n        }\n        self.nums[self.front as usize]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fn to_vector(&self) -> Vec<i32> {\n        let cap = self.que_capacity;\n        let mut j = self.front;\n        let mut arr = vec![0; self.que_size as usize];\n        for i in 0..self.que_size {\n            arr[i as usize] = self.nums[(j % cap) as usize];\n            j += 1;\n        }\n        arr\n    }\n}\n
    array_queue.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayQueue *newArrayQueue(int capacity) {\n    ArrayQueue *queue = (ArrayQueue *)malloc(sizeof(ArrayQueue));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    queue->queCapacity = capacity;\n    queue->nums = (int *)malloc(sizeof(int) * queue->queCapacity);\n    queue->front = queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayQueue(ArrayQueue *queue) {\n    free(queue->nums);\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayQueue *queue) {\n    return queue->queCapacity;\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayQueue *queue) {\n    return queue->queSize == 0;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(ArrayQueue *queue) {\n    assert(size(queue) != 0);\n    return queue->nums[queue->front];\n}\n\n/* \u5165\u961f */\nvoid push(ArrayQueue *queue, int num) {\n    if (size(queue) == capacity(queue)) {\n        printf(\"\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (queue->front + queue->queSize) % queue->queCapacity;\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    queue->nums[rear] = num;\n    queue->queSize++;\n}\n\n/* \u51fa\u961f */\nint pop(ArrayQueue *queue) {\n    int num = peek(queue);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    queue->front = (queue->front + 1) % queue->queCapacity;\n    queue->queSize--;\n    return num;\n}\n
    array_queue.kt
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue(capacity: Int) {\n    private val nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        val rear = (front + queSize) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[j % capacity()]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_queue.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 ###\nclass ArrayQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(size)\n    @nums = Array.new(size, 0) # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    @front = 0 # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    @size = 0 # \u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    raise IndexError, '\u961f\u5217\u5df2\u6ee1' if size == capacity\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear = (@front + size) % capacity\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    @front = (@front + 1) % capacity\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    res = Array.new(size, 0)\n    j = @front\n\n    for i in 0...size\n      res[i] = @nums[j % capacity]\n      j += 1\n    end\n\n    res\n  end\nend\n
    array_queue.zig
    // \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\nfn ArrayQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        nums: []T = undefined,                          // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4     \n        cap: usize = 0,                                 // \u961f\u5217\u5bb9\u91cf\n        front: usize = 0,                               // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        queSize: usize = 0,                             // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6570\u7ec4\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator, cap: usize) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.cap = cap;\n            self.nums = try self.mem_allocator.alloc(T, self.cap);\n            @memset(self.nums, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.cap;\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.queSize;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.queSize == 0;\n        }\n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            if (self.size() == self.capacity()) {\n                std.debug.print(\"\u961f\u5217\u5df2\u6ee1\\n\", .{});\n                return;\n            }\n            // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n            // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n            var rear = (self.front + self.queSize) % self.capacity();\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            self.nums[rear] = num;\n            self.queSize += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n            self.front = (self.front + 1) % self.capacity();\n            self.queSize -= 1;\n            return num;\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.nums[self.front];\n        } \n\n        // \u8fd4\u56de\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            var j: usize = self.front;\n            while (i < self.size()) : ({ i += 1; j += 1; }) {\n                res[i] = self.nums[j % self.capacity()];\n            }\n            return res;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    The above implementation of the queue still has its limitations: its length is fixed. However, this issue is not difficult to resolve. We can replace the array with a dynamic array that can expand itself if needed. Interested readers can try to implement this themselves.

    The comparison of the two implementations is consistent with that of the stack and is not repeated here.

    "},{"location":"chapter_stack_and_queue/queue/#523-typical-applications-of-queue","title":"5.2.3 \u00a0 Typical applications of queue","text":"
    • Amazon orders: After shoppers place orders, these orders join a queue, and the system processes them in order. During events like Singles' Day, a massive number of orders are generated in a short time, making high concurrency a key challenge for engineers.
    • Various to-do lists: Any scenario requiring a \"first-come, first-served\" functionality, such as a printer's task queue or a restaurant's food delivery queue, can effectively maintain the order of processing with a queue.
    "},{"location":"chapter_stack_and_queue/stack/","title":"5.1 \u00a0 Stack","text":"

    A \"Stack\" is a linear data structure that follows the principle of Last-In-First-Out (LIFO).

    We can compare a stack to a pile of plates on a table. To access the bottom plate, one must first remove the plates on top. By replacing the plates with various types of elements (such as integers, characters, objects, etc.), we obtain the data structure known as a stack.

    As shown in the Figure 5-1 , we refer to the top of the pile of elements as the \"top of the stack\" and the bottom as the \"bottom of the stack.\" The operation of adding elements to the top of the stack is called \"push,\" and the operation of removing the top element is called \"pop.\"

    Figure 5-1 \u00a0 Stack's last-in-first-out rule

    "},{"location":"chapter_stack_and_queue/stack/#511-common-operations-on-stack","title":"5.1.1 \u00a0 Common operations on stack","text":"

    The common operations on a stack are shown in the Table 5-1 . The specific method names depend on the programming language used. Here, we use push(), pop(), and peek() as examples.

    Table 5-1 \u00a0 Efficiency of stack operations

    Method Description Time Complexity push() Push an element onto the stack (add to the top) \\(O(1)\\) pop() Pop the top element from the stack \\(O(1)\\) peek() Access the top element of the stack \\(O(1)\\)

    Typically, we can directly use the stack class built into the programming language. However, some languages may not specifically provide a stack class. In these cases, we can use the language's \"array\" or \"linked list\" as a stack and ignore operations that are not related to stack logic in the program.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinZig stack.py
    # Initialize the stack\n# Python does not have a built-in stack class, so a list can be used as a stack\nstack: list[int] = []\n\n# Push elements onto the stack\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n# Access the top element of the stack\npeek: int = stack[-1]\n\n# Pop an element from the stack\npop: int = stack.pop()\n\n# Get the length of the stack\nsize: int = len(stack)\n\n# Check if the stack is empty\nis_empty: bool = len(stack) == 0\n
    stack.cpp
    /* Initialize the stack */\nstack<int> stack;\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nint top = stack.top();\n\n/* Pop an element from the stack */\nstack.pop(); // No return value\n\n/* Get the length of the stack */\nint size = stack.size();\n\n/* Check if the stack is empty */\nbool empty = stack.empty();\n
    stack.java
    /* Initialize the stack */\nStack<Integer> stack = new Stack<>();\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nint peek = stack.peek();\n\n/* Pop an element from the stack */\nint pop = stack.pop();\n\n/* Get the length of the stack */\nint size = stack.size();\n\n/* Check if the stack is empty */\nboolean isEmpty = stack.isEmpty();\n
    stack.cs
    /* Initialize the stack */\nStack<int> stack = new();\n\n/* Push elements onto the stack */\nstack.Push(1);\nstack.Push(3);\nstack.Push(2);\nstack.Push(5);\nstack.Push(4);\n\n/* Access the top element of the stack */\nint peek = stack.Peek();\n\n/* Pop an element from the stack */\nint pop = stack.Pop();\n\n/* Get the length of the stack */\nint size = stack.Count;\n\n/* Check if the stack is empty */\nbool isEmpty = stack.Count == 0;\n
    stack_test.go
    /* Initialize the stack */\n// In Go, it is recommended to use a Slice as a stack\nvar stack []int\n\n/* Push elements onto the stack */\nstack = append(stack, 1)\nstack = append(stack, 3)\nstack = append(stack, 2)\nstack = append(stack, 5)\nstack = append(stack, 4)\n\n/* Access the top element of the stack */\npeek := stack[len(stack)-1]\n\n/* Pop an element from the stack */\npop := stack[len(stack)-1]\nstack = stack[:len(stack)-1]\n\n/* Get the length of the stack */\nsize := len(stack)\n\n/* Check if the stack is empty */\nisEmpty := len(stack) == 0\n
    stack.swift
    /* Initialize the stack */\n// Swift does not have a built-in stack class, so Array can be used as a stack\nvar stack: [Int] = []\n\n/* Push elements onto the stack */\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n/* Access the top element of the stack */\nlet peek = stack.last!\n\n/* Pop an element from the stack */\nlet pop = stack.removeLast()\n\n/* Get the length of the stack */\nlet size = stack.count\n\n/* Check if the stack is empty */\nlet isEmpty = stack.isEmpty\n
    stack.js
    /* Initialize the stack */\n// JavaScript does not have a built-in stack class, so Array can be used as a stack\nconst stack = [];\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nconst peek = stack[stack.length-1];\n\n/* Pop an element from the stack */\nconst pop = stack.pop();\n\n/* Get the length of the stack */\nconst size = stack.length;\n\n/* Check if the stack is empty */\nconst is_empty = stack.length === 0;\n
    stack.ts
    /* Initialize the stack */\n// TypeScript does not have a built-in stack class, so Array can be used as a stack\nconst stack: number[] = [];\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nconst peek = stack[stack.length - 1];\n\n/* Pop an element from the stack */\nconst pop = stack.pop();\n\n/* Get the length of the stack */\nconst size = stack.length;\n\n/* Check if the stack is empty */\nconst is_empty = stack.length === 0;\n
    stack.dart
    /* Initialize the stack */\n// Dart does not have a built-in stack class, so List can be used as a stack\nList<int> stack = [];\n\n/* Push elements onto the stack */\nstack.add(1);\nstack.add(3);\nstack.add(2);\nstack.add(5);\nstack.add(4);\n\n/* Access the top element of the stack */\nint peek = stack.last;\n\n/* Pop an element from the stack */\nint pop = stack.removeLast();\n\n/* Get the length of the stack */\nint size = stack.length;\n\n/* Check if the stack is empty */\nbool isEmpty = stack.isEmpty;\n
    stack.rs
    /* Initialize the stack */\n// Use Vec as a stack\nlet mut stack: Vec<i32> = Vec::new();\n\n/* Push elements onto the stack */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* Access the top element of the stack */\nlet top = stack.last().unwrap();\n\n/* Pop an element from the stack */\nlet pop = stack.pop().unwrap();\n\n/* Get the length of the stack */\nlet size = stack.len();\n\n/* Check if the stack is empty */\nlet is_empty = stack.is_empty();\n
    stack.c
    // C does not provide a built-in stack\n
    stack.kt
    \n
    stack.zig
    \n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/stack/#512-implementing-a-stack","title":"5.1.2 \u00a0 Implementing a stack","text":"

    To gain a deeper understanding of how a stack operates, let's try implementing a stack class ourselves.

    A stack follows the principle of Last-In-First-Out, which means we can only add or remove elements at the top of the stack. However, both arrays and linked lists allow adding and removing elements at any position, therefore a stack can be seen as a restricted array or linked list. In other words, we can \"shield\" certain irrelevant operations of an array or linked list, aligning their external behavior with the characteristics of a stack.

    "},{"location":"chapter_stack_and_queue/stack/#1-implementation-based-on-a-linked-list","title":"1. \u00a0 Implementation based on a linked list","text":"

    When implementing a stack using a linked list, we can consider the head node of the list as the top of the stack and the tail node as the bottom of the stack.

    As shown in the Figure 5-2 , for the push operation, we simply insert elements at the head of the linked list. This method of node insertion is known as \"head insertion.\" For the pop operation, we just need to remove the head node from the list.

    LinkedListStackpush()pop()

    Figure 5-2 \u00a0 Implementing Stack with Linked List for Push and Pop Operations

    Below is an example code for implementing a stack based on a linked list:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_stack.py
    class LinkedListStack:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._peek: ListNode | None = None\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, val: int):\n        \"\"\"\u5165\u6808\"\"\"\n        node = ListNode(val)\n        node.next = self._peek\n        self._peek = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        num = self.peek()\n        self._peek = self._peek.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._peek.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        arr = []\n        node = self._peek\n        while node:\n            arr.append(node.val)\n            node = node.next\n        arr.reverse()\n        return arr\n
    linkedlist_stack.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  private:\n    ListNode *stackTop; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize;        // \u6808\u7684\u957f\u5ea6\n\n  public:\n    LinkedListStack() {\n        stackTop = nullptr;\n        stkSize = 0;\n    }\n\n    ~LinkedListStack() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(stackTop);\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        ListNode *node = new ListNode(num);\n        node->next = stackTop;\n        stackTop = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        ListNode *tmp = stackTop;\n        stackTop = stackTop->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stackTop->val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = stackTop;\n        vector<int> res(size());\n        for (int i = res.size() - 1; i >= 0; i--) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_stack.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private ListNode stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private int stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        ListNode node = new ListNode(num);\n        node.next = stackPeek;\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        int num = peek();\n        stackPeek = stackPeek.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stackPeek.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = stackPeek;\n        int[] res = new int[size()];\n        for (int i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    ListNode? stackPeek;  // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize = 0;   // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        ListNode node = new(num) {\n            next = stackPeek\n        };\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        int num = Peek();\n        stackPeek = stackPeek!.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stackPeek!.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (stackPeek == null)\n            return [];\n\n        ListNode? node = stackPeek;\n        int[] res = new int[Size()];\n        for (int i = res.Length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntype linkedListStack struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u6808\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newLinkedListStack() *linkedListStack {\n    return &linkedListStack{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u6808 */\nfunc (s *linkedListStack) push(value int) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u6808 */\nfunc (s *linkedListStack) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nfunc (s *linkedListStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nfunc (s *linkedListStack) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListStack) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListStack) toList() *list.List {\n    return s.data\n}\n
    linkedlist_stack.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private var _peek: ListNode? // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var _size: Int // \u6808\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        let node = ListNode(x: num)\n        node.next = _peek\n        _peek = node\n        _size += 1\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        _peek = _peek?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return _peek!.val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = _peek\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices.reversed() {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    #stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    #stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        const node = new ListNode(num);\n        node.next = this.#stackPeek;\n        this.#stackPeek = node;\n        this.#stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        const num = this.peek();\n        this.#stackPeek = this.#stackPeek.next;\n        this.#stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek() {\n        if (!this.#stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#stackPeek;\n        const res = new Array(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private stackPeek: ListNode | null; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private stkSize: number = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        const node = new ListNode(num);\n        node.next = this.stackPeek;\n        this.stackPeek = node;\n        this.stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        this.stackPeek = this.stackPeek.next;\n        this.stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek(): number {\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.stackPeek;\n        const res = new Array<number>(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.dart
    /* \u57fa\u4e8e\u94fe\u8868\u7c7b\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  ListNode? _stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n  int _stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n  LinkedListStack() {\n    _stackPeek = null;\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stkSize;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stkSize == 0;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    final ListNode node = ListNode(_num);\n    node.next = _stackPeek;\n    _stackPeek = node;\n    _stkSize++;\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    final int _num = peek();\n    _stackPeek = _stackPeek!.next;\n    _stkSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (_stackPeek == null) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stackPeek!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a List \u5e76\u8fd4\u56de */\n  List<int> toList() {\n    ListNode? node = _stackPeek;\n    List<int> list = [];\n    while (node != null) {\n      list.add(node.val);\n      node = node.next;\n    }\n    list = list.reversed.toList();\n    return list;\n  }\n}\n
    linkedlist_stack.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\n#[allow(dead_code)]\npub struct LinkedListStack<T> {\n    stack_peek: Option<Rc<RefCell<ListNode<T>>>>, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    stk_size: usize,                              // \u6808\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListStack<T> {\n    pub fn new() -> Self {\n        Self {\n            stack_peek: None,\n            stk_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.stk_size;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    pub fn push(&mut self, num: T) {\n        let node = ListNode::new(num);\n        node.borrow_mut().next = self.stack_peek.take();\n        self.stack_peek = Some(node);\n        self.stk_size += 1;\n    }\n\n    /* \u51fa\u6808 */\n    pub fn pop(&mut self) -> Option<T> {\n        self.stack_peek.take().map(|old_head| {\n            match old_head.borrow_mut().next.take() {\n                Some(new_head) => {\n                    self.stack_peek = Some(new_head);\n                }\n                None => {\n                    self.stack_peek = None;\n                }\n            }\n            self.stk_size -= 1;\n            Rc::try_unwrap(old_head).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.stack_peek.as_ref()\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.push(node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_stack.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    ListNode *top; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int size;      // \u6808\u7684\u957f\u5ea6\n} LinkedListStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListStack *newLinkedListStack() {\n    LinkedListStack *s = malloc(sizeof(LinkedListStack));\n    s->top = NULL;\n    s->size = 0;\n    return s;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListStack(LinkedListStack *s) {\n    while (s->top) {\n        ListNode *n = s->top->next;\n        free(s->top);\n        s->top = n;\n    }\n    free(s);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(LinkedListStack *s) {\n    return s->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(LinkedListStack *s) {\n    return size(s) == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(LinkedListStack *s, int num) {\n    ListNode *node = (ListNode *)malloc(sizeof(ListNode));\n    node->next = s->top; // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6307\u9488\u57df\n    node->val = num;     // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6570\u636e\u57df\n    s->top = node;       // \u66f4\u65b0\u6808\u9876\n    s->size++;           // \u66f4\u65b0\u6808\u5927\u5c0f\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(LinkedListStack *s) {\n    if (s->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return s->top->val;\n}\n\n/* \u51fa\u6808 */\nint pop(LinkedListStack *s) {\n    int val = peek(s);\n    ListNode *tmp = s->top;\n    s->top = s->top->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n    s->size--;\n    return val;\n}\n
    linkedlist_stack.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack(\n    private var stackPeek: ListNode? = null, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var stkSize: Int = 0 // \u6808\u7684\u957f\u5ea6\n) {\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stkSize\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        val node = ListNode(num)\n        node.next = stackPeek\n        stackPeek = node\n        stkSize++\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int? {\n        val num = peek()\n        stackPeek = stackPeek?.next\n        stkSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int? {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stackPeek?._val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = stackPeek\n        val res = IntArray(size())\n        for (i in res.size - 1 downTo 0) {\n            res[i] = node?._val!!\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 ###\nclass LinkedListStack\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @peek.nil?\n  end\n\n  ### \u5165\u6808 ###\n  def push(val)\n    node = ListNode.new(val)\n    node.next = @peek\n    @peek = node\n    @size += 1\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    num = peek\n    @peek = @peek.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @peek.val\n  end\n\n  ### \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u53cd\u56de ###\n  def to_array\n    arr = []\n    node = @peek\n    while node\n      arr << node.val\n      node = node.next\n    end\n    arr.reverse\n  end\nend\n
    linkedlist_stack.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\nfn LinkedListStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack_top: ?*inc.ListNode(T) = null,             // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n        stk_size: usize = 0,                             // \u6808\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,    // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.stack_top = null;\n            self.stk_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stk_size;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack_top.?.val;\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            node.next = self.stack_top;\n            self.stack_top = node;\n            self.stk_size += 1;\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            self.stack_top = self.stack_top.?.next;\n            self.stk_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u6808\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.stack_top;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[res.len - i - 1] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/stack/#2-implementation-based-on-an-array","title":"2. \u00a0 Implementation based on an array","text":"

    When implementing a stack using an array, we can consider the end of the array as the top of the stack. As shown in the Figure 5-3 , push and pop operations correspond to adding and removing elements at the end of the array, respectively, both with a time complexity of \\(O(1)\\).

    ArrayStackpush()pop()

    Figure 5-3 \u00a0 Implementing Stack with Array for Push and Pop Operations

    Since the elements to be pushed onto the stack may continuously increase, we can use a dynamic array, thus avoiding the need to handle array expansion ourselves. Here is an example code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_stack.py
    class ArrayStack:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._stack: list[int] = []\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return len(self._stack)\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self.size() == 0\n\n    def push(self, item: int):\n        \"\"\"\u5165\u6808\"\"\"\n        self._stack.append(item)\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack.pop()\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack[-1]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        return self._stack\n
    array_stack.cpp
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  private:\n    vector<int> stack;\n\n  public:\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return stack.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        stack.push_back(num);\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        stack.pop_back();\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stack.back();\n    }\n\n    /* \u8fd4\u56de Vector */\n    vector<int> toVector() {\n        return stack;\n    }\n};\n
    array_stack.java
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private ArrayList<Integer> stack;\n\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = new ArrayList<>();\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        stack.add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.remove(size() - 1);\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.get(size() - 1);\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public Object[] toArray() {\n        return stack.toArray();\n    }\n}\n
    array_stack.cs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    List<int> stack;\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stack.Count;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        stack.Add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        if (IsEmpty())\n            throw new Exception();\n        var val = Peek();\n        stack.RemoveAt(Size() - 1);\n        return val;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stack[Size() - 1];\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        return [.. stack];\n    }\n}\n
    array_stack.go
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntype arrayStack struct {\n    data []int // \u6570\u636e\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newArrayStack() *arrayStack {\n    return &arrayStack{\n        // \u8bbe\u7f6e\u6808\u7684\u957f\u5ea6\u4e3a 0\uff0c\u5bb9\u91cf\u4e3a 16\n        data: make([]int, 0, 16),\n    }\n}\n\n/* \u6808\u7684\u957f\u5ea6 */\nfunc (s *arrayStack) size() int {\n    return len(s.data)\n}\n\n/* \u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *arrayStack) isEmpty() bool {\n    return s.size() == 0\n}\n\n/* \u5165\u6808 */\nfunc (s *arrayStack) push(v int) {\n    // \u5207\u7247\u4f1a\u81ea\u52a8\u6269\u5bb9\n    s.data = append(s.data, v)\n}\n\n/* \u51fa\u6808 */\nfunc (s *arrayStack) pop() any {\n    val := s.peek()\n    s.data = s.data[:len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6\u6808\u9876\u5143\u7d20 */\nfunc (s *arrayStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    val := s.data[len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (s *arrayStack) toSlice() []int {\n    return s.data\n}\n
    array_stack.swift
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private var stack: [Int]\n\n    init() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = []\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        stack.count\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        stack.isEmpty\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        stack.append(num)\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.removeLast()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.last!\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        stack\n    }\n}\n
    array_stack.js
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    #stack;\n    constructor() {\n        this.#stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        this.#stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack[this.#stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.#stack;\n    }\n}\n
    array_stack.ts
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private stack: number[];\n    constructor() {\n        this.stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        this.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack[this.stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.stack;\n    }\n}\n
    array_stack.dart
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  late List<int> _stack;\n  ArrayStack() {\n    _stack = [];\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stack.length;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stack.isEmpty;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    _stack.add(_num);\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.removeLast();\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.last;\n  }\n\n  /* \u5c06\u6808\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() => _stack;\n}\n
    array_stack.rs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nstruct ArrayStack<T> {\n    stack: Vec<T>,\n}\n\nimpl<T> ArrayStack<T> {\n    /* \u521d\u59cb\u5316\u6808 */\n    fn new() -> ArrayStack<T> {\n        ArrayStack::<T> {\n            stack: Vec::<T>::new(),\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fn size(&self) -> usize {\n        self.stack.len()\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fn push(&mut self, num: T) {\n        self.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    fn pop(&mut self) -> Option<T> {\n        self.stack.pop()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fn peek(&self) -> Option<&T> {\n        if self.is_empty() {\n            panic!(\"\u6808\u4e3a\u7a7a\")\n        };\n        self.stack.last()\n    }\n\n    /* \u8fd4\u56de &Vec */\n    fn to_array(&self) -> &Vec<T> {\n        &self.stack\n    }\n}\n
    array_stack.c
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    int *data;\n    int size;\n} ArrayStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayStack *newArrayStack() {\n    ArrayStack *stack = malloc(sizeof(ArrayStack));\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5927\u5bb9\u91cf\uff0c\u907f\u514d\u6269\u5bb9\n    stack->data = malloc(sizeof(int) * MAX_SIZE);\n    stack->size = 0;\n    return stack;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayStack(ArrayStack *stack) {\n    free(stack->data);\n    free(stack);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(ArrayStack *stack) {\n    return stack->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(ArrayStack *stack) {\n    return stack->size == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(ArrayStack *stack, int num) {\n    if (stack->size == MAX_SIZE) {\n        printf(\"\u6808\u5df2\u6ee1\\n\");\n        return;\n    }\n    stack->data[stack->size] = num;\n    stack->size++;\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(ArrayStack *stack) {\n    if (stack->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return stack->data[stack->size - 1];\n}\n\n/* \u51fa\u6808 */\nint pop(ArrayStack *stack) {\n    int val = peek(stack);\n    stack->size--;\n    return val;\n}\n
    array_stack.kt
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n    private val stack = mutableListOf<Int>()\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stack.size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        stack.add(num)\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack.removeAt(size() - 1)\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack[size() - 1]\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): Array<Any> {\n        return stack.toTypedArray()\n    }\n}\n
    array_stack.rb
    ### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 ###\nclass ArrayStack\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @stack = []\n  end\n\n  ### \u83b7\u53d6\u6808\u7684\u957f\u5ea6 ###\n  def size\n    @stack.length\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @stack.empty?\n  end\n\n  ### \u5165\u6808 ###\n  def push(item)\n    @stack << item\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.pop\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.last\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    @stack\n  end\nend\n
    array_stack.zig
    // \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\nfn ArrayStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack: ?std.ArrayList(T) = null,     \n\n        // \u6784\u9020\u65b9\u6cd5\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) void {\n            if (self.stack == null) {\n                self.stack = std.ArrayList(T).init(allocator);\n            }\n        }\n\n        // \u6790\u6784\u65b9\u6cd5\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.stack == null) return;\n            self.stack.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stack.?.items.len;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack.?.items[self.size() - 1];\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            try self.stack.?.append(num);\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.stack.?.pop();\n            return num;\n        } \n\n        // \u8fd4\u56de ArrayList\n        pub fn toList(self: *Self) std.ArrayList(T) {\n            return self.stack.?;\n        }\n    };\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_stack_and_queue/stack/#513-comparison-of-the-two-implementations","title":"5.1.3 \u00a0 Comparison of the two implementations","text":"

    Supported Operations

    Both implementations support all the operations defined in a stack. The array implementation additionally supports random access, but this is beyond the scope of a stack definition and is generally not used.

    Time Efficiency

    In the array-based implementation, both push and pop operations occur in pre-allocated contiguous memory, which has good cache locality and therefore higher efficiency. However, if the push operation exceeds the array capacity, it triggers a resizing mechanism, making the time complexity of that push operation \\(O(n)\\).

    In the linked list implementation, list expansion is very flexible, and there is no efficiency decrease issue as in array expansion. However, the push operation requires initializing a node object and modifying pointers, so its efficiency is relatively lower. If the elements being pushed are already node objects, then the initialization step can be skipped, improving efficiency.

    Thus, when the elements for push and pop operations are basic data types like int or double, we can draw the following conclusions:

    • The array-based stack implementation's efficiency decreases during expansion, but since expansion is a low-frequency operation, its average efficiency is higher.
    • The linked list-based stack implementation provides more stable efficiency performance.

    Space Efficiency

    When initializing a list, the system allocates an \"initial capacity,\" which might exceed the actual need; moreover, the expansion mechanism usually increases capacity by a specific factor (like doubling), which may also exceed the actual need. Therefore, the array-based stack might waste some space.

    However, since linked list nodes require extra space for storing pointers, the space occupied by linked list nodes is relatively larger.

    In summary, we cannot simply determine which implementation is more memory-efficient. It requires analysis based on specific circumstances.

    "},{"location":"chapter_stack_and_queue/stack/#514-typical-applications-of-stack","title":"5.1.4 \u00a0 Typical applications of stack","text":"
    • Back and forward in browsers, undo and redo in software. Every time we open a new webpage, the browser pushes the previous page onto the stack, allowing us to go back to the previous page through the back operation, which is essentially a pop operation. To support both back and forward, two stacks are needed to work together.
    • Memory management in programs. Each time a function is called, the system adds a stack frame at the top of the stack to record the function's context information. In recursive functions, the downward recursion phase keeps pushing onto the stack, while the upward backtracking phase keeps popping from the stack.
    "},{"location":"chapter_stack_and_queue/summary/","title":"5.4 \u00a0 Summary","text":""},{"location":"chapter_stack_and_queue/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • Stack is a data structure that follows the Last-In-First-Out (LIFO) principle and can be implemented using arrays or linked lists.
    • In terms of time efficiency, the array implementation of the stack has a higher average efficiency. However, during expansion, the time complexity for a single push operation can degrade to \\(O(n)\\). In contrast, the linked list implementation of a stack offers more stable efficiency.
    • Regarding space efficiency, the array implementation of the stack may lead to a certain degree of space wastage. However, it's important to note that the memory space occupied by nodes in a linked list is generally larger than that for elements in an array.
    • A queue is a data structure that follows the First-In-First-Out (FIFO) principle, and it can also be implemented using arrays or linked lists. The conclusions regarding time and space efficiency for queues are similar to those for stacks.
    • A double-ended queue (deque) is a more flexible type of queue that allows adding and removing elements at both ends.
    "},{"location":"chapter_stack_and_queue/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: Is the browser's forward and backward functionality implemented with a doubly linked list?

    A browser's forward and backward navigation is essentially a manifestation of the \"stack\" concept. When a user visits a new page, the page is added to the top of the stack; when they click the back button, the page is popped from the top of the stack. A double-ended queue (deque) can conveniently implement some additional operations, as mentioned in the \"Double-Ended Queue\" section.

    Q: After popping from a stack, is it necessary to free the memory of the popped node?

    If the popped node will still be used later, it's not necessary to free its memory. In languages like Java and Python that have automatic garbage collection, manual memory release is not necessary; in C and C++, manual memory release is required.

    Q: A double-ended queue seems like two stacks joined together. What are its uses?

    A double-ended queue, which is a combination of a stack and a queue or two stacks joined together, exhibits both stack and queue logic. Thus, it can implement all applications of stacks and queues while offering more flexibility.

    Q: How exactly are undo and redo implemented?

    Undo and redo operations are implemented using two stacks: Stack A for undo and Stack B for redo.

    1. Each time a user performs an operation, it is pushed onto Stack A, and Stack B is cleared.
    2. When the user executes an \"undo\", the most recent operation is popped from Stack A and pushed onto Stack B.
    3. When the user executes a \"redo\", the most recent operation is popped from Stack B and pushed back onto Stack A.
    "},{"location":"chapter_tree/","title":"Chapter 7. \u00a0 Tree","text":"

    Abstract

    The towering tree, vibrant with it's deep roots and lush leaves, branches spreading wide.

    It vividly illustrates the concept of divide-and-conquer in data.

    "},{"location":"chapter_tree/#chapter-contents","title":"Chapter contents","text":"
    • 7.1 \u00a0 Binary tree
    • 7.2 \u00a0 Binary tree traversal
    • 7.3 \u00a0 Array Representation of tree
    • 7.4 \u00a0 Binary Search tree
    • 7.5 \u00a0 AVL tree *
    • 7.6 \u00a0 Summary
    "},{"location":"chapter_tree/array_representation_of_tree/","title":"7.3 \u00a0 Array representation of binary trees","text":"

    Under the linked list representation, the storage unit of a binary tree is a node TreeNode, with nodes connected by pointers. The basic operations of binary trees under the linked list representation were introduced in the previous section.

    So, can we use an array to represent a binary tree? The answer is yes.

    "},{"location":"chapter_tree/array_representation_of_tree/#731-representing-perfect-binary-trees","title":"7.3.1 \u00a0 Representing perfect binary trees","text":"

    Let's analyze a simple case first. Given a perfect binary tree, we store all nodes in an array according to the order of level-order traversal, where each node corresponds to a unique array index.

    Based on the characteristics of level-order traversal, we can deduce a \"mapping formula\" between the index of a parent node and its children: If a node's index is \\(i\\), then the index of its left child is \\(2i + 1\\) and the right child is \\(2i + 2\\). The Figure 7-12 shows the mapping relationship between the indices of various nodes.

    Figure 7-12 \u00a0 Array representation of a perfect binary tree

    The mapping formula plays a role similar to the node references (pointers) in linked lists. Given any node in the array, we can access its left (right) child node using the mapping formula.

    "},{"location":"chapter_tree/array_representation_of_tree/#732-representing-any-binary-tree","title":"7.3.2 \u00a0 Representing any binary tree","text":"

    Perfect binary trees are a special case; there are often many None values in the middle levels of a binary tree. Since the sequence of level-order traversal does not include these None values, we cannot solely rely on this sequence to deduce the number and distribution of None values. This means that multiple binary tree structures can match the same level-order traversal sequence.

    As shown in the Figure 7-13 , given a non-perfect binary tree, the above method of array representation fails.

    Figure 7-13 \u00a0 Level-order traversal sequence corresponds to multiple binary tree possibilities

    To solve this problem, we can consider explicitly writing out all None values in the level-order traversal sequence. As shown in the following figure, after this treatment, the level-order traversal sequence can uniquely represent a binary tree. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # Array representation of a binary tree\n# Using None to represent empty slots\ntree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]\n
    /* Array representation of a binary tree */\n// Using the maximum integer value INT_MAX to mark empty slots\nvector<int> tree = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* Array representation of a binary tree */\n// Using the Integer wrapper class allows for using null to mark empty slots\nInteger[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };\n
    /* Array representation of a binary tree */\n// Using nullable int (int?) allows for using null to mark empty slots\nint?[] tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using an any type slice, allowing for nil to mark empty slots\ntree := []any{1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15}\n
    /* Array representation of a binary tree */\n// Using optional Int (Int?) allows for using nil to mark empty slots\nlet tree: [Int?] = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]\n
    /* Array representation of a binary tree */\n// Using null to represent empty slots\nlet tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using null to represent empty slots\nlet tree: (number | null)[] = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using nullable int (int?) allows for using null to mark empty slots\nList<int?> tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* Array representation of a binary tree */\n// Using None to mark empty slots\nlet tree = [Some(1), Some(2), Some(3), Some(4), None, Some(6), Some(7), Some(8), Some(9), None, None, Some(12), None, None, Some(15)];\n
    /* Array representation of a binary tree */\n// Using the maximum int value to mark empty slots, therefore, node values must not be INT_MAX\nint tree[] = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* Array representation of a binary tree */\n// Using null to represent empty slots\nval tree = mutableListOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )\n
    \n
    \n

    Figure 7-14 \u00a0 Array representation of any type of binary tree

    It's worth noting that complete binary trees are very suitable for array representation. Recalling the definition of a complete binary tree, None appears only at the bottom level and towards the right, meaning all None values definitely appear at the end of the level-order traversal sequence.

    This means that when using an array to represent a complete binary tree, it's possible to omit storing all None values, which is very convenient. The Figure 7-15 gives an example.

    Figure 7-15 \u00a0 Array representation of a complete binary tree

    The following code implements a binary tree based on array representation, including the following operations:

    • Given a node, obtain its value, left (right) child node, and parent node.
    • Obtain the preorder, inorder, postorder, and level-order traversal sequences.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_binary_tree.py
    class ArrayBinaryTree:\n    \"\"\"\u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b\"\"\"\n\n    def __init__(self, arr: list[int | None]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._tree = list(arr)\n\n    def size(self):\n        \"\"\"\u5217\u8868\u5bb9\u91cf\"\"\"\n        return len(self._tree)\n\n    def val(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c\"\"\"\n        # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 or i >= self.size():\n            return None\n        return self._tree[i]\n\n    def left(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 1\n\n    def right(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 2\n\n    def parent(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return (i - 1) // 2\n\n    def level_order(self) -> list[int]:\n        \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in range(self.size()):\n            if self.val(i) is not None:\n                self.res.append(self.val(i))\n        return self.res\n\n    def dfs(self, i: int, order: str):\n        \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n        if self.val(i) is None:\n            return\n        # \u524d\u5e8f\u904d\u5386\n        if order == \"pre\":\n            self.res.append(self.val(i))\n        self.dfs(self.left(i), order)\n        # \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\":\n            self.res.append(self.val(i))\n        self.dfs(self.right(i), order)\n        # \u540e\u5e8f\u904d\u5386\n        if order == \"post\":\n            self.res.append(self.val(i))\n\n    def pre_order(self) -> list[int]:\n        \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"pre\")\n        return self.res\n\n    def in_order(self) -> list[int]:\n        \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"in\")\n        return self.res\n\n    def post_order(self) -> list[int]:\n        \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"post\")\n        return self.res\n
    array_binary_tree.cpp
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayBinaryTree(vector<int> arr) {\n        tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    int val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return INT_MAX;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    int parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    vector<int> levelOrder() {\n        vector<int> res;\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != INT_MAX)\n                res.push_back(val(i));\n        }\n        return res;\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    vector<int> preOrder() {\n        vector<int> res;\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    vector<int> inOrder() {\n        vector<int> res;\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    vector<int> postOrder() {\n        vector<int> res;\n        dfs(0, \"post\", res);\n        return res;\n    }\n\n  private:\n    vector<int> tree;\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void dfs(int i, string order, vector<int> &res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == INT_MAX)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.push_back(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.push_back(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.push_back(val(i));\n    }\n};\n
    array_binary_tree.java
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private List<Integer> tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayBinaryTree(List<Integer> arr) {\n        tree = new ArrayList<>(arr);\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public Integer val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return null;\n        return tree.get(i);\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<Integer> levelOrder() {\n        List<Integer> res = new ArrayList<>();\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != null)\n                res.add(val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private void dfs(Integer i, String order, List<Integer> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == null)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\".equals(order))\n            res.add(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\".equals(order))\n            res.add(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\".equals(order))\n            res.add(val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<Integer> preOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<Integer> inOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<Integer> postOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.cs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(List<int?> arr) {\n    List<int?> tree = new(arr);\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int Size() {\n        return tree.Count;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public int? Val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= Size())\n            return null;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<int> LevelOrder() {\n        List<int> res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < Size(); i++) {\n            if (Val(i).HasValue)\n                res.Add(Val(i)!.Value);\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void DFS(int i, string order, List<int> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (!Val(i).HasValue)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.Add(Val(i)!.Value);\n        DFS(Left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.Add(Val(i)!.Value);\n        DFS(Right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.Add(Val(i)!.Value);\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<int> PreOrder() {\n        List<int> res = [];\n        DFS(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<int> InOrder() {\n        List<int> res = [];\n        DFS(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<int> PostOrder() {\n        List<int> res = [];\n        DFS(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.go
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\ntype arrayBinaryTree struct {\n    tree []any\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newArrayBinaryTree(arr []any) *arrayBinaryTree {\n    return &arrayBinaryTree{\n        tree: arr,\n    }\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nfunc (abt *arrayBinaryTree) size() int {\n    return len(abt.tree)\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nfunc (abt *arrayBinaryTree) val(i int) any {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if i < 0 || i >= abt.size() {\n        return nil\n    }\n    return abt.tree[i]\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) parent(i int) int {\n    return (i - 1) / 2\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) levelOrder() []any {\n    var res []any\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i := 0; i < abt.size(); i++ {\n        if abt.val(i) != nil {\n            res = append(res, abt.val(i))\n        }\n    }\n    return res\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nfunc (abt *arrayBinaryTree) dfs(i int, order string, res *[]any) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if abt.val(i) == nil {\n        return\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if order == \"pre\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.left(i), order, res)\n    // \u4e2d\u5e8f\u904d\u5386\n    if order == \"in\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.right(i), order, res)\n    // \u540e\u5e8f\u904d\u5386\n    if order == \"post\" {\n        *res = append(*res, abt.val(i))\n    }\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) preOrder() []any {\n    var res []any\n    abt.dfs(0, \"pre\", &res)\n    return res\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) inOrder() []any {\n    var res []any\n    abt.dfs(0, \"in\", &res)\n    return res\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) postOrder() []any {\n    var res []any\n    abt.dfs(0, \"post\", &res)\n    return res\n}\n
    array_binary_tree.swift
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private var tree: [Int?]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(arr: [Int?]) {\n        tree = arr\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    func size() -> Int {\n        tree.count\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    func val(i: Int) -> Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= size() {\n            return nil\n        }\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func left(i: Int) -> Int {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func right(i: Int) -> Int {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    func parent(i: Int) -> Int {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    func levelOrder() -> [Int] {\n        var res: [Int] = []\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0 ..< size() {\n            if let val = val(i: i) {\n                res.append(val)\n            }\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private func dfs(i: Int, order: String, res: inout [Int]) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        guard let val = val(i: i) else {\n            return\n        }\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.append(val)\n        }\n        dfs(i: left(i: i), order: order, res: &res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.append(val)\n        }\n        dfs(i: right(i: i), order: order, res: &res)\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.append(val)\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    func preOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"pre\", res: &res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    func inOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"in\", res: &res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    func postOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"post\", res: &res)\n        return res\n    }\n}\n
    array_binary_tree.js
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size() {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i) {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder() {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i, order, res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder() {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder() {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder() {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.ts
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree: (number | null)[];\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr: (number | null)[]) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size(): number {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i: number): number | null {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i: number): number {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i: number): number {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i: number): number {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder(): number[] {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i: number, order: Order, res: (number | null)[]): void {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.dart
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  late List<int?> _tree;\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayBinaryTree(this._tree);\n\n  /* \u5217\u8868\u5bb9\u91cf */\n  int size() {\n    return _tree.length;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n  int? val(int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size()) {\n      return null;\n    }\n    return _tree[i];\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? left(int i) {\n    return 2 * i + 1;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? right(int i) {\n    return 2 * i + 2;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? parent(int i) {\n    return (i - 1) ~/ 2;\n  }\n\n  /* \u5c42\u5e8f\u904d\u5386 */\n  List<int> levelOrder() {\n    List<int> res = [];\n    for (int i = 0; i < size(); i++) {\n      if (val(i) != null) {\n        res.add(val(i)!);\n      }\n    }\n    return res;\n  }\n\n  /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n  void dfs(int i, String order, List<int?> res) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(i) == null) {\n      return;\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if (order == 'pre') {\n      res.add(val(i));\n    }\n    dfs(left(i)!, order, res);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (order == 'in') {\n      res.add(val(i));\n    }\n    dfs(right(i)!, order, res);\n    // \u540e\u5e8f\u904d\u5386\n    if (order == 'post') {\n      res.add(val(i));\n    }\n  }\n\n  /* \u524d\u5e8f\u904d\u5386 */\n  List<int?> preOrder() {\n    List<int?> res = [];\n    dfs(0, 'pre', res);\n    return res;\n  }\n\n  /* \u4e2d\u5e8f\u904d\u5386 */\n  List<int?> inOrder() {\n    List<int?> res = [];\n    dfs(0, 'in', res);\n    return res;\n  }\n\n  /* \u540e\u5e8f\u904d\u5386 */\n  List<int?> postOrder() {\n    List<int?> res = [];\n    dfs(0, 'post', res);\n    return res;\n  }\n}\n
    array_binary_tree.rs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nstruct ArrayBinaryTree {\n    tree: Vec<Option<i32>>,\n}\n\nimpl ArrayBinaryTree {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(arr: Vec<Option<i32>>) -> Self {\n        Self { tree: arr }\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    fn size(&self) -> i32 {\n        self.tree.len() as i32\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fn val(&self, i: i32) -> Option<i32> {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= self.size() {\n            None\n        } else {\n            self.tree[i as usize]\n        }\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn left(&self, i: i32) -> i32 {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn right(&self, i: i32) -> i32 {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn parent(&self, i: i32) -> i32 {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fn level_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0..self.size() {\n            if let Some(val) = self.val(i) {\n                res.push(val)\n            }\n        }\n        res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fn dfs(&self, i: i32, order: &str, res: &mut Vec<i32>) {\n        if self.val(i).is_none() {\n            return;\n        }\n        let val = self.val(i).unwrap();\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.push(val);\n        }\n        self.dfs(self.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.push(val);\n        }\n        self.dfs(self.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.push(val);\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fn pre_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"pre\", &mut res);\n        res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fn in_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"in\", &mut res);\n        res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fn post_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"post\", &mut res);\n        res\n    }\n}\n
    array_binary_tree.c
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int *tree;\n    int size;\n} ArrayBinaryTree;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayBinaryTree *newArrayBinaryTree(int *arr, int arrSize) {\n    ArrayBinaryTree *abt = (ArrayBinaryTree *)malloc(sizeof(ArrayBinaryTree));\n    abt->tree = malloc(sizeof(int) * arrSize);\n    memcpy(abt->tree, arr, sizeof(int) * arrSize);\n    abt->size = arrSize;\n    return abt;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayBinaryTree(ArrayBinaryTree *abt) {\n    free(abt->tree);\n    free(abt);\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nint size(ArrayBinaryTree *abt) {\n    return abt->size;\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nint val(ArrayBinaryTree *abt, int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size(abt))\n        return INT_MAX;\n    return abt->tree[i];\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size(abt); i++) {\n        if (val(abt, i) != INT_MAX)\n            res[index++] = val(abt, i);\n    }\n    *returnSize = index;\n    return res;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nvoid dfs(ArrayBinaryTree *abt, int i, char *order, int *res, int *index) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(abt, i) == INT_MAX)\n        return;\n    // \u524d\u5e8f\u904d\u5386\n    if (strcmp(order, \"pre\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, left(i), order, res, index);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (strcmp(order, \"in\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, right(i), order, res, index);\n    // \u540e\u5e8f\u904d\u5386\n    if (strcmp(order, \"post\") == 0)\n        res[(*index)++] = val(abt, i);\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nint *preOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"pre\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nint *inOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"in\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nint *postOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"post\", res, &index);\n    *returnSize = index;\n    return res;\n}\n
    array_binary_tree.kt
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(val tree: MutableList<Int?>) {\n    /* \u5217\u8868\u5bb9\u91cf */\n    fun size(): Int {\n        return tree.size\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fun _val(i: Int): Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size()) return null\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun parent(i: Int): Int {\n        return (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fun levelOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (i in 0..<size()) {\n            if (_val(i) != null)\n                res.add(_val(i))\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fun dfs(i: Int, order: String, res: MutableList<Int?>) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (_val(i) == null)\n            return\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\" == order)\n            res.add(_val(i))\n        dfs(left(i), order, res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\" == order)\n            res.add(_val(i))\n        dfs(right(i), order, res)\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\" == order)\n            res.add(_val(i))\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fun preOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"pre\", res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fun inOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"in\", res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fun postOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"post\", res)\n        return res\n    }\n}\n
    array_binary_tree.rb
    ### \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b ###\nclass ArrayBinaryTree\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(arr)\n    @tree = arr.to_a\n  end\n\n  ### \u5217\u8868\u5bb9\u91cf ###\n  def size\n    @tree.length\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c ###\n  def val(i)\n    # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de nil \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    return if i < 0 || i >= size\n\n    @tree[i]\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def left(i)\n    2 * i + 1\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def right(i)\n    2 * i + 2\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def parent(i)\n    (i - 1) / 2\n  end\n\n  ### \u5c42\u5e8f\u904d\u5386 ###\n  def level_order\n    @res = []\n\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i in 0...size\n      @res << val(i) unless val(i).nil?\n    end\n\n    @res\n  end\n\n  ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\n  def dfs(i, order)\n    return if val(i).nil?\n    # \u524d\u5e8f\u904d\u5386\n    @res << val(i) if order == :pre\n    dfs(left(i), order)\n    # \u4e2d\u5e8f\u904d\u5386\n    @res << val(i) if order == :in\n    dfs(right(i), order)\n    # \u540e\u5e8f\u904d\u5386\n    @res << val(i) if order == :post\n  end\n\n  ### \u524d\u5e8f\u904d\u5386 ###\n  def pre_order\n    @res = []\n    dfs(0, :pre)\n    @res\n  end\n\n  ### \u4e2d\u5e8f\u904d\u5386 ###\n  def in_order\n    @res = []\n    dfs(0, :in)\n    @res\n  end\n\n  ### \u540e\u5e8f\u904d\u5386 ###\n  def post_order\n    @res = []\n    dfs(0, :post)\n    @res\n  end\nend\n
    array_binary_tree.zig
    [class]{ArrayBinaryTree}-[func]{}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/array_representation_of_tree/#733-advantages-and-limitations","title":"7.3.3 \u00a0 Advantages and limitations","text":"

    The array representation of binary trees has the following advantages:

    • Arrays are stored in contiguous memory spaces, which is cache-friendly and allows for faster access and traversal.
    • It does not require storing pointers, which saves space.
    • It allows random access to nodes.

    However, the array representation also has some limitations:

    • Array storage requires contiguous memory space, so it is not suitable for storing trees with a large amount of data.
    • Adding or deleting nodes requires array insertion and deletion operations, which are less efficient.
    • When there are many None values in the binary tree, the proportion of node data contained in the array is low, leading to lower space utilization.
    "},{"location":"chapter_tree/avl_tree/","title":"7.5 \u00a0 AVL tree *","text":"

    In the \"Binary Search Tree\" section, we mentioned that after multiple insertions and removals, a binary search tree might degrade to a linked list. In such cases, the time complexity of all operations degrades from \\(O(\\log n)\\) to \\(O(n)\\).

    As shown in the Figure 7-24 , after two node removal operations, this binary search tree will degrade into a linked list.

    Figure 7-24 \u00a0 Degradation of an AVL tree after removing nodes

    For example, in the perfect binary tree shown in the Figure 7-25 , after inserting two nodes, the tree will lean heavily to the left, and the time complexity of search operations will also degrade.

    Figure 7-25 \u00a0 Degradation of an AVL tree after inserting nodes

    In 1962, G. M. Adelson-Velsky and E. M. Landis proposed the \"AVL Tree\" in their paper \"An algorithm for the organization of information\". The paper detailed a series of operations to ensure that after continuously adding and removing nodes, the AVL tree would not degrade, thus maintaining the time complexity of various operations at \\(O(\\log n)\\) level. In other words, in scenarios where frequent additions, removals, searches, and modifications are needed, the AVL tree can always maintain efficient data operation performance, which has great application value.

    "},{"location":"chapter_tree/avl_tree/#751-common-terminology-in-avl-trees","title":"7.5.1 \u00a0 Common terminology in AVL trees","text":"

    An AVL tree is both a binary search tree and a balanced binary tree, satisfying all properties of these two types of binary trees, hence it is a \"balanced binary search tree\".

    "},{"location":"chapter_tree/avl_tree/#1-node-height","title":"1. \u00a0 Node height","text":"

    Since the operations related to AVL trees require obtaining node heights, we need to add a height variable to the node class:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"AVL tree node\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                 # Node value\n        self.height: int = 0                # Node height\n        self.left: TreeNode | None = None   # Left child reference\n        self.right: TreeNode | None = None  # Right child reference\n
    /* AVL tree node */\nstruct TreeNode {\n    int val{};          // Node value\n    int height = 0;     // Node height\n    TreeNode *left{};   // Left child\n    TreeNode *right{};  // Right child\n    TreeNode() = default;\n    explicit TreeNode(int x) : val(x){}\n};\n
    /* AVL tree node */\nclass TreeNode {\n    public int val;        // Node value\n    public int height;     // Node height\n    public TreeNode left;  // Left child\n    public TreeNode right; // Right child\n    public TreeNode(int x) { val = x; }\n}\n
    /* AVL tree node */\nclass TreeNode(int? x) {\n    public int? val = x;    // Node value\n    public int height;      // Node height\n    public TreeNode? left;  // Left child reference\n    public TreeNode? right; // Right child reference\n}\n
    /* AVL tree node */\ntype TreeNode struct {\n    Val    int       // Node value\n    Height int       // Node height\n    Left   *TreeNode // Left child reference\n    Right  *TreeNode // Right child reference\n}\n
    /* AVL tree node */\nclass TreeNode {\n    var val: Int // Node value\n    var height: Int // Node height\n    var left: TreeNode? // Left child\n    var right: TreeNode? // Right child\n\n    init(x: Int) {\n        val = x\n        height = 0\n    }\n}\n
    /* AVL tree node */\nclass TreeNode {\n    val; // Node value\n    height; // Node height\n    left; // Left child pointer\n    right; // Right child pointer\n    constructor(val, left, right, height) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* AVL tree node */\nclass TreeNode {\n    val: number;            // Node value\n    height: number;         // Node height\n    left: TreeNode | null;  // Left child pointer\n    right: TreeNode | null; // Right child pointer\n    constructor(val?: number, height?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height; \n        this.left = left === undefined ? null : left; \n        this.right = right === undefined ? null : right; \n    }\n}\n
    /* AVL tree node */\nclass TreeNode {\n  int val;         // Node value\n  int height;      // Node height\n  TreeNode? left;  // Left child\n  TreeNode? right; // Right child\n  TreeNode(this.val, [this.height = 0, this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* AVL tree node */\nstruct TreeNode {\n    val: i32,                               // Node value\n    height: i32,                            // Node height\n    left: Option<Rc<RefCell<TreeNode>>>,    // Left child\n    right: Option<Rc<RefCell<TreeNode>>>,   // Right child\n}\n\nimpl TreeNode {\n    /* Constructor */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            height: 0,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* AVL tree node */\nTreeNode struct TreeNode {\n    int val;\n    int height;\n    struct TreeNode *left;\n    struct TreeNode *right;\n} TreeNode;\n\n/* Constructor */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* AVL tree node */\nclass TreeNode(val _val: Int) {  // Node value\n    val height: Int = 0          // Node height\n    val left: TreeNode? = null   // Left child\n    val right: TreeNode? = null  // Right child\n}\n
    \n
    \n

    The \"node height\" refers to the distance from that node to its farthest leaf node, i.e., the number of \"edges\" passed. It is important to note that the height of a leaf node is \\(0\\), and the height of a null node is \\(-1\\). We will create two utility functions for getting and updating the height of a node:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def height(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node is not None:\n        return node.height\n    return -1\n\ndef update_height(self, node: TreeNode | None):\n    \"\"\"\u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = max([self.height(node.left), self.height(node.right)]) + 1\n
    avl_tree.cpp
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == nullptr ? -1 : node->height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node->height = max(height(node->left), height(node->right)) + 1;\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint Height(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid UpdateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.Max(Height(node.left), Height(node.right)) + 1;\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) height(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node != nil {\n        return node.Height\n    }\n    return -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) updateHeight(node *TreeNode) {\n    lh := t.height(node.Left)\n    rh := t.height(node.Right)\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if lh > rh {\n        node.Height = lh + 1\n    } else {\n        node.Height = rh + 1\n    }\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc height(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    node?.height ?? -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node: node?.left), height(node: node?.right)) + 1\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\n#updateHeight(node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nupdateHeight(node: TreeNode): void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode? node) {\n  // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node!.height = max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfn height(node: OptionTreeNodeRc) -> i32 {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    match node {\n        Some(node) => node.borrow().height,\n        None => -1,\n    }\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfn update_height(node: OptionTreeNodeRc) {\n    if let Some(node) = node {\n        let left = node.borrow().left.clone();\n        let right = node.borrow().right.clone();\n        // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n        node.borrow_mut().height = std::cmp::max(Self::height(left), Self::height(right)) + 1;\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if (node != NULL) {\n        return node->height;\n    }\n    return -1;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    int lh = height(node->left);\n    int rh = height(node->right);\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if (lh > rh) {\n        node->height = lh + 1;\n    } else {\n        node->height = rh + 1;\n    }\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfun height(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node?.height ?: -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfun updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node?.left), height(node?.right)) + 1\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 ###\ndef height(node)\n  # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node.height unless node.nil?\n\n  -1\nend\n\n### \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 ###\ndef update_height(node)\n  # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node.height = [height(node.left), height(node.right)].max + 1\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\nfn height(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    _ = self;\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return if (node == null) -1 else node.?.height;\n}\n\n// \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\nfn updateHeight(self: *Self, node: ?*inc.TreeNode(T)) void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.?.height = @max(self.height(node.?.left), self.height(node.?.right)) + 1;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2-node-balance-factor","title":"2. \u00a0 Node balance factor","text":"

    The \"balance factor\" of a node is defined as the height of the node's left subtree minus the height of its right subtree, with the balance factor of a null node defined as \\(0\\). We will also encapsulate the functionality of obtaining the node balance factor into a function for easy use later on:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def balance_factor(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u5e73\u8861\u56e0\u5b50\"\"\"\n    # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node is None:\n        return 0\n    # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.left) - self.height(node.right)\n
    avl_tree.cpp
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == nullptr)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right);\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint BalanceFactor(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return Height(node.left) - Height(node.right);\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc (t *aVLTree) balanceFactor(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node == nil {\n        return 0\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return t.height(node.Left) - t.height(node.Right)\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc balanceFactor(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    guard let node = node else { return 0 }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node: node.left) - height(node: node.right)\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  if (node == null) return 0;\n  // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  return height(node.left) - height(node.right);\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfn balance_factor(node: OptionTreeNodeRc) -> i32 {\n    match node {\n        // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n        None => 0,\n        // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n        Some(node) => {\n            Self::height(node.borrow().left.clone()) - Self::height(node.borrow().right.clone())\n        }\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == NULL) {\n        return 0;\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfun balanceFactor(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right)\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 ###\ndef balance_factor(node)\n  # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  return 0 if node.nil?\n\n  # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  height(node.left) - height(node.right)\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u5e73\u8861\u56e0\u5b50\nfn balanceFactor(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.?.left) - self.height(node.?.right);\n}\n

    Tip

    Let the balance factor be \\(f\\), then the balance factor of any node in an AVL tree satisfies \\(-1 \\le f \\le 1\\).

    "},{"location":"chapter_tree/avl_tree/#752-rotations-in-avl-trees","title":"7.5.2 \u00a0 Rotations in AVL trees","text":"

    The characteristic feature of an AVL tree is the \"rotation\" operation, which can restore balance to an unbalanced node without affecting the in-order traversal sequence of the binary tree. In other words, the rotation operation can maintain the property of a \"binary search tree\" while also turning the tree back into a \"balanced binary tree\".

    We call nodes with an absolute balance factor \\(> 1\\) \"unbalanced nodes\". Depending on the type of imbalance, there are four kinds of rotations: right rotation, left rotation, right-left rotation, and left-right rotation. Below, we detail these rotation operations.

    "},{"location":"chapter_tree/avl_tree/#1-right-rotation","title":"1. \u00a0 Right rotation","text":"

    As shown in the Figure 7-26 , the first unbalanced node from the bottom up in the binary tree is \"node 3\". Focusing on the subtree with this unbalanced node as the root, denoted as node, and its left child as child, perform a \"right rotation\". After the right rotation, the subtree is balanced again while still maintaining the properties of a binary search tree.

    <1><2><3><4>

    Figure 7-26 \u00a0 Steps of right rotation

    As shown in the Figure 7-27 , when the child node has a right child (denoted as grand_child), a step needs to be added in the right rotation: set grand_child as the left child of node.

    Figure 7-27 \u00a0 Right rotation with grand_child

    \"Right rotation\" is a figurative term; in practice, it is achieved by modifying node pointers, as shown in the following code:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def right_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u53f3\u65cb\u64cd\u4f5c\"\"\"\n    child = node.left\n    grand_child = child.right\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child = node->left;\n    TreeNode *grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode rightRotate(TreeNode node) {\n    TreeNode child = node.left;\n    TreeNode grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? RightRotate(TreeNode? node) {\n    TreeNode? child = node?.left;\n    TreeNode? grandChild = child?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) rightRotate(node *TreeNode) *TreeNode {\n    child := node.Left\n    grandChild := child.Right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.Right = node\n    node.Left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc rightRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.left\n    let grandChild = child?.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child?.right = node\n    node?.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u53f3\u65cb\u64cd\u4f5c */\n#rightRotate(node) {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u53f3\u65cb\u64cd\u4f5c */\nrightRotate(node: TreeNode): TreeNode {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? rightRotate(TreeNode? node) {\n  TreeNode? child = node!.left;\n  TreeNode? grandChild = child!.right;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node;\n  node.left = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u53f3\u65cb\u64cd\u4f5c */\nfn right_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().left.clone().unwrap();\n            let grand_child = child.borrow().right.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n            child.borrow_mut().right = Some(node.clone());\n            node.borrow_mut().left = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->left;\n    grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u53f3\u65cb\u64cd\u4f5c */\nfun rightRotate(node: TreeNode?): TreeNode {\n    val child = node!!.left\n    val grandChild = child!!.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u53f3\u65cb\u64cd\u4f5c ###\ndef right_rotate(node)\n  child = node.left\n  grand_child = child.right\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node\n  node.left = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u53f3\u65cb\u64cd\u4f5c\nfn rightRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.left;\n    var grandChild = child.?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.?.right = node;\n    node.?.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2-left-rotation","title":"2. \u00a0 Left rotation","text":"

    Correspondingly, if considering the \"mirror\" of the above unbalanced binary tree, the \"left rotation\" operation shown in the Figure 7-28 needs to be performed.

    Figure 7-28 \u00a0 Left rotation operation

    Similarly, as shown in the Figure 7-29 , when the child node has a left child (denoted as grand_child), a step needs to be added in the left rotation: set grand_child as the right child of node.

    Figure 7-29 \u00a0 Left rotation with grand_child

    It can be observed that the right and left rotation operations are logically symmetrical, and they solve two symmetrical types of imbalance. Based on symmetry, by replacing all left with right, and all right with left in the implementation code of right rotation, we can get the implementation code for left rotation:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def left_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u5de6\u65cb\u64cd\u4f5c\"\"\"\n    child = node.right\n    grand_child = child.left\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child = node->right;\n    TreeNode *grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode leftRotate(TreeNode node) {\n    TreeNode child = node.right;\n    TreeNode grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? LeftRotate(TreeNode? node) {\n    TreeNode? child = node?.right;\n    TreeNode? grandChild = child?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) leftRotate(node *TreeNode) *TreeNode {\n    child := node.Right\n    grandChild := child.Left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.Left = node\n    node.Right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc leftRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.right\n    let grandChild = child?.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child?.left = node\n    node?.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u5de6\u65cb\u64cd\u4f5c */\n#leftRotate(node) {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u5de6\u65cb\u64cd\u4f5c */\nleftRotate(node: TreeNode): TreeNode {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? leftRotate(TreeNode? node) {\n  TreeNode? child = node!.right;\n  TreeNode? grandChild = child!.left;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node;\n  node.right = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u5de6\u65cb\u64cd\u4f5c */\nfn left_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().right.clone().unwrap();\n            let grand_child = child.borrow().left.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n            child.borrow_mut().left = Some(node.clone());\n            node.borrow_mut().right = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->right;\n    grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u5de6\u65cb\u64cd\u4f5c */\nfun leftRotate(node: TreeNode?): TreeNode {\n    val child = node!!.right\n    val grandChild = child!!.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u5de6\u65cb\u64cd\u4f5c ###\ndef left_rotate(node)\n  child = node.right\n  grand_child = child.left\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node\n  node.right = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u5de6\u65cb\u64cd\u4f5c\nfn leftRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.right;\n    var grandChild = child.?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.?.left = node;\n    node.?.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3-right-left-rotation","title":"3. \u00a0 Right-left rotation","text":"

    For the unbalanced node 3 shown in the Figure 7-30 , using either left or right rotation alone cannot restore balance to the subtree. In this case, a \"left rotation\" needs to be performed on child first, followed by a \"right rotation\" on node.

    Figure 7-30 \u00a0 Right-left rotation

    "},{"location":"chapter_tree/avl_tree/#4-left-right-rotation","title":"4. \u00a0 Left-right rotation","text":"

    As shown in the Figure 7-31 , for the mirror case of the above unbalanced binary tree, a \"right rotation\" needs to be performed on child first, followed by a \"left rotation\" on node.

    Figure 7-31 \u00a0 Left-right rotation

    "},{"location":"chapter_tree/avl_tree/#5-choice-of-rotation","title":"5. \u00a0 Choice of rotation","text":"

    The four kinds of imbalances shown in the Figure 7-32 correspond to the cases described above, respectively requiring right rotation, left-right rotation, right-left rotation, and left rotation.

    Figure 7-32 \u00a0 The four rotation cases of AVL tree

    As shown in the Table 7-3 , we determine which of the above cases an unbalanced node belongs to by judging the sign of the balance factor of the unbalanced node and its higher-side child's balance factor.

    Table 7-3 \u00a0 Conditions for Choosing Among the Four Rotation Cases

    Balance factor of unbalanced node Balance factor of child node Rotation method to use \\(> 1\\) (Left-leaning tree) \\(\\geq 0\\) Right rotation \\(> 1\\) (Left-leaning tree) \\(<0\\) Left rotation then right rotation \\(< -1\\) (Right-leaning tree) \\(\\leq 0\\) Left rotation \\(< -1\\) (Right-leaning tree) \\(>0\\) Right rotation then left rotation

    For convenience, we encapsulate the rotation operations into a function. With this function, we can perform rotations on various kinds of imbalances, restoring balance to unbalanced nodes. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\"\"\"\n    # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    balance_factor = self.balance_factor(node)\n    # \u5de6\u504f\u6811\n    if balance_factor > 1:\n        if self.balance_factor(node.left) >= 0:\n            # \u53f3\u65cb\n            return self.right_rotate(node)\n        else:\n            # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = self.left_rotate(node.left)\n            return self.right_rotate(node)\n    # \u53f3\u504f\u6811\n    elif balance_factor < -1:\n        if self.balance_factor(node.right) <= 0:\n            # \u5de6\u65cb\n            return self.left_rotate(node)\n        else:\n            # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = self.right_rotate(node.right)\n            return self.left_rotate(node)\n    # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n
    avl_tree.cpp
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int _balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (_balanceFactor > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (_balanceFactor < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.java
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode rotate(TreeNode node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.cs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? Rotate(TreeNode? node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactorInt = BalanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactorInt > 1) {\n        if (BalanceFactor(node?.left) >= 0) {\n            // \u53f3\u65cb\n            return RightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node!.left = LeftRotate(node!.left);\n            return RightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactorInt < -1) {\n        if (BalanceFactor(node?.right) <= 0) {\n            // \u5de6\u65cb\n            return LeftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node!.right = RightRotate(node!.right);\n            return LeftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.go
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc (t *aVLTree) rotate(node *TreeNode) *TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    // Go \u63a8\u8350\u77ed\u53d8\u91cf\uff0c\u8fd9\u91cc bf \u6307\u4ee3 t.balanceFactor\n    bf := t.balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if bf > 1 {\n        if t.balanceFactor(node.Left) >= 0 {\n            // \u53f3\u65cb\n            return t.rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.Left = t.leftRotate(node.Left)\n            return t.rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if bf < -1 {\n        if t.balanceFactor(node.Right) <= 0 {\n            // \u5de6\u65cb\n            return t.leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.Right = t.rightRotate(node.Right)\n            return t.leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.swift
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc rotate(node: TreeNode?) -> TreeNode? {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balanceFactor = balanceFactor(node: node)\n    // \u5de6\u504f\u6811\n    if balanceFactor > 1 {\n        if self.balanceFactor(node: node?.left) >= 0 {\n            // \u53f3\u65cb\n            return rightRotate(node: node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node?.left = leftRotate(node: node?.left)\n            return rightRotate(node: node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if balanceFactor < -1 {\n        if self.balanceFactor(node: node?.right) <= 0 {\n            // \u5de6\u65cb\n            return leftRotate(node: node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node?.right = rightRotate(node: node?.right)\n            return leftRotate(node: node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.js
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n#rotate(node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.#rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.#leftRotate(node.left);\n            return this.#rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.#leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.#rightRotate(node.right);\n            return this.#leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.ts
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nrotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.leftRotate(node.left);\n            return this.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.rightRotate(node.right);\n            return this.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.dart
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? rotate(TreeNode? node) {\n  // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  int factor = balanceFactor(node);\n  // \u5de6\u504f\u6811\n  if (factor > 1) {\n    if (balanceFactor(node!.left) >= 0) {\n      // \u53f3\u65cb\n      return rightRotate(node);\n    } else {\n      // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = leftRotate(node.left);\n      return rightRotate(node);\n    }\n  }\n  // \u53f3\u504f\u6811\n  if (factor < -1) {\n    if (balanceFactor(node!.right) <= 0) {\n      // \u5de6\u65cb\n      return leftRotate(node);\n    } else {\n      // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = rightRotate(node.right);\n      return leftRotate(node);\n    }\n  }\n  // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  return node;\n}\n
    avl_tree.rs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfn rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balance_factor = Self::balance_factor(node.clone());\n    // \u5de6\u504f\u6811\n    if balance_factor > 1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().left.clone()) >= 0 {\n            // \u53f3\u65cb\n            Self::right_rotate(Some(node))\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            let left = node.borrow().left.clone();\n            node.borrow_mut().left = Self::left_rotate(left);\n            Self::right_rotate(Some(node))\n        }\n    }\n    // \u53f3\u504f\u6811\n    else if balance_factor < -1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().right.clone()) <= 0 {\n            // \u5de6\u65cb\n            Self::left_rotate(Some(node))\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            let right = node.borrow().right.clone();\n            node.borrow_mut().right = Self::right_rotate(right);\n            Self::left_rotate(Some(node))\n        }\n    } else {\n        // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n        node\n    }\n}\n
    avl_tree.c
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int bf = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (bf > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (bf < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.kt
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfun rotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    val balanceFactor = balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left)\n            return rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right)\n            return leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.rb
    ### \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 ###\ndef rotate(node)\n  # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  balance_factor = balance_factor(node)\n  # \u5de6\u904d\u6811\n  if balance_factor > 1\n    if balance_factor(node.left) >= 0\n      # \u53f3\u65cb\n      return right_rotate(node)\n    else\n      # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = left_rotate(node.left)\n      return right_rotate(node)\n    end\n  # \u53f3\u904d\u6811\n  elsif balance_factor < -1\n    if balance_factor(node.right) <= 0\n      # \u5de6\u65cb\n      return left_rotate(node)\n    else\n      # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = right_rotate(node.right)\n      return left_rotate(node)\n    end\n  end\n  # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  node\nend\n
    avl_tree.zig
    // \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\nfn rotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    var balance_factor = self.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balance_factor > 1) {\n        if (self.balanceFactor(node.?.left) >= 0) {\n            // \u53f3\u65cb\n            return self.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.?.left = self.leftRotate(node.?.left);\n            return self.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balance_factor < -1) {\n        if (self.balanceFactor(node.?.right) <= 0) {\n            // \u5de6\u65cb\n            return self.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.?.right = self.rightRotate(node.?.right);\n            return self.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#753-common-operations-in-avl-trees","title":"7.5.3 \u00a0 Common operations in AVL trees","text":""},{"location":"chapter_tree/avl_tree/#1-node-insertion","title":"1. \u00a0 Node insertion","text":"

    The node insertion operation in AVL trees is similar to that in binary search trees. The only difference is that after inserting a node in an AVL tree, a series of unbalanced nodes may appear along the path from that node to the root node. Therefore, we need to start from this node and perform rotation operations upwards to restore balance to all unbalanced nodes. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def insert(self, val):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    self._root = self.insert_helper(self._root, val)\n\ndef insert_helper(self, node: TreeNode | None, val: int) -> TreeNode:\n    \"\"\"\u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return TreeNode(val)\n    # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if val < node.val:\n        node.left = self.insert_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.insert_helper(node.right, val)\n    else:\n        # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val)\n        node->left = insertHelper(node->left, val);\n    else if (val > node->val)\n        node->right = insertHelper(node->right, val);\n    else\n        return node;    // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode insertHelper(TreeNode node, int val) {\n    if (node == null)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = insertHelper(node.right, val);\n    else\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int val) {\n    root = InsertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? InsertHelper(TreeNode? node, int val) {\n    if (node == null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = InsertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = InsertHelper(node.right, val);\n    else\n        return node;     // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (t *aVLTree) insert(val int) {\n    t.root = t.insertHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return NewTreeNode(val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node.Val.(int) {\n        node.Left = t.insertHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.insertHelper(node.Right, val)\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(val: Int) {\n    root = insertHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc insertHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return TreeNode(x: val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node!.val {\n        node?.left = insertHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = insertHelper(node: node?.right, val: val)\n    } else {\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val) {\n    this.root = this.#insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#insertHelper(node, val) {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) node.left = this.#insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#insertHelper(node.right, val);\n    else return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val: number): void {\n    this.root = this.insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\ninsertHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) {\n        node.left = this.insertHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.insertHelper(node.right, val);\n    } else {\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n  root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? insertHelper(TreeNode? node, int val) {\n  if (node == null) return TreeNode(val);\n  /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n  if (val < node.val)\n    node.left = insertHelper(node.left, val);\n  else if (val > node.val)\n    node.right = insertHelper(node.right, val);\n  else\n    return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\nfn insert(&mut self, val: i32) {\n    self.root = Self::insert_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn insert_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n            match {\n                let node_val = node.borrow().val;\n                node_val\n            }\n            .cmp(&val)\n            {\n                Ordering::Greater => {\n                    let left = node.borrow().left.clone();\n                    node.borrow_mut().left = Self::insert_helper(left, val);\n                }\n                Ordering::Less => {\n                    let right = node.borrow().right.clone();\n                    node.borrow_mut().right = Self::insert_helper(right, val);\n                }\n                Ordering::Equal => {\n                    return Some(node); // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n                }\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => Some(TreeNode::new(val)),\n    }\n}\n
    avl_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(AVLTree *tree, int val) {\n    tree->root = insertHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == NULL) {\n        return newTreeNode(val);\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val) {\n        node->left = insertHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = insertHelper(node->right, val);\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node;\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(_val: Int) {\n    root = insertHelper(root, _val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun insertHelper(n: TreeNode?, _val: Int): TreeNode {\n    if (n == null)\n        return TreeNode(_val)\n    var node = n\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (_val < node._val)\n        node.left = insertHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = insertHelper(node.right, _val)\n    else\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(val)\n  @root = insert_helper(@root, val)\nend\n\n### \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef insert_helper(node, val)\n  return TreeNode.new(val) if node.nil?\n  # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n  if val < node.val\n    node.left = insert_helper(node.left, val)\n  elsif val > node.val\n    node.right = insert_helper(node.right, val)\n  else\n    # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, val: T) !void {\n    self.root = (try self.insertHelper(self.root, val)).?;\n}\n\n// \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn insertHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) !?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) {\n        var tmp_node = try self.mem_allocator.create(inc.TreeNode(T));\n        tmp_node.init(val);\n        return tmp_node;\n    }\n    // 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if (val < node.?.val) {\n        node.?.left = try self.insertHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = try self.insertHelper(node.?.right, val);\n    } else {\n        return node;            // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    self.updateHeight(node);    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2-node-removal","title":"2. \u00a0 Node removal","text":"

    Similarly, based on the method of removing nodes in binary search trees, rotation operations need to be performed from the bottom up to restore balance to all unbalanced nodes. The code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def remove(self, val: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    self._root = self.remove_helper(self._root, val)\n\ndef remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None:\n    \"\"\"\u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return None\n    # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if val < node.val:\n        node.left = self.remove_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.remove_helper(node.right, val)\n    else:\n        if node.left is None or node.right is None:\n            child = node.left or node.right\n            # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child is None:\n                return None\n            # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else:\n                node = child\n        else:\n            # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp = node.right\n            while temp.left is not None:\n                temp = temp.left\n            node.right = self.remove_helper(node.right, temp.val)\n            node.val = temp.val\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return nullptr;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val)\n        node->left = removeHelper(node->left, val);\n    else if (val > node->val)\n        node->right = removeHelper(node->right, val);\n    else {\n        if (node->left == nullptr || node->right == nullptr) {\n            TreeNode *child = node->left != nullptr ? node->left : node->right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == nullptr) {\n                delete node;\n                return nullptr;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                delete node;\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != nullptr) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode removeHelper(TreeNode node, int val) {\n    if (node == null)\n        return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = removeHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode child = node.left != null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int val) {\n    root = RemoveHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? RemoveHelper(TreeNode? node, int val) {\n    if (node == null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = RemoveHelper(node.left, val);\n    else if (val > node.val)\n        node.right = RemoveHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode? child = node.left ?? node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode? temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = RemoveHelper(node.right, temp.val!.Value);\n            node.val = temp.val;\n        }\n    }\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (t *aVLTree) remove(val int) {\n    t.root = t.removeHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node.Val.(int) {\n        node.Left = t.removeHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.removeHelper(node.Right, val)\n    } else {\n        if node.Left == nil || node.Right == nil {\n            child := node.Left\n            if node.Right != nil {\n                child = node.Right\n            }\n            if child == nil {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                return nil\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp := node.Right\n            for temp.Left != nil {\n                temp = temp.Left\n            }\n            node.Right = t.removeHelper(node.Right, temp.Val.(int))\n            node.Val = temp.Val\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(val: Int) {\n    root = removeHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc removeHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node!.val {\n        node?.left = removeHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = removeHelper(node: node?.right, val: val)\n    } else {\n        if node?.left == nil || node?.right == nil {\n            let child = node?.left ?? node?.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child == nil {\n                return nil\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node?.right\n            while temp?.left != nil {\n                temp = temp?.left\n            }\n            node?.right = removeHelper(node: node?.right, val: temp!.val)\n            node?.val = temp!.val\n        }\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(val) {\n    this.root = this.#removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#removeHelper(node, val) {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) node.left = this.#removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#removeHelper(node.right, val);\n    else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.#removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(val: number): void {\n    this.root = this.removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nremoveHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) {\n        node.left = this.removeHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.removeHelper(node.right, val);\n    } else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) {\n                return null;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n  root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? removeHelper(TreeNode? node, int val) {\n  if (node == null) return null;\n  /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n  if (val < node.val)\n    node.left = removeHelper(node.left, val);\n  else if (val > node.val)\n    node.right = removeHelper(node.right, val);\n  else {\n    if (node.left == null || node.right == null) {\n      TreeNode? child = node.left ?? node.right;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      if (child == null)\n        return null;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      else\n        node = child;\n    } else {\n      // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      TreeNode? temp = node.right;\n      while (temp!.left != null) {\n        temp = temp.left;\n      }\n      node.right = removeHelper(node.right, temp.val);\n      node.val = temp.val;\n    }\n  }\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\nfn remove(&self, val: i32) {\n    Self::remove_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn remove_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n            if val < node.borrow().val {\n                let left = node.borrow().left.clone();\n                node.borrow_mut().left = Self::remove_helper(left, val);\n            } else if val > node.borrow().val {\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, val);\n            } else if node.borrow().left.is_none() || node.borrow().right.is_none() {\n                let child = if node.borrow().left.is_some() {\n                    node.borrow().left.clone()\n                } else {\n                    node.borrow().right.clone()\n                };\n                match child {\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                    None => {\n                        return None;\n                    }\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                    Some(child) => node = child,\n                }\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n                let mut temp = node.borrow().right.clone().unwrap();\n                loop {\n                    let temp_left = temp.borrow().left.clone();\n                    if temp_left.is_none() {\n                        break;\n                    }\n                    temp = temp_left.unwrap();\n                }\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, temp.borrow().val);\n                node.borrow_mut().val = temp.borrow().val;\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(AVLTree *tree, int val) {\n    TreeNode *root = removeHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    TreeNode *child, *grandChild;\n    if (node == NULL) {\n        return NULL;\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val) {\n        node->left = removeHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = removeHelper(node->right, val);\n    } else {\n        if (node->left == NULL || node->right == NULL) {\n            child = node->left;\n            if (node->right != NULL) {\n                child = node->right;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == NULL) {\n                return NULL;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != NULL) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(_val: Int) {\n    root = removeHelper(root, _val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun removeHelper(n: TreeNode?, _val: Int): TreeNode? {\n    var node = n ?: return null\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (_val < node._val)\n        node.left = removeHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = removeHelper(node.right, _val)\n    else {\n        if (node.left == null || node.right == null) {\n            val child = if (node.left != null)\n                node.left\n            else\n                node.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.right\n            while (temp!!.left != null) {\n                temp = temp.left\n            }\n            node.right = removeHelper(node.right, temp._val)\n            node._val = temp._val\n        }\n    }\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(val)\n  @root = remove_helper(@root, val)\nend\n\n### \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef remove_helper(node, val)\n  return if node.nil?\n  # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n  if val < node.val\n    node.left = remove_helper(node.left, val)\n  elsif val > node.val\n    node.right = remove_helper(node.right, val)\n  else\n    if node.left.nil? || node.right.nil?\n      child = node.left || node.right\n      # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      return if child.nil?\n      # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      node = child\n    else\n      # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      temp = node.right\n      while !temp.left.nil?\n        temp = temp.left\n      end\n      node.right = remove_helper(node.right, temp.val)\n      node.val = temp.val\n    end\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, val: T) void {\n   self.root = self.removeHelper(self.root, val).?;\n}\n\n// \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn removeHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) ?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) return null;\n    // 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if (val < node.?.val) {\n        node.?.left = self.removeHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = self.removeHelper(node.?.right, val);\n    } else {\n        if (node.?.left == null or node.?.right == null) {\n            var child = if (node.?.left != null) node.?.left else node.?.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null) {\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            } else {\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.?.right;\n            while (temp.?.left != null) {\n                temp = temp.?.left;\n            }\n            node.?.right = self.removeHelper(node.?.right, temp.?.val);\n            node.?.val = temp.?.val;\n        }\n    }\n    self.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3-node-search","title":"3. \u00a0 Node search","text":"

    The node search operation in AVL trees is consistent with that in binary search trees and will not be detailed here.

    "},{"location":"chapter_tree/avl_tree/#754-typical-applications-of-avl-trees","title":"7.5.4 \u00a0 Typical applications of AVL trees","text":"
    • Organizing and storing large amounts of data, suitable for scenarios with high-frequency searches and low-frequency intertions and removals.
    • Used to build index systems in databases.
    • Red-black trees are also a common type of balanced binary search tree. Compared to AVL trees, red-black trees have more relaxed balancing conditions, require fewer rotations for node insertion and removal, and have a higher average efficiency for node addition and removal operations.
    "},{"location":"chapter_tree/binary_search_tree/","title":"7.4 \u00a0 Binary search tree","text":"

    As shown in the Figure 7-16 , a \"binary search tree\" satisfies the following conditions.

    1. For the root node, the value of all nodes in the left subtree < the value of the root node < the value of all nodes in the right subtree.
    2. The left and right subtrees of any node are also binary search trees, i.e., they satisfy condition 1. as well.

    Figure 7-16 \u00a0 Binary search tree

    "},{"location":"chapter_tree/binary_search_tree/#741-operations-on-a-binary-search-tree","title":"7.4.1 \u00a0 Operations on a binary search tree","text":"

    We encapsulate the binary search tree as a class BinarySearchTree and declare a member variable root, pointing to the tree's root node.

    "},{"location":"chapter_tree/binary_search_tree/#1-searching-for-a-node","title":"1. \u00a0 Searching for a node","text":"

    Given a target node value num, one can search according to the properties of the binary search tree. As shown in the Figure 7-17 , we declare a node cur and start from the binary tree's root node root, looping to compare the size relationship between the node value cur.val and num.

    • If cur.val < num, it means the target node is in cur's right subtree, thus execute cur = cur.right.
    • If cur.val > num, it means the target node is in cur's left subtree, thus execute cur = cur.left.
    • If cur.val = num, it means the target node is found, exit the loop and return the node.
    <1><2><3><4>

    Figure 7-17 \u00a0 Example of searching for a node in a binary search tree

    The search operation in a binary search tree works on the same principle as the binary search algorithm, eliminating half of the possibilities in each round. The number of loops is at most the height of the binary tree. When the binary tree is balanced, it uses \\(O(\\log n)\\) time. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def search(self, num: int) -> TreeNode | None:\n    \"\"\"\u67e5\u627e\u8282\u70b9\"\"\"\n    cur = self._root\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur is not None:\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        elif cur.val > num:\n            cur = cur.left\n        # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else:\n            break\n    return cur\n
    binary_search_tree.cpp
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(int num) {\n    TreeNode *cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur->val > num)\n            cur = cur->left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.java
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode search(int num) {\n    TreeNode cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.cs
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? Search(int num) {\n    TreeNode? cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur =\n            cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.go
    /* \u67e5\u627e\u8282\u70b9 */\nfunc (bst *binarySearchTree) search(num int) *TreeNode {\n    node := bst.root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for node != nil {\n        if node.Val.(int) < num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            node = node.Right\n        } else if node.Val.(int) > num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            node = node.Left\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return node\n}\n
    binary_search_tree.swift
    /* \u67e5\u627e\u8282\u70b9 */\nfunc search(num: Int) -> TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if cur!.val > num {\n            cur = cur?.left\n        }\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else {\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.js
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num) {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.ts
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num: number): TreeNode | null {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.dart
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? search(int _num) {\n  TreeNode? cur = _root;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else if (cur.val > _num)\n      cur = cur.left;\n    // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break;\n  }\n  // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n  return cur;\n}\n
    binary_search_tree.rs
    /* \u67e5\u627e\u8282\u70b9 */\npub fn search(&self, num: i32) -> OptionTreeNodeRc {\n    let mut cur = self.root.clone();\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => cur = node.borrow().right.clone(),\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => cur = node.borrow().left.clone(),\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n        }\n    }\n\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    cur\n}\n
    binary_search_tree.c
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(BinarySearchTree *bst, int num) {\n    TreeNode *cur = bst->root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        if (cur->val < num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else if (cur->val > num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.kt
    /* \u67e5\u627e\u8282\u70b9 */\nfun search(num: Int): TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur._val > num)\n            cur.left\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.rb
    ### \u67e5\u627e\u8282\u70b9 ###\ndef search(num)\n  cur = @root\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while !cur.nil?\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    elsif cur.val > num\n      cur = cur.left\n    # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break\n    end\n  end\n\n  cur\nend\n
    binary_search_tree.zig
    // \u67e5\u627e\u8282\u70b9\nfn search(self: *Self, num: T) ?*inc.TreeNode(T) {\n    var cur = self.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else if (cur.?.val > num) {\n            cur = cur.?.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        } else {\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/binary_search_tree/#2-inserting-a-node","title":"2. \u00a0 Inserting a node","text":"

    Given an element num to be inserted, to maintain the property of the binary search tree \"left subtree < root node < right subtree,\" the insertion operation proceeds as shown in the Figure 7-18 .

    1. Finding the insertion position: Similar to the search operation, start from the root node and loop downwards according to the size relationship between the current node value and num until passing through the leaf node (traversing to None) then exit the loop.
    2. Insert the node at that position: Initialize the node num and place it where None was.

    Figure 7-18 \u00a0 Inserting a node into a binary search tree

    In the code implementation, note the following two points.

    • The binary search tree does not allow duplicate nodes; otherwise, it will violate its definition. Therefore, if the node to be inserted already exists in the tree, the insertion is not performed, and it directly returns.
    • To perform the insertion operation, we need to use the node pre to save the node from the last loop. This way, when traversing to None, we can get its parent node, thus completing the node insertion operation.
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def insert(self, num: int):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self._root is None:\n        self._root = TreeNode(num)\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur.val == num:\n            return\n        pre = cur\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u63d2\u5165\u8282\u70b9\n    node = TreeNode(num)\n    if pre.val < num:\n        pre.right = node\n    else:\n        pre.left = node\n
    binary_search_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == nullptr) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = new TreeNode(num);\n    if (pre->val < num)\n        pre->right = node;\n    else\n        pre->left = node;\n}\n
    binary_search_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new TreeNode(num);\n    if (pre.val < num)\n        pre.right = node;\n    else\n        pre.left = node;\n}\n
    binary_search_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new(num);\n    if (pre != null) {\n        if (pre.val < num)\n            pre.right = node;\n        else\n            pre.left = node;\n    }\n}\n
    binary_search_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (bst *binarySearchTree) insert(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if cur == nil {\n        bst.root = NewTreeNode(num)\n        return\n    }\n    // \u5f85\u63d2\u5165\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            return\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            cur = cur.Right\n        } else {\n            cur = cur.Left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    node := NewTreeNode(num)\n    if pre.Val.(int) < num {\n        pre.Right = node\n    } else {\n        pre.Left = node\n    }\n}\n
    binary_search_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if root == nil {\n        root = TreeNode(x: num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur!.val == num {\n            return\n        }\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let node = TreeNode(x: num)\n    if pre!.val < num {\n        pre?.right = node\n    } else {\n        pre?.left = node\n    }\n}\n
    binary_search_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre.val < num) pre.right = node;\n    else pre.left = node;\n}\n
    binary_search_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre!.val < num) pre!.right = node;\n    else pre!.left = node;\n}\n
    binary_search_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if (_root == null) {\n    _root = TreeNode(_num);\n    return;\n  }\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    if (cur.val == _num) return;\n    pre = cur;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u63d2\u5165\u8282\u70b9\n  TreeNode? node = TreeNode(_num);\n  if (pre!.val < _num)\n    pre.right = node;\n  else\n    pre.left = node;\n}\n
    binary_search_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\npub fn insert(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self.root.is_none() {\n        self.root = Some(TreeNode::new(num));\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n            Ordering::Equal => return,\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let pre = pre.unwrap();\n    let node = Some(TreeNode::new(num));\n    if num > pre.borrow().val {\n        pre.borrow_mut().right = node;\n    } else {\n        pre.borrow_mut().left = node;\n    }\n}\n
    binary_search_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (bst->root == NULL) {\n        bst->root = newTreeNode(num);\n        return;\n    }\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num) {\n            return;\n        }\n        pre = cur;\n        if (cur->val < num) {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = newTreeNode(num);\n    if (pre->val < num) {\n        pre->right = node;\n    } else {\n        pre->left = node;\n    }\n}\n
    binary_search_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = TreeNode(num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur._val == num)\n            return\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u63d2\u5165\u8282\u70b9\n    val node = TreeNode(num)\n    if (pre?._val!! < num)\n        pre.right = node\n    else\n        pre.left = node\n}\n
    binary_search_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if @root.nil?\n    @root = TreeNode.new(num)\n    return\n  end\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    return if cur.val == num\n\n    pre = cur\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n\n  # \u63d2\u5165\u8282\u70b9\n  node = TreeNode.new(num)\n  if pre.val < num\n    pre.right = node\n  else\n    pre.left = node\n  end\nend\n
    binary_search_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, num: T) !void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (self.root == null) {\n        self.root = try self.mem_allocator.create(inc.TreeNode(T));\n        return;\n    }\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.?.val == num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    var node = try self.mem_allocator.create(inc.TreeNode(T));\n    node.init(num);\n    if (pre.?.val < num) {\n        pre.?.right = node;\n    } else {\n        pre.?.left = node;\n    }\n}\n
    Code Visualization

    Full Screen >

    Similar to searching for a node, inserting a node uses \\(O(\\log n)\\) time.

    "},{"location":"chapter_tree/binary_search_tree/#3-removing-a-node","title":"3. \u00a0 Removing a node","text":"

    First, find the target node in the binary tree, then remove it. Similar to inserting a node, we need to ensure that after the removal operation is completed, the property of the binary search tree \"left subtree < root node < right subtree\" is still satisfied. Therefore, based on the number of child nodes of the target node, we divide it into 0, 1, and 2 cases, performing the corresponding node removal operations.

    As shown in the Figure 7-19 , when the degree of the node to be removed is \\(0\\), it means the node is a leaf node, and it can be directly removed.

    Figure 7-19 \u00a0 Removing a node in a binary search tree (degree 0)

    As shown in the Figure 7-20 , when the degree of the node to be removed is \\(1\\), replacing the node to be removed with its child node is sufficient.

    Figure 7-20 \u00a0 Removing a node in a binary search tree (degree 1)

    When the degree of the node to be removed is \\(2\\), we cannot remove it directly, but need to use a node to replace it. To maintain the property of the binary search tree \"left subtree < root node < right subtree,\" this node can be either the smallest node of the right subtree or the largest node of the left subtree.

    Assuming we choose the smallest node of the right subtree (the next node in in-order traversal), then the removal operation proceeds as shown in the Figure 7-21 .

    1. Find the next node in the \"in-order traversal sequence\" of the node to be removed, denoted as tmp.
    2. Replace the value of the node to be removed with tmp's value, and recursively remove the node tmp in the tree.
    <1><2><3><4>

    Figure 7-21 \u00a0 Removing a node in a binary search tree (degree 2)

    The operation of removing a node also uses \\(O(\\log n)\\) time, where finding the node to be removed requires \\(O(\\log n)\\) time, and obtaining the in-order traversal successor node requires \\(O(\\log n)\\) time. Example code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def remove(self, num: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self._root is None:\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur.val == num:\n            break\n        pre = cur\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur is None:\n        return\n\n    # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur.left is None or cur.right is None:\n        # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        child = cur.left or cur.right\n        # \u5220\u9664\u8282\u70b9 cur\n        if cur != self._root:\n            if pre.left == cur:\n                pre.left = child\n            else:\n                pre.right = child\n        else:\n            # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            self._root = child\n    # \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else:\n        # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp: TreeNode = cur.right\n        while tmp.left is not None:\n            tmp = tmp.left\n        # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.val)\n        # \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val\n
    binary_search_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == nullptr)\n        return;\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == nullptr)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur->left == nullptr || cur->right == nullptr) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != nullptr ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre->left == cur)\n                pre->left = child;\n            else\n                pre->right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete cur;\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != nullptr) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode child = cur.left != null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode? child = cur.left ?? cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode? tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        Remove(tmp.val!.Value);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (bst *binarySearchTree) remove(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5f85\u5220\u9664\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            break\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u53f3\u5b50\u6811\u4e2d\n            cur = cur.Right\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u5de6\u5b50\u6811\u4e2d\n            cur = cur.Left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u4e3a 0 \u6216 1\n    if cur.Left == nil || cur.Right == nil {\n        var child *TreeNode = nil\n        // \u53d6\u51fa\u5f85\u5220\u9664\u8282\u70b9\u7684\u5b50\u8282\u70b9\n        if cur.Left != nil {\n            child = cur.Left\n        } else {\n            child = cur.Right\n        }\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur != bst.root {\n            if pre.Left == cur {\n                pre.Left = child\n            } else {\n                pre.Right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            bst.root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u4e3a 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d\u5f85\u5220\u9664\u8282\u70b9 cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp := cur.Right\n        for tmp.Left != nil {\n            tmp = tmp.Left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        bst.remove(tmp.Val.(int))\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.Val = tmp.Val\n    }\n}\n
    binary_search_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if root == nil {\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur!.val == num {\n            break\n        }\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur?.left == nil || cur?.right == nil {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        let child = cur?.left ?? cur?.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur !== root {\n            if pre?.left === cur {\n                pre?.left = child\n            } else {\n                pre?.right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur?.right\n        while tmp?.left != nil {\n            tmp = tmp?.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(num: tmp!.val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur?.val = tmp!.val\n    }\n}\n
    binary_search_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child = cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre.left === cur) pre.left = child;\n            else pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp = cur.right;\n        while (tmp.left !== null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child: TreeNode | null =\n            cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre!.left === cur) pre!.left = child;\n            else pre!.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp: TreeNode | null = cur.right;\n        while (tmp!.left !== null) {\n            tmp = tmp!.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp!.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp!.val;\n    }\n}\n
    binary_search_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  if (_root == null) return;\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    if (cur.val == _num) break;\n    pre = cur;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n  if (cur == null) return;\n  // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if (cur.left == null || cur.right == null) {\n    // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    TreeNode? child = cur.left ?? cur.right;\n    // \u5220\u9664\u8282\u70b9 cur\n    if (cur != _root) {\n      if (pre!.left == cur)\n        pre.left = child;\n      else\n        pre.right = child;\n    } else {\n      // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      _root = child;\n    }\n  } else {\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    TreeNode? tmp = cur.right;\n    while (tmp!.left != null) {\n      tmp = tmp.left;\n    }\n    // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val);\n    // \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val;\n  }\n}\n
    binary_search_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\npub fn remove(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self.root.is_none() {\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur.is_none() {\n        return;\n    }\n    let cur = cur.unwrap();\n    let (left_child, right_child) = (cur.borrow().left.clone(), cur.borrow().right.clone());\n    match (left_child.clone(), right_child.clone()) {\n        // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n        (None, None) | (Some(_), None) | (None, Some(_)) => {\n            // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n            let child = left_child.or(right_child);\n            let pre = pre.unwrap();\n            // \u5220\u9664\u8282\u70b9 cur\n            if !Rc::ptr_eq(&cur, self.root.as_ref().unwrap()) {\n                let left = pre.borrow().left.clone();\n                if left.is_some() && Rc::ptr_eq(&left.as_ref().unwrap(), &cur) {\n                    pre.borrow_mut().left = child;\n                } else {\n                    pre.borrow_mut().right = child;\n                }\n            } else {\n                // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n                self.root = child;\n            }\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n        (Some(_), Some(_)) => {\n            // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n            let mut tmp = cur.borrow().right.clone();\n            while let Some(node) = tmp.clone() {\n                if node.borrow().left.is_some() {\n                    tmp = node.borrow().left.clone();\n                } else {\n                    break;\n                }\n            }\n            let tmpval = tmp.unwrap().borrow().val;\n            // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n            self.remove(tmpval);\n            // \u7528 tmp \u8986\u76d6 cur\n            cur.borrow_mut().val = tmpval;\n        }\n    }\n}\n
    binary_search_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (bst->root == NULL)\n        return;\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        if (cur->val < num) {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == NULL)\n        return;\n    // \u5224\u65ad\u5f85\u5220\u9664\u8282\u70b9\u662f\u5426\u5b58\u5728\u5b50\u8282\u70b9\n    if (cur->left == NULL || cur->right == NULL) {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1 */\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != NULL ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre->left == cur) {\n            pre->left = child;\n        } else {\n            pre->right = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(cur);\n    } else {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 2 */\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != NULL) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        removeItem(bst, tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur._val == num)\n            break\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        val child = if (cur.left != null)\n            cur.left\n        else\n            cur.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!!.left == cur)\n                pre.left = child\n            else\n                pre.right = child\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.right\n        while (tmp!!.left != null) {\n            tmp = tmp.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp._val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur._val = tmp._val\n    }\n}\n
    binary_search_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  return if @root.nil?\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    break if cur.val == num\n\n    pre = cur\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n  # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  return if cur.nil?\n\n  # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if cur.left.nil? || cur.right.nil?\n    # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    child = cur.left || cur.right\n    # \u5220\u9664\u8282\u70b9 cur\n    if cur != @root\n      if pre.left == cur\n        pre.left = child\n      else\n        pre.right = child\n      end\n    else\n      # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      @root = child\n    end\n  # \u5b50\u8282\u70b9\u6570\u91cf = 2\n  else\n    # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    tmp = cur.right\n    while !tmp.left.nil?\n      tmp = tmp.left\n    end\n    # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val)\n    # \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val\n  end\nend\n
    binary_search_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, num: T) void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (self.root == null) return;\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.?.val == num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.?.left == null or cur.?.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        var child = if (cur.?.left != null) cur.?.left else cur.?.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre.?.left == cur) {\n            pre.?.left = child;\n        } else {\n            pre.?.right = child;\n        }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.?.right;\n        while (tmp.?.left != null) {\n            tmp = tmp.?.left;\n        }\n        var tmp_val = tmp.?.val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.?.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.?.val = tmp_val;\n    }\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/binary_search_tree/#4-in-order-traversal-is-ordered","title":"4. \u00a0 In-order traversal is ordered","text":"

    As shown in the Figure 7-22 , the in-order traversal of a binary tree follows the \"left \\(\\rightarrow\\) root \\(\\rightarrow\\) right\" traversal order, and a binary search tree satisfies the size relationship \"left child node < root node < right child node\".

    This means that in-order traversal in a binary search tree always traverses the next smallest node first, thus deriving an important property: The in-order traversal sequence of a binary search tree is ascending.

    Using the ascending property of in-order traversal, obtaining ordered data in a binary search tree requires only \\(O(n)\\) time, without the need for additional sorting operations, which is very efficient.

    Figure 7-22 \u00a0 In-order traversal sequence of a binary search tree

    "},{"location":"chapter_tree/binary_search_tree/#742-efficiency-of-binary-search-trees","title":"7.4.2 \u00a0 Efficiency of binary search trees","text":"

    Given a set of data, we consider using an array or a binary search tree for storage. Observing the Table 7-2 , the operations on a binary search tree all have logarithmic time complexity, which is stable and efficient. Only in scenarios of high-frequency addition and low-frequency search and removal, arrays are more efficient than binary search trees.

    Table 7-2 \u00a0 Efficiency comparison between arrays and search trees

    Unsorted array Binary search tree Search element \\(O(n)\\) \\(O(\\log n)\\) Insert element \\(O(1)\\) \\(O(\\log n)\\) Remove element \\(O(n)\\) \\(O(\\log n)\\)

    In ideal conditions, the binary search tree is \"balanced,\" thus any node can be found within \\(\\log n\\) loops.

    However, continuously inserting and removing nodes in a binary search tree may lead to the binary tree degenerating into a chain list as shown in the Figure 7-23 , at which point the time complexity of various operations also degrades to \\(O(n)\\).

    Figure 7-23 \u00a0 Degradation of a binary search tree

    "},{"location":"chapter_tree/binary_search_tree/#743-common-applications-of-binary-search-trees","title":"7.4.3 \u00a0 Common applications of binary search trees","text":"
    • Used as multi-level indexes in systems to implement efficient search, insertion, and removal operations.
    • Serves as the underlying data structure for certain search algorithms.
    • Used to store data streams to maintain their ordered state.
    "},{"location":"chapter_tree/binary_tree/","title":"7.1 \u00a0 Binary tree","text":"

    A \"binary tree\" is a non-linear data structure that represents the ancestral and descendent relationships, embodying the \"divide and conquer\" logic. Similar to a linked list, the basic unit of a binary tree is a node, each containing a value, a reference to the left child node, and a reference to the right child node.

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"Binary tree node\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # Node value\n        self.left: TreeNode | None = None  # Reference to left child node\n        self.right: TreeNode | None = None # Reference to right child node\n
    /* Binary tree node */\nstruct TreeNode {\n    int val;          // Node value\n    TreeNode *left;   // Pointer to left child node\n    TreeNode *right;  // Pointer to right child node\n    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n};\n
    /* Binary tree node */\nclass TreeNode {\n    int val;         // Node value\n    TreeNode left;   // Reference to left child node\n    TreeNode right;  // Reference to right child node\n    TreeNode(int x) { val = x; }\n}\n
    /* Binary tree node */\nclass TreeNode(int? x) {\n    public int? val = x;    // Node value\n    public TreeNode? left;  // Reference to left child node\n    public TreeNode? right; // Reference to right child node\n}\n
    /* Binary tree node */\ntype TreeNode struct {\n    Val   int\n    Left  *TreeNode\n    Right *TreeNode\n}\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc NewTreeNode(v int) *TreeNode {\n    return &TreeNode{\n        Left:  nil, // Pointer to left child node\n        Right: nil, // Pointer to right child node\n        Val:   v,   // Node value\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n    var val: Int // Node value\n    var left: TreeNode? // Reference to left child node\n    var right: TreeNode? // Reference to right child node\n\n    init(x: Int) {\n        val = x\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n    val; // Node value\n    left; // Pointer to left child node\n    right; // Pointer to right child node\n    constructor(val, left, right) {\n        this.val = val === undefined ? 0 : val;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n    val: number;\n    left: TreeNode | null;\n    right: TreeNode | null;\n\n    constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val; // Node value\n        this.left = left === undefined ? null : left; // Reference to left child node\n        this.right = right === undefined ? null : right; // Reference to right child node\n    }\n}\n
    /* Binary tree node */\nclass TreeNode {\n  int val;         // Node value\n  TreeNode? left;  // Reference to left child node\n  TreeNode? right; // Reference to right child node\n  TreeNode(this.val, [this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* Binary tree node */\nstruct TreeNode {\n    val: i32,                               // Node value\n    left: Option<Rc<RefCell<TreeNode>>>,    // Reference to left child node\n    right: Option<Rc<RefCell<TreeNode>>>,   // Reference to right child node\n}\n\nimpl TreeNode {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* Binary tree node */\ntypedef struct TreeNode {\n    int val;                // Node value\n    int height;             // \u8282\u70b9\u9ad8\u5ea6\n    struct TreeNode *left;  // Pointer to left child node\n    struct TreeNode *right; // Pointer to right child node\n} TreeNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* Binary tree node */\nclass TreeNode(val _val: Int) {  // Node value\n    val left: TreeNode? = null   // Reference to left child node\n    val right: TreeNode? = null  // Reference to right child node\n}\n
    \n
    \n

    Each node has two references (pointers), pointing to the \"left-child node\" and \"right-child node,\" respectively. This node is called the \"parent node\" of these two child nodes. When given a node of a binary tree, we call the tree formed by this node's left child and all nodes under it the \"left subtree\" of this node. Similarly, the \"right subtree\" can be defined.

    In a binary tree, except for leaf nodes, all other nodes contain child nodes and non-empty subtrees. As shown in the Figure 7-1 , if \"Node 2\" is considered as the parent node, then its left and right child nodes are \"Node 4\" and \"Node 5,\" respectively. The left subtree is \"the tree formed by Node 4 and all nodes under it,\" and the right subtree is \"the tree formed by Node 5 and all nodes under it.\"

    Figure 7-1 \u00a0 Parent Node, child Node, subtree

    "},{"location":"chapter_tree/binary_tree/#711-common-terminology-of-binary-trees","title":"7.1.1 \u00a0 Common terminology of binary trees","text":"

    The commonly used terminology of binary trees is shown in the following figure.

    • \"Root node\": The node at the top level of the binary tree, which has no parent node.
    • \"Leaf node\": A node with no children, both of its pointers point to None.
    • \"Edge\": The line segment connecting two nodes, i.e., node reference (pointer).
    • The \"level\" of a node: Incrementing from top to bottom, with the root node's level being 1.
    • The \"degree\" of a node: The number of a node's children. In a binary tree, the degree can be 0, 1, or 2.
    • The \"height\" of a binary tree: The number of edges passed from the root node to the farthest leaf node.
    • The \"depth\" of a node: The number of edges passed from the root node to the node.
    • The \"height\" of a node: The number of edges from the farthest leaf node to the node.

    Figure 7-2 \u00a0 Common Terminology of Binary Trees

    Tip

    Please note that we usually define \"height\" and \"depth\" as \"the number of edges passed,\" but some problems or textbooks may define them as \"the number of nodes passed.\" In this case, both height and depth need to be incremented by 1.

    "},{"location":"chapter_tree/binary_tree/#712-basic-operations-of-binary-trees","title":"7.1.2 \u00a0 Basic operations of binary trees","text":""},{"location":"chapter_tree/binary_tree/#1-initializing-a-binary-tree","title":"1. \u00a0 Initializing a binary tree","text":"

    Similar to a linked list, initialize nodes first, then construct references (pointers).

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # Initializing a binary tree\n# Initializing nodes\nn1 = TreeNode(val=1)\nn2 = TreeNode(val=2)\nn3 = TreeNode(val=3)\nn4 = TreeNode(val=4)\nn5 = TreeNode(val=5)\n# Linking references (pointers) between nodes\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.cpp
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode* n1 = new TreeNode(1);\nTreeNode* n2 = new TreeNode(2);\nTreeNode* n3 = new TreeNode(3);\nTreeNode* n4 = new TreeNode(4);\nTreeNode* n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.java
    // Initializing nodes\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.cs
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode n1 = new(1);\nTreeNode n2 = new(2);\nTreeNode n3 = new(3);\nTreeNode n4 = new(4);\nTreeNode n5 = new(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.go
    /* Initializing a binary tree */\n// Initializing nodes\nn1 := NewTreeNode(1)\nn2 := NewTreeNode(2)\nn3 := NewTreeNode(3)\nn4 := NewTreeNode(4)\nn5 := NewTreeNode(5)\n// Linking references (pointers) between nodes\nn1.Left = n2\nn1.Right = n3\nn2.Left = n4\nn2.Right = n5\n
    binary_tree.swift
    // Initializing nodes\nlet n1 = TreeNode(x: 1)\nlet n2 = TreeNode(x: 2)\nlet n3 = TreeNode(x: 3)\nlet n4 = TreeNode(x: 4)\nlet n5 = TreeNode(x: 5)\n// Linking references (pointers) between nodes\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.js
    /* Initializing a binary tree */\n// Initializing nodes\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.ts
    /* Initializing a binary tree */\n// Initializing nodes\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.dart
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// Linking references (pointers) between nodes\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.rs
    // Initializing nodes\nlet n1 = TreeNode::new(1);\nlet n2 = TreeNode::new(2);\nlet n3 = TreeNode::new(3);\nlet n4 = TreeNode::new(4);\nlet n5 = TreeNode::new(5);\n// Linking references (pointers) between nodes\nn1.borrow_mut().left = Some(n2.clone());\nn1.borrow_mut().right = Some(n3);\nn2.borrow_mut().left = Some(n4);\nn2.borrow_mut().right = Some(n5);\n
    binary_tree.c
    /* Initializing a binary tree */\n// Initializing nodes\nTreeNode *n1 = newTreeNode(1);\nTreeNode *n2 = newTreeNode(2);\nTreeNode *n3 = newTreeNode(3);\nTreeNode *n4 = newTreeNode(4);\nTreeNode *n5 = newTreeNode(5);\n// Linking references (pointers) between nodes\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.kt
    // Initializing nodes\nval n1 = TreeNode(1)\nval n2 = TreeNode(2)\nval n3 = TreeNode(3)\nval n4 = TreeNode(4)\nval n5 = TreeNode(5)\n// Linking references (pointers) between nodes\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.rb
    \n
    binary_tree.zig
    \n
    Code visualization

    https://pythontutor.com/render.html#code=class%20TreeNode%3A%0A%20%20%20%20%22%22%22%E4%BA%8C%E5%8F%89%E6%A0%91%E8%8A%82%E7%82%B9%E7%B1%BB%22%22%22%0A%20%20%20%20def%20__init__%28self,%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8A%82%E7%82%B9%E5%80%BC%0A%20%20%20%20%20%20%20%20self.left%3A%20TreeNode%20%7C%20None%20%3D%20None%20%20%23%20%E5%B7%A6%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%20%20%20%20%20%20%20%20self.right%3A%20TreeNode%20%7C%20None%20%3D%20None%20%23%20%E5%8F%B3%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BA%8C%E5%8F%89%E6%A0%91%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E8%8A%82%E7%82%B9%0A%20%20%20%20n1%20%3D%20TreeNode%28val%3D1%29%0A%20%20%20%20n2%20%3D%20TreeNode%28val%3D2%29%0A%20%20%20%20n3%20%3D%20TreeNode%28val%3D3%29%0A%20%20%20%20n4%20%3D%20TreeNode%28val%3D4%29%0A%20%20%20%20n5%20%3D%20TreeNode%28val%3D5%29%0A%20%20%20%20%23%20%E6%9E%84%E5%BB%BA%E8%8A%82%E7%82%B9%E4%B9%8B%E9%97%B4%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%88%E6%8C%87%E9%92%88%EF%BC%89%0A%20%20%20%20n1.left%20%3D%20n2%0A%20%20%20%20n1.right%20%3D%20n3%0A%20%20%20%20n2.left%20%3D%20n4%0A%20%20%20%20n2.right%20%3D%20n5&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    "},{"location":"chapter_tree/binary_tree/#2-inserting-and-removing-nodes","title":"2. \u00a0 Inserting and removing nodes","text":"

    Similar to a linked list, inserting and removing nodes in a binary tree can be achieved by modifying pointers. The Figure 7-3 provides an example.

    Figure 7-3 \u00a0 Inserting and removing nodes in a binary tree

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # Inserting and removing nodes\np = TreeNode(0)\n# Inserting node P between n1 -> n2\nn1.left = p\np.left = n2\n# Removing node P\nn1.left = n2\n
    binary_tree.cpp
    /* Inserting and removing nodes */\nTreeNode* P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1->left = P;\nP->left = n2;\n// Removing node P\nn1->left = n2;\n
    binary_tree.java
    TreeNode P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.cs
    /* Inserting and removing nodes */\nTreeNode P = new(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.go
    /* Inserting and removing nodes */\n// Inserting node P between n1 and n2\np := NewTreeNode(0)\nn1.Left = p\np.Left = n2\n// Removing node P\nn1.Left = n2\n
    binary_tree.swift
    let P = TreeNode(x: 0)\n// Inserting node P between n1 and n2\nn1.left = P\nP.left = n2\n// Removing node P\nn1.left = n2\n
    binary_tree.js
    /* Inserting and removing nodes */\nlet P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.ts
    /* Inserting and removing nodes */\nconst P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.dart
    /* Inserting and removing nodes */\nTreeNode P = new TreeNode(0);\n// Inserting node P between n1 and n2\nn1.left = P;\nP.left = n2;\n// Removing node P\nn1.left = n2;\n
    binary_tree.rs
    let p = TreeNode::new(0);\n// Inserting node P between n1 and n2\nn1.borrow_mut().left = Some(p.clone());\np.borrow_mut().left = Some(n2.clone());\n// Removing node P\nn1.borrow_mut().left = Some(n2);\n
    binary_tree.c
    /* Inserting and removing nodes */\nTreeNode *P = newTreeNode(0);\n// Inserting node P between n1 and n2\nn1->left = P;\nP->left = n2;\n// Removing node P\nn1->left = n2;\n
    binary_tree.kt
    val P = TreeNode(0)\n// Inserting node P between n1 and n2\nn1.left = P\nP.left = n2\n// Removing node P\nn1.left = n2\n
    binary_tree.rb
    \n
    binary_tree.zig
    \n
    Code visualization

    https://pythontutor.com/render.html#code=class%20TreeNode%3A%0A%20%20%20%20%22%22%22%E4%BA%8C%E5%8F%89%E6%A0%91%E8%8A%82%E7%82%B9%E7%B1%BB%22%22%22%0A%20%20%20%20def%20__init__%28self,%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8A%82%E7%82%B9%E5%80%BC%0A%20%20%20%20%20%20%20%20self.left%3A%20TreeNode%20%7C%20None%20%3D%20None%20%20%23%20%E5%B7%A6%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%20%20%20%20%20%20%20%20self.right%3A%20TreeNode%20%7C%20None%20%3D%20None%20%23%20%E5%8F%B3%E5%AD%90%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BA%8C%E5%8F%89%E6%A0%91%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E8%8A%82%E7%82%B9%0A%20%20%20%20n1%20%3D%20TreeNode%28val%3D1%29%0A%20%20%20%20n2%20%3D%20TreeNode%28val%3D2%29%0A%20%20%20%20n3%20%3D%20TreeNode%28val%3D3%29%0A%20%20%20%20n4%20%3D%20TreeNode%28val%3D4%29%0A%20%20%20%20n5%20%3D%20TreeNode%28val%3D5%29%0A%20%20%20%20%23%20%E6%9E%84%E5%BB%BA%E8%8A%82%E7%82%B9%E4%B9%8B%E9%97%B4%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%88%E6%8C%87%E9%92%88%EF%BC%89%0A%20%20%20%20n1.left%20%3D%20n2%0A%20%20%20%20n1.right%20%3D%20n3%0A%20%20%20%20n2.left%20%3D%20n4%0A%20%20%20%20n2.right%20%3D%20n5%0A%0A%20%20%20%20%23%20%E6%8F%92%E5%85%A5%E4%B8%8E%E5%88%A0%E9%99%A4%E8%8A%82%E7%82%B9%0A%20%20%20%20p%20%3D%20TreeNode%280%29%0A%20%20%20%20%23%20%E5%9C%A8%20n1%20-%3E%20n2%20%E4%B8%AD%E9%97%B4%E6%8F%92%E5%85%A5%E8%8A%82%E7%82%B9%20P%0A%20%20%20%20n1.left%20%3D%20p%0A%20%20%20%20p.left%20%3D%20n2%0A%20%20%20%20%23%20%E5%88%A0%E9%99%A4%E8%8A%82%E7%82%B9%20P%0A%20%20%20%20n1.left%20%3D%20n2&cumulative=false&curInstr=37&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false

    Tip

    It's important to note that inserting nodes may change the original logical structure of the binary tree, while removing nodes usually means removing the node and all its subtrees. Therefore, in a binary tree, insertion and removal are usually performed through a set of operations to achieve meaningful actions.

    "},{"location":"chapter_tree/binary_tree/#713-common-types-of-binary-trees","title":"7.1.3 \u00a0 Common types of binary trees","text":""},{"location":"chapter_tree/binary_tree/#1-perfect-binary-tree","title":"1. \u00a0 Perfect binary tree","text":"

    As shown in the Figure 7-4 , in a \"perfect binary tree,\" all levels of nodes are fully filled. In a perfect binary tree, the degree of leaf nodes is \\(0\\), and the degree of all other nodes is \\(2\\); if the tree's height is \\(h\\), then the total number of nodes is \\(2^{h+1} - 1\\), showing a standard exponential relationship, reflecting the common phenomenon of cell division in nature.

    Tip

    Please note that in the Chinese community, a perfect binary tree is often referred to as a \"full binary tree.\"

    Figure 7-4 \u00a0 Perfect binary tree

    "},{"location":"chapter_tree/binary_tree/#2-complete-binary-tree","title":"2. \u00a0 Complete binary tree","text":"

    As shown in the Figure 7-5 , a \"complete binary tree\" has only the bottom level nodes not fully filled, and the bottom level nodes are filled as far left as possible.

    Figure 7-5 \u00a0 Complete binary tree

    "},{"location":"chapter_tree/binary_tree/#3-full-binary-tree","title":"3. \u00a0 Full binary tree","text":"

    As shown in the Figure 7-6 , a \"full binary tree\" has all nodes except leaf nodes having two children.

    Figure 7-6 \u00a0 Full binary tree

    "},{"location":"chapter_tree/binary_tree/#4-balanced-binary-tree","title":"4. \u00a0 Balanced binary tree","text":"

    As shown in the Figure 7-7 , in a \"balanced binary tree,\" the absolute difference in height between the left and right subtrees of any node does not exceed 1.

    Figure 7-7 \u00a0 Balanced binary tree

    "},{"location":"chapter_tree/binary_tree/#714-degeneration-of-binary-trees","title":"7.1.4 \u00a0 Degeneration of binary trees","text":"

    The Figure 7-8 shows the ideal and degenerate structures of binary trees. When every level of a binary tree is filled, it reaches the \"perfect binary tree\"; when all nodes are biased towards one side, the binary tree degenerates into a \"linked list\".

    • The perfect binary tree is the ideal situation, fully leveraging the \"divide and conquer\" advantage of binary trees.
    • A linked list is another extreme, where operations become linear, degrading the time complexity to \\(O(n)\\).

    Figure 7-8 \u00a0 The Best and Worst Structures of Binary Trees

    As shown in the Table 7-1 , in the best and worst structures, the number of leaf nodes, total number of nodes, and height of the binary tree reach their maximum or minimum values.

    Table 7-1 \u00a0 The Best and Worst Structures of Binary Trees

    Perfect binary tree Linked list Number of nodes at level \\(i\\) \\(2^{i-1}\\) \\(1\\) Number of leaf nodes in a tree with height \\(h\\) \\(2^h\\) \\(1\\) Total number of nodes in a tree with height \\(h\\) \\(2^{h+1} - 1\\) \\(h + 1\\) Height of a tree with \\(n\\) total nodes \\(\\log_2 (n+1) - 1\\) \\(n - 1\\)"},{"location":"chapter_tree/binary_tree_traversal/","title":"7.2 \u00a0 Binary tree traversal","text":"

    From the perspective of physical structure, a tree is a data structure based on linked lists, hence its traversal method involves accessing nodes one by one through pointers. However, a tree is a non-linear data structure, which makes traversing a tree more complex than traversing a linked list, requiring the assistance of search algorithms to achieve.

    Common traversal methods for binary trees include level-order traversal, preorder traversal, inorder traversal, and postorder traversal, among others.

    "},{"location":"chapter_tree/binary_tree_traversal/#721-level-order-traversal","title":"7.2.1 \u00a0 Level-order traversal","text":"

    As shown in the Figure 7-9 , \"level-order traversal\" traverses the binary tree from top to bottom, layer by layer, and accesses nodes in each layer in a left-to-right order.

    Level-order traversal essentially belongs to \"breadth-first traversal\", also known as \"breadth-first search (BFS)\", which embodies a \"circumferentially outward expanding\" layer-by-layer traversal method.

    Figure 7-9 \u00a0 Level-order traversal of a binary tree

    "},{"location":"chapter_tree/binary_tree_traversal/#1-code-implementation","title":"1. \u00a0 Code implementation","text":"

    Breadth-first traversal is usually implemented with the help of a \"queue\". The queue follows the \"first in, first out\" rule, while breadth-first traversal follows the \"layer-by-layer progression\" rule, the underlying ideas of the two are consistent. The implementation code is as follows:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_bfs.py
    def level_order(root: TreeNode | None) -> list[int]:\n    \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n    # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue: deque[TreeNode] = deque()\n    queue.append(root)\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    res = []\n    while queue:\n        node: TreeNode = queue.popleft()  # \u961f\u5217\u51fa\u961f\n        res.append(node.val)  # \u4fdd\u5b58\u8282\u70b9\u503c\n        if node.left is not None:\n            queue.append(node.left)  # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if node.right is not None:\n            queue.append(node.right)  # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    return res\n
    binary_tree_bfs.cpp
    /* \u5c42\u5e8f\u904d\u5386 */\nvector<int> levelOrder(TreeNode *root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue<TreeNode *> queue;\n    queue.push(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    vector<int> vec;\n    while (!queue.empty()) {\n        TreeNode *node = queue.front();\n        queue.pop();              // \u961f\u5217\u51fa\u961f\n        vec.push_back(node->val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node->left != nullptr)\n            queue.push(node->left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node->right != nullptr)\n            queue.push(node->right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return vec;\n}\n
    binary_tree_bfs.java
    /* \u5c42\u5e8f\u904d\u5386 */\nList<Integer> levelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new LinkedList<>();\n    queue.add(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<Integer> list = new ArrayList<>();\n    while (!queue.isEmpty()) {\n        TreeNode node = queue.poll(); // \u961f\u5217\u51fa\u961f\n        list.add(node.val);           // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left);   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right);  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.cs
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> LevelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new();\n    queue.Enqueue(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<int> list = [];\n    while (queue.Count != 0) {\n        TreeNode node = queue.Dequeue(); // \u961f\u5217\u51fa\u961f\n        list.Add(node.val!.Value);       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.Enqueue(node.left);    // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.Enqueue(node.right);   // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.go
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root *TreeNode) []any {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue := list.New()\n    queue.PushBack(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5207\u7247\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    nums := make([]any, 0)\n    for queue.Len() > 0 {\n        // \u961f\u5217\u51fa\u961f\n        node := queue.Remove(queue.Front()).(*TreeNode)\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        nums = append(nums, node.Val)\n        if node.Left != nil {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Left)\n        }\n        if node.Right != nil {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Right)\n        }\n    }\n    return nums\n}\n
    binary_tree_bfs.swift
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root: TreeNode) -> [Int] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    var queue: [TreeNode] = [root]\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list: [Int] = []\n    while !queue.isEmpty {\n        let node = queue.removeFirst() // \u961f\u5217\u51fa\u961f\n        list.append(node.val) // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let left = node.left {\n            queue.append(left) // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let right = node.right {\n            queue.append(right) // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list\n}\n
    binary_tree_bfs.js
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list = [];\n    while (queue.length) {\n        let node = queue.shift(); // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right) queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.ts
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root: TreeNode | null): number[] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list: number[] = [];\n    while (queue.length) {\n        let node = queue.shift() as TreeNode; // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) {\n            queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right) {\n            queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list;\n}\n
    binary_tree_bfs.dart
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> levelOrder(TreeNode? root) {\n  // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  Queue<TreeNode?> queue = Queue();\n  queue.add(root);\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  List<int> res = [];\n  while (queue.isNotEmpty) {\n    TreeNode? node = queue.removeFirst(); // \u961f\u5217\u51fa\u961f\n    res.add(node!.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n    if (node.left != null) queue.add(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    if (node.right != null) queue.add(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  }\n  return res;\n}\n
    binary_tree_bfs.rs
    /* \u5c42\u5e8f\u904d\u5386 */\nfn level_order(root: &Rc<RefCell<TreeNode>>) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    let mut que = VecDeque::new();\n    que.push_back(root.clone());\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    let mut vec = Vec::new();\n\n    while let Some(node) = que.pop_front() {\n        // \u961f\u5217\u51fa\u961f\n        vec.push(node.borrow().val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let Some(left) = node.borrow().left.as_ref() {\n            que.push_back(left.clone()); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let Some(right) = node.borrow().right.as_ref() {\n            que.push_back(right.clone()); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        };\n    }\n    vec\n}\n
    binary_tree_bfs.c
    /* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(TreeNode *root, int *size) {\n    /* \u8f85\u52a9\u961f\u5217 */\n    int front, rear;\n    int index, *arr;\n    TreeNode *node;\n    TreeNode **queue;\n\n    /* \u8f85\u52a9\u961f\u5217 */\n    queue = (TreeNode **)malloc(sizeof(TreeNode *) * MAX_SIZE);\n    // \u961f\u5217\u6307\u9488\n    front = 0, rear = 0;\n    // \u52a0\u5165\u6839\u8282\u70b9\n    queue[rear++] = root;\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    /* \u8f85\u52a9\u6570\u7ec4 */\n    arr = (int *)malloc(sizeof(int) * MAX_SIZE);\n    // \u6570\u7ec4\u6307\u9488\n    index = 0;\n    while (front < rear) {\n        // \u961f\u5217\u51fa\u961f\n        node = queue[front++];\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        arr[index++] = node->val;\n        if (node->left != NULL) {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->left;\n        }\n        if (node->right != NULL) {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->right;\n        }\n    }\n    // \u66f4\u65b0\u6570\u7ec4\u957f\u5ea6\u7684\u503c\n    *size = index;\n    arr = realloc(arr, sizeof(int) * (*size));\n\n    // \u91ca\u653e\u8f85\u52a9\u6570\u7ec4\u7a7a\u95f4\n    free(queue);\n    return arr;\n}\n
    binary_tree_bfs.kt
    /* \u5c42\u5e8f\u904d\u5386 */\nfun levelOrder(root: TreeNode?): MutableList<Int> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    val queue = LinkedList<TreeNode?>()\n    queue.add(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    val list = mutableListOf<Int>()\n    while (queue.isNotEmpty()) {\n        val node = queue.poll()      // \u961f\u5217\u51fa\u961f\n        list.add(node?._val!!)       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left)   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right)  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list\n}\n
    binary_tree_bfs.rb
    ### \u5c42\u5e8f\u904d\u5386 ###\ndef level_order(root)\n  # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  queue = [root]\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  res = []\n  while !queue.empty?\n    node = queue.shift # \u961f\u5217\u51fa\u961f\n    res << node.val # \u4fdd\u5b58\u8282\u70b9\u503c\n    queue << node.left unless node.left.nil? # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    queue << node.right unless node.right.nil? # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  end\n  res\nend\n
    binary_tree_bfs.zig
    // \u5c42\u5e8f\u904d\u5386\nfn levelOrder(comptime T: type, mem_allocator: std.mem.Allocator, root: *inc.TreeNode(T)) !std.ArrayList(T) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const L = std.TailQueue(*inc.TreeNode(T));\n    var queue = L{};\n    var root_node = try mem_allocator.create(L.Node);\n    root_node.data = root;\n    queue.append(root_node); \n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list = std.ArrayList(T).init(std.heap.page_allocator);\n    while (queue.len > 0) {\n        var queue_node = queue.popFirst().?;    // \u961f\u5217\u51fa\u961f\n        var node = queue_node.data;\n        try list.append(node.val);              // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.left.?;\n            queue.append(tmp_node);             // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.right.?;\n            queue.append(tmp_node);             // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }        \n    }\n    return list;\n}\n
    Code Visualization

    Full Screen >

    "},{"location":"chapter_tree/binary_tree_traversal/#2-complexity-analysis","title":"2. \u00a0 Complexity analysis","text":"
    • Time complexity is \\(O(n)\\): All nodes are visited once, using \\(O(n)\\) time, where \\(n\\) is the number of nodes.
    • Space complexity is \\(O(n)\\): In the worst case, i.e., a full binary tree, before traversing to the lowest level, the queue can contain at most \\((n + 1) / 2\\) nodes at the same time, occupying \\(O(n)\\) space.
    "},{"location":"chapter_tree/binary_tree_traversal/#722-preorder-inorder-and-postorder-traversal","title":"7.2.2 \u00a0 Preorder, inorder, and postorder traversal","text":"

    Correspondingly, preorder, inorder, and postorder traversal all belong to \"depth-first traversal\", also known as \"depth-first search (DFS)\", which embodies a \"proceed to the end first, then backtrack and continue\" traversal method.

    The Figure 7-10 shows the working principle of performing a depth-first traversal on a binary tree. Depth-first traversal is like walking around the perimeter of the entire binary tree, encountering three positions at each node, corresponding to preorder traversal, inorder traversal, and postorder traversal.

    Figure 7-10 \u00a0 Preorder, inorder, and postorder traversal of a binary search tree

    "},{"location":"chapter_tree/binary_tree_traversal/#1-code-implementation_1","title":"1. \u00a0 Code implementation","text":"

    Depth-first search is usually implemented based on recursion:

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_dfs.py
    def pre_order(root: TreeNode | None):\n    \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    res.append(root.val)\n    pre_order(root=root.left)\n    pre_order(root=root.right)\n\ndef in_order(root: TreeNode | None):\n    \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    in_order(root=root.left)\n    res.append(root.val)\n    in_order(root=root.right)\n\ndef post_order(root: TreeNode | None):\n    \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    post_order(root=root.left)\n    post_order(root=root.right)\n    res.append(root.val)\n
    binary_tree_dfs.cpp
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    vec.push_back(root->val);\n    preOrder(root->left);\n    preOrder(root->right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left);\n    vec.push_back(root->val);\n    inOrder(root->right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left);\n    postOrder(root->right);\n    vec.push_back(root->val);\n}\n
    binary_tree_dfs.java
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.add(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.add(root.val);\n}\n
    binary_tree_dfs.cs
    /* \u524d\u5e8f\u904d\u5386 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.Add(root.val!.Value);\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid InOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    InOrder(root.left);\n    list.Add(root.val!.Value);\n    InOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid PostOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    PostOrder(root.left);\n    PostOrder(root.right);\n    list.Add(root.val!.Value);\n}\n
    binary_tree_dfs.go
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    nums = append(nums, node.Val)\n    preOrder(node.Left)\n    preOrder(node.Right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(node.Left)\n    nums = append(nums, node.Val)\n    inOrder(node.Right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(node.Left)\n    postOrder(node.Right)\n    nums = append(nums, node.Val)\n}\n
    binary_tree_dfs.swift
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.append(root.val)\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root: root.left)\n    list.append(root.val)\n    inOrder(root: root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root: root.left)\n    postOrder(root: root.right)\n    list.append(root.val)\n}\n
    binary_tree_dfs.js
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.ts
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.dart
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  list.add(node.val);\n  preOrder(node.left);\n  preOrder(node.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  inOrder(node.left);\n  list.add(node.val);\n  inOrder(node.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  postOrder(node.left);\n  postOrder(node.right);\n  list.add(node.val);\n}\n
    binary_tree_dfs.rs
    /* \u524d\u5e8f\u904d\u5386 */\nfn pre_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n        result.push(node.borrow().val);\n        result.extend(pre_order(node.borrow().left.as_ref()));\n        result.extend(pre_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfn in_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n        result.extend(in_order(node.borrow().left.as_ref()));\n        result.push(node.borrow().val);\n        result.extend(in_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfn post_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n        result.extend(post_order(node.borrow().left.as_ref()));\n        result.extend(post_order(node.borrow().right.as_ref()));\n        result.push(node.borrow().val);\n    }\n    result\n}\n
    binary_tree_dfs.c
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    arr[(*size)++] = root->val;\n    preOrder(root->left, size);\n    preOrder(root->right, size);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left, size);\n    arr[(*size)++] = root->val;\n    inOrder(root->right, size);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left, size);\n    postOrder(root->right, size);\n    arr[(*size)++] = root->val;\n}\n
    binary_tree_dfs.kt
    /* \u524d\u5e8f\u904d\u5386 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root._val)\n    preOrder(root.left)\n    preOrder(root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfun inOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left)\n    list.add(root._val)\n    inOrder(root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfun postOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left)\n    postOrder(root.right)\n    list.add(root._val)\n}\n
    binary_tree_dfs.rb
    ### \u524d\u5e8f\u904d\u5386 ###\ndef pre_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  $res << root.val\n  pre_order(root.left)\n  pre_order(root.right)\nend\n\n### \u4e2d\u5e8f\u904d\u5386 ###\ndef in_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  in_order(root.left)\n  $res << root.val\n  in_order(root.right)\nend\n\n### \u540e\u5e8f\u904d\u5386 ###\ndef post_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  post_order(root.left)\n  post_order(root.right)\n  $res << root.val\nend\n
    binary_tree_dfs.zig
    // \u524d\u5e8f\u904d\u5386\nfn preOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    try list.append(root.?.val);\n    try preOrder(T, root.?.left);\n    try preOrder(T, root.?.right);\n}\n\n// \u4e2d\u5e8f\u904d\u5386\nfn inOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    try inOrder(T, root.?.left);\n    try list.append(root.?.val);\n    try inOrder(T, root.?.right);\n}\n\n// \u540e\u5e8f\u904d\u5386\nfn postOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    try postOrder(T, root.?.left);\n    try postOrder(T, root.?.right);\n    try list.append(root.?.val);\n}\n
    Code Visualization

    Full Screen >

    Tip

    Depth-first search can also be implemented based on iteration, interested readers can study this on their own.

    The Figure 7-11 shows the recursive process of preorder traversal of a binary tree, which can be divided into two opposite parts: \"recursion\" and \"return\".

    1. \"Recursion\" means starting a new method, the program accesses the next node in this process.
    2. \"Return\" means the function returns, indicating the current node has been fully accessed.
    <1><2><3><4><5><6><7><8><9><10><11>

    Figure 7-11 \u00a0 The recursive process of preorder traversal

    "},{"location":"chapter_tree/binary_tree_traversal/#2-complexity-analysis_1","title":"2. \u00a0 Complexity analysis","text":"
    • Time complexity is \\(O(n)\\): All nodes are visited once, using \\(O(n)\\) time.
    • Space complexity is \\(O(n)\\): In the worst case, i.e., the tree degrades into a linked list, the recursion depth reaches \\(n\\), the system occupies \\(O(n)\\) stack frame space.
    "},{"location":"chapter_tree/summary/","title":"7.6 \u00a0 Summary","text":""},{"location":"chapter_tree/summary/#1-key-review","title":"1. \u00a0 Key review","text":"
    • A binary tree is a non-linear data structure that reflects the \"divide and conquer\" logic of splitting one into two. Each binary tree node contains a value and two pointers, which point to its left and right child nodes, respectively.
    • For a node in a binary tree, the tree formed by its left (right) child node and all nodes under it is called the node's left (right) subtree.
    • Related terminology of binary trees includes root node, leaf node, level, degree, edge, height, and depth, among others.
    • The operations of initializing a binary tree, inserting nodes, and removing nodes are similar to those of linked list operations.
    • Common types of binary trees include perfect binary trees, complete binary trees, full binary trees, and balanced binary trees. The perfect binary tree represents the ideal state, while the linked list is the worst state after degradation.
    • A binary tree can be represented using an array by arranging the node values and empty slots in a level-order traversal sequence and implementing pointers based on the index mapping relationship between parent nodes and child nodes.
    • The level-order traversal of a binary tree is a breadth-first search method, which reflects a layer-by-layer traversal manner of \"expanding circle by circle.\" It is usually implemented using a queue.
    • Pre-order, in-order, and post-order traversals are all depth-first search methods, reflecting the traversal manner of \"going to the end first, then backtracking to continue.\" They are usually implemented using recursion.
    • A binary search tree is an efficient data structure for element searching, with the time complexity of search, insert, and remove operations all being \\(O(\\log n)\\). When a binary search tree degrades into a linked list, these time complexities deteriorate to \\(O(n)\\).
    • An AVL tree, also known as a balanced binary search tree, ensures that the tree remains balanced after continuous node insertions and removals through rotation operations.
    • Rotation operations in an AVL tree include right rotation, left rotation, right-then-left rotation, and left-then-right rotation. After inserting or removing nodes, an AVL tree performs rotation operations from bottom to top to rebalance the tree.
    "},{"location":"chapter_tree/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q: For a binary tree with only one node, are both the height of the tree and the depth of the root node \\(0\\)?

    Yes, because height and depth are typically defined as \"the number of edges passed.\"

    Q: The insertion and removal in a binary tree are generally completed by a set of operations. What does \"a set of operations\" refer to here? Can it be understood as the release of resources of the child nodes?

    Taking the binary search tree as an example, the operation of removing a node needs to be handled in three different scenarios, each requiring multiple steps of node operations.

    Q: Why are there three sequences: pre-order, in-order, and post-order for DFS traversal of a binary tree, and what are their uses?

    Similar to sequential and reverse traversal of arrays, pre-order, in-order, and post-order traversals are three methods of traversing a binary tree, allowing us to obtain a traversal result in a specific order. For example, in a binary search tree, since the node sizes satisfy left child node value < root node value < right child node value, we can obtain an ordered node sequence by traversing the tree in the \"left \u2192 root \u2192 right\" priority.

    Q: In a right rotation operation that deals with the relationship between the imbalance nodes node, child, grand_child, isn't the connection between node and its parent node and the original link of node lost after the right rotation?

    We need to view this problem from a recursive perspective. The right_rotate(root) operation passes the root node of the subtree and eventually returns the root node of the rotated subtree with return child. The connection between the subtree's root node and its parent node is established after this function returns, which is outside the scope of the right rotation operation's maintenance.

    Q: In C++, functions are divided into private and public sections. What considerations are there for this? Why are the height() function and the updateHeight() function placed in public and private, respectively?

    It depends on the scope of the method's use. If a method is only used within the class, then it is designed to be private. For example, it makes no sense for users to call updateHeight() on their own, as it is just a step in the insertion or removal operations. However, height() is for accessing node height, similar to vector.size(), thus it is set to public for use.

    Q: How do you build a binary search tree from a set of input data? Is the choice of root node very important?

    Yes, the method for building the tree is provided in the build_tree() method in the binary search tree code. As for the choice of the root node, we usually sort the input data and then select the middle element as the root node, recursively building the left and right subtrees. This approach maximizes the balance of the tree.

    Q: In Java, do you always have to use the equals() method for string comparison?

    In Java, for primitive data types, == is used to compare whether the values of two variables are equal. For reference types, the working principles of the two symbols are different.

    • ==: Used to compare whether two variables point to the same object, i.e., whether their positions in memory are the same.
    • equals(): Used to compare whether the values of two objects are equal.

    Therefore, to compare values, we should use equals(). However, strings initialized with String a = \"hi\"; String b = \"hi\"; are stored in the string constant pool and point to the same object, so a == b can also be used to compare the contents of two strings.

    Q: Before reaching the bottom level, is the number of nodes in the queue \\(2^h\\) in breadth-first traversal?

    Yes, for example, a full binary tree with height \\(h = 2\\) has a total of \\(n = 7\\) nodes, then the bottom level has \\(4 = 2^h = (n + 1) / 2\\) nodes.

    "}]} \ No newline at end of file diff --git a/en/sitemap.xml b/en/sitemap.xml index 69866f239..95bf56e0b 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -2,277 +2,527 @@ https://www.hello-algo.com/en/ - 2024-04-28 + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_appendix/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_appendix/contribution/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_appendix/installation/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_appendix/terminology/ + 2024-04-30 daily https://www.hello-algo.com/en/chapter_array_and_linkedlist/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_array_and_linkedlist/array/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_array_and_linkedlist/linked_list/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_array_and_linkedlist/list/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_array_and_linkedlist/ram_and_cache/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_array_and_linkedlist/summary/ - 2024-04-28 + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_backtracking/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_backtracking/backtracking_algorithm/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_backtracking/n_queens_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_backtracking/permutations_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_backtracking/subset_sum_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_backtracking/summary/ + 2024-04-30 daily https://www.hello-algo.com/en/chapter_computational_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_computational_complexity/iteration_and_recursion/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_computational_complexity/performance_evaluation/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_computational_complexity/space_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_computational_complexity/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_computational_complexity/time_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_data_structure/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_data_structure/basic_data_types/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_data_structure/character_encoding/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_data_structure/classification_of_data_structure/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_data_structure/number_encoding/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_data_structure/summary/ - 2024-04-28 + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_divide_and_conquer/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_divide_and_conquer/binary_search_recur/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_divide_and_conquer/build_binary_tree_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_divide_and_conquer/divide_and_conquer/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_divide_and_conquer/hanota_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_divide_and_conquer/summary/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/dp_problem_features/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/dp_solution_pipeline/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/edit_distance_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/intro_to_dynamic_programming/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/knapsack_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/summary/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_dynamic_programming/unbounded_knapsack_problem/ + 2024-04-30 daily https://www.hello-algo.com/en/chapter_graph/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_graph/graph/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_graph/graph_operations/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_graph/graph_traversal/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_graph/summary/ - 2024-04-28 + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_greedy/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_greedy/fractional_knapsack_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_greedy/greedy_algorithm/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_greedy/max_capacity_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_greedy/max_product_cutting_problem/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_greedy/summary/ + 2024-04-30 daily https://www.hello-algo.com/en/chapter_hashing/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_hashing/hash_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_hashing/hash_collision/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_hashing/hash_map/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_hashing/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_heap/build_heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_heap/heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_heap/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_heap/top_k/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_hello_algo/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_introduction/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_introduction/algorithms_are_everywhere/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_introduction/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_introduction/what_is_dsa/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_preface/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_preface/about_the_book/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_preface/suggestions/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_preface/summary/ - 2024-04-28 + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_reference/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/binary_search/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/binary_search_edge/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/binary_search_insertion/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/replace_linear_by_hashing/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/searching_algorithm_revisited/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_searching/summary/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/bubble_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/bucket_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/counting_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/heap_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/insertion_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/merge_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/quick_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/radix_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/selection_sort/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/sorting_algorithm/ + 2024-04-30 + daily + + + https://www.hello-algo.com/en/chapter_sorting/summary/ + 2024-04-30 daily https://www.hello-algo.com/en/chapter_stack_and_queue/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_stack_and_queue/deque/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_stack_and_queue/queue/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_stack_and_queue/stack/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_stack_and_queue/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/array_representation_of_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/avl_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/binary_search_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/binary_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/binary_tree_traversal/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/en/chapter_tree/summary/ - 2024-04-28 + 2024-04-30 daily \ No newline at end of file diff --git a/en/sitemap.xml.gz b/en/sitemap.xml.gz index b9b8a3bb7ae7734af57ca29fcfe1c9a442662416..336f2ab2b1c90b674714323ce67a0d89fedf4af6 100644 GIT binary patch literal 1007 zcmV5k*`)lB7bAhO=KFzeph4T8m&v@GI7IF2+v=C~X7$2W zI;HLKw)*?8KVN@a{oH-q=3pYHmr~fqx7C=E|D)^9=kq%1#1r|rc46qE97`g0OJ=uO z|GwINdnup#fcdU{w#La_eM(#&GqN%6mCWGQ(oG%PZrjx|AAdqIO-}8;Z@&L{-TZj{ zbyJEgc^`_&k?g?xz{i~;ZLZtyL(a_7-C+JZR(Y6D90YmKR_O~2r*t+2-RD#q8U|Y1 zn8+A{f-Z?kTW8#GeR}2)=qku6VYEH4GCC$m=9URbKHm!1nui4sG_@>AWz>RH5c4!q zc=~SNlRTtQ{**Zd6zj)?sHKBW;{+waieqNBQTX6`!&vaX45T@=!5>pV%zc?Pi(;ps z_z?c3B>mD&$h4Hu^3sO6lQuAUHP+nW?be?s3ud4D-f&Ce zAj?C26#@uZx@=qc7zw(ry`g|_!wVGk#9_cPz+=|(07V=~=?fHbWWy4!FE3Y|&5;{8 z$mAl`ed~I5^O!j^8m{6a9yDZ4w=^6yh7r~?_YjQpoBm}58#uB}x7U4e1e^>G>|>|{ d4I7ac=UiVS|KHqOyF^aAe*hY40HKph002y&?JocT literal 605 zcmV-j0;2sNiwFpLur6i-|8r?{Wo=<_E_iKh0Nt6vlG-o~K=1n%40j02>|xu1?5$tW zo;|`5i3i6Hk_^k=*Kt@1$6h+9xg=H;&y#IQwzB#7?EUP7#4d*I{B^mS&oJ27xX^Cr zzkdE$yw5-CmrWwiD6^~_csuVzhVNB%KA)HD1bY~G8L6$> z(^I)NKH7Thg|FRo=zUy(Z{yO&zQRy#s!`|u6JY6MQ?FO+x5eshv3}1gSJ|DK?I5(c zCp^{-IDgqxcan*vy21QCR_<&NBm+cnF%TN#T{vLl9g9llB2-B}JsPzmuNIu3FCq)s z-&I<`sqcZFe%a^dkOU;hX7Huu@zaT3?wl8>h|7c!+EfycT6+eheWV_OMS~~sspzOR zhX=@p{0HkyyMK%8HO)f<0)~Z>l|-nFb_eY2B$Ug5tPDSk3GDddYu~QTfK0+}@9dNq z;$HW13aQ`eoeU*`vn3ch9gx~kO&qR!G}c5d1Y;Egybfq3e%1kZ3WC@d=6E-w0y*h= zRn#{6d@@yVczB>5i+oCWwRjvV7}Ak(mz;0(;Hm-Dv`!@s=J5Qa`Ax|R&ra%sP;Bx} zTtOOmV7;YWHb7$~4C!+2@cGYf4^}Agya(oU2VxwXhT++{2f{sA)Pf1Sn8ZkjW*6f@ z3pJ;iQ>w(?5kQc9E1hSnvY>m8n>aB(RpM|$_W0d+gc?tM5StkGh6AUt) diff --git a/search/search_index.json b/search/search_index.json index 56cbb2f42..d69126156 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\u200b\\u3000\\-\u3001\u3002\uff0c\uff0e\uff1f\uff01\uff1b]+","pipeline":["stemmer"]},"docs":[{"location":"chapter_appendix/","title":"\u7b2c 16 \u7ae0 \u00a0 \u9644\u5f55","text":""},{"location":"chapter_appendix/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 16.1 \u00a0 \u7f16\u7a0b\u73af\u5883\u5b89\u88c5
    • 16.2 \u00a0 \u4e00\u8d77\u53c2\u4e0e\u521b\u4f5c
    • 16.3 \u00a0 \u672f\u8bed\u8868
    "},{"location":"chapter_appendix/contribution/","title":"16.2 \u00a0 \u4e00\u8d77\u53c2\u4e0e\u521b\u4f5c","text":"

    \u7531\u4e8e\u7b14\u8005\u80fd\u529b\u6709\u9650\uff0c\u4e66\u4e2d\u96be\u514d\u5b58\u5728\u4e00\u4e9b\u9057\u6f0f\u548c\u9519\u8bef\uff0c\u8bf7\u60a8\u8c05\u89e3\u3002\u5982\u679c\u60a8\u53d1\u73b0\u4e86\u7b14\u8bef\u3001\u94fe\u63a5\u5931\u6548\u3001\u5185\u5bb9\u7f3a\u5931\u3001\u6587\u5b57\u6b67\u4e49\u3001\u89e3\u91ca\u4e0d\u6e05\u6670\u6216\u884c\u6587\u7ed3\u6784\u4e0d\u5408\u7406\u7b49\u95ee\u9898\uff0c\u8bf7\u534f\u52a9\u6211\u4eec\u8fdb\u884c\u4fee\u6b63\uff0c\u4ee5\u7ed9\u8bfb\u8005\u63d0\u4f9b\u66f4\u4f18\u8d28\u7684\u5b66\u4e60\u8d44\u6e90\u3002

    \u6240\u6709\u64b0\u7a3f\u4eba\u7684 GitHub ID \u5c06\u5728\u672c\u4e66\u4ed3\u5e93\u3001\u7f51\u9875\u7248\u548c PDF \u7248\u7684\u4e3b\u9875\u4e0a\u8fdb\u884c\u5c55\u793a\uff0c\u4ee5\u611f\u8c22\u4ed6\u4eec\u5bf9\u5f00\u6e90\u793e\u533a\u7684\u65e0\u79c1\u5949\u732e\u3002

    \u5f00\u6e90\u7684\u9b45\u529b

    \u7eb8\u8d28\u56fe\u4e66\u7684\u4e24\u6b21\u5370\u5237\u7684\u95f4\u9694\u65f6\u95f4\u5f80\u5f80\u8f83\u4e45\uff0c\u5185\u5bb9\u66f4\u65b0\u975e\u5e38\u4e0d\u65b9\u4fbf\u3002

    \u800c\u5728\u672c\u5f00\u6e90\u4e66\u4e2d\uff0c\u5185\u5bb9\u66f4\u8fed\u7684\u65f6\u95f4\u88ab\u7f29\u77ed\u81f3\u6570\u65e5\u751a\u81f3\u51e0\u4e2a\u5c0f\u65f6\u3002

    "},{"location":"chapter_appendix/contribution/#1","title":"1. \u00a0 \u5185\u5bb9\u5fae\u8c03","text":"

    \u5982\u56fe 16-3 \u6240\u793a\uff0c\u6bcf\u4e2a\u9875\u9762\u7684\u53f3\u4e0a\u89d2\u90fd\u6709\u201c\u7f16\u8f91\u56fe\u6807\u201d\u3002\u60a8\u53ef\u4ee5\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u4fee\u6539\u6587\u672c\u6216\u4ee3\u7801\u3002

    1. \u70b9\u51fb\u201c\u7f16\u8f91\u56fe\u6807\u201d\uff0c\u5982\u679c\u9047\u5230\u201c\u9700\u8981 Fork \u6b64\u4ed3\u5e93\u201d\u7684\u63d0\u793a\uff0c\u8bf7\u540c\u610f\u8be5\u64cd\u4f5c\u3002
    2. \u4fee\u6539 Markdown \u6e90\u6587\u4ef6\u5185\u5bb9\uff0c\u68c0\u67e5\u5185\u5bb9\u7684\u6b63\u786e\u6027\uff0c\u5e76\u5c3d\u91cf\u4fdd\u6301\u6392\u7248\u683c\u5f0f\u7684\u7edf\u4e00\u3002
    3. \u5728\u9875\u9762\u5e95\u90e8\u586b\u5199\u4fee\u6539\u8bf4\u660e\uff0c\u7136\u540e\u70b9\u51fb\u201cPropose file change\u201d\u6309\u94ae\u3002\u9875\u9762\u8df3\u8f6c\u540e\uff0c\u70b9\u51fb\u201cCreate pull request\u201d\u6309\u94ae\u5373\u53ef\u53d1\u8d77\u62c9\u53d6\u8bf7\u6c42\u3002

    \u56fe 16-3 \u00a0 \u9875\u9762\u7f16\u8f91\u6309\u952e

    \u56fe\u7247\u65e0\u6cd5\u76f4\u63a5\u4fee\u6539\uff0c\u9700\u8981\u901a\u8fc7\u65b0\u5efa Issue \u6216\u8bc4\u8bba\u7559\u8a00\u6765\u63cf\u8ff0\u95ee\u9898\uff0c\u6211\u4eec\u4f1a\u5c3d\u5feb\u91cd\u65b0\u7ed8\u5236\u5e76\u66ff\u6362\u56fe\u7247\u3002

    "},{"location":"chapter_appendix/contribution/#2","title":"2. \u00a0 \u5185\u5bb9\u521b\u4f5c","text":"

    \u5982\u679c\u60a8\u6709\u5174\u8da3\u53c2\u4e0e\u6b64\u5f00\u6e90\u9879\u76ee\uff0c\u5305\u62ec\u5c06\u4ee3\u7801\u7ffb\u8bd1\u6210\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u3001\u6269\u5c55\u6587\u7ae0\u5185\u5bb9\u7b49\uff0c\u90a3\u4e48\u9700\u8981\u5b9e\u65bd\u4ee5\u4e0b Pull Request \u5de5\u4f5c\u6d41\u7a0b\u3002

    1. \u767b\u5f55 GitHub \uff0c\u5c06\u672c\u4e66\u7684\u4ee3\u7801\u4ed3\u5e93 Fork \u5230\u4e2a\u4eba\u8d26\u53f7\u4e0b\u3002
    2. \u8fdb\u5165\u60a8\u7684 Fork \u4ed3\u5e93\u7f51\u9875\uff0c\u4f7f\u7528 git clone \u547d\u4ee4\u5c06\u4ed3\u5e93\u514b\u9686\u81f3\u672c\u5730\u3002
    3. \u5728\u672c\u5730\u8fdb\u884c\u5185\u5bb9\u521b\u4f5c\uff0c\u5e76\u8fdb\u884c\u5b8c\u6574\u6d4b\u8bd5\uff0c\u9a8c\u8bc1\u4ee3\u7801\u7684\u6b63\u786e\u6027\u3002
    4. \u5c06\u672c\u5730\u6240\u505a\u66f4\u6539 Commit \uff0c\u7136\u540e Push \u81f3\u8fdc\u7a0b\u4ed3\u5e93\u3002
    5. \u5237\u65b0\u4ed3\u5e93\u7f51\u9875\uff0c\u70b9\u51fb\u201cCreate pull request\u201d\u6309\u94ae\u5373\u53ef\u53d1\u8d77\u62c9\u53d6\u8bf7\u6c42\u3002
    "},{"location":"chapter_appendix/contribution/#3-docker","title":"3. \u00a0 Docker \u90e8\u7f72","text":"

    \u5728 hello-algo \u6839\u76ee\u5f55\u4e0b\uff0c\u6267\u884c\u4ee5\u4e0b Docker \u811a\u672c\uff0c\u5373\u53ef\u5728 http://localhost:8000 \u8bbf\u95ee\u672c\u9879\u76ee\uff1a

    docker-compose up -d\n

    \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u5373\u53ef\u5220\u9664\u90e8\u7f72\uff1a

    docker-compose down\n
    "},{"location":"chapter_appendix/installation/","title":"16.1 \u00a0 \u7f16\u7a0b\u73af\u5883\u5b89\u88c5","text":""},{"location":"chapter_appendix/installation/#1611-ide","title":"16.1.1 \u00a0 \u5b89\u88c5 IDE","text":"

    \u63a8\u8350\u4f7f\u7528\u5f00\u6e90\u3001\u8f7b\u91cf\u7684 VS Code \u4f5c\u4e3a\u672c\u5730\u96c6\u6210\u5f00\u53d1\u73af\u5883\uff08IDE\uff09\u3002\u8bbf\u95ee VS Code \u5b98\u7f51\uff0c\u6839\u636e\u64cd\u4f5c\u7cfb\u7edf\u9009\u62e9\u76f8\u5e94\u7248\u672c\u7684 VS Code \u8fdb\u884c\u4e0b\u8f7d\u548c\u5b89\u88c5\u3002

    \u56fe 16-1 \u00a0 \u4ece\u5b98\u7f51\u4e0b\u8f7d VS Code

    VS Code \u62e5\u6709\u5f3a\u5927\u7684\u6269\u5c55\u5305\u751f\u6001\u7cfb\u7edf\uff0c\u652f\u6301\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u7684\u8fd0\u884c\u548c\u8c03\u8bd5\u3002\u4ee5 Python \u4e3a\u4f8b\uff0c\u5b89\u88c5\u201cPython Extension Pack\u201d\u6269\u5c55\u5305\u4e4b\u540e\uff0c\u5373\u53ef\u8fdb\u884c Python \u4ee3\u7801\u8c03\u8bd5\u3002\u5b89\u88c5\u6b65\u9aa4\u5982\u56fe 16-2 \u6240\u793a\u3002

    \u56fe 16-2 \u00a0 \u5b89\u88c5 VS Code \u6269\u5c55\u5305

    "},{"location":"chapter_appendix/installation/#1612","title":"16.1.2 \u00a0 \u5b89\u88c5\u8bed\u8a00\u73af\u5883","text":""},{"location":"chapter_appendix/installation/#1-python","title":"1. \u00a0 Python \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Miniconda3 \uff0c\u9700\u8981 Python 3.10 \u6216\u66f4\u65b0\u7248\u672c\u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 python \uff0c\u5b89\u88c5 Python Extension Pack \u3002
    3. \uff08\u53ef\u9009\uff09\u5728\u547d\u4ee4\u884c\u8f93\u5165 pip install black \uff0c\u5b89\u88c5\u4ee3\u7801\u683c\u5f0f\u5316\u5de5\u5177\u3002
    "},{"location":"chapter_appendix/installation/#2-cc","title":"2. \u00a0 C/C++ \u73af\u5883","text":"
    1. Windows \u7cfb\u7edf\u9700\u8981\u5b89\u88c5 MinGW\uff08\u914d\u7f6e\u6559\u7a0b\uff09\uff1bMacOS \u81ea\u5e26 Clang \uff0c\u65e0\u987b\u5b89\u88c5\u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 c++ \uff0c\u5b89\u88c5 C/C++ Extension Pack \u3002
    3. \uff08\u53ef\u9009\uff09\u6253\u5f00 Settings \u9875\u9762\uff0c\u641c\u7d22 Clang_format_fallback Style \u4ee3\u7801\u683c\u5f0f\u5316\u9009\u9879\uff0c\u8bbe\u7f6e\u4e3a { BasedOnStyle: Microsoft, BreakBeforeBraces: Attach } \u3002
    "},{"location":"chapter_appendix/installation/#3-java","title":"3. \u00a0 Java \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 OpenJDK\uff08\u7248\u672c\u9700\u6ee1\u8db3 > JDK 9\uff09\u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 java \uff0c\u5b89\u88c5 Extension Pack for Java \u3002
    "},{"location":"chapter_appendix/installation/#4-c","title":"4. \u00a0 C# \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 .Net 8.0 \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 C# Dev Kit \uff0c\u5b89\u88c5 C# Dev Kit \uff08\u914d\u7f6e\u6559\u7a0b\uff09\u3002
    3. \u4e5f\u53ef\u4f7f\u7528 Visual Studio\uff08\u5b89\u88c5\u6559\u7a0b\uff09\u3002
    "},{"location":"chapter_appendix/installation/#5-go","title":"5. \u00a0 Go \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 go \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 go \uff0c\u5b89\u88c5 Go \u3002
    3. \u6309\u5feb\u6377\u952e Ctrl + Shift + P \u547c\u51fa\u547d\u4ee4\u680f\uff0c\u8f93\u5165 go \uff0c\u9009\u62e9 Go: Install/Update Tools \uff0c\u5168\u90e8\u52fe\u9009\u5e76\u5b89\u88c5\u5373\u53ef\u3002
    "},{"location":"chapter_appendix/installation/#6-swift","title":"6. \u00a0 Swift \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Swift \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 swift \uff0c\u5b89\u88c5 Swift for Visual Studio Code \u3002
    "},{"location":"chapter_appendix/installation/#7-javascript","title":"7. \u00a0 JavaScript \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Node.js \u3002
    2. \uff08\u53ef\u9009\uff09\u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 Prettier \uff0c\u5b89\u88c5\u4ee3\u7801\u683c\u5f0f\u5316\u5de5\u5177\u3002
    "},{"location":"chapter_appendix/installation/#8-typescript","title":"8. \u00a0 TypeScript \u73af\u5883","text":"
    1. \u540c JavaScript \u73af\u5883\u5b89\u88c5\u6b65\u9aa4\u3002
    2. \u5b89\u88c5 TypeScript Execute (tsx) \u3002
    3. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 typescript \uff0c\u5b89\u88c5 Pretty TypeScript Errors \u3002
    "},{"location":"chapter_appendix/installation/#9-dart","title":"9. \u00a0 Dart \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Dart \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 dart \uff0c\u5b89\u88c5 Dart \u3002
    "},{"location":"chapter_appendix/installation/#10-rust","title":"10. \u00a0 Rust \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Rust \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 rust \uff0c\u5b89\u88c5 rust-analyzer \u3002
    "},{"location":"chapter_appendix/terminology/","title":"16.3 \u00a0 \u672f\u8bed\u8868","text":"

    \u8868 16-1 \u5217\u51fa\u4e86\u4e66\u4e2d\u51fa\u73b0\u7684\u91cd\u8981\u672f\u8bed\uff0c\u503c\u5f97\u6ce8\u610f\u4ee5\u4e0b\u51e0\u70b9\u3002

    • \u5efa\u8bae\u8bb0\u4f4f\u540d\u8bcd\u7684\u82f1\u6587\u53eb\u6cd5\uff0c\u4ee5\u4fbf\u9605\u8bfb\u82f1\u6587\u6587\u732e\u3002
    • \u90e8\u5206\u540d\u8bcd\u5728\u7b80\u4f53\u4e2d\u6587\u548c\u7e41\u4f53\u4e2d\u6587\u4e0b\u7684\u53eb\u6cd5\u4e0d\u540c\u3002

    \u8868 16-1 \u00a0 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u91cd\u8981\u540d\u8bcd

    English \u7b80\u4f53\u4e2d\u6587 \u7e41\u4f53\u4e2d\u6587 algorithm \u7b97\u6cd5 \u6f14\u7b97\u6cd5 data structure \u6570\u636e\u7ed3\u6784 \u8cc7\u6599\u7d50\u69cb code \u4ee3\u7801 \u7a0b\u5f0f\u78bc file \u6587\u4ef6 \u6a94\u6848 function \u51fd\u6570 \u51fd\u5f0f method \u65b9\u6cd5 \u65b9\u6cd5 variable \u53d8\u91cf \u8b8a\u6578 asymptotic complexity analysis \u6e10\u8fd1\u590d\u6742\u5ea6\u5206\u6790 \u6f38\u8fd1\u8907\u96dc\u5ea6\u5206\u6790 time complexity \u65f6\u95f4\u590d\u6742\u5ea6 \u6642\u9593\u8907\u96dc\u5ea6 space complexity \u7a7a\u95f4\u590d\u6742\u5ea6 \u7a7a\u9593\u8907\u96dc\u5ea6 loop \u5faa\u73af \u8ff4\u5708 iteration \u8fed\u4ee3 \u8fed\u4ee3 recursion \u9012\u5f52 \u905e\u8ff4 tail recursion \u5c3e\u9012\u5f52 \u5c3e\u905e\u8ff4 recursion tree \u9012\u5f52\u6811 \u905e\u8ff4\u6a39 big-\\(O\\) notation \u5927 \\(O\\) \u8bb0\u53f7 \u5927 \\(O\\) \u8a18\u865f asymptotic upper bound \u6e10\u8fd1\u4e0a\u754c \u6f38\u8fd1\u4e0a\u754c sign-magnitude \u539f\u7801 \u539f\u78bc 1\u2019s complement \u53cd\u7801 \u4e00\u88dc\u6578 2\u2019s complement \u8865\u7801 \u4e8c\u88dc\u6578 array \u6570\u7ec4 \u9663\u5217 index \u7d22\u5f15 \u7d22\u5f15 linked list \u94fe\u8868 \u93c8\u7d50\u4e32\u5217 linked list node, list node \u94fe\u8868\u8282\u70b9 \u93c8\u7d50\u4e32\u5217\u7bc0\u9ede head node \u5934\u8282\u70b9 \u982d\u7bc0\u9ede tail node \u5c3e\u8282\u70b9 \u5c3e\u7bc0\u9ede list \u5217\u8868 \u4e32\u5217 dynamic array \u52a8\u6001\u6570\u7ec4 \u52d5\u614b\u9663\u5217 hard disk \u786c\u76d8 \u786c\u789f random-access memory (RAM) \u5185\u5b58 \u8a18\u61b6\u9ad4 cache memory \u7f13\u5b58 \u5feb\u53d6 cache miss \u7f13\u5b58\u672a\u547d\u4e2d \u5feb\u53d6\u672a\u547d\u4e2d cache hit rate \u7f13\u5b58\u547d\u4e2d\u7387 \u5feb\u53d6\u547d\u4e2d\u7387 stack \u6808 \u5806\u758a top of the stack \u6808\u9876 \u5806\u758a\u9802 bottom of the stack \u6808\u5e95 \u5806\u758a\u5e95 queue \u961f\u5217 \u4f47\u5217 double-ended queue \u53cc\u5411\u961f\u5217 \u96d9\u5411\u4f47\u5217 front of the queue \u961f\u9996 \u4f47\u5217\u9996 rear of the queue \u961f\u5c3e \u4f47\u5217\u5c3e hash table \u54c8\u5e0c\u8868 \u96dc\u6e4a\u8868 hash set \u54c8\u5e0c\u96c6\u5408 \u96dc\u6e4a\u96c6\u5408 bucket \u6876 \u6876 hash function \u54c8\u5e0c\u51fd\u6570 \u96dc\u6e4a\u51fd\u5f0f hash collision \u54c8\u5e0c\u51b2\u7a81 \u96dc\u6e4a\u885d\u7a81 load factor \u8d1f\u8f7d\u56e0\u5b50 \u8ca0\u8f09\u56e0\u5b50 separate chaining \u94fe\u5f0f\u5730\u5740 \u93c8\u7d50\u4f4d\u5740 open addressing \u5f00\u653e\u5bfb\u5740 \u958b\u653e\u5b9a\u5740 linear probing \u7ebf\u6027\u63a2\u6d4b \u7dda\u6027\u63a2\u67e5 lazy deletion \u61d2\u5220\u9664 \u61f6\u522a\u9664 binary tree \u4e8c\u53c9\u6811 \u4e8c\u5143\u6a39 tree node \u6811\u8282\u70b9 \u6a39\u7bc0\u9ede left-child node \u5de6\u5b50\u8282\u70b9 \u5de6\u5b50\u7bc0\u9ede right-child node \u53f3\u5b50\u8282\u70b9 \u53f3\u5b50\u7bc0\u9ede parent node \u7236\u8282\u70b9 \u7236\u7bc0\u9ede left subtree \u5de6\u5b50\u6811 \u5de6\u5b50\u6a39 right subtree \u53f3\u5b50\u6811 \u53f3\u5b50\u6a39 root node \u6839\u8282\u70b9 \u6839\u7bc0\u9ede leaf node \u53f6\u8282\u70b9 \u8449\u7bc0\u9ede edge \u8fb9 \u908a level \u5c42 \u5c64 degree \u5ea6 \u5ea6 height \u9ad8\u5ea6 \u9ad8\u5ea6 depth \u6df1\u5ea6 \u6df1\u5ea6 perfect binary tree \u5b8c\u7f8e\u4e8c\u53c9\u6811 \u5b8c\u7f8e\u4e8c\u5143\u6a39 complete binary tree \u5b8c\u5168\u4e8c\u53c9\u6811 \u5b8c\u5168\u4e8c\u5143\u6a39 full binary tree \u5b8c\u6ee1\u4e8c\u53c9\u6811 \u5b8c\u6eff\u4e8c\u5143\u6a39 balanced binary tree \u5e73\u8861\u4e8c\u53c9\u6811 \u5e73\u8861\u4e8c\u5143\u6a39 binary search tree \u4e8c\u53c9\u641c\u7d22\u6811 \u4e8c\u5143\u641c\u5c0b\u6a39 AVL tree AVL \u6811 AVL \u6a39 red-black tree \u7ea2\u9ed1\u6811 \u7d05\u9ed1\u6a39 level-order traversal \u5c42\u5e8f\u904d\u5386 \u5c64\u5e8f\u8d70\u8a2a breadth-first traversal \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 \u5ee3\u5ea6\u512a\u5148\u8d70\u8a2a depth-first traversal \u6df1\u5ea6\u4f18\u5148\u904d\u5386 \u6df1\u5ea6\u512a\u5148\u8d70\u8a2a binary search tree \u4e8c\u53c9\u641c\u7d22\u6811 \u4e8c\u5143\u641c\u5c0b\u6a39 balanced binary search tree \u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811 \u5e73\u8861\u4e8c\u5143\u641c\u5c0b\u6a39 balance factor \u5e73\u8861\u56e0\u5b50 \u5e73\u8861\u56e0\u5b50 heap \u5806 \u5806\u7a4d max heap \u5927\u9876\u5806 \u5927\u9802\u5806\u7a4d min heap \u5c0f\u9876\u5806 \u5c0f\u9802\u5806\u7a4d priority queue \u4f18\u5148\u961f\u5217 \u512a\u5148\u4f47\u5217 heapify \u5806\u5316 \u5806\u7a4d\u5316 top-\\(k\\) problem Top-\\(k\\) \u95ee\u9898 Top-\\(k\\) \u554f\u984c graph \u56fe \u5716 vertex \u9876\u70b9 \u9802\u9ede undirected graph \u65e0\u5411\u56fe \u7121\u5411\u5716 directed graph \u6709\u5411\u56fe \u6709\u5411\u5716 connected graph \u8fde\u901a\u56fe \u9023\u901a\u5716 disconnected graph \u975e\u8fde\u901a\u56fe \u975e\u9023\u901a\u5716 weighted graph \u6709\u6743\u56fe \u6709\u6b0a\u5716 adjacency \u90bb\u63a5 \u9130\u63a5 path \u8def\u5f84 \u8def\u5f91 in-degree \u5165\u5ea6 \u5165\u5ea6 out-degree \u51fa\u5ea6 \u51fa\u5ea6 adjacency matrix \u90bb\u63a5\u77e9\u9635 \u9130\u63a5\u77e9\u9663 adjacency list \u90bb\u63a5\u8868 \u9130\u63a5\u8868 breadth-first search \u5e7f\u5ea6\u4f18\u5148\u641c\u7d22 \u5ee3\u5ea6\u512a\u5148\u641c\u5c0b depth-first search \u6df1\u5ea6\u4f18\u5148\u641c\u7d22 \u6df1\u5ea6\u512a\u5148\u641c\u5c0b binary search \u4e8c\u5206\u67e5\u627e \u4e8c\u5206\u641c\u5c0b searching algorithm \u641c\u7d22\u7b97\u6cd5 \u641c\u5c0b\u6f14\u7b97\u6cd5 sorting algorithm \u6392\u5e8f\u7b97\u6cd5 \u6392\u5e8f\u6f14\u7b97\u6cd5 selection sort \u9009\u62e9\u6392\u5e8f \u9078\u64c7\u6392\u5e8f bubble sort \u5192\u6ce1\u6392\u5e8f \u6ce1\u6cab\u6392\u5e8f insertion sort \u63d2\u5165\u6392\u5e8f \u63d2\u5165\u6392\u5e8f quick sort \u5feb\u901f\u6392\u5e8f \u5feb\u901f\u6392\u5e8f merge sort \u5f52\u5e76\u6392\u5e8f \u5408\u4f75\u6392\u5e8f heap sort \u5806\u6392\u5e8f \u5806\u7a4d\u6392\u5e8f bucket sort \u6876\u6392\u5e8f \u6876\u6392\u5e8f counting sort \u8ba1\u6570\u6392\u5e8f \u8a08\u6578\u6392\u5e8f radix sort \u57fa\u6570\u6392\u5e8f \u57fa\u6578\u6392\u5e8f divide and conquer \u5206\u6cbb \u5206\u6cbb hanota problem \u6c49\u8bfa\u5854\u95ee\u9898 \u6cb3\u5167\u5854\u554f\u984c backtracking algorithm \u56de\u6eaf\u7b97\u6cd5 \u56de\u6eaf\u6f14\u7b97\u6cd5 constraint \u7ea6\u675f \u7d04\u675f solution \u89e3 \u89e3 state \u72b6\u6001 \u72c0\u614b pruning \u526a\u679d \u526a\u679d permutations problem \u5168\u6392\u5217\u95ee\u9898 \u5168\u6392\u5217\u554f\u984c subset-sum problem \u5b50\u96c6\u548c\u95ee\u9898 \u5b50\u96c6\u5408\u554f\u984c \\(n\\)-queens problem \\(n\\) \u7687\u540e\u95ee\u9898 \\(n\\) \u7687\u540e\u554f\u984c dynamic programming \u52a8\u6001\u89c4\u5212 \u52d5\u614b\u898f\u5283 initial state \u521d\u59cb\u72b6\u6001 \u521d\u59cb\u72c0\u614b state-transition equation \u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b \u72c0\u614b\u8f49\u79fb\u65b9\u7a0b knapsack problem \u80cc\u5305\u95ee\u9898 \u80cc\u5305\u554f\u984c edit distance problem \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898 \u7de8\u8f2f\u8ddd\u96e2\u554f\u984c greedy algorithm \u8d2a\u5fc3\u7b97\u6cd5 \u8caa\u5a6a\u6f14\u7b97\u6cd5"},{"location":"chapter_array_and_linkedlist/","title":"\u7b2c 4 \u7ae0 \u00a0 \u6570\u7ec4\u4e0e\u94fe\u8868","text":"

    Abstract

    \u6570\u636e\u7ed3\u6784\u7684\u4e16\u754c\u5982\u540c\u4e00\u5835\u539a\u5b9e\u7684\u7816\u5899\u3002

    \u6570\u7ec4\u7684\u7816\u5757\u6574\u9f50\u6392\u5217\uff0c\u9010\u4e2a\u7d27\u8d34\u3002\u94fe\u8868\u7684\u7816\u5757\u5206\u6563\u5404\u5904\uff0c\u8fde\u63a5\u7684\u85e4\u8513\u81ea\u7531\u5730\u7a7f\u68ad\u4e8e\u7816\u7f1d\u4e4b\u95f4\u3002

    "},{"location":"chapter_array_and_linkedlist/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 4.1 \u00a0 \u6570\u7ec4
    • 4.2 \u00a0 \u94fe\u8868
    • 4.3 \u00a0 \u5217\u8868
    • 4.4 \u00a0 \u5185\u5b58\u4e0e\u7f13\u5b58 *
    • 4.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_array_and_linkedlist/array/","title":"4.1 \u00a0 \u6570\u7ec4","text":"

    \u6570\u7ec4\uff08array\uff09\u662f\u4e00\u79cd\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u5176\u5c06\u76f8\u540c\u7c7b\u578b\u7684\u5143\u7d20\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\u3002\u6211\u4eec\u5c06\u5143\u7d20\u5728\u6570\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u79f0\u4e3a\u8be5\u5143\u7d20\u7684\u7d22\u5f15\uff08index\uff09\u3002\u56fe 4-1 \u5c55\u793a\u4e86\u6570\u7ec4\u7684\u4e3b\u8981\u6982\u5ff5\u548c\u5b58\u50a8\u65b9\u5f0f\u3002

    \u56fe 4-1 \u00a0 \u6570\u7ec4\u5b9a\u4e49\u4e0e\u5b58\u50a8\u65b9\u5f0f

    "},{"location":"chapter_array_and_linkedlist/array/#411","title":"4.1.1 \u00a0 \u6570\u7ec4\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_array_and_linkedlist/array/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u6570\u7ec4","text":"

    \u6211\u4eec\u53ef\u4ee5\u6839\u636e\u9700\u6c42\u9009\u7528\u6570\u7ec4\u7684\u4e24\u79cd\u521d\u59cb\u5316\u65b9\u5f0f\uff1a\u65e0\u521d\u59cb\u503c\u3001\u7ed9\u5b9a\u521d\u59cb\u503c\u3002\u5728\u672a\u6307\u5b9a\u521d\u59cb\u503c\u7684\u60c5\u51b5\u4e0b\uff0c\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4f1a\u5c06\u6570\u7ec4\u5143\u7d20\u521d\u59cb\u5316\u4e3a \\(0\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    # \u521d\u59cb\u5316\u6570\u7ec4\narr: list[int] = [0] * 5  # [ 0, 0, 0, 0, 0 ]\nnums: list[int] = [1, 3, 2, 5, 4]  \n
    array.cpp
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\n// \u5b58\u50a8\u5728\u6808\u4e0a\nint arr[5];\nint nums[5] = { 1, 3, 2, 5, 4 };\n// \u5b58\u50a8\u5728\u5806\u4e0a\uff08\u9700\u8981\u624b\u52a8\u91ca\u653e\u7a7a\u95f4\uff09\nint* arr1 = new int[5];\nint* nums1 = new int[5] { 1, 3, 2, 5, 4 };\n
    array.java
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nint[] arr = new int[5]; // { 0, 0, 0, 0, 0 }\nint[] nums = { 1, 3, 2, 5, 4 };\n
    array.cs
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nint[] arr = new int[5]; // [ 0, 0, 0, 0, 0 ]\nint[] nums = [1, 3, 2, 5, 4];\n
    array.go
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nvar arr [5]int\n// \u5728 Go \u4e2d\uff0c\u6307\u5b9a\u957f\u5ea6\u65f6\uff08[5]int\uff09\u4e3a\u6570\u7ec4\uff0c\u4e0d\u6307\u5b9a\u957f\u5ea6\u65f6\uff08[]int\uff09\u4e3a\u5207\u7247\n// \u7531\u4e8e Go \u7684\u6570\u7ec4\u88ab\u8bbe\u8ba1\u4e3a\u5728\u7f16\u8bd1\u671f\u786e\u5b9a\u957f\u5ea6\uff0c\u56e0\u6b64\u53ea\u80fd\u4f7f\u7528\u5e38\u91cf\u6765\u6307\u5b9a\u957f\u5ea6\n// \u4e3a\u4e86\u65b9\u4fbf\u5b9e\u73b0\u6269\u5bb9 extend() \u65b9\u6cd5\uff0c\u4ee5\u4e0b\u5c06\u5207\u7247\uff08Slice\uff09\u770b\u4f5c\u6570\u7ec4\uff08Array\uff09\nnums := []int{1, 3, 2, 5, 4}\n
    array.swift
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nlet arr = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]\nlet nums = [1, 3, 2, 5, 4]\n
    array.js
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nvar arr = new Array(5).fill(0);\nvar nums = [1, 3, 2, 5, 4];\n
    array.ts
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nlet arr: number[] = new Array(5).fill(0);\nlet nums: number[] = [1, 3, 2, 5, 4];\n
    array.dart
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nList<int> arr = List.filled(5, 0); // [0, 0, 0, 0, 0]\nList<int> nums = [1, 3, 2, 5, 4];\n
    array.rs
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nlet arr: Vec<i32> = vec![0; 5]; // [0, 0, 0, 0, 0]\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    array.c
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nint arr[5] = { 0 }; // { 0, 0, 0, 0, 0 }\nint nums[5] = { 1, 3, 2, 5, 4 };\n
    array.kt
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nvar arr = IntArray(5) // { 0, 0, 0, 0, 0 }\nvar nums = intArrayOf(1, 3, 2, 5, 4)\n
    array.rb
    # \u521d\u59cb\u5316\u6570\u7ec4\narr = Array.new(5, 0)\nnums = [1, 3, 2, 5, 4]\n
    array.zig
    // \u521d\u59cb\u5316\u6570\u7ec4\nvar arr = [_]i32{0} ** 5; // { 0, 0, 0, 0, 0 }\nvar nums = [_]i32{ 1, 3, 2, 5, 4 };\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#2","title":"2. \u00a0 \u8bbf\u95ee\u5143\u7d20","text":"

    \u6570\u7ec4\u5143\u7d20\u88ab\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\uff0c\u8fd9\u610f\u5473\u7740\u8ba1\u7b97\u6570\u7ec4\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u975e\u5e38\u5bb9\u6613\u3002\u7ed9\u5b9a\u6570\u7ec4\u5185\u5b58\u5730\u5740\uff08\u9996\u5143\u7d20\u5185\u5b58\u5730\u5740\uff09\u548c\u67d0\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u56fe 4-2 \u6240\u793a\u7684\u516c\u5f0f\u8ba1\u7b97\u5f97\u5230\u8be5\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\uff0c\u4ece\u800c\u76f4\u63a5\u8bbf\u95ee\u8be5\u5143\u7d20\u3002

    \u56fe 4-2 \u00a0 \u6570\u7ec4\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u8ba1\u7b97

    \u89c2\u5bdf\u56fe 4-2 \uff0c\u6211\u4eec\u53d1\u73b0\u6570\u7ec4\u9996\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u4e3a \\(0\\) \uff0c\u8fd9\u4f3c\u4e4e\u6709\u4e9b\u53cd\u76f4\u89c9\uff0c\u56e0\u4e3a\u4ece \\(1\\) \u5f00\u59cb\u8ba1\u6570\u4f1a\u66f4\u81ea\u7136\u3002\u4f46\u4ece\u5730\u5740\u8ba1\u7b97\u516c\u5f0f\u7684\u89d2\u5ea6\u770b\uff0c\u7d22\u5f15\u672c\u8d28\u4e0a\u662f\u5185\u5b58\u5730\u5740\u7684\u504f\u79fb\u91cf\u3002\u9996\u4e2a\u5143\u7d20\u7684\u5730\u5740\u504f\u79fb\u91cf\u662f \\(0\\) \uff0c\u56e0\u6b64\u5b83\u7684\u7d22\u5f15\u4e3a \\(0\\) \u662f\u5408\u7406\u7684\u3002

    \u5728\u6570\u7ec4\u4e2d\u8bbf\u95ee\u5143\u7d20\u975e\u5e38\u9ad8\u6548\uff0c\u6211\u4eec\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u968f\u673a\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u4e00\u4e2a\u5143\u7d20\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def random_access(nums: list[int]) -> int:\n    \"\"\"\u968f\u673a\u8bbf\u95ee\u5143\u7d20\"\"\"\n    # \u5728\u533a\u95f4 [0, len(nums)-1] \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    random_index = random.randint(0, len(nums) - 1)\n    # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    random_num = nums[random_index]\n    return random_num\n
    array.cpp
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.java
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int[] nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = ThreadLocalRandom.current().nextInt(0, nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.cs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint RandomAccess(int[] nums) {\n    Random random = new();\n    // \u5728\u533a\u95f4 [0, nums.Length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = random.Next(nums.Length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.go
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums []int) (randomNum int) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    randomIndex := rand.Intn(len(nums))\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    randomNum = nums[randomIndex]\n    return\n}\n
    array.swift
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums: [Int]) -> Int {\n    // \u5728\u533a\u95f4 [0, nums.count) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let randomIndex = nums.indices.randomElement()!\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.js
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.ts
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums: number[]): number {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.dart
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(List<int> nums) {\n  // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  int randomIndex = Random().nextInt(nums.length);\n  // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  int randomNum = nums[randomIndex];\n  return randomNum;\n}\n
    array.rs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfn random_access(nums: &[i32]) -> i32 {\n    // \u5728\u533a\u95f4 [0, nums.len()) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let random_index = rand::thread_rng().gen_range(0..nums.len());\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let random_num = nums[random_index];\n    random_num\n}\n
    array.c
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.kt
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfun randomAccess(nums: IntArray): Int {\n    // \u5728\u533a\u95f4 [0, nums.size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    val randomIndex = ThreadLocalRandom.current().nextInt(0, nums.size)\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    val randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.rb
    ### \u968f\u673a\u8bbf\u95ee\u5143\u7d20 ###\ndef random_access(nums)\n  # \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  random_index = Random.rand(0...nums.length)\n\n  # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  nums[random_index]\nend\n
    array.zig
    // \u968f\u673a\u8bbf\u95ee\u5143\u7d20\nfn randomAccess(nums: []i32) i32 {\n    // \u5728\u533a\u95f4 [0, nums.len) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6574\u6570\n    var randomIndex = std.crypto.random.intRangeLessThan(usize, 0, nums.len);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    var randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#3","title":"3. \u00a0 \u63d2\u5165\u5143\u7d20","text":"

    \u6570\u7ec4\u5143\u7d20\u5728\u5185\u5b58\u4e2d\u662f\u201c\u7d27\u6328\u7740\u7684\u201d\uff0c\u5b83\u4eec\u4e4b\u95f4\u6ca1\u6709\u7a7a\u95f4\u518d\u5b58\u653e\u4efb\u4f55\u6570\u636e\u3002\u5982\u56fe 4-3 \u6240\u793a\uff0c\u5982\u679c\u60f3\u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff0c\u5219\u9700\u8981\u5c06\u8be5\u5143\u7d20\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u4e4b\u540e\u518d\u628a\u5143\u7d20\u8d4b\u503c\u7ed9\u8be5\u7d22\u5f15\u3002

    \u56fe 4-3 \u00a0 \u6570\u7ec4\u63d2\u5165\u5143\u7d20\u793a\u4f8b

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u7531\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\u662f\u56fa\u5b9a\u7684\uff0c\u56e0\u6b64\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\u5fc5\u5b9a\u4f1a\u5bfc\u81f4\u6570\u7ec4\u5c3e\u90e8\u5143\u7d20\u201c\u4e22\u5931\u201d\u3002\u6211\u4eec\u5c06\u8fd9\u4e2a\u95ee\u9898\u7684\u89e3\u51b3\u65b9\u6848\u7559\u5728\u201c\u5217\u8868\u201d\u7ae0\u8282\u4e2d\u8ba8\u8bba\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def insert(nums: list[int], num: int, index: int):\n    \"\"\"\u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\"\"\"\n    # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in range(len(nums) - 1, index, -1):\n        nums[i] = nums[i - 1]\n    # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n
    array.cpp
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid Insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.Length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums []int, num int, index int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i := len(nums) - 1; i > index; i-- {\n        nums[i] = nums[i-1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums: inout [Int], num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).reversed() {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums, num, index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums: number[], num: number, index: number): void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 _num */\nvoid insert(List<int> nums, int _num, int index) {\n  // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for (var i = nums.length - 1; i > index; i--) {\n    nums[i] = nums[i - 1];\n  }\n  // \u5c06 _num \u8d4b\u7ed9 index \u5904\u5143\u7d20\n  nums[index] = _num;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfn insert(nums: &mut Vec<i32>, num: i32, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in (index + 1..nums.len()).rev() {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfun insert(nums: IntArray, num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (i in nums.size - 1 downTo index + 1) {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num ###\ndef insert(nums, num, index)\n  # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for i in (nums.length - 1).downto(index + 1)\n    nums[i] = nums[i - 1]\n  end\n\n  # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n  nums[index] = num\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\nfn insert(nums: []i32, num: i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    var i = nums.len - 1;\n    while (i > index) : (i -= 1) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#4","title":"4. \u00a0 \u5220\u9664\u5143\u7d20","text":"

    \u540c\u7406\uff0c\u5982\u56fe 4-4 \u6240\u793a\uff0c\u82e5\u60f3\u5220\u9664\u7d22\u5f15 \\(i\\) \u5904\u7684\u5143\u7d20\uff0c\u5219\u9700\u8981\u628a\u7d22\u5f15 \\(i\\) \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\u3002

    \u56fe 4-4 \u00a0 \u6570\u7ec4\u5220\u9664\u5143\u7d20\u793a\u4f8b

    \u8bf7\u6ce8\u610f\uff0c\u5220\u9664\u5143\u7d20\u5b8c\u6210\u540e\uff0c\u539f\u5148\u672b\u5c3e\u7684\u5143\u7d20\u53d8\u5f97\u201c\u65e0\u610f\u4e49\u201d\u4e86\uff0c\u6240\u4ee5\u6211\u4eec\u65e0\u987b\u7279\u610f\u53bb\u4fee\u6539\u5b83\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def remove(nums: list[int], index: int):\n    \"\"\"\u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\"\"\"\n    # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in range(index, len(nums) - 1):\n        nums[i] = nums[i + 1]\n
    array.cpp
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.java
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.cs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid Remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.Length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.go
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums []int, index int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i := index; i < len(nums)-1; i++ {\n        nums[i] = nums[i+1]\n    }\n}\n
    array.swift
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums: inout [Int], index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).dropLast() {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.js
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums, index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.ts
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums: number[], index: number): void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.dart
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(List<int> nums, int index) {\n  // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for (var i = index; i < nums.length - 1; i++) {\n    nums[i] = nums[i + 1];\n  }\n}\n
    array.rs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfn remove(nums: &mut Vec<i32>, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in index..nums.len() - 1 {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.c
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.kt
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfun remove(nums: IntArray, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (i in index..<nums.size - 1) {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.rb
    ### \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 ###\ndef remove(nums, index)\n  # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for i in index...(nums.length - 1)\n    nums[i] = nums[i + 1]\n  end\nend\n
    array.zig
    // \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\nfn remove(nums: []i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    var i = index;\n    while (i < nums.len - 1) : (i += 1) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u603b\u7684\u6765\u770b\uff0c\u6570\u7ec4\u7684\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u6709\u4ee5\u4e0b\u7f3a\u70b9\u3002

    • \u65f6\u95f4\u590d\u6742\u5ea6\u9ad8\uff1a\u6570\u7ec4\u7684\u63d2\u5165\u548c\u5220\u9664\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u6570\u7ec4\u957f\u5ea6\u3002
    • \u4e22\u5931\u5143\u7d20\uff1a\u7531\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u5728\u63d2\u5165\u5143\u7d20\u540e\uff0c\u8d85\u51fa\u6570\u7ec4\u957f\u5ea6\u8303\u56f4\u7684\u5143\u7d20\u4f1a\u4e22\u5931\u3002
    • \u5185\u5b58\u6d6a\u8d39\uff1a\u6211\u4eec\u53ef\u4ee5\u521d\u59cb\u5316\u4e00\u4e2a\u6bd4\u8f83\u957f\u7684\u6570\u7ec4\uff0c\u53ea\u7528\u524d\u9762\u4e00\u90e8\u5206\uff0c\u8fd9\u6837\u5728\u63d2\u5165\u6570\u636e\u65f6\uff0c\u4e22\u5931\u7684\u672b\u5c3e\u5143\u7d20\u90fd\u662f\u201c\u65e0\u610f\u4e49\u201d\u7684\uff0c\u4f46\u8fd9\u6837\u505a\u4f1a\u9020\u6210\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u3002
    "},{"location":"chapter_array_and_linkedlist/array/#5","title":"5. \u00a0 \u904d\u5386\u6570\u7ec4","text":"

    \u5728\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u6211\u4eec\u65e2\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u904d\u5386\u83b7\u53d6\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def traverse(nums: list[int]):\n    \"\"\"\u904d\u5386\u6570\u7ec4\"\"\"\n    count = 0\n    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in range(len(nums)):\n        count += nums[i]\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums:\n        count += num\n    # \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num in enumerate(nums):\n        count += nums[i]\n        count += num\n
    array.cpp
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.java
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (int num : nums) {\n        count += num;\n    }\n}\n
    array.cs
    /* \u904d\u5386\u6570\u7ec4 */\nvoid Traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    foreach (int num in nums) {\n        count += num;\n    }\n}\n
    array.go
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums []int) {\n    count := 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i := 0; i < len(nums); i++ {\n        count += nums[i]\n    }\n    count = 0\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for _, num := range nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num := range nums {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.swift
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums: [Int]) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in nums.indices {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for (i, num) in nums.enumerated() {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.js
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums) {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.ts
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums: number[]): void {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.dart
    /* \u904d\u5386\u6570\u7ec4\u5143\u7d20 */\nvoid traverse(List<int> nums) {\n  int count = 0;\n  // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n  }\n  // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for (int _num in nums) {\n    count += _num;\n  }\n  // \u901a\u8fc7 forEach \u65b9\u6cd5\u904d\u5386\u6570\u7ec4\n  nums.forEach((_num) {\n    count += _num;\n  });\n}\n
    array.rs
    /* \u904d\u5386\u6570\u7ec4 */\nfn traverse(nums: &[i32]) {\n    let mut _count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in 0..nums.len() {\n        _count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        _count += num;\n    }\n}\n
    array.c
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.kt
    /* \u904d\u5386\u6570\u7ec4 */\nfun traverse(nums: IntArray) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (i in nums.indices) {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (j in nums) {\n        count += j\n    }\n}\n
    array.rb
    ### \u904d\u5386\u6570\u7ec4 ###\ndef traverse(nums)\n  count = 0\n\n  # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for i in 0...nums.length\n    count += nums[i]\n  end\n\n  # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for num in nums\n    count += num\n  end\nend\n
    array.zig
    // \u904d\u5386\u6570\u7ec4\nfn traverse(nums: []i32) void {\n    var count: i32 = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    var i: i32 = 0;\n    while (i < nums.len) : (i += 1) {\n        count += nums[i];\n    }\n    count = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (nums) |num| {\n        count += num;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#6","title":"6. \u00a0 \u67e5\u627e\u5143\u7d20","text":"

    \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\u9700\u8981\u904d\u5386\u6570\u7ec4\uff0c\u6bcf\u8f6e\u5224\u65ad\u5143\u7d20\u503c\u662f\u5426\u5339\u914d\uff0c\u82e5\u5339\u914d\u5219\u8f93\u51fa\u5bf9\u5e94\u7d22\u5f15\u3002

    \u56e0\u4e3a\u6570\u7ec4\u662f\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u6240\u4ee5\u4e0a\u8ff0\u67e5\u627e\u64cd\u4f5c\u88ab\u79f0\u4e3a\u201c\u7ebf\u6027\u67e5\u627e\u201d\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def find(nums: list[int], target: int) -> int:\n    \"\"\"\u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\"\"\"\n    for i in range(len(nums)):\n        if nums[i] == target:\n            return i\n    return -1\n
    array.cpp
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int[] nums, int target) {\n    for (int i = 0; i < nums.length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint Find(int[] nums, int target) {\n    for (int i = 0; i < nums.Length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums []int, target int) (index int) {\n    index = -1\n    for i := 0; i < len(nums); i++ {\n        if nums[i] == target {\n            index = i\n            break\n        }\n    }\n    return\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums: [Int], target: Int) -> Int {\n    for i in nums.indices {\n        if nums[i] == target {\n            return i\n        }\n    }\n    return -1\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums, target) {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) return i;\n    }\n    return -1;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums: number[], target: number): number {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(List<int> nums, int target) {\n  for (var i = 0; i < nums.length; i++) {\n    if (nums[i] == target) return i;\n  }\n  return -1;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfn find(nums: &[i32], target: i32) -> Option<usize> {\n    for i in 0..nums.len() {\n        if nums[i] == target {\n            return Some(i);\n        }\n    }\n    None\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfun find(nums: IntArray, target: Int): Int {\n    for (i in nums.indices) {\n        if (nums[i] == target)\n            return i\n    }\n    return -1\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 ###\ndef find(nums, target)\n  for i in 0...nums.length\n    return i if nums[i] == target\n  end\n\n  -1\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\nfn find(nums: []i32, target: i32) i32 {\n    for (nums, 0..) |num, i| {\n        if (num == target) return @intCast(i);\n    }\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#7","title":"7. \u00a0 \u6269\u5bb9\u6570\u7ec4","text":"

    \u5728\u590d\u6742\u7684\u7cfb\u7edf\u73af\u5883\u4e2d\uff0c\u7a0b\u5e8f\u96be\u4ee5\u4fdd\u8bc1\u6570\u7ec4\u4e4b\u540e\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u53ef\u7528\u7684\uff0c\u4ece\u800c\u65e0\u6cd5\u5b89\u5168\u5730\u6269\u5c55\u6570\u7ec4\u5bb9\u91cf\u3002\u56e0\u6b64\u5728\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u6570\u7ec4\u7684\u957f\u5ea6\u662f\u4e0d\u53ef\u53d8\u7684\u3002

    \u5982\u679c\u6211\u4eec\u5e0c\u671b\u6269\u5bb9\u6570\u7ec4\uff0c\u5219\u9700\u91cd\u65b0\u5efa\u7acb\u4e00\u4e2a\u66f4\u5927\u7684\u6570\u7ec4\uff0c\u7136\u540e\u628a\u539f\u6570\u7ec4\u5143\u7d20\u4f9d\u6b21\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002\u8fd9\u662f\u4e00\u4e2a \\(O(n)\\) \u7684\u64cd\u4f5c\uff0c\u5728\u6570\u7ec4\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\u975e\u5e38\u8017\u65f6\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def extend(nums: list[int], enlarge: int) -> list[int]:\n    \"\"\"\u6269\u5c55\u6570\u7ec4\u957f\u5ea6\"\"\"\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res = [0] * (len(nums) + enlarge)\n    # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in range(len(nums)):\n        res[i] = nums[i]\n    # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n
    array.cpp
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = new int[size + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    delete[] nums;\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.java
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.cs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] Extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.Length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.go
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums []int, enlarge int) []int {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res := make([]int, len(nums)+enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i, num := range nums {\n        res[i] = num\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.swift
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums: [Int], enlarge: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = Array(repeating: 0, count: nums.count + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in nums.indices {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.js
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cJavaScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums, enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.ts
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cTypeScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums: number[], enlarge: number): number[] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.dart
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nList<int> extend(List<int> nums, int enlarge) {\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  List<int> res = List.filled(nums.length + enlarge, 0);\n  // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    res[i] = nums[i];\n  }\n  // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  return res;\n}\n
    array.rs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfn extend(nums: Vec<i32>, enlarge: usize) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    let mut res: Vec<i32> = vec![0; nums.len() + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\n    for i in 0..nums.len() {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    res\n}\n
    array.c
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = (int *)malloc(sizeof(int) * (size + enlarge));\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u521d\u59cb\u5316\u6269\u5c55\u540e\u7684\u7a7a\u95f4\n    for (int i = size; i < size + enlarge; i++) {\n        res[i] = 0;\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.kt
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfun extend(nums: IntArray, enlarge: Int): IntArray {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    val res = IntArray(nums.size + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (i in nums.indices) {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.rb
    ### \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 ###\n# \u8bf7\u6ce8\u610f\uff0cRuby \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n# \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\ndef extend(nums, enlarge)\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  res = Array.new(nums.length + enlarge, 0)\n\n  # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for i in 0...nums.length\n    res[i] = nums[i]\n  end\n\n  # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  res\nend\n
    array.zig
    // \u6269\u5c55\u6570\u7ec4\u957f\u5ea6\nfn extend(mem_allocator: std.mem.Allocator, nums: []i32, enlarge: usize) ![]i32 {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = try mem_allocator.alloc(i32, nums.len + enlarge);\n    @memset(res, 0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    std.mem.copy(i32, res, nums);\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#412","title":"4.1.2 \u00a0 \u6570\u7ec4\u7684\u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u6570\u7ec4\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u5185\uff0c\u4e14\u5143\u7d20\u7c7b\u578b\u76f8\u540c\u3002\u8fd9\u79cd\u505a\u6cd5\u5305\u542b\u4e30\u5bcc\u7684\u5148\u9a8c\u4fe1\u606f\uff0c\u7cfb\u7edf\u53ef\u4ee5\u5229\u7528\u8fd9\u4e9b\u4fe1\u606f\u6765\u4f18\u5316\u6570\u636e\u7ed3\u6784\u7684\u64cd\u4f5c\u6548\u7387\u3002

    • \u7a7a\u95f4\u6548\u7387\u9ad8\uff1a\u6570\u7ec4\u4e3a\u6570\u636e\u5206\u914d\u4e86\u8fde\u7eed\u7684\u5185\u5b58\u5757\uff0c\u65e0\u987b\u989d\u5916\u7684\u7ed3\u6784\u5f00\u9500\u3002
    • \u652f\u6301\u968f\u673a\u8bbf\u95ee\uff1a\u6570\u7ec4\u5141\u8bb8\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u8bbf\u95ee\u4efb\u4f55\u5143\u7d20\u3002
    • \u7f13\u5b58\u5c40\u90e8\u6027\uff1a\u5f53\u8bbf\u95ee\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u8ba1\u7b97\u673a\u4e0d\u4ec5\u4f1a\u52a0\u8f7d\u5b83\uff0c\u8fd8\u4f1a\u7f13\u5b58\u5176\u5468\u56f4\u7684\u5176\u4ed6\u6570\u636e\uff0c\u4ece\u800c\u501f\u52a9\u9ad8\u901f\u7f13\u5b58\u6765\u63d0\u5347\u540e\u7eed\u64cd\u4f5c\u7684\u6267\u884c\u901f\u5ea6\u3002

    \u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\u662f\u4e00\u628a\u53cc\u5203\u5251\uff0c\u5176\u5b58\u5728\u4ee5\u4e0b\u5c40\u9650\u6027\u3002

    • \u63d2\u5165\u4e0e\u5220\u9664\u6548\u7387\u4f4e\uff1a\u5f53\u6570\u7ec4\u4e2d\u5143\u7d20\u8f83\u591a\u65f6\uff0c\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u9700\u8981\u79fb\u52a8\u5927\u91cf\u7684\u5143\u7d20\u3002
    • \u957f\u5ea6\u4e0d\u53ef\u53d8\uff1a\u6570\u7ec4\u5728\u521d\u59cb\u5316\u540e\u957f\u5ea6\u5c31\u56fa\u5b9a\u4e86\uff0c\u6269\u5bb9\u6570\u7ec4\u9700\u8981\u5c06\u6240\u6709\u6570\u636e\u590d\u5236\u5230\u65b0\u6570\u7ec4\uff0c\u5f00\u9500\u5f88\u5927\u3002
    • \u7a7a\u95f4\u6d6a\u8d39\uff1a\u5982\u679c\u6570\u7ec4\u5206\u914d\u7684\u5927\u5c0f\u8d85\u8fc7\u5b9e\u9645\u6240\u9700\uff0c\u90a3\u4e48\u591a\u4f59\u7684\u7a7a\u95f4\u5c31\u88ab\u6d6a\u8d39\u4e86\u3002
    "},{"location":"chapter_array_and_linkedlist/array/#413","title":"4.1.3 \u00a0 \u6570\u7ec4\u5178\u578b\u5e94\u7528","text":"

    \u6570\u7ec4\u662f\u4e00\u79cd\u57fa\u7840\u4e14\u5e38\u89c1\u7684\u6570\u636e\u7ed3\u6784\uff0c\u65e2\u9891\u7e41\u5e94\u7528\u5728\u5404\u7c7b\u7b97\u6cd5\u4e4b\u4e2d\uff0c\u4e5f\u53ef\u7528\u4e8e\u5b9e\u73b0\u5404\u79cd\u590d\u6742\u6570\u636e\u7ed3\u6784\u3002

    • \u968f\u673a\u8bbf\u95ee\uff1a\u5982\u679c\u6211\u4eec\u60f3\u968f\u673a\u62bd\u53d6\u4e00\u4e9b\u6837\u672c\uff0c\u90a3\u4e48\u53ef\u4ee5\u7528\u6570\u7ec4\u5b58\u50a8\uff0c\u5e76\u751f\u6210\u4e00\u4e2a\u968f\u673a\u5e8f\u5217\uff0c\u6839\u636e\u7d22\u5f15\u5b9e\u73b0\u968f\u673a\u62bd\u6837\u3002
    • \u6392\u5e8f\u548c\u641c\u7d22\uff1a\u6570\u7ec4\u662f\u6392\u5e8f\u548c\u641c\u7d22\u7b97\u6cd5\u6700\u5e38\u7528\u7684\u6570\u636e\u7ed3\u6784\u3002\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u3001\u4e8c\u5206\u67e5\u627e\u7b49\u90fd\u4e3b\u8981\u5728\u6570\u7ec4\u4e0a\u8fdb\u884c\u3002
    • \u67e5\u627e\u8868\uff1a\u5f53\u9700\u8981\u5feb\u901f\u67e5\u627e\u4e00\u4e2a\u5143\u7d20\u6216\u5176\u5bf9\u5e94\u5173\u7cfb\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6570\u7ec4\u4f5c\u4e3a\u67e5\u627e\u8868\u3002\u5047\u5982\u6211\u4eec\u60f3\u5b9e\u73b0\u5b57\u7b26\u5230 ASCII \u7801\u7684\u6620\u5c04\uff0c\u5219\u53ef\u4ee5\u5c06\u5b57\u7b26\u7684 ASCII \u7801\u503c\u4f5c\u4e3a\u7d22\u5f15\uff0c\u5bf9\u5e94\u7684\u5143\u7d20\u5b58\u653e\u5728\u6570\u7ec4\u4e2d\u7684\u5bf9\u5e94\u4f4d\u7f6e\u3002
    • \u673a\u5668\u5b66\u4e60\uff1a\u795e\u7ecf\u7f51\u7edc\u4e2d\u5927\u91cf\u4f7f\u7528\u4e86\u5411\u91cf\u3001\u77e9\u9635\u3001\u5f20\u91cf\u4e4b\u95f4\u7684\u7ebf\u6027\u4ee3\u6570\u8fd0\u7b97\uff0c\u8fd9\u4e9b\u6570\u636e\u90fd\u662f\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u6784\u5efa\u7684\u3002\u6570\u7ec4\u662f\u795e\u7ecf\u7f51\u7edc\u7f16\u7a0b\u4e2d\u6700\u5e38\u4f7f\u7528\u7684\u6570\u636e\u7ed3\u6784\u3002
    • \u6570\u636e\u7ed3\u6784\u5b9e\u73b0\uff1a\u6570\u7ec4\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u5806\u3001\u56fe\u7b49\u6570\u636e\u7ed3\u6784\u3002\u4f8b\u5982\uff0c\u56fe\u7684\u90bb\u63a5\u77e9\u9635\u8868\u793a\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002
    "},{"location":"chapter_array_and_linkedlist/linked_list/","title":"4.2 \u00a0 \u94fe\u8868","text":"

    \u5185\u5b58\u7a7a\u95f4\u662f\u6240\u6709\u7a0b\u5e8f\u7684\u516c\u5171\u8d44\u6e90\uff0c\u5728\u4e00\u4e2a\u590d\u6742\u7684\u7cfb\u7edf\u8fd0\u884c\u73af\u5883\u4e0b\uff0c\u7a7a\u95f2\u7684\u5185\u5b58\u7a7a\u95f4\u53ef\u80fd\u6563\u843d\u5728\u5185\u5b58\u5404\u5904\u3002\u6211\u4eec\u77e5\u9053\uff0c\u5b58\u50a8\u6570\u7ec4\u7684\u5185\u5b58\u7a7a\u95f4\u5fc5\u987b\u662f\u8fde\u7eed\u7684\uff0c\u800c\u5f53\u6570\u7ec4\u975e\u5e38\u5927\u65f6\uff0c\u5185\u5b58\u53ef\u80fd\u65e0\u6cd5\u63d0\u4f9b\u5982\u6b64\u5927\u7684\u8fde\u7eed\u7a7a\u95f4\u3002\u6b64\u65f6\u94fe\u8868\u7684\u7075\u6d3b\u6027\u4f18\u52bf\u5c31\u4f53\u73b0\u51fa\u6765\u4e86\u3002

    \u94fe\u8868\uff08linked list\uff09\u662f\u4e00\u79cd\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u5176\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u8282\u70b9\u5bf9\u8c61\uff0c\u5404\u4e2a\u8282\u70b9\u901a\u8fc7\u201c\u5f15\u7528\u201d\u76f8\u8fde\u63a5\u3002\u5f15\u7528\u8bb0\u5f55\u4e86\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5185\u5b58\u5730\u5740\uff0c\u901a\u8fc7\u5b83\u53ef\u4ee5\u4ece\u5f53\u524d\u8282\u70b9\u8bbf\u95ee\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002

    \u94fe\u8868\u7684\u8bbe\u8ba1\u4f7f\u5f97\u5404\u4e2a\u8282\u70b9\u53ef\u4ee5\u5206\u6563\u5b58\u50a8\u5728\u5185\u5b58\u5404\u5904\uff0c\u5b83\u4eec\u7684\u5185\u5b58\u5730\u5740\u65e0\u987b\u8fde\u7eed\u3002

    \u56fe 4-5 \u00a0 \u94fe\u8868\u5b9a\u4e49\u4e0e\u5b58\u50a8\u65b9\u5f0f

    \u89c2\u5bdf\u56fe 4-5 \uff0c\u94fe\u8868\u7684\u7ec4\u6210\u5355\u4f4d\u662f\u8282\u70b9\uff08node\uff09\u5bf9\u8c61\u3002\u6bcf\u4e2a\u8282\u70b9\u90fd\u5305\u542b\u4e24\u9879\u6570\u636e\uff1a\u8282\u70b9\u7684\u201c\u503c\u201d\u548c\u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u201c\u5f15\u7528\u201d\u3002

    • \u94fe\u8868\u7684\u9996\u4e2a\u8282\u70b9\u88ab\u79f0\u4e3a\u201c\u5934\u8282\u70b9\u201d\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u88ab\u79f0\u4e3a\u201c\u5c3e\u8282\u70b9\u201d\u3002
    • \u5c3e\u8282\u70b9\u6307\u5411\u7684\u662f\u201c\u7a7a\u201d\uff0c\u5b83\u5728 Java\u3001C++ \u548c Python \u4e2d\u5206\u522b\u88ab\u8bb0\u4e3a null\u3001nullptr \u548c None \u3002
    • \u5728 C\u3001C++\u3001Go \u548c Rust \u7b49\u652f\u6301\u6307\u9488\u7684\u8bed\u8a00\u4e2d\uff0c\u4e0a\u8ff0\u201c\u5f15\u7528\u201d\u5e94\u88ab\u66ff\u6362\u4e3a\u201c\u6307\u9488\u201d\u3002

    \u5982\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff0c\u94fe\u8868\u8282\u70b9 ListNode \u9664\u4e86\u5305\u542b\u503c\uff0c\u8fd8\u9700\u989d\u5916\u4fdd\u5b58\u4e00\u4e2a\u5f15\u7528\uff08\u6307\u9488\uff09\u3002\u56e0\u6b64\u5728\u76f8\u540c\u6570\u636e\u91cf\u4e0b\uff0c\u94fe\u8868\u6bd4\u6570\u7ec4\u5360\u7528\u66f4\u591a\u7684\u5185\u5b58\u7a7a\u95f4\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class ListNode:\n    \"\"\"\u94fe\u8868\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val               # \u8282\u70b9\u503c\n        self.next: ListNode | None = None # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n
    /* \u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct ListNode {\n    int val;         // \u8282\u70b9\u503c\n    ListNode *next;  // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n    ListNode(int x) : val(x), next(nullptr) {}  // \u6784\u9020\u51fd\u6570\n};\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    int val;        // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    ListNode(int x) { val = x; }  // \u6784\u9020\u51fd\u6570\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode(int x) {  //\u6784\u9020\u51fd\u6570\n    int val = x;         // \u8282\u70b9\u503c\n    ListNode? next;      // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype ListNode struct {\n    Val  int       // \u8282\u70b9\u503c\n    Next *ListNode // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n}\n\n// NewListNode \u6784\u9020\u51fd\u6570\uff0c\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u94fe\u8868\nfunc NewListNode(val int) *ListNode {\n    return &ListNode{\n        Val:  val,\n        Next: nil,\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\n    init(x: Int) { // \u6784\u9020\u51fd\u6570\n        val = x\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    constructor(val, next) {\n        this.val = (val === undefined ? 0 : val);       // \u8282\u70b9\u503c\n        this.next = (next === undefined ? null : next); // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    constructor(val?: number, next?: ListNode | null) {\n        this.val = val === undefined ? 0 : val;        // \u8282\u70b9\u503c\n        this.next = next === undefined ? null : next;  // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n  int val; // \u8282\u70b9\u503c\n  ListNode? next; // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n  ListNode(this.val, [this.next]); // \u6784\u9020\u51fd\u6570\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n/* \u94fe\u8868\u8282\u70b9\u7c7b */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // \u8282\u70b9\u503c\n    next: Option<Rc<RefCell<ListNode>>>, // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct ListNode {\n    int val;               // \u8282\u70b9\u503c\n    struct ListNode *next; // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n} ListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nListNode *newListNode(int val) {\n    ListNode *node;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    return node;\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\n// \u6784\u9020\u65b9\u6cd5\nclass ListNode(x: Int) {\n    val _val: Int = x          // \u8282\u70b9\u503c\n    val next: ListNode? = null // \u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\n}\n
    # \u94fe\u8868\u8282\u70b9\u7c7b\nclass ListNode\n  attr_accessor :val  # \u8282\u70b9\u503c\n  attr_accessor :next # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\n  def initialize(val=0, next_node=nil)\n    @val = val\n    @next = next_node\n  end\nend\n
    // \u94fe\u8868\u8282\u70b9\u7c7b\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // \u8282\u70b9\u503c\n        next: ?*Self = null, // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n        }\n    };\n}\n
    "},{"location":"chapter_array_and_linkedlist/linked_list/#421","title":"4.2.1 \u00a0 \u94fe\u8868\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_array_and_linkedlist/linked_list/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u94fe\u8868","text":"

    \u5efa\u7acb\u94fe\u8868\u5206\u4e3a\u4e24\u6b65\uff0c\u7b2c\u4e00\u6b65\u662f\u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\u5bf9\u8c61\uff0c\u7b2c\u4e8c\u6b65\u662f\u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\u5173\u7cfb\u3002\u521d\u59cb\u5316\u5b8c\u6210\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u51fa\u53d1\uff0c\u901a\u8fc7\u5f15\u7528\u6307\u5411 next \u4f9d\u6b21\u8bbf\u95ee\u6240\u6709\u8282\u70b9\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    # \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4\n# \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nn0 = ListNode(1)\nn1 = ListNode(3)\nn2 = ListNode(2)\nn3 = ListNode(5)\nn4 = ListNode(4)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.cpp
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode* n0 = new ListNode(1);\nListNode* n1 = new ListNode(3);\nListNode* n2 = new ListNode(2);\nListNode* n3 = new ListNode(5);\nListNode* n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.java
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode n0 = new ListNode(1);\nListNode n1 = new ListNode(3);\nListNode n2 = new ListNode(2);\nListNode n3 = new ListNode(5);\nListNode n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.cs
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode n0 = new(1);\nListNode n1 = new(3);\nListNode n2 = new(2);\nListNode n3 = new(5);\nListNode n4 = new(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.go
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nn0 := NewListNode(1)\nn1 := NewListNode(3)\nn2 := NewListNode(2)\nn3 := NewListNode(5)\nn4 := NewListNode(4)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.Next = n1\nn1.Next = n2\nn2.Next = n3\nn3.Next = n4\n
    linked_list.swift
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nlet n0 = ListNode(x: 1)\nlet n1 = ListNode(x: 3)\nlet n2 = ListNode(x: 2)\nlet n3 = ListNode(x: 5)\nlet n4 = ListNode(x: 4)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.js
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.ts
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.dart
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\\\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode n0 = ListNode(1);\nListNode n1 = ListNode(3);\nListNode n2 = ListNode(2);\nListNode n3 = ListNode(5);\nListNode n4 = ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.rs
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nlet n0 = Rc::new(RefCell::new(ListNode { val: 1, next: None }));\nlet n1 = Rc::new(RefCell::new(ListNode { val: 3, next: None }));\nlet n2 = Rc::new(RefCell::new(ListNode { val: 2, next: None }));\nlet n3 = Rc::new(RefCell::new(ListNode { val: 5, next: None }));\nlet n4 = Rc::new(RefCell::new(ListNode { val: 4, next: None }));\n\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.borrow_mut().next = Some(n1.clone());\nn1.borrow_mut().next = Some(n2.clone());\nn2.borrow_mut().next = Some(n3.clone());\nn3.borrow_mut().next = Some(n4.clone());\n
    linked_list.c
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode* n0 = newListNode(1);\nListNode* n1 = newListNode(3);\nListNode* n2 = newListNode(2);\nListNode* n3 = newListNode(5);\nListNode* n4 = newListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.kt
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nval n0 = ListNode(1)\nval n1 = ListNode(3)\nval n2 = ListNode(2)\nval n3 = ListNode(5)\nval n4 = ListNode(4)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.rb
    # \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4\n# \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nn0 = ListNode.new(1)\nn1 = ListNode.new(3)\nn2 = ListNode.new(2)\nn3 = ListNode.new(5)\nn4 = ListNode.new(4)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.zig
    // \u521d\u59cb\u5316\u94fe\u8868\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nvar n0 = inc.ListNode(i32){.val = 1};\nvar n1 = inc.ListNode(i32){.val = 3};\nvar n2 = inc.ListNode(i32){.val = 2};\nvar n3 = inc.ListNode(i32){.val = 5};\nvar n4 = inc.ListNode(i32){.val = 4};\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = &n1;\nn1.next = &n2;\nn2.next = &n3;\nn3.next = &n4;\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6570\u7ec4\u6574\u4f53\u662f\u4e00\u4e2a\u53d8\u91cf\uff0c\u6bd4\u5982\u6570\u7ec4 nums \u5305\u542b\u5143\u7d20 nums[0] \u548c nums[1] \u7b49\uff0c\u800c\u94fe\u8868\u662f\u7531\u591a\u4e2a\u72ec\u7acb\u7684\u8282\u70b9\u5bf9\u8c61\u7ec4\u6210\u7684\u3002\u6211\u4eec\u901a\u5e38\u5c06\u5934\u8282\u70b9\u5f53\u4f5c\u94fe\u8868\u7684\u4ee3\u79f0\uff0c\u6bd4\u5982\u4ee5\u4e0a\u4ee3\u7801\u4e2d\u7684\u94fe\u8868\u53ef\u8bb0\u4f5c\u94fe\u8868 n0 \u3002

    "},{"location":"chapter_array_and_linkedlist/linked_list/#2","title":"2. \u00a0 \u63d2\u5165\u8282\u70b9","text":"

    \u5728\u94fe\u8868\u4e2d\u63d2\u5165\u8282\u70b9\u975e\u5e38\u5bb9\u6613\u3002\u5982\u56fe 4-6 \u6240\u793a\uff0c\u5047\u8bbe\u6211\u4eec\u60f3\u5728\u76f8\u90bb\u7684\u4e24\u4e2a\u8282\u70b9 n0 \u548c n1 \u4e4b\u95f4\u63d2\u5165\u4e00\u4e2a\u65b0\u8282\u70b9 P \uff0c\u5219\u53ea\u9700\u6539\u53d8\u4e24\u4e2a\u8282\u70b9\u5f15\u7528\uff08\u6307\u9488\uff09\u5373\u53ef\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    \u76f8\u6bd4\u4e4b\u4e0b\uff0c\u5728\u6570\u7ec4\u4e2d\u63d2\u5165\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u5728\u5927\u6570\u636e\u91cf\u4e0b\u7684\u6548\u7387\u8f83\u4f4e\u3002

    \u56fe 4-6 \u00a0 \u94fe\u8868\u63d2\u5165\u8282\u70b9\u793a\u4f8b

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def insert(n0: ListNode, P: ListNode):\n    \"\"\"\u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\"\"\"\n    n1 = n0.next\n    P.next = n1\n    n0.next = P\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n    ListNode n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid Insert(ListNode n0, ListNode P) {\n    ListNode? n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insertNode(n0 *ListNode, P *ListNode) {\n    n1 := n0.Next\n    P.Next = n1\n    n0.Next = P\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insert(n0: ListNode, P: ListNode) {\n    let n1 = n0.next\n    P.next = n1\n    n0.next = P\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0, P) {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0: ListNode, P: ListNode): void {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n  ListNode? n1 = n0.next;\n  P.next = n1;\n  n0.next = P;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\n#[allow(non_snake_case)]\npub fn insert<T>(n0: &Rc<RefCell<ListNode<T>>>, P: Rc<RefCell<ListNode<T>>>) {\n    let n1 = n0.borrow_mut().next.take();\n    P.borrow_mut().next = n1;\n    n0.borrow_mut().next = Some(P);\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfun insert(n0: ListNode?, p: ListNode?) {\n    val n1 = n0?.next\n    p?.next = n1\n    n0?.next = p\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 _p ###\n# Ruby \u7684 `p` \u662f\u4e00\u4e2a\u5185\u7f6e\u51fd\u6570\uff0c `P` \u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u4f7f\u7528 `_p` \u4ee3\u66ff\ndef insert(n0, _p)\n  n1 = n0.next\n  _p.next = n1\n  n0.next = _p\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\nfn insert(n0: ?*inc.ListNode(i32), P: ?*inc.ListNode(i32)) void {\n    var n1 = n0.?.next;\n    P.?.next = n1;\n    n0.?.next = P;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#3","title":"3. \u00a0 \u5220\u9664\u8282\u70b9","text":"

    \u5982\u56fe 4-7 \u6240\u793a\uff0c\u5728\u94fe\u8868\u4e2d\u5220\u9664\u8282\u70b9\u4e5f\u975e\u5e38\u65b9\u4fbf\uff0c\u53ea\u9700\u6539\u53d8\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\u5373\u53ef\u3002

    \u8bf7\u6ce8\u610f\uff0c\u5c3d\u7ba1\u5728\u5220\u9664\u64cd\u4f5c\u5b8c\u6210\u540e\u8282\u70b9 P \u4ecd\u7136\u6307\u5411 n1 \uff0c\u4f46\u5b9e\u9645\u4e0a\u904d\u5386\u6b64\u94fe\u8868\u5df2\u7ecf\u65e0\u6cd5\u8bbf\u95ee\u5230 P \uff0c\u8fd9\u610f\u5473\u7740 P \u5df2\u7ecf\u4e0d\u518d\u5c5e\u4e8e\u8be5\u94fe\u8868\u4e86\u3002

    \u56fe 4-7 \u00a0 \u94fe\u8868\u5220\u9664\u8282\u70b9

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def remove(n0: ListNode):\n    \"\"\"\u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    if not n0.next:\n        return\n    # n0 -> P -> n1\n    P = n0.next\n    n1 = P.next\n    n0.next = n1\n
    linked_list.cpp
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode *n0) {\n    if (n0->next == nullptr)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    delete P;\n}\n
    linked_list.java
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.cs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid Remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode? n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.go
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc removeItem(n0 *ListNode) {\n    if n0.Next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    P := n0.Next\n    n1 := P.Next\n    n0.Next = n1\n}\n
    linked_list.swift
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc remove(n0: ListNode) {\n    if n0.next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    let P = n0.next\n    let n1 = P?.next\n    n0.next = n1\n}\n
    linked_list.js
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0) {\n    if (!n0.next) return;\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.ts
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0: ListNode): void {\n    if (!n0.next) {\n        return;\n    }\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.dart
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n  if (n0.next == null) return;\n  // n0 -> P -> n1\n  ListNode P = n0.next!;\n  ListNode? n1 = P.next;\n  n0.next = n1;\n}\n
    linked_list.rs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n#[allow(non_snake_case)]\npub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {\n    if n0.borrow().next.is_none() {\n        return;\n    };\n    // n0 -> P -> n1\n    let P = n0.borrow_mut().next.take();\n    if let Some(node) = P {\n        let n1 = node.borrow_mut().next.take();\n        n0.borrow_mut().next = n1;\n    }\n}\n
    linked_list.c
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(ListNode *n0) {\n    if (!n0->next)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    free(P);\n}\n
    linked_list.kt
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfun remove(n0: ListNode?) {\n    if (n0?.next == null)\n        return\n    // n0 -> P -> n1\n    val p = n0.next\n    val n1 = p?.next\n    n0.next = n1\n}\n
    linked_list.rb
    ### \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 ###\ndef remove(n0)\n  return if n0.next.nil?\n\n  # n0 -> remove_node -> n1\n  remove_node = n0.next\n  n1 = remove_node.next\n  n0.next = n1\nend\n
    linked_list.zig
    // \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\nfn remove(n0: ?*inc.ListNode(i32)) void {\n    if (n0.?.next == null) return;\n    // n0 -> P -> n1\n    var P = n0.?.next;\n    var n1 = P.?.next;\n    n0.?.next = n1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#4","title":"4. \u00a0 \u8bbf\u95ee\u8282\u70b9","text":"

    \u5728\u94fe\u8868\u4e2d\u8bbf\u95ee\u8282\u70b9\u7684\u6548\u7387\u8f83\u4f4e\u3002\u5982\u4e0a\u4e00\u8282\u6240\u8ff0\uff0c\u6211\u4eec\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u4e0b\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u5143\u7d20\u3002\u94fe\u8868\u5219\u4e0d\u7136\uff0c\u7a0b\u5e8f\u9700\u8981\u4ece\u5934\u8282\u70b9\u51fa\u53d1\uff0c\u9010\u4e2a\u5411\u540e\u904d\u5386\uff0c\u76f4\u81f3\u627e\u5230\u76ee\u6807\u8282\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8bbf\u95ee\u94fe\u8868\u7684\u7b2c \\(i\\) \u4e2a\u8282\u70b9\u9700\u8981\u5faa\u73af \\(i - 1\\) \u8f6e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def access(head: ListNode, index: int) -> ListNode | None:\n    \"\"\"\u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\"\"\"\n    for _ in range(index):\n        if not head:\n            return None\n        head = head.next\n    return head\n
    linked_list.cpp
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == nullptr)\n            return nullptr;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.java
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode access(ListNode head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.cs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? Access(ListNode? head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.go
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head *ListNode, index int) *ListNode {\n    for i := 0; i < index; i++ {\n        if head == nil {\n            return nil\n        }\n        head = head.Next\n    }\n    return head\n}\n
    linked_list.swift
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head: ListNode, index: Int) -> ListNode? {\n    var head: ListNode? = head\n    for _ in 0 ..< index {\n        if head == nil {\n            return nil\n        }\n        head = head?.next\n    }\n    return head\n}\n
    linked_list.js
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head, index) {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.ts
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head: ListNode | null, index: number): ListNode | null {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.dart
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? access(ListNode? head, int index) {\n  for (var i = 0; i < index; i++) {\n    if (head == null) return null;\n    head = head.next;\n  }\n  return head;\n}\n
    linked_list.rs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\npub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Rc<RefCell<ListNode<T>>> {\n    if index <= 0 {\n        return head;\n    };\n    if let Some(node) = &head.borrow().next {\n        return access(node.clone(), index - 1);\n    }\n\n    return head;\n}\n
    linked_list.c
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == NULL)\n            return NULL;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.kt
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfun access(head: ListNode?, index: Int): ListNode? {\n    var h = head\n    for (i in 0..<index) {\n        if (h == null)\n            return null\n        h = h.next\n    }\n    return h\n}\n
    linked_list.rb
    ### \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 ###\ndef access(head, index)\n  for i in 0...index\n    return nil if head.nil?\n    head = head.next\n  end\n\n  head\nend\n
    linked_list.zig
    // \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\nfn access(node: ?*inc.ListNode(i32), index: i32) ?*inc.ListNode(i32) {\n    var head = node;\n    var i: i32 = 0;\n    while (i < index) : (i += 1) {\n        head = head.?.next;\n        if (head == null) return null;\n    }\n    return head;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#5","title":"5. \u00a0 \u67e5\u627e\u8282\u70b9","text":"

    \u904d\u5386\u94fe\u8868\uff0c\u67e5\u627e\u5176\u4e2d\u503c\u4e3a target \u7684\u8282\u70b9\uff0c\u8f93\u51fa\u8be5\u8282\u70b9\u5728\u94fe\u8868\u4e2d\u7684\u7d22\u5f15\u3002\u6b64\u8fc7\u7a0b\u4e5f\u5c5e\u4e8e\u7ebf\u6027\u67e5\u627e\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def find(head: ListNode, target: int) -> int:\n    \"\"\"\u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    index = 0\n    while head:\n        if head.val == target:\n            return index\n        head = head.next\n        index += 1\n    return -1\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head != nullptr) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint Find(ListNode? head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc findNode(head *ListNode, target int) int {\n    index := 0\n    for head != nil {\n        if head.Val == target {\n            return index\n        }\n        head = head.Next\n        index++\n    }\n    return -1\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc find(head: ListNode, target: Int) -> Int {\n    var head: ListNode? = head\n    var index = 0\n    while head != nil {\n        if head?.val == target {\n            return index\n        }\n        head = head?.next\n        index += 1\n    }\n    return -1\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head, target) {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head: ListNode | null, target: number): number {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode? head, int target) {\n  int index = 0;\n  while (head != null) {\n    if (head.val == target) {\n      return index;\n    }\n    head = head.next;\n    index++;\n  }\n  return -1;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\npub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T, index: i32) -> i32 {\n    if head.borrow().val == target {\n        return index;\n    };\n    if let Some(node) = &head.borrow_mut().next {\n        return find(node.clone(), target, index + 1);\n    }\n    return -1;\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfun find(head: ListNode?, target: Int): Int {\n    var index = 0\n    var h = head\n    while (h != null) {\n        if (h._val == target)\n            return index\n        h = h.next\n        index++\n    }\n    return -1\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 ###\ndef find(head, target)\n  index = 0\n  while head\n    return index if head.val == target\n    head = head.next\n    index += 1\n  end\n\n  -1\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\nfn find(node: ?*inc.ListNode(i32), target: i32) i32 {\n    var head = node;\n    var index: i32 = 0;\n    while (head != null) {\n        if (head.?.val == target) return index;\n        head = head.?.next;\n        index += 1;\n    }\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#422-vs","title":"4.2.2 \u00a0 \u6570\u7ec4 vs. \u94fe\u8868","text":"

    \u8868 4-1 \u603b\u7ed3\u4e86\u6570\u7ec4\u548c\u94fe\u8868\u7684\u5404\u9879\u7279\u70b9\u5e76\u5bf9\u6bd4\u4e86\u64cd\u4f5c\u6548\u7387\u3002\u7531\u4e8e\u5b83\u4eec\u91c7\u7528\u4e24\u79cd\u76f8\u53cd\u7684\u5b58\u50a8\u7b56\u7565\uff0c\u56e0\u6b64\u5404\u79cd\u6027\u8d28\u548c\u64cd\u4f5c\u6548\u7387\u4e5f\u5448\u73b0\u5bf9\u7acb\u7684\u7279\u70b9\u3002

    \u8868 4-1 \u00a0 \u6570\u7ec4\u4e0e\u94fe\u8868\u7684\u6548\u7387\u5bf9\u6bd4

    \u6570\u7ec4 \u94fe\u8868 \u5b58\u50a8\u65b9\u5f0f \u8fde\u7eed\u5185\u5b58\u7a7a\u95f4 \u5206\u6563\u5185\u5b58\u7a7a\u95f4 \u5bb9\u91cf\u6269\u5c55 \u957f\u5ea6\u4e0d\u53ef\u53d8 \u53ef\u7075\u6d3b\u6269\u5c55 \u5185\u5b58\u6548\u7387 \u5143\u7d20\u5360\u7528\u5185\u5b58\u5c11\u3001\u4f46\u53ef\u80fd\u6d6a\u8d39\u7a7a\u95f4 \u5143\u7d20\u5360\u7528\u5185\u5b58\u591a \u8bbf\u95ee\u5143\u7d20 \\(O(1)\\) \\(O(n)\\) \u6dfb\u52a0\u5143\u7d20 \\(O(n)\\) \\(O(1)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(1)\\)"},{"location":"chapter_array_and_linkedlist/linked_list/#423","title":"4.2.3 \u00a0 \u5e38\u89c1\u94fe\u8868\u7c7b\u578b","text":"

    \u5982\u56fe 4-8 \u6240\u793a\uff0c\u5e38\u89c1\u7684\u94fe\u8868\u7c7b\u578b\u5305\u62ec\u4e09\u79cd\u3002

    • \u5355\u5411\u94fe\u8868\uff1a\u5373\u524d\u9762\u4ecb\u7ecd\u7684\u666e\u901a\u94fe\u8868\u3002\u5355\u5411\u94fe\u8868\u7684\u8282\u70b9\u5305\u542b\u503c\u548c\u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\u4e24\u9879\u6570\u636e\u3002\u6211\u4eec\u5c06\u9996\u4e2a\u8282\u70b9\u79f0\u4e3a\u5934\u8282\u70b9\uff0c\u5c06\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u79f0\u4e3a\u5c3e\u8282\u70b9\uff0c\u5c3e\u8282\u70b9\u6307\u5411\u7a7a None \u3002
    • \u73af\u5f62\u94fe\u8868\uff1a\u5982\u679c\u6211\u4eec\u4ee4\u5355\u5411\u94fe\u8868\u7684\u5c3e\u8282\u70b9\u6307\u5411\u5934\u8282\u70b9\uff08\u9996\u5c3e\u76f8\u63a5\uff09\uff0c\u5219\u5f97\u5230\u4e00\u4e2a\u73af\u5f62\u94fe\u8868\u3002\u5728\u73af\u5f62\u94fe\u8868\u4e2d\uff0c\u4efb\u610f\u8282\u70b9\u90fd\u53ef\u4ee5\u89c6\u4f5c\u5934\u8282\u70b9\u3002
    • \u53cc\u5411\u94fe\u8868\uff1a\u4e0e\u5355\u5411\u94fe\u8868\u76f8\u6bd4\uff0c\u53cc\u5411\u94fe\u8868\u8bb0\u5f55\u4e86\u4e24\u4e2a\u65b9\u5411\u7684\u5f15\u7528\u3002\u53cc\u5411\u94fe\u8868\u7684\u8282\u70b9\u5b9a\u4e49\u540c\u65f6\u5305\u542b\u6307\u5411\u540e\u7ee7\u8282\u70b9\uff08\u4e0b\u4e00\u4e2a\u8282\u70b9\uff09\u548c\u524d\u9a71\u8282\u70b9\uff08\u4e0a\u4e00\u4e2a\u8282\u70b9\uff09\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\u3002\u76f8\u8f83\u4e8e\u5355\u5411\u94fe\u8868\uff0c\u53cc\u5411\u94fe\u8868\u66f4\u5177\u7075\u6d3b\u6027\uff0c\u53ef\u4ee5\u671d\u4e24\u4e2a\u65b9\u5411\u904d\u5386\u94fe\u8868\uff0c\u4f46\u76f8\u5e94\u5730\u4e5f\u9700\u8981\u5360\u7528\u66f4\u591a\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class ListNode:\n    \"\"\"\u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # \u8282\u70b9\u503c\n        self.next: ListNode | None = None  # \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n        self.prev: ListNode | None = None  # \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct ListNode {\n    int val;         // \u8282\u70b9\u503c\n    ListNode *next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    ListNode *prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n    ListNode(int x) : val(x), next(nullptr), prev(nullptr) {}  // \u6784\u9020\u51fd\u6570\n};\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    int val;        // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    ListNode prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    ListNode(int x) { val = x; }  // \u6784\u9020\u51fd\u6570\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode(int x) {  // \u6784\u9020\u51fd\u6570\n    int val = x;    // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    ListNode prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype DoublyListNode struct {\n    Val  int             // \u8282\u70b9\u503c\n    Next *DoublyListNode // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    Prev *DoublyListNode // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n}\n\n// NewDoublyListNode \u521d\u59cb\u5316\nfunc NewDoublyListNode(val int) *DoublyListNode {\n    return &DoublyListNode{\n        Val:  val,\n        Next: nil,\n        Prev: nil,\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    var prev: ListNode? // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n\n    init(x: Int) { // \u6784\u9020\u51fd\u6570\n        val = x\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    constructor(val, next, prev) {\n        this.val = val  ===  undefined ? 0 : val;        // \u8282\u70b9\u503c\n        this.next = next  ===  undefined ? null : next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n        this.prev = prev  ===  undefined ? null : prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    prev: ListNode | null;\n    constructor(val?: number, next?: ListNode | null, prev?: ListNode | null) {\n        this.val = val  ===  undefined ? 0 : val;        // \u8282\u70b9\u503c\n        this.next = next  ===  undefined ? null : next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n        this.prev = prev  ===  undefined ? null : prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    int val;        // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    ListNode prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    ListNode(this.val, [this.next, this.prev]);  // \u6784\u9020\u51fd\u6570\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\u578b */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // \u8282\u70b9\u503c\n    next: Option<Rc<RefCell<ListNode>>>, // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    prev: Option<Rc<RefCell<ListNode>>>, // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nimpl ListNode {\n    fn new(val: i32) -> Self {\n        ListNode {\n            val,\n            next: None,\n            prev: None,\n        }\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct ListNode {\n    int val;               // \u8282\u70b9\u503c\n    struct ListNode *next; // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    struct ListNode *prev; // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n} ListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nListNode *newListNode(int val) {\n    ListNode *node;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    node->prev = NULL;\n    return node;\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\n// \u6784\u9020\u65b9\u6cd5\nclass ListNode(x: Int) {\n    val _val: Int = x           // \u8282\u70b9\u503c\n    val next: ListNode? = null  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    val prev: ListNode? = null  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n}\n
    # \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\nclass ListNode\n  attr_accessor :val    # \u8282\u70b9\u503c\n  attr_accessor :next   # \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n  attr_accessor :prev   # \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n\n  def initialize(val=0, next_node=nil, prev_node=nil)\n    @val = val\n    @next = next_node\n    @prev = prev_node\n  end\nend\n
    // \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // \u8282\u70b9\u503c\n        next: ?*Self = null, // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n        prev: ?*Self = null, // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n

    \u56fe 4-8 \u00a0 \u5e38\u89c1\u94fe\u8868\u79cd\u7c7b

    "},{"location":"chapter_array_and_linkedlist/linked_list/#424","title":"4.2.4 \u00a0 \u94fe\u8868\u5178\u578b\u5e94\u7528","text":"

    \u5355\u5411\u94fe\u8868\u901a\u5e38\u7528\u4e8e\u5b9e\u73b0\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u548c\u56fe\u7b49\u6570\u636e\u7ed3\u6784\u3002

    • \u6808\u4e0e\u961f\u5217\uff1a\u5f53\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u90fd\u5728\u94fe\u8868\u7684\u4e00\u7aef\u8fdb\u884c\u65f6\uff0c\u5b83\u8868\u73b0\u7684\u7279\u6027\u4e3a\u5148\u8fdb\u540e\u51fa\uff0c\u5bf9\u5e94\u6808\uff1b\u5f53\u63d2\u5165\u64cd\u4f5c\u5728\u94fe\u8868\u7684\u4e00\u7aef\u8fdb\u884c\uff0c\u5220\u9664\u64cd\u4f5c\u5728\u94fe\u8868\u7684\u53e6\u4e00\u7aef\u8fdb\u884c\uff0c\u5b83\u8868\u73b0\u7684\u7279\u6027\u4e3a\u5148\u8fdb\u5148\u51fa\uff0c\u5bf9\u5e94\u961f\u5217\u3002
    • \u54c8\u5e0c\u8868\uff1a\u94fe\u5f0f\u5730\u5740\u662f\u89e3\u51b3\u54c8\u5e0c\u51b2\u7a81\u7684\u4e3b\u6d41\u65b9\u6848\u4e4b\u4e00\uff0c\u5728\u8be5\u65b9\u6848\u4e2d\uff0c\u6240\u6709\u51b2\u7a81\u7684\u5143\u7d20\u90fd\u4f1a\u88ab\u653e\u5230\u4e00\u4e2a\u94fe\u8868\u4e2d\u3002
    • \u56fe\uff1a\u90bb\u63a5\u8868\u662f\u8868\u793a\u56fe\u7684\u4e00\u79cd\u5e38\u7528\u65b9\u5f0f\uff0c\u5176\u4e2d\u56fe\u7684\u6bcf\u4e2a\u9876\u70b9\u90fd\u4e0e\u4e00\u4e2a\u94fe\u8868\u76f8\u5173\u8054\uff0c\u94fe\u8868\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u4ee3\u8868\u4e0e\u8be5\u9876\u70b9\u76f8\u8fde\u7684\u5176\u4ed6\u9876\u70b9\u3002

    \u53cc\u5411\u94fe\u8868\u5e38\u7528\u4e8e\u9700\u8981\u5feb\u901f\u67e5\u627e\u524d\u4e00\u4e2a\u548c\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u573a\u666f\u3002

    • \u9ad8\u7ea7\u6570\u636e\u7ed3\u6784\uff1a\u6bd4\u5982\u5728\u7ea2\u9ed1\u6811\u3001B \u6811\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u8bbf\u95ee\u8282\u70b9\u7684\u7236\u8282\u70b9\uff0c\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5728\u8282\u70b9\u4e2d\u4fdd\u5b58\u4e00\u4e2a\u6307\u5411\u7236\u8282\u70b9\u7684\u5f15\u7528\u6765\u5b9e\u73b0\uff0c\u7c7b\u4f3c\u4e8e\u53cc\u5411\u94fe\u8868\u3002
    • \u6d4f\u89c8\u5668\u5386\u53f2\uff1a\u5728\u7f51\u9875\u6d4f\u89c8\u5668\u4e2d\uff0c\u5f53\u7528\u6237\u70b9\u51fb\u524d\u8fdb\u6216\u540e\u9000\u6309\u94ae\u65f6\uff0c\u6d4f\u89c8\u5668\u9700\u8981\u77e5\u9053\u7528\u6237\u8bbf\u95ee\u8fc7\u7684\u524d\u4e00\u4e2a\u548c\u540e\u4e00\u4e2a\u7f51\u9875\u3002\u53cc\u5411\u94fe\u8868\u7684\u7279\u6027\u4f7f\u5f97\u8fd9\u79cd\u64cd\u4f5c\u53d8\u5f97\u7b80\u5355\u3002
    • LRU \u7b97\u6cd5\uff1a\u5728\u7f13\u5b58\u6dd8\u6c70\uff08LRU\uff09\u7b97\u6cd5\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u5feb\u901f\u627e\u5230\u6700\u8fd1\u6700\u5c11\u4f7f\u7528\u7684\u6570\u636e\uff0c\u4ee5\u53ca\u652f\u6301\u5feb\u901f\u6dfb\u52a0\u548c\u5220\u9664\u8282\u70b9\u3002\u8fd9\u65f6\u5019\u4f7f\u7528\u53cc\u5411\u94fe\u8868\u5c31\u975e\u5e38\u5408\u9002\u3002

    \u73af\u5f62\u94fe\u8868\u5e38\u7528\u4e8e\u9700\u8981\u5468\u671f\u6027\u64cd\u4f5c\u7684\u573a\u666f\uff0c\u6bd4\u5982\u64cd\u4f5c\u7cfb\u7edf\u7684\u8d44\u6e90\u8c03\u5ea6\u3002

    • \u65f6\u95f4\u7247\u8f6e\u8f6c\u8c03\u5ea6\u7b97\u6cd5\uff1a\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u65f6\u95f4\u7247\u8f6e\u8f6c\u8c03\u5ea6\u7b97\u6cd5\u662f\u4e00\u79cd\u5e38\u89c1\u7684 CPU \u8c03\u5ea6\u7b97\u6cd5\uff0c\u5b83\u9700\u8981\u5bf9\u4e00\u7ec4\u8fdb\u7a0b\u8fdb\u884c\u5faa\u73af\u3002\u6bcf\u4e2a\u8fdb\u7a0b\u88ab\u8d4b\u4e88\u4e00\u4e2a\u65f6\u95f4\u7247\uff0c\u5f53\u65f6\u95f4\u7247\u7528\u5b8c\u65f6\uff0cCPU \u5c06\u5207\u6362\u5230\u4e0b\u4e00\u4e2a\u8fdb\u7a0b\u3002\u8fd9\u79cd\u5faa\u73af\u64cd\u4f5c\u53ef\u4ee5\u901a\u8fc7\u73af\u5f62\u94fe\u8868\u6765\u5b9e\u73b0\u3002
    • \u6570\u636e\u7f13\u51b2\u533a\uff1a\u5728\u67d0\u4e9b\u6570\u636e\u7f13\u51b2\u533a\u7684\u5b9e\u73b0\u4e2d\uff0c\u4e5f\u53ef\u80fd\u4f1a\u4f7f\u7528\u73af\u5f62\u94fe\u8868\u3002\u6bd4\u5982\u5728\u97f3\u9891\u3001\u89c6\u9891\u64ad\u653e\u5668\u4e2d\uff0c\u6570\u636e\u6d41\u53ef\u80fd\u4f1a\u88ab\u5206\u6210\u591a\u4e2a\u7f13\u51b2\u5757\u5e76\u653e\u5165\u4e00\u4e2a\u73af\u5f62\u94fe\u8868\uff0c\u4ee5\u4fbf\u5b9e\u73b0\u65e0\u7f1d\u64ad\u653e\u3002
    "},{"location":"chapter_array_and_linkedlist/list/","title":"4.3 \u00a0 \u5217\u8868","text":"

    \u5217\u8868\uff08list\uff09\u662f\u4e00\u4e2a\u62bd\u8c61\u7684\u6570\u636e\u7ed3\u6784\u6982\u5ff5\uff0c\u5b83\u8868\u793a\u5143\u7d20\u7684\u6709\u5e8f\u96c6\u5408\uff0c\u652f\u6301\u5143\u7d20\u8bbf\u95ee\u3001\u4fee\u6539\u3001\u6dfb\u52a0\u3001\u5220\u9664\u548c\u904d\u5386\u7b49\u64cd\u4f5c\uff0c\u65e0\u987b\u4f7f\u7528\u8005\u8003\u8651\u5bb9\u91cf\u9650\u5236\u7684\u95ee\u9898\u3002\u5217\u8868\u53ef\u4ee5\u57fa\u4e8e\u94fe\u8868\u6216\u6570\u7ec4\u5b9e\u73b0\u3002

    • \u94fe\u8868\u5929\u7136\u53ef\u4ee5\u770b\u4f5c\u4e00\u4e2a\u5217\u8868\uff0c\u5176\u652f\u6301\u5143\u7d20\u589e\u5220\u67e5\u6539\u64cd\u4f5c\uff0c\u5e76\u4e14\u53ef\u4ee5\u7075\u6d3b\u52a8\u6001\u6269\u5bb9\u3002
    • \u6570\u7ec4\u4e5f\u652f\u6301\u5143\u7d20\u589e\u5220\u67e5\u6539\uff0c\u4f46\u7531\u4e8e\u5176\u957f\u5ea6\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u53ea\u80fd\u770b\u4f5c\u4e00\u4e2a\u5177\u6709\u957f\u5ea6\u9650\u5236\u7684\u5217\u8868\u3002

    \u5f53\u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\u5217\u8868\u65f6\uff0c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6027\u8d28\u4f1a\u5bfc\u81f4\u5217\u8868\u7684\u5b9e\u7528\u6027\u964d\u4f4e\u3002\u8fd9\u662f\u56e0\u4e3a\u6211\u4eec\u901a\u5e38\u65e0\u6cd5\u4e8b\u5148\u786e\u5b9a\u9700\u8981\u5b58\u50a8\u591a\u5c11\u6570\u636e\uff0c\u4ece\u800c\u96be\u4ee5\u9009\u62e9\u5408\u9002\u7684\u5217\u8868\u957f\u5ea6\u3002\u82e5\u957f\u5ea6\u8fc7\u5c0f\uff0c\u5219\u5f88\u53ef\u80fd\u65e0\u6cd5\u6ee1\u8db3\u4f7f\u7528\u9700\u6c42\uff1b\u82e5\u957f\u5ea6\u8fc7\u5927\uff0c\u5219\u4f1a\u9020\u6210\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u3002

    \u4e3a\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u52a8\u6001\u6570\u7ec4\uff08dynamic array\uff09\u6765\u5b9e\u73b0\u5217\u8868\u3002\u5b83\u7ee7\u627f\u4e86\u6570\u7ec4\u7684\u5404\u9879\u4f18\u70b9\uff0c\u5e76\u4e14\u53ef\u4ee5\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u8fdb\u884c\u52a8\u6001\u6269\u5bb9\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u6807\u51c6\u5e93\u63d0\u4f9b\u7684\u5217\u8868\u662f\u57fa\u4e8e\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u7684\uff0c\u4f8b\u5982 Python \u4e2d\u7684 list \u3001Java \u4e2d\u7684 ArrayList \u3001C++ \u4e2d\u7684 vector \u548c C# \u4e2d\u7684 List \u7b49\u3002\u5728\u63a5\u4e0b\u6765\u7684\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u5c06\u628a\u201c\u5217\u8868\u201d\u548c\u201c\u52a8\u6001\u6570\u7ec4\u201d\u89c6\u4e3a\u7b49\u540c\u7684\u6982\u5ff5\u3002

    "},{"location":"chapter_array_and_linkedlist/list/#431","title":"4.3.1 \u00a0 \u5217\u8868\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_array_and_linkedlist/list/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u5217\u8868","text":"

    \u6211\u4eec\u901a\u5e38\u4f7f\u7528\u201c\u65e0\u521d\u59cb\u503c\u201d\u548c\u201c\u6709\u521d\u59cb\u503c\u201d\u8fd9\u4e24\u79cd\u521d\u59cb\u5316\u65b9\u6cd5\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u521d\u59cb\u5316\u5217\u8868\n# \u65e0\u521d\u59cb\u503c\nnums1: list[int] = []\n# \u6709\u521d\u59cb\u503c\nnums: list[int] = [1, 3, 2, 5, 4]\n
    list.cpp
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u9700\u6ce8\u610f\uff0cC++ \u4e2d vector \u5373\u662f\u672c\u6587\u63cf\u8ff0\u7684 nums\n// \u65e0\u521d\u59cb\u503c\nvector<int> nums1;\n// \u6709\u521d\u59cb\u503c\nvector<int> nums = { 1, 3, 2, 5, 4 };\n
    list.java
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nList<Integer> nums1 = new ArrayList<>();\n// \u6709\u521d\u59cb\u503c\uff08\u6ce8\u610f\u6570\u7ec4\u7684\u5143\u7d20\u7c7b\u578b\u9700\u4e3a int[] \u7684\u5305\u88c5\u7c7b Integer[]\uff09\nInteger[] numbers = new Integer[] { 1, 3, 2, 5, 4 };\nList<Integer> nums = new ArrayList<>(Arrays.asList(numbers));\n
    list.cs
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nList<int> nums1 = [];\n// \u6709\u521d\u59cb\u503c\nint[] numbers = [1, 3, 2, 5, 4];\nList<int> nums = [.. numbers];\n
    list_test.go
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nnums1 := []int{}\n// \u6709\u521d\u59cb\u503c\nnums := []int{1, 3, 2, 5, 4}\n
    list.swift
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nlet nums1: [Int] = []\n// \u6709\u521d\u59cb\u503c\nvar nums = [1, 3, 2, 5, 4]\n
    list.js
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nconst nums1 = [];\n// \u6709\u521d\u59cb\u503c\nconst nums = [1, 3, 2, 5, 4];\n
    list.ts
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nconst nums1: number[] = [];\n// \u6709\u521d\u59cb\u503c\nconst nums: number[] = [1, 3, 2, 5, 4];\n
    list.dart
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nList<int> nums1 = [];\n// \u6709\u521d\u59cb\u503c\nList<int> nums = [1, 3, 2, 5, 4];\n
    list.rs
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nlet nums1: Vec<i32> = Vec::new();\n// \u6709\u521d\u59cb\u503c\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nvar nums1 = listOf<Int>()\n// \u6709\u521d\u59cb\u503c\nvar numbers = arrayOf(1, 3, 2, 5, 4)\nvar nums = numbers.toMutableList()\n
    list.rb
    # \u521d\u59cb\u5316\u5217\u8868\n# \u65e0\u521d\u59cb\u503c\nnums1 = []\n# \u6709\u521d\u59cb\u503c\nnums = [1, 3, 2, 5, 4]\n
    list.zig
    // \u521d\u59cb\u5316\u5217\u8868\nvar nums = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums.deinit();\ntry nums.appendSlice(&[_]i32{ 1, 3, 2, 5, 4 });\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#2","title":"2. \u00a0 \u8bbf\u95ee\u5143\u7d20","text":"

    \u5217\u8868\u672c\u8d28\u4e0a\u662f\u6570\u7ec4\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u8bbf\u95ee\u548c\u66f4\u65b0\u5143\u7d20\uff0c\u6548\u7387\u5f88\u9ad8\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u8bbf\u95ee\u5143\u7d20\nnum: int = nums[1]  # \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n# \u66f4\u65b0\u5143\u7d20\nnums[1] = 0    # \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.cpp
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.java
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums.get(1);  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums.set(1, 0);  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.cs
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list_test.go
    /* \u8bbf\u95ee\u5143\u7d20 */\nnum := nums[1]  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0     // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.swift
    /* \u8bbf\u95ee\u5143\u7d20 */\nlet num = nums[1] // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0 // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.js
    /* \u8bbf\u95ee\u5143\u7d20 */\nconst num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.ts
    /* \u8bbf\u95ee\u5143\u7d20 */\nconst num: number = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.dart
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.rs
    /* \u8bbf\u95ee\u5143\u7d20 */\nlet num: i32 = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;             // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u8bbf\u95ee\u5143\u7d20 */\nval num = nums[1]       // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0             // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.rb
    # \u8bbf\u95ee\u5143\u7d20\nnum = nums[1] # \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n# \u66f4\u65b0\u5143\u7d20\nnums[1] = 0 # \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.zig
    // \u8bbf\u95ee\u5143\u7d20\nvar num = nums.items[1]; // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n// \u66f4\u65b0\u5143\u7d20\nnums.items[1] = 0; // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#3","title":"3. \u00a0 \u63d2\u5165\u4e0e\u5220\u9664\u5143\u7d20","text":"

    \u76f8\u8f83\u4e8e\u6570\u7ec4\uff0c\u5217\u8868\u53ef\u4ee5\u81ea\u7531\u5730\u6dfb\u52a0\u4e0e\u5220\u9664\u5143\u7d20\u3002\u5728\u5217\u8868\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff0c\u4f46\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u7684\u6548\u7387\u4ecd\u4e0e\u6570\u7ec4\u76f8\u540c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u6e05\u7a7a\u5217\u8868\nnums.clear()\n\n# \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n# \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\nnums.insert(3, 6)  # \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n# \u5220\u9664\u5143\u7d20\nnums.pop(3)        # \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.cpp
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push_back(1);\nnums.push_back(3);\nnums.push_back(2);\nnums.push_back(5);\nnums.push_back(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(nums.begin() + 3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.erase(nums.begin() + 3);      // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.java
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.add(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(3);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.cs
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.Clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.Add(1);\nnums.Add(3);\nnums.Add(2);\nnums.Add(5);\nnums.Add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.Insert(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.RemoveAt(3);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list_test.go
    /* \u6e05\u7a7a\u5217\u8868 */\nnums = nil\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums = append(nums, 1)\nnums = append(nums, 3)\nnums = append(nums, 2)\nnums = append(nums, 5)\nnums = append(nums, 4)\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums = append(nums[:3], append([]int{6}, nums[3:]...)...) // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums = append(nums[:3], nums[4:]...) // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.swift
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.removeAll()\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(6, at: 3) // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(at: 3) // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.js
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.length = 0;\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.splice(3, 0, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.splice(3, 1);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.ts
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.length = 0;\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.splice(3, 0, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.splice(3, 1);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.dart
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(3, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.removeAt(3); // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.rs
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(3);    // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.add(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(3);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.rb
    # \u6e05\u7a7a\u5217\u8868\nnums.clear\n\n# \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\nnums << 1\nnums << 3\nnums << 2\nnums << 5\nnums << 4\n\n# \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\nnums.insert(3, 6) # \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n# \u5220\u9664\u5143\u7d20\nnums.delete_at(3) # \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.zig
    // \u6e05\u7a7a\u5217\u8868\nnums.clearRetainingCapacity();\n\n// \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\ntry nums.append(1);\ntry nums.append(3);\ntry nums.append(2);\ntry nums.append(5);\ntry nums.append(4);\n\n// \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\ntry nums.insert(3, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n// \u5220\u9664\u5143\u7d20\n_ = nums.orderedRemove(3); // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#4","title":"4. \u00a0 \u904d\u5386\u5217\u8868","text":"

    \u4e0e\u6570\u7ec4\u4e00\u6837\uff0c\u5217\u8868\u53ef\u4ee5\u6839\u636e\u7d22\u5f15\u904d\u5386\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u904d\u5386\u5404\u5143\u7d20\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\ncount = 0\nfor i in range(len(nums)):\n    count += nums[i]\n\n# \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\nfor num in nums:\n    count += num\n
    list.cpp
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (int num : nums) {\n    count += num;\n}\n
    list.java
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums.get(i);\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\nfor (int num : nums) {\n    count += num;\n}\n
    list.cs
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (int i = 0; i < nums.Count; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nforeach (int num in nums) {\n    count += num;\n}\n
    list_test.go
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\ncount := 0\nfor i := 0; i < len(nums); i++ {\n    count += nums[i]\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0\nfor _, num := range nums {\n    count += num\n}\n
    list.swift
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nvar count = 0\nfor i in nums.indices {\n    count += nums[i]\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0\nfor num in nums {\n    count += num\n}\n
    list.js
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.ts
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.dart
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (var num in nums) {\n    count += num;\n}\n
    list.rs
    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\nlet mut _count = 0;\nfor i in 0..nums.len() {\n    _count += nums[i];\n}\n\n// \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\n_count = 0;\nfor num in &nums {\n    _count += num;\n}\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nvar count = 0\nfor (i in nums.indices) {\n    count += nums[i]\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\nfor (num in nums) {\n    count += num\n}\n
    list.rb
    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\ncount = 0\nfor i in 0...nums.length\n    count += nums[i]\nend\n\n# \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\ncount = 0\nfor num in nums\n    count += num\nend\n
    list.zig
    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\nvar count: i32 = 0;\nvar i: i32 = 0;\nwhile (i < nums.items.len) : (i += 1) {\n    count += nums[i];\n}\n\n// \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\ncount = 0;\nfor (nums.items) |num| {\n    count += num;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#5","title":"5. \u00a0 \u62fc\u63a5\u5217\u8868","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u65b0\u5217\u8868 nums1 \uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5176\u62fc\u63a5\u5230\u539f\u5217\u8868\u7684\u5c3e\u90e8\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u62fc\u63a5\u4e24\u4e2a\u5217\u8868\nnums1: list[int] = [6, 8, 7, 10, 9]\nnums += nums1  # \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.cpp
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nvector<int> nums1 = { 6, 8, 7, 10, 9 };\n// \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\nnums.insert(nums.end(), nums1.begin(), nums1.end());\n
    list.java
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nList<Integer> nums1 = new ArrayList<>(Arrays.asList(new Integer[] { 6, 8, 7, 10, 9 }));\nnums.addAll(nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.cs
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.AddRange(nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list_test.go
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nnums1 := []int{6, 8, 7, 10, 9}\nnums = append(nums, nums1...)  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.swift
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nlet nums1 = [6, 8, 7, 10, 9]\nnums.append(contentsOf: nums1) // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.js
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nconst nums1 = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.ts
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nconst nums1: number[] = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.dart
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.addAll(nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.rs
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nlet nums1: Vec<i32> = vec![6, 8, 7, 10, 9];\nnums.extend(nums1);\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nval nums1 = intArrayOf(6, 8, 7, 10, 9).toMutableList()\nnums.addAll(nums1)  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.rb
    # \u62fc\u63a5\u4e24\u4e2a\u5217\u8868\nnums1 = [6, 8, 7, 10, 9]\nnums += nums1\n
    list.zig
    // \u62fc\u63a5\u4e24\u4e2a\u5217\u8868\nvar nums1 = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums1.deinit();\ntry nums1.appendSlice(&[_]i32{ 6, 8, 7, 10, 9 });\ntry nums.insertSlice(nums.items.len, nums1.items); // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#6","title":"6. \u00a0 \u6392\u5e8f\u5217\u8868","text":"

    \u5b8c\u6210\u5217\u8868\u6392\u5e8f\u540e\uff0c\u6211\u4eec\u4fbf\u53ef\u4ee5\u4f7f\u7528\u5728\u6570\u7ec4\u7c7b\u7b97\u6cd5\u9898\u4e2d\u7ecf\u5e38\u8003\u67e5\u7684\u201c\u4e8c\u5206\u67e5\u627e\u201d\u548c\u201c\u53cc\u6307\u9488\u201d\u7b97\u6cd5\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u6392\u5e8f\u5217\u8868\nnums.sort()  # \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.cpp
    /* \u6392\u5e8f\u5217\u8868 */\nsort(nums.begin(), nums.end());  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.java
    /* \u6392\u5e8f\u5217\u8868 */\nCollections.sort(nums);  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.cs
    /* \u6392\u5e8f\u5217\u8868 */\nnums.Sort(); // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list_test.go
    /* \u6392\u5e8f\u5217\u8868 */\nsort.Ints(nums)  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.swift
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort() // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.js
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort((a, b) => a - b);  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.ts
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort((a, b) => a - b);  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.dart
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort(); // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.rs
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort(); // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort() // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.rb
    # \u6392\u5e8f\u5217\u8868\nnums = nums.sort { |a, b| a <=> b } # \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.zig
    // \u6392\u5e8f\u5217\u8868\nstd.sort.sort(i32, nums.items, {}, comptime std.sort.asc(i32));\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#432","title":"4.3.2 \u00a0 \u5217\u8868\u5b9e\u73b0","text":"

    \u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u5185\u7f6e\u4e86\u5217\u8868\uff0c\u4f8b\u5982 Java\u3001C++\u3001Python \u7b49\u3002\u5b83\u4eec\u7684\u5b9e\u73b0\u6bd4\u8f83\u590d\u6742\uff0c\u5404\u4e2a\u53c2\u6570\u7684\u8bbe\u5b9a\u4e5f\u975e\u5e38\u8003\u7a76\uff0c\u4f8b\u5982\u521d\u59cb\u5bb9\u91cf\u3001\u6269\u5bb9\u500d\u6570\u7b49\u3002\u611f\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u67e5\u9605\u6e90\u7801\u8fdb\u884c\u5b66\u4e60\u3002

    \u4e3a\u4e86\u52a0\u6df1\u5bf9\u5217\u8868\u5de5\u4f5c\u539f\u7406\u7684\u7406\u89e3\uff0c\u6211\u4eec\u5c1d\u8bd5\u5b9e\u73b0\u4e00\u4e2a\u7b80\u6613\u7248\u5217\u8868\uff0c\u5305\u62ec\u4ee5\u4e0b\u4e09\u4e2a\u91cd\u70b9\u8bbe\u8ba1\u3002

    • \u521d\u59cb\u5bb9\u91cf\uff1a\u9009\u53d6\u4e00\u4e2a\u5408\u7406\u7684\u6570\u7ec4\u521d\u59cb\u5bb9\u91cf\u3002\u5728\u672c\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u9009\u62e9 10 \u4f5c\u4e3a\u521d\u59cb\u5bb9\u91cf\u3002
    • \u6570\u91cf\u8bb0\u5f55\uff1a\u58f0\u660e\u4e00\u4e2a\u53d8\u91cf size \uff0c\u7528\u4e8e\u8bb0\u5f55\u5217\u8868\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff0c\u5e76\u968f\u7740\u5143\u7d20\u63d2\u5165\u548c\u5220\u9664\u5b9e\u65f6\u66f4\u65b0\u3002\u6839\u636e\u6b64\u53d8\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4f4d\u5217\u8868\u5c3e\u90e8\uff0c\u4ee5\u53ca\u5224\u65ad\u662f\u5426\u9700\u8981\u6269\u5bb9\u3002
    • \u6269\u5bb9\u673a\u5236\uff1a\u82e5\u63d2\u5165\u5143\u7d20\u65f6\u5217\u8868\u5bb9\u91cf\u5df2\u6ee1\uff0c\u5219\u9700\u8981\u8fdb\u884c\u6269\u5bb9\u3002\u5148\u6839\u636e\u6269\u5bb9\u500d\u6570\u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u6570\u7ec4\uff0c\u518d\u5c06\u5f53\u524d\u6570\u7ec4\u7684\u6240\u6709\u5143\u7d20\u4f9d\u6b21\u79fb\u52a8\u81f3\u65b0\u6570\u7ec4\u3002\u5728\u672c\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u89c4\u5b9a\u6bcf\u6b21\u5c06\u6570\u7ec4\u6269\u5bb9\u81f3\u4e4b\u524d\u7684 2 \u500d\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_list.py
    class MyList:\n    \"\"\"\u5217\u8868\u7c7b\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._capacity: int = 10  # \u5217\u8868\u5bb9\u91cf\n        self._arr: list[int] = [0] * self._capacity  # \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        self._size: int = 0  # \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        self._extend_ratio: int = 2  # \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\"\"\"\n        return self._size\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u5bb9\u91cf\"\"\"\n        return self._capacity\n\n    def get(self, index: int) -> int:\n        \"\"\"\u8bbf\u95ee\u5143\u7d20\"\"\"\n        # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        return self._arr[index]\n\n    def set(self, num: int, index: int):\n        \"\"\"\u66f4\u65b0\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        self._arr[index] = num\n\n    def add(self, num: int):\n        \"\"\"\u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\"\"\"\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size() == self.capacity():\n            self.extend_capacity()\n        self._arr[self._size] = num\n        self._size += 1\n\n    def insert(self, num: int, index: int):\n        \"\"\"\u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self._size == self.capacity():\n            self.extend_capacity()\n        # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in range(self._size - 1, index - 1, -1):\n            self._arr[j + 1] = self._arr[j]\n        self._arr[index] = num\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size += 1\n\n    def remove(self, index: int) -> int:\n        \"\"\"\u5220\u9664\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        num = self._arr[index]\n        # \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in range(index, self._size - 1):\n            self._arr[j] = self._arr[j + 1]\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size -= 1\n        # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n\n    def extend_capacity(self):\n        \"\"\"\u5217\u8868\u6269\u5bb9\"\"\"\n        # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1)\n        # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self._capacity = len(self._arr)\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868\"\"\"\n        return self._arr[: self._size]\n
    my_list.cpp
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  private:\n    int *arr;             // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int arrCapacity = 10; // \u5217\u8868\u5bb9\u91cf\n    int arrSize = 0;      // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    int extendRatio = 2;   // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~MyList() {\n        delete[] arr;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    int size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    int capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    void set(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        arr[size()] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    void insert(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size() - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    int remove(int index) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size() - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n        int newCapacity = capacity() * extendRatio;\n        int *tmp = arr;\n        arr = new int[newCapacity];\n        // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            arr[i] = tmp[i];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete[] tmp;\n        arrCapacity = newCapacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Vector \u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> vec(size());\n        for (int i = 0; i < size(); i++) {\n            vec[i] = arr[i];\n        }\n        return vec;\n    }\n};\n
    my_list.java
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    private int size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private int extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[capacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    public int size() {\n        return size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int capacity() {\n        return capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void set(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        arr[size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void insert(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int remove(int index) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = Arrays.copyOf(arr, capacity() * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] toArray() {\n        int size = size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[size];\n        for (int i = 0; i < size; i++) {\n            arr[i] = get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.cs
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr;           // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int arrCapacity = 10;    // \u5217\u8868\u5bb9\u91cf\n    private int arrSize = 0;         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private readonly int extendRatio = 2;  // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public int Size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int Capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int Get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void Set(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void Add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        arr[arrSize] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void Insert(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = arrSize - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int Remove(int index) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < arrSize - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void ExtendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a arrCapacity * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        Array.Resize(ref arr, arrCapacity * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        arrCapacity = arr.Length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[arrSize];\n        for (int i = 0; i < arrSize; i++) {\n            arr[i] = Get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.go
    /* \u5217\u8868\u7c7b */\ntype myList struct {\n    arrCapacity int\n    arr         []int\n    arrSize     int\n    extendRatio int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newMyList() *myList {\n    return &myList{\n        arrCapacity: 10,              // \u5217\u8868\u5bb9\u91cf\n        arr:         make([]int, 10), // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrSize:     0,               // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: 2,               // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n    }\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\nfunc (l *myList) size() int {\n    return l.arrSize\n}\n\n/*  \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nfunc (l *myList) capacity() int {\n    return l.arrCapacity\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nfunc (l *myList) get(index int) int {\n    // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    return l.arr[index]\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nfunc (l *myList) set(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    l.arr[index] = num\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nfunc (l *myList) add(num int) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    l.arr[l.arrSize] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nfunc (l *myList) insert(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j := l.arrSize - 1; j >= index; j-- {\n        l.arr[j+1] = l.arr[j]\n    }\n    l.arr[index] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5220\u9664\u5143\u7d20 */\nfunc (l *myList) remove(index int) int {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    num := l.arr[index]\n    // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j := index; j < l.arrSize-1; j++ {\n        l.arr[j] = l.arr[j+1]\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize--\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return num\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nfunc (l *myList) extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    l.arr = append(l.arr, make([]int, l.arrCapacity*(l.extendRatio-1))...)\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    l.arrCapacity = len(l.arr)\n}\n\n/* \u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868 */\nfunc (l *myList) toArray() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    return l.arr[:l.arrSize]\n}\n
    my_list.swift
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: [Int] // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var _capacity: Int // \u5217\u8868\u5bb9\u91cf\n    private var _size: Int // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private let extendRatio: Int // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        _capacity = 10\n        _size = 0\n        extendRatio = 2\n        arr = Array(repeating: 0, count: _capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    func size() -> Int {\n        _size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    func capacity() -> Int {\n        _capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    func get(index: Int) -> Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\u5219\u629b\u51fa\u9519\u8bef\uff0c\u4e0b\u540c\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    func set(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    func add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        arr[size()] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    func insert(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index ..< size()).reversed() {\n            arr[j + 1] = arr[j]\n        }\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    @discardableResult\n    func remove(index: Int) -> Int {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        let num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in index ..< (size() - 1) {\n            arr[j] = arr[j + 1]\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size -= 1\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    func extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr + Array(repeating: 0, count: capacity() * (extendRatio - 1))\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        _capacity = arr.count\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        Array(arr.prefix(size()))\n    }\n}\n
    my_list.js
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    #arr = new Array(); // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    #capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    #size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    #extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#arr = new Array(this.#capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    size() {\n        return this.#size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    capacity() {\n        return this.#capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    get(index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.#arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    set(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.#arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    add(num) {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.#arr[this.#size] = num;\n        this.#size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    insert(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this.#size - 1; j >= index; j--) {\n            this.#arr[j + 1] = this.#arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#arr[index] = num;\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    remove(index) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.#arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this.#size - 1; j++) {\n            this.#arr[j] = this.#arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.#arr = this.#arr.concat(\n            new Array(this.capacity() * (this.#extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this.#capacity = this.#arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    toArray() {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.ts
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private arr: Array<number>; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private _capacity: number = 10; // \u5217\u8868\u5bb9\u91cf\n    private _size: number = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private extendRatio: number = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.arr = new Array(this._capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public size(): number {\n        return this._size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public capacity(): number {\n        return this._capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public get(index: number): number {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public set(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public add(num: number): void {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this._size === this._capacity) this.extendCapacity();\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.arr[this._size] = num;\n        this._size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public insert(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this._size === this._capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this._size - 1; j >= index; j--) {\n            this.arr[j + 1] = this.arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.arr[index] = num;\n        this._size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public remove(index: number): number {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this._size - 1; j++) {\n            this.arr[j] = this.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this._size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public extendCapacity(): void {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.arr = this.arr.concat(\n            new Array(this.capacity() * (this.extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this._capacity = this.arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public toArray(): number[] {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.dart
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  late List<int> _arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n  int _capacity = 10; // \u5217\u8868\u5bb9\u91cf\n  int _size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  int _extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  MyList() {\n    _arr = List.filled(_capacity, 0);\n  }\n\n  /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n  int size() => _size;\n\n  /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n  int capacity() => _capacity;\n\n  /* \u8bbf\u95ee\u5143\u7d20 */\n  int get(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    return _arr[index];\n  }\n\n  /* \u66f4\u65b0\u5143\u7d20 */\n  void set(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    _arr[index] = _num;\n  }\n\n  /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n  void add(int _num) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    _arr[_size] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n  void insert(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (var j = _size - 1; j >= index; j--) {\n      _arr[j + 1] = _arr[j];\n    }\n    _arr[index] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5220\u9664\u5143\u7d20 */\n  int remove(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    int _num = _arr[index];\n    // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (var j = index; j < _size - 1; j++) {\n      _arr[j] = _arr[j + 1];\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size--;\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return _num;\n  }\n\n  /* \u5217\u8868\u6269\u5bb9 */\n  void extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n    final _newNums = List.filled(_capacity * _extendRatio, 0);\n    // \u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    List.copyRange(_newNums, 0, _arr);\n    // \u66f4\u65b0 _arr \u7684\u5f15\u7528\n    _arr = _newNums;\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    _capacity = _arr.length;\n  }\n\n  /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n  List<int> toArray() {\n    List<int> arr = [];\n    for (var i = 0; i < _size; i++) {\n      arr.add(get(i));\n    }\n    return arr;\n  }\n}\n
    my_list.rs
    /* \u5217\u8868\u7c7b */\n#[allow(dead_code)]\nstruct MyList {\n    arr: Vec<i32>,       // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    capacity: usize,     // \u5217\u8868\u5bb9\u91cf\n    size: usize,         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    extend_ratio: usize, // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n}\n\n#[allow(unused, unused_comparisons)]\nimpl MyList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        let mut vec = Vec::new();\n        vec.resize(capacity, 0);\n        Self {\n            arr: vec,\n            capacity,\n            size: 0,\n            extend_ratio: 2,\n        }\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    pub fn size(&self) -> usize {\n        return self.size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        return self.capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    pub fn get(&self, index: usize) -> i32 {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        return self.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    pub fn set(&mut self, index: usize, num: i32) {\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        self.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    pub fn add(&mut self, num: i32) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        self.arr[self.size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    pub fn insert(&mut self, index: usize, num: i32) {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size).rev() {\n            self.arr[j + 1] = self.arr[j];\n        }\n        self.arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    pub fn remove(&mut self, index: usize) -> i32 {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        let num = self.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size - 1) {\n            self.arr[j] = self.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size -= 1;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    pub fn extend_capacity(&mut self) {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        let new_capacity = self.capacity * self.extend_ratio;\n        self.arr.resize(new_capacity, 0);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self.capacity = new_capacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    pub fn to_array(&mut self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut arr = Vec::new();\n        for i in 0..self.size {\n            arr.push(self.get(i));\n        }\n        arr\n    }\n}\n
    my_list.c
    /* \u5217\u8868\u7c7b */\ntypedef struct {\n    int *arr;        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int capacity;    // \u5217\u8868\u5bb9\u91cf\n    int size;        // \u5217\u8868\u5927\u5c0f\n    int extendRatio; // \u5217\u8868\u6bcf\u6b21\u6269\u5bb9\u7684\u500d\u6570\n} MyList;\n\n/* \u6784\u9020\u51fd\u6570 */\nMyList *newMyList() {\n    MyList *nums = malloc(sizeof(MyList));\n    nums->capacity = 10;\n    nums->arr = malloc(sizeof(int) * nums->capacity);\n    nums->size = 0;\n    nums->extendRatio = 2;\n    return nums;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delMyList(MyList *nums) {\n    free(nums->arr);\n    free(nums);\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6 */\nint size(MyList *nums) {\n    return nums->size;\n}\n\n/* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nint capacity(MyList *nums) {\n    return nums->capacity;\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint get(MyList *nums, int index) {\n    assert(index >= 0 && index < nums->size);\n    return nums->arr[index];\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nvoid set(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < nums->size);\n    nums->arr[index] = num;\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nvoid add(MyList *nums, int num) {\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    nums->arr[size(nums)] = num;\n    nums->size++;\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nvoid insert(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < size(nums));\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    for (int i = size(nums); i > index; --i) {\n        nums->arr[i] = nums->arr[i - 1];\n    }\n    nums->arr[index] = num;\n    nums->size++;\n}\n\n/* \u5220\u9664\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nint removeItem(MyList *nums, int index) {\n    assert(index >= 0 && index < size(nums));\n    int num = nums->arr[index];\n    for (int i = index; i < size(nums) - 1; i++) {\n        nums->arr[i] = nums->arr[i + 1];\n    }\n    nums->size--;\n    return num;\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nvoid extendCapacity(MyList *nums) {\n    // \u5148\u5206\u914d\u7a7a\u95f4\n    int newCapacity = capacity(nums) * nums->extendRatio;\n    int *extend = (int *)malloc(sizeof(int) * newCapacity);\n    int *temp = nums->arr;\n\n    // \u62f7\u8d1d\u65e7\u6570\u636e\u5230\u65b0\u6570\u636e\n    for (int i = 0; i < size(nums); i++)\n        extend[i] = nums->arr[i];\n\n    // \u91ca\u653e\u65e7\u6570\u636e\n    free(temp);\n\n    // \u66f4\u65b0\u65b0\u6570\u636e\n    nums->arr = extend;\n    nums->capacity = newCapacity;\n}\n\n/* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Array \u7528\u4e8e\u6253\u5370 */\nint *toArray(MyList *nums) {\n    return nums->arr;\n}\n
    my_list.kt
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: IntArray = intArrayOf() // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var capacity: Int = 10 // \u5217\u8868\u5bb9\u91cf\n    private var size: Int = 0 // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private var extendRatio: Int = 2 // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        arr = IntArray(capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    fun size(): Int {\n        return size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    fun capacity(): Int {\n        return capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    fun get(index: Int): Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    fun set(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    fun add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        arr[size] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    fun insert(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (j in size - 1 downTo index)\n            arr[j + 1] = arr[j]\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    fun remove(index: Int): Int {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        val num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (j in index..<size - 1)\n            arr[j] = arr[j + 1]\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    fun extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr.copyOf(capacity() * extendRatio)\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.size\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        val size = size()\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val arr = IntArray(size)\n        for (i in 0..<size) {\n            arr[i] = get(i)\n        }\n        return arr\n    }\n}\n
    my_list.rb
    ### \u5217\u8868\u7c7b ###\nclass MyList\n  attr_reader :size       # \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  attr_reader :capacity   # \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @capacity = 10\n    @size = 0\n    @extend_ratio = 2\n    @arr = Array.new(capacity)\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def get(index)\n    # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index]\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def set(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index] = num\n  end\n\n  ### \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 ###\n  def add(num)\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n    @arr[size] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 ###\n  def insert(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n\n    # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j in (size - 1).downto(index)\n      @arr[j + 1] = @arr[j]\n    end\n    @arr[index] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5220\u9664\u5143\u7d20 ###\n  def remove(index)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    num = @arr[index]\n\n    # \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j in index...size\n      @arr[j] = @arr[j + 1]\n    end\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size -= 1\n\n    # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    num\n  end\n\n  ### \u5217\u8868\u6269\u5bb9 ###\n  def extend_capacity\n    # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1))\n    # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    @capacity = arr.length\n  end\n\n  ### \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 ###\n  def to_array\n    sz = size\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    arr = Array.new(sz)\n    for i in 0...sz\n      arr[i] = get(i)\n    end\n    arr\n  end\nend\n
    my_list.zig
    // \u5217\u8868\u7c7b\nfn MyList(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        arr: []T = undefined,                        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrCapacity: usize = 10,                     // \u5217\u8868\u5bb9\u91cf\n        numSize: usize = 0,                           // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: usize = 2,                       // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined, // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u5217\u8868\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.arr = try self.mem_allocator.alloc(T, self.arrCapacity);\n            @memset(self.arr, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        pub fn size(self: *Self) usize {\n            return self.numSize;\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.arrCapacity;\n        }\n\n        // \u8bbf\u95ee\u5143\u7d20\n        pub fn get(self: *Self, index: usize) T {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            return self.arr[index];\n        }  \n\n        // \u66f4\u65b0\u5143\u7d20\n        pub fn set(self: *Self, index: usize, num: T) void {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            self.arr[index] = num;\n        }  \n\n        // \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\n        pub fn add(self: *Self, num: T) !void {\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            self.arr[self.size()] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }  \n\n        // \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\n        pub fn insert(self: *Self, index: usize, num: T) !void {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n            var j = self.size() - 1;\n            while (j >= index) : (j -= 1) {\n                self.arr[j + 1] = self.arr[j];\n            }\n            self.arr[index] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }\n\n        // \u5220\u9664\u5143\u7d20\n        pub fn remove(self: *Self, index: usize) T {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            var num = self.arr[index];\n            // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n            var j = index;\n            while (j < self.size() - 1) : (j += 1) {\n                self.arr[j] = self.arr[j + 1];\n            }\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize -= 1;\n            // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n            return num;\n        }\n\n        // \u5217\u8868\u6269\u5bb9\n        pub fn extendCapacity(self: *Self) !void {\n            // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            var newCapacity = self.capacity() * self.extendRatio;\n            var extend = try self.mem_allocator.alloc(T, newCapacity);\n            @memset(extend, @as(T, 0));\n            // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            std.mem.copy(T, extend, self.arr);\n            self.arr = extend;\n            // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n            self.arrCapacity = newCapacity;\n        }\n\n        // \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var arr = try self.mem_allocator.alloc(T, self.size());\n           @memset(arr, @as(T, 0));\n            for (arr, 0..) |*num, i| {\n                num.* = self.get(i);\n            }\n            return arr;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/","title":"4.4 \u00a0 \u5185\u5b58\u4e0e\u7f13\u5b58 *","text":"

    \u5728\u672c\u7ae0\u7684\u524d\u4e24\u8282\u4e2d\uff0c\u6211\u4eec\u63a2\u8ba8\u4e86\u6570\u7ec4\u548c\u94fe\u8868\u8fd9\u4e24\u79cd\u57fa\u7840\u4e14\u91cd\u8981\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5b83\u4eec\u5206\u522b\u4ee3\u8868\u4e86\u201c\u8fde\u7eed\u5b58\u50a8\u201d\u548c\u201c\u5206\u6563\u5b58\u50a8\u201d\u4e24\u79cd\u7269\u7406\u7ed3\u6784\u3002

    \u5b9e\u9645\u4e0a\uff0c\u7269\u7406\u7ed3\u6784\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u51b3\u5b9a\u4e86\u7a0b\u5e8f\u5bf9\u5185\u5b58\u548c\u7f13\u5b58\u7684\u4f7f\u7528\u6548\u7387\uff0c\u8fdb\u800c\u5f71\u54cd\u7b97\u6cd5\u7a0b\u5e8f\u7684\u6574\u4f53\u6027\u80fd\u3002

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#441","title":"4.4.1 \u00a0 \u8ba1\u7b97\u673a\u5b58\u50a8\u8bbe\u5907","text":"

    \u8ba1\u7b97\u673a\u4e2d\u5305\u62ec\u4e09\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\u8bbe\u5907\uff1a\u786c\u76d8\uff08hard disk\uff09\u3001\u5185\u5b58\uff08random-access memory, RAM\uff09\u3001\u7f13\u5b58\uff08cache memory\uff09\u3002\u8868 4-2 \u5c55\u793a\u4e86\u5b83\u4eec\u5728\u8ba1\u7b97\u673a\u7cfb\u7edf\u4e2d\u7684\u4e0d\u540c\u89d2\u8272\u548c\u6027\u80fd\u7279\u70b9\u3002

    \u8868 4-2 \u00a0 \u8ba1\u7b97\u673a\u7684\u5b58\u50a8\u8bbe\u5907

    \u786c\u76d8 \u5185\u5b58 \u7f13\u5b58 \u7528\u9014 \u957f\u671f\u5b58\u50a8\u6570\u636e\uff0c\u5305\u62ec\u64cd\u4f5c\u7cfb\u7edf\u3001\u7a0b\u5e8f\u3001\u6587\u4ef6\u7b49 \u4e34\u65f6\u5b58\u50a8\u5f53\u524d\u8fd0\u884c\u7684\u7a0b\u5e8f\u548c\u6b63\u5728\u5904\u7406\u7684\u6570\u636e \u5b58\u50a8\u7ecf\u5e38\u8bbf\u95ee\u7684\u6570\u636e\u548c\u6307\u4ee4\uff0c\u51cf\u5c11 CPU \u8bbf\u95ee\u5185\u5b58\u7684\u6b21\u6570 \u6613\u5931\u6027 \u65ad\u7535\u540e\u6570\u636e\u4e0d\u4f1a\u4e22\u5931 \u65ad\u7535\u540e\u6570\u636e\u4f1a\u4e22\u5931 \u65ad\u7535\u540e\u6570\u636e\u4f1a\u4e22\u5931 \u5bb9\u91cf \u8f83\u5927\uff0cTB \u7ea7\u522b \u8f83\u5c0f\uff0cGB \u7ea7\u522b \u975e\u5e38\u5c0f\uff0cMB \u7ea7\u522b \u901f\u5ea6 \u8f83\u6162\uff0c\u51e0\u767e\u5230\u51e0\u5343 MB/s \u8f83\u5feb\uff0c\u51e0\u5341 GB/s \u975e\u5e38\u5feb\uff0c\u51e0\u5341\u5230\u51e0\u767e GB/s \u4ef7\u683c \u8f83\u4fbf\u5b9c\uff0c\u51e0\u6bdb\u5230\u51e0\u5143 / GB \u8f83\u8d35\uff0c\u51e0\u5341\u5230\u51e0\u767e\u5143 / GB \u975e\u5e38\u8d35\uff0c\u968f CPU \u6253\u5305\u8ba1\u4ef7

    \u6211\u4eec\u53ef\u4ee5\u5c06\u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf\u60f3\u8c61\u4e3a\u56fe 4-9 \u6240\u793a\u7684\u91d1\u5b57\u5854\u7ed3\u6784\u3002\u8d8a\u9760\u8fd1\u91d1\u5b57\u5854\u9876\u7aef\u7684\u5b58\u50a8\u8bbe\u5907\u7684\u901f\u5ea6\u8d8a\u5feb\u3001\u5bb9\u91cf\u8d8a\u5c0f\u3001\u6210\u672c\u8d8a\u9ad8\u3002\u8fd9\u79cd\u591a\u5c42\u7ea7\u7684\u8bbe\u8ba1\u5e76\u975e\u5076\u7136\uff0c\u800c\u662f\u8ba1\u7b97\u673a\u79d1\u5b66\u5bb6\u548c\u5de5\u7a0b\u5e08\u4eec\u7ecf\u8fc7\u6df1\u601d\u719f\u8651\u7684\u7ed3\u679c\u3002

    • \u786c\u76d8\u96be\u4ee5\u88ab\u5185\u5b58\u53d6\u4ee3\u3002\u9996\u5148\uff0c\u5185\u5b58\u4e2d\u7684\u6570\u636e\u5728\u65ad\u7535\u540e\u4f1a\u4e22\u5931\uff0c\u56e0\u6b64\u5b83\u4e0d\u9002\u5408\u957f\u671f\u5b58\u50a8\u6570\u636e\uff1b\u5176\u6b21\uff0c\u5185\u5b58\u7684\u6210\u672c\u662f\u786c\u76d8\u7684\u51e0\u5341\u500d\uff0c\u8fd9\u4f7f\u5f97\u5b83\u96be\u4ee5\u5728\u6d88\u8d39\u8005\u5e02\u573a\u666e\u53ca\u3002
    • \u7f13\u5b58\u7684\u5927\u5bb9\u91cf\u548c\u9ad8\u901f\u5ea6\u96be\u4ee5\u517c\u5f97\u3002\u968f\u7740 L1\u3001L2\u3001L3 \u7f13\u5b58\u7684\u5bb9\u91cf\u9010\u6b65\u589e\u5927\uff0c\u5176\u7269\u7406\u5c3a\u5bf8\u4f1a\u53d8\u5927\uff0c\u4e0e CPU \u6838\u5fc3\u4e4b\u95f4\u7684\u7269\u7406\u8ddd\u79bb\u4f1a\u53d8\u8fdc\uff0c\u4ece\u800c\u5bfc\u81f4\u6570\u636e\u4f20\u8f93\u65f6\u95f4\u589e\u52a0\uff0c\u5143\u7d20\u8bbf\u95ee\u5ef6\u8fdf\u53d8\u9ad8\u3002\u5728\u5f53\u524d\u6280\u672f\u4e0b\uff0c\u591a\u5c42\u7ea7\u7684\u7f13\u5b58\u7ed3\u6784\u662f\u5bb9\u91cf\u3001\u901f\u5ea6\u548c\u6210\u672c\u4e4b\u95f4\u7684\u6700\u4f73\u5e73\u8861\u70b9\u3002

    \u56fe 4-9 \u00a0 \u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf

    Tip

    \u8ba1\u7b97\u673a\u7684\u5b58\u50a8\u5c42\u6b21\u7ed3\u6784\u4f53\u73b0\u4e86\u901f\u5ea6\u3001\u5bb9\u91cf\u548c\u6210\u672c\u4e09\u8005\u4e4b\u95f4\u7684\u7cbe\u5999\u5e73\u8861\u3002\u5b9e\u9645\u4e0a\uff0c\u8fd9\u79cd\u6743\u8861\u666e\u904d\u5b58\u5728\u4e8e\u6240\u6709\u5de5\u4e1a\u9886\u57df\uff0c\u5b83\u8981\u6c42\u6211\u4eec\u5728\u4e0d\u540c\u7684\u4f18\u52bf\u548c\u9650\u5236\u4e4b\u95f4\u627e\u5230\u6700\u4f73\u5e73\u8861\u70b9\u3002

    \u603b\u7684\u6765\u8bf4\uff0c\u786c\u76d8\u7528\u4e8e\u957f\u671f\u5b58\u50a8\u5927\u91cf\u6570\u636e\uff0c\u5185\u5b58\u7528\u4e8e\u4e34\u65f6\u5b58\u50a8\u7a0b\u5e8f\u8fd0\u884c\u4e2d\u6b63\u5728\u5904\u7406\u7684\u6570\u636e\uff0c\u800c\u7f13\u5b58\u5219\u7528\u4e8e\u5b58\u50a8\u7ecf\u5e38\u8bbf\u95ee\u7684\u6570\u636e\u548c\u6307\u4ee4\uff0c\u4ee5\u63d0\u9ad8\u7a0b\u5e8f\u8fd0\u884c\u6548\u7387\u3002\u4e09\u8005\u5171\u540c\u534f\u4f5c\uff0c\u786e\u4fdd\u8ba1\u7b97\u673a\u7cfb\u7edf\u9ad8\u6548\u8fd0\u884c\u3002

    \u5982\u56fe 4-10 \u6240\u793a\uff0c\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6570\u636e\u4f1a\u4ece\u786c\u76d8\u4e2d\u88ab\u8bfb\u53d6\u5230\u5185\u5b58\u4e2d\uff0c\u4f9b CPU \u8ba1\u7b97\u4f7f\u7528\u3002\u7f13\u5b58\u53ef\u4ee5\u770b\u4f5c CPU \u7684\u4e00\u90e8\u5206\uff0c\u5b83\u901a\u8fc7\u667a\u80fd\u5730\u4ece\u5185\u5b58\u52a0\u8f7d\u6570\u636e\uff0c\u7ed9 CPU \u63d0\u4f9b\u9ad8\u901f\u7684\u6570\u636e\u8bfb\u53d6\uff0c\u4ece\u800c\u663e\u8457\u63d0\u5347\u7a0b\u5e8f\u7684\u6267\u884c\u6548\u7387\uff0c\u51cf\u5c11\u5bf9\u8f83\u6162\u7684\u5185\u5b58\u7684\u4f9d\u8d56\u3002

    \u56fe 4-10 \u00a0 \u786c\u76d8\u3001\u5185\u5b58\u548c\u7f13\u5b58\u4e4b\u95f4\u7684\u6570\u636e\u6d41\u901a

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#442","title":"4.4.2 \u00a0 \u6570\u636e\u7ed3\u6784\u7684\u5185\u5b58\u6548\u7387","text":"

    \u5728\u5185\u5b58\u7a7a\u95f4\u5229\u7528\u65b9\u9762\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u5404\u81ea\u5177\u6709\u4f18\u52bf\u548c\u5c40\u9650\u6027\u3002

    \u4e00\u65b9\u9762\uff0c\u5185\u5b58\u662f\u6709\u9650\u7684\uff0c\u4e14\u540c\u4e00\u5757\u5185\u5b58\u4e0d\u80fd\u88ab\u591a\u4e2a\u7a0b\u5e8f\u5171\u4eab\uff0c\u56e0\u6b64\u6211\u4eec\u5e0c\u671b\u6570\u636e\u7ed3\u6784\u80fd\u591f\u5c3d\u53ef\u80fd\u9ad8\u6548\u5730\u5229\u7528\u7a7a\u95f4\u3002\u6570\u7ec4\u7684\u5143\u7d20\u7d27\u5bc6\u6392\u5217\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u7a7a\u95f4\u6765\u5b58\u50a8\u94fe\u8868\u8282\u70b9\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\uff0c\u56e0\u6b64\u7a7a\u95f4\u6548\u7387\u66f4\u9ad8\u3002\u7136\u800c\uff0c\u6570\u7ec4\u9700\u8981\u4e00\u6b21\u6027\u5206\u914d\u8db3\u591f\u7684\u8fde\u7eed\u5185\u5b58\u7a7a\u95f4\uff0c\u8fd9\u53ef\u80fd\u5bfc\u81f4\u5185\u5b58\u6d6a\u8d39\uff0c\u6570\u7ec4\u6269\u5bb9\u4e5f\u9700\u8981\u989d\u5916\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u6210\u672c\u3002\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u94fe\u8868\u4ee5\u201c\u8282\u70b9\u201d\u4e3a\u5355\u4f4d\u8fdb\u884c\u52a8\u6001\u5185\u5b58\u5206\u914d\u548c\u56de\u6536\uff0c\u63d0\u4f9b\u4e86\u66f4\u5927\u7684\u7075\u6d3b\u6027\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u968f\u7740\u53cd\u590d\u7533\u8bf7\u4e0e\u91ca\u653e\u5185\u5b58\uff0c\u7a7a\u95f2\u5185\u5b58\u7684\u788e\u7247\u5316\u7a0b\u5ea6\u4f1a\u8d8a\u6765\u8d8a\u9ad8\uff0c\u4ece\u800c\u5bfc\u81f4\u5185\u5b58\u7684\u5229\u7528\u6548\u7387\u964d\u4f4e\u3002\u6570\u7ec4\u7531\u4e8e\u5176\u8fde\u7eed\u7684\u5b58\u50a8\u65b9\u5f0f\uff0c\u76f8\u5bf9\u4e0d\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\u3002\u76f8\u53cd\uff0c\u94fe\u8868\u7684\u5143\u7d20\u662f\u5206\u6563\u5b58\u50a8\u7684\uff0c\u5728\u9891\u7e41\u7684\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u4e2d\uff0c\u66f4\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\u3002

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#443","title":"4.4.3 \u00a0 \u6570\u636e\u7ed3\u6784\u7684\u7f13\u5b58\u6548\u7387","text":"

    \u7f13\u5b58\u867d\u7136\u5728\u7a7a\u95f4\u5bb9\u91cf\u4e0a\u8fdc\u5c0f\u4e8e\u5185\u5b58\uff0c\u4f46\u5b83\u6bd4\u5185\u5b58\u5feb\u5f97\u591a\uff0c\u5728\u7a0b\u5e8f\u6267\u884c\u901f\u5ea6\u4e0a\u8d77\u7740\u81f3\u5173\u91cd\u8981\u7684\u4f5c\u7528\u3002\u7531\u4e8e\u7f13\u5b58\u7684\u5bb9\u91cf\u6709\u9650\uff0c\u53ea\u80fd\u5b58\u50a8\u4e00\u5c0f\u90e8\u5206\u9891\u7e41\u8bbf\u95ee\u7684\u6570\u636e\uff0c\u56e0\u6b64\u5f53 CPU \u5c1d\u8bd5\u8bbf\u95ee\u7684\u6570\u636e\u4e0d\u5728\u7f13\u5b58\u4e2d\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u7f13\u5b58\u672a\u547d\u4e2d\uff08cache miss\uff09\uff0c\u6b64\u65f6 CPU \u4e0d\u5f97\u4e0d\u4ece\u901f\u5ea6\u8f83\u6162\u7684\u5185\u5b58\u4e2d\u52a0\u8f7d\u6240\u9700\u6570\u636e\u3002

    \u663e\u7136\uff0c\u201c\u7f13\u5b58\u672a\u547d\u4e2d\u201d\u8d8a\u5c11\uff0cCPU \u8bfb\u5199\u6570\u636e\u7684\u6548\u7387\u5c31\u8d8a\u9ad8\uff0c\u7a0b\u5e8f\u6027\u80fd\u4e5f\u5c31\u8d8a\u597d\u3002\u6211\u4eec\u5c06 CPU \u4ece\u7f13\u5b58\u4e2d\u6210\u529f\u83b7\u53d6\u6570\u636e\u7684\u6bd4\u4f8b\u79f0\u4e3a\u7f13\u5b58\u547d\u4e2d\u7387\uff08cache hit rate\uff09\uff0c\u8fd9\u4e2a\u6307\u6807\u901a\u5e38\u7528\u6765\u8861\u91cf\u7f13\u5b58\u6548\u7387\u3002

    \u4e3a\u4e86\u5c3d\u53ef\u80fd\u8fbe\u5230\u66f4\u9ad8\u7684\u6548\u7387\uff0c\u7f13\u5b58\u4f1a\u91c7\u53d6\u4ee5\u4e0b\u6570\u636e\u52a0\u8f7d\u673a\u5236\u3002

    • \u7f13\u5b58\u884c\uff1a\u7f13\u5b58\u4e0d\u662f\u5355\u4e2a\u5b57\u8282\u5730\u5b58\u50a8\u4e0e\u52a0\u8f7d\u6570\u636e\uff0c\u800c\u662f\u4ee5\u7f13\u5b58\u884c\u4e3a\u5355\u4f4d\u3002\u76f8\u6bd4\u4e8e\u5355\u4e2a\u5b57\u8282\u7684\u4f20\u8f93\uff0c\u7f13\u5b58\u884c\u7684\u4f20\u8f93\u5f62\u5f0f\u66f4\u52a0\u9ad8\u6548\u3002
    • \u9884\u53d6\u673a\u5236\uff1a\u5904\u7406\u5668\u4f1a\u5c1d\u8bd5\u9884\u6d4b\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\uff08\u4f8b\u5982\u987a\u5e8f\u8bbf\u95ee\u3001\u56fa\u5b9a\u6b65\u957f\u8df3\u8dc3\u8bbf\u95ee\u7b49\uff09\uff0c\u5e76\u6839\u636e\u7279\u5b9a\u6a21\u5f0f\u5c06\u6570\u636e\u52a0\u8f7d\u81f3\u7f13\u5b58\u4e4b\u4e2d\uff0c\u4ece\u800c\u63d0\u5347\u547d\u4e2d\u7387\u3002
    • \u7a7a\u95f4\u5c40\u90e8\u6027\uff1a\u5982\u679c\u4e00\u4e2a\u6570\u636e\u88ab\u8bbf\u95ee\uff0c\u90a3\u4e48\u5b83\u9644\u8fd1\u7684\u6570\u636e\u53ef\u80fd\u8fd1\u671f\u4e5f\u4f1a\u88ab\u8bbf\u95ee\u3002\u56e0\u6b64\uff0c\u7f13\u5b58\u5728\u52a0\u8f7d\u67d0\u4e00\u6570\u636e\u65f6\uff0c\u4e5f\u4f1a\u52a0\u8f7d\u5176\u9644\u8fd1\u7684\u6570\u636e\uff0c\u4ee5\u63d0\u9ad8\u547d\u4e2d\u7387\u3002
    • \u65f6\u95f4\u5c40\u90e8\u6027\uff1a\u5982\u679c\u4e00\u4e2a\u6570\u636e\u88ab\u8bbf\u95ee\uff0c\u90a3\u4e48\u5b83\u5728\u4e0d\u4e45\u7684\u5c06\u6765\u5f88\u53ef\u80fd\u518d\u6b21\u88ab\u8bbf\u95ee\u3002\u7f13\u5b58\u5229\u7528\u8fd9\u4e00\u539f\u7406\uff0c\u901a\u8fc7\u4fdd\u7559\u6700\u8fd1\u8bbf\u95ee\u8fc7\u7684\u6570\u636e\u6765\u63d0\u9ad8\u547d\u4e2d\u7387\u3002

    \u5b9e\u9645\u4e0a\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u5bf9\u7f13\u5b58\u7684\u5229\u7528\u6548\u7387\u662f\u4e0d\u540c\u7684\uff0c\u4e3b\u8981\u4f53\u73b0\u5728\u4ee5\u4e0b\u51e0\u4e2a\u65b9\u9762\u3002

    • \u5360\u7528\u7a7a\u95f4\uff1a\u94fe\u8868\u5143\u7d20\u6bd4\u6570\u7ec4\u5143\u7d20\u5360\u7528\u7a7a\u95f4\u66f4\u591a\uff0c\u5bfc\u81f4\u7f13\u5b58\u4e2d\u5bb9\u7eb3\u7684\u6709\u6548\u6570\u636e\u91cf\u66f4\u5c11\u3002
    • \u7f13\u5b58\u884c\uff1a\u94fe\u8868\u6570\u636e\u5206\u6563\u5728\u5185\u5b58\u5404\u5904\uff0c\u800c\u7f13\u5b58\u662f\u201c\u6309\u884c\u52a0\u8f7d\u201d\u7684\uff0c\u56e0\u6b64\u52a0\u8f7d\u5230\u65e0\u6548\u6570\u636e\u7684\u6bd4\u4f8b\u66f4\u9ad8\u3002
    • \u9884\u53d6\u673a\u5236\uff1a\u6570\u7ec4\u6bd4\u94fe\u8868\u7684\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\u66f4\u5177\u201c\u53ef\u9884\u6d4b\u6027\u201d\uff0c\u5373\u7cfb\u7edf\u66f4\u5bb9\u6613\u731c\u51fa\u5373\u5c06\u88ab\u52a0\u8f7d\u7684\u6570\u636e\u3002
    • \u7a7a\u95f4\u5c40\u90e8\u6027\uff1a\u6570\u7ec4\u88ab\u5b58\u50a8\u5728\u96c6\u4e2d\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\uff0c\u56e0\u6b64\u88ab\u52a0\u8f7d\u6570\u636e\u9644\u8fd1\u7684\u6570\u636e\u66f4\u6709\u53ef\u80fd\u5373\u5c06\u88ab\u8bbf\u95ee\u3002

    \u603b\u4f53\u800c\u8a00\uff0c\u6570\u7ec4\u5177\u6709\u66f4\u9ad8\u7684\u7f13\u5b58\u547d\u4e2d\u7387\uff0c\u56e0\u6b64\u5b83\u5728\u64cd\u4f5c\u6548\u7387\u4e0a\u901a\u5e38\u4f18\u4e8e\u94fe\u8868\u3002\u8fd9\u4f7f\u5f97\u5728\u89e3\u51b3\u7b97\u6cd5\u95ee\u9898\u65f6\uff0c\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u5f80\u5f80\u66f4\u53d7\u6b22\u8fce\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u9ad8\u7f13\u5b58\u6548\u7387\u5e76\u4e0d\u610f\u5473\u7740\u6570\u7ec4\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u4f18\u4e8e\u94fe\u8868\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\u9009\u62e9\u54ea\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u5e94\u6839\u636e\u5177\u4f53\u9700\u6c42\u6765\u51b3\u5b9a\u3002\u4f8b\u5982\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u90fd\u53ef\u4ee5\u5b9e\u73b0\u201c\u6808\u201d\u6570\u636e\u7ed3\u6784\uff08\u4e0b\u4e00\u7ae0\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\uff09\uff0c\u4f46\u5b83\u4eec\u9002\u7528\u4e8e\u4e0d\u540c\u573a\u666f\u3002

    • \u5728\u505a\u7b97\u6cd5\u9898\u65f6\uff0c\u6211\u4eec\u4f1a\u503e\u5411\u4e8e\u9009\u62e9\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\uff0c\u56e0\u4e3a\u5b83\u63d0\u4f9b\u4e86\u66f4\u9ad8\u7684\u64cd\u4f5c\u6548\u7387\u548c\u968f\u673a\u8bbf\u95ee\u7684\u80fd\u529b\uff0c\u4ee3\u4ef7\u4ec5\u662f\u9700\u8981\u9884\u5148\u4e3a\u6570\u7ec4\u5206\u914d\u4e00\u5b9a\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    • \u5982\u679c\u6570\u636e\u91cf\u975e\u5e38\u5927\u3001\u52a8\u6001\u6027\u5f88\u9ad8\u3001\u6808\u7684\u9884\u671f\u5927\u5c0f\u96be\u4ee5\u4f30\u8ba1\uff0c\u90a3\u4e48\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\u66f4\u52a0\u5408\u9002\u3002\u94fe\u8868\u80fd\u591f\u5c06\u5927\u91cf\u6570\u636e\u5206\u6563\u5b58\u50a8\u4e8e\u5185\u5b58\u7684\u4e0d\u540c\u90e8\u5206\uff0c\u5e76\u4e14\u907f\u514d\u4e86\u6570\u7ec4\u6269\u5bb9\u4ea7\u751f\u7684\u989d\u5916\u5f00\u9500\u3002
    "},{"location":"chapter_array_and_linkedlist/summary/","title":"4.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_array_and_linkedlist/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u6570\u7ec4\u548c\u94fe\u8868\u662f\u4e24\u79cd\u57fa\u672c\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5206\u522b\u4ee3\u8868\u6570\u636e\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u7684\u4e24\u79cd\u5b58\u50a8\u65b9\u5f0f\uff1a\u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\u548c\u5206\u6563\u7a7a\u95f4\u5b58\u50a8\u3002\u4e24\u8005\u7684\u7279\u70b9\u5448\u73b0\u51fa\u4e92\u8865\u7684\u7279\u6027\u3002
    • \u6570\u7ec4\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3001\u5360\u7528\u5185\u5b58\u8f83\u5c11\uff1b\u4f46\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u6548\u7387\u4f4e\uff0c\u4e14\u521d\u59cb\u5316\u540e\u957f\u5ea6\u4e0d\u53ef\u53d8\u3002
    • \u94fe\u8868\u901a\u8fc7\u66f4\u6539\u5f15\u7528\uff08\u6307\u9488\uff09\u5b9e\u73b0\u9ad8\u6548\u7684\u8282\u70b9\u63d2\u5165\u4e0e\u5220\u9664\uff0c\u4e14\u53ef\u4ee5\u7075\u6d3b\u8c03\u6574\u957f\u5ea6\uff1b\u4f46\u8282\u70b9\u8bbf\u95ee\u6548\u7387\u4f4e\u3001\u5360\u7528\u5185\u5b58\u8f83\u591a\u3002\u5e38\u89c1\u7684\u94fe\u8868\u7c7b\u578b\u5305\u62ec\u5355\u5411\u94fe\u8868\u3001\u73af\u5f62\u94fe\u8868\u3001\u53cc\u5411\u94fe\u8868\u3002
    • \u5217\u8868\u662f\u4e00\u79cd\u652f\u6301\u589e\u5220\u67e5\u6539\u7684\u5143\u7d20\u6709\u5e8f\u96c6\u5408\uff0c\u901a\u5e38\u57fa\u4e8e\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u3002\u5b83\u4fdd\u7559\u4e86\u6570\u7ec4\u7684\u4f18\u52bf\uff0c\u540c\u65f6\u53ef\u4ee5\u7075\u6d3b\u8c03\u6574\u957f\u5ea6\u3002
    • \u5217\u8868\u7684\u51fa\u73b0\u5927\u5e45\u63d0\u9ad8\u4e86\u6570\u7ec4\u7684\u5b9e\u7528\u6027\uff0c\u4f46\u53ef\u80fd\u5bfc\u81f4\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u3002
    • \u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6570\u636e\u4e3b\u8981\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\u3002\u6570\u7ec4\u53ef\u63d0\u4f9b\u66f4\u9ad8\u7684\u5185\u5b58\u7a7a\u95f4\u6548\u7387\uff0c\u800c\u94fe\u8868\u5219\u5728\u5185\u5b58\u4f7f\u7528\u4e0a\u66f4\u52a0\u7075\u6d3b\u3002
    • \u7f13\u5b58\u901a\u8fc7\u7f13\u5b58\u884c\u3001\u9884\u53d6\u673a\u5236\u4ee5\u53ca\u7a7a\u95f4\u5c40\u90e8\u6027\u548c\u65f6\u95f4\u5c40\u90e8\u6027\u7b49\u6570\u636e\u52a0\u8f7d\u673a\u5236\uff0c\u4e3a CPU \u63d0\u4f9b\u5feb\u901f\u6570\u636e\u8bbf\u95ee\uff0c\u663e\u8457\u63d0\u5347\u7a0b\u5e8f\u7684\u6267\u884c\u6548\u7387\u3002
    • \u7531\u4e8e\u6570\u7ec4\u5177\u6709\u66f4\u9ad8\u7684\u7f13\u5b58\u547d\u4e2d\u7387\uff0c\u56e0\u6b64\u5b83\u901a\u5e38\u6bd4\u94fe\u8868\u66f4\u9ad8\u6548\u3002\u5728\u9009\u62e9\u6570\u636e\u7ed3\u6784\u65f6\uff0c\u5e94\u6839\u636e\u5177\u4f53\u9700\u6c42\u548c\u573a\u666f\u505a\u51fa\u6070\u5f53\u9009\u62e9\u3002
    "},{"location":"chapter_array_and_linkedlist/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6570\u7ec4\u5b58\u50a8\u5728\u6808\u4e0a\u548c\u5b58\u50a8\u5728\u5806\u4e0a\uff0c\u5bf9\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u662f\u5426\u6709\u5f71\u54cd\uff1f

    \u5b58\u50a8\u5728\u6808\u4e0a\u548c\u5806\u4e0a\u7684\u6570\u7ec4\u90fd\u88ab\u5b58\u50a8\u5728\u8fde\u7eed\u5185\u5b58\u7a7a\u95f4\u5185\uff0c\u6570\u636e\u64cd\u4f5c\u6548\u7387\u57fa\u672c\u4e00\u81f4\u3002\u7136\u800c\uff0c\u6808\u548c\u5806\u5177\u6709\u5404\u81ea\u7684\u7279\u70b9\uff0c\u4ece\u800c\u5bfc\u81f4\u4ee5\u4e0b\u4e0d\u540c\u70b9\u3002

    1. \u5206\u914d\u548c\u91ca\u653e\u6548\u7387\uff1a\u6808\u662f\u4e00\u5757\u8f83\u5c0f\u7684\u5185\u5b58\uff0c\u5206\u914d\u7531\u7f16\u8bd1\u5668\u81ea\u52a8\u5b8c\u6210\uff1b\u800c\u5806\u5185\u5b58\u76f8\u5bf9\u66f4\u5927\uff0c\u53ef\u4ee5\u5728\u4ee3\u7801\u4e2d\u52a8\u6001\u5206\u914d\uff0c\u66f4\u5bb9\u6613\u788e\u7247\u5316\u3002\u56e0\u6b64\uff0c\u5806\u4e0a\u7684\u5206\u914d\u548c\u91ca\u653e\u64cd\u4f5c\u901a\u5e38\u6bd4\u6808\u4e0a\u7684\u6162\u3002
    2. \u5927\u5c0f\u9650\u5236\uff1a\u6808\u5185\u5b58\u76f8\u5bf9\u8f83\u5c0f\uff0c\u5806\u7684\u5927\u5c0f\u4e00\u822c\u53d7\u9650\u4e8e\u53ef\u7528\u5185\u5b58\u3002\u56e0\u6b64\u5806\u66f4\u52a0\u9002\u5408\u5b58\u50a8\u5927\u578b\u6570\u7ec4\u3002
    3. \u7075\u6d3b\u6027\uff1a\u6808\u4e0a\u7684\u6570\u7ec4\u7684\u5927\u5c0f\u9700\u8981\u5728\u7f16\u8bd1\u65f6\u786e\u5b9a\uff0c\u800c\u5806\u4e0a\u7684\u6570\u7ec4\u7684\u5927\u5c0f\u53ef\u4ee5\u5728\u8fd0\u884c\u65f6\u52a8\u6001\u786e\u5b9a\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u6570\u7ec4\u8981\u6c42\u76f8\u540c\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u800c\u5728\u94fe\u8868\u4e2d\u5374\u6ca1\u6709\u5f3a\u8c03\u76f8\u540c\u7c7b\u578b\u5462\uff1f

    \u94fe\u8868\u7531\u8282\u70b9\u7ec4\u6210\uff0c\u8282\u70b9\u4e4b\u95f4\u901a\u8fc7\u5f15\u7528\uff08\u6307\u9488\uff09\u8fde\u63a5\uff0c\u5404\u4e2a\u8282\u70b9\u53ef\u4ee5\u5b58\u50a8\u4e0d\u540c\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f8b\u5982 int\u3001double\u3001string\u3001object \u7b49\u3002

    \u76f8\u5bf9\u5730\uff0c\u6570\u7ec4\u5143\u7d20\u5219\u5fc5\u987b\u662f\u76f8\u540c\u7c7b\u578b\u7684\uff0c\u8fd9\u6837\u624d\u80fd\u901a\u8fc7\u8ba1\u7b97\u504f\u79fb\u91cf\u6765\u83b7\u53d6\u5bf9\u5e94\u5143\u7d20\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u6570\u7ec4\u540c\u65f6\u5305\u542b int \u548c long \u4e24\u79cd\u7c7b\u578b\uff0c\u5355\u4e2a\u5143\u7d20\u5206\u522b\u5360\u7528 4 \u5b57\u8282 \u548c 8 \u5b57\u8282 \uff0c\u6b64\u65f6\u5c31\u4e0d\u80fd\u7528\u4ee5\u4e0b\u516c\u5f0f\u8ba1\u7b97\u504f\u79fb\u91cf\u4e86\uff0c\u56e0\u4e3a\u6570\u7ec4\u4e2d\u5305\u542b\u4e86\u4e24\u79cd\u201c\u5143\u7d20\u957f\u5ea6\u201d\u3002

    # \u5143\u7d20\u5185\u5b58\u5730\u5740 = \u6570\u7ec4\u5185\u5b58\u5730\u5740\uff08\u9996\u5143\u7d20\u5185\u5b58\u5730\u5740\uff09 + \u5143\u7d20\u957f\u5ea6 * \u5143\u7d20\u7d22\u5f15\n

    Q\uff1a\u5220\u9664\u8282\u70b9 P \u540e\uff0c\u662f\u5426\u9700\u8981\u628a P.next \u8bbe\u4e3a None \u5462\uff1f

    \u4e0d\u4fee\u6539 P.next \u4e5f\u53ef\u4ee5\u3002\u4ece\u8be5\u94fe\u8868\u7684\u89d2\u5ea6\u770b\uff0c\u4ece\u5934\u8282\u70b9\u904d\u5386\u5230\u5c3e\u8282\u70b9\u5df2\u7ecf\u4e0d\u4f1a\u9047\u5230 P \u4e86\u3002\u8fd9\u610f\u5473\u7740\u8282\u70b9 P \u5df2\u7ecf\u4ece\u94fe\u8868\u4e2d\u5220\u9664\u4e86\uff0c\u6b64\u65f6\u8282\u70b9 P \u6307\u5411\u54ea\u91cc\u90fd\u4e0d\u4f1a\u5bf9\u8be5\u94fe\u8868\u4ea7\u751f\u5f71\u54cd\u3002

    \u4ece\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\uff08\u505a\u9898\uff09\u7684\u89d2\u5ea6\u770b\uff0c\u4e0d\u65ad\u5f00\u6ca1\u6709\u5173\u7cfb\uff0c\u53ea\u8981\u4fdd\u8bc1\u7a0b\u5e8f\u7684\u903b\u8f91\u662f\u6b63\u786e\u7684\u5c31\u884c\u3002\u4ece\u6807\u51c6\u5e93\u7684\u89d2\u5ea6\u770b\uff0c\u65ad\u5f00\u66f4\u52a0\u5b89\u5168\u3001\u903b\u8f91\u66f4\u52a0\u6e05\u6670\u3002\u5982\u679c\u4e0d\u65ad\u5f00\uff0c\u5047\u8bbe\u88ab\u5220\u9664\u8282\u70b9\u672a\u88ab\u6b63\u5e38\u56de\u6536\uff0c\u90a3\u4e48\u5b83\u4f1a\u5f71\u54cd\u540e\u7ee7\u8282\u70b9\u7684\u5185\u5b58\u56de\u6536\u3002

    Q\uff1a\u5728\u94fe\u8868\u4e2d\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u3002\u4f46\u662f\u589e\u5220\u4e4b\u524d\u90fd\u9700\u8981 \\(O(n)\\) \u7684\u65f6\u95f4\u67e5\u627e\u5143\u7d20\uff0c\u90a3\u4e3a\u4ec0\u4e48\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u662f \\(O(n)\\) \u5462\uff1f

    \u5982\u679c\u662f\u5148\u67e5\u627e\u5143\u7d20\u3001\u518d\u5220\u9664\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u786e\u5b9e\u662f \\(O(n)\\) \u3002\u7136\u800c\uff0c\u94fe\u8868\u7684 \\(O(1)\\) \u589e\u5220\u7684\u4f18\u52bf\u53ef\u4ee5\u5728\u5176\u4ed6\u5e94\u7528\u4e0a\u5f97\u5230\u4f53\u73b0\u3002\u4f8b\u5982\uff0c\u53cc\u5411\u961f\u5217\u9002\u5408\u4f7f\u7528\u94fe\u8868\u5b9e\u73b0\uff0c\u6211\u4eec\u7ef4\u62a4\u4e00\u4e2a\u6307\u9488\u53d8\u91cf\u59cb\u7ec8\u6307\u5411\u5934\u8282\u70b9\u3001\u5c3e\u8282\u70b9\uff0c\u6bcf\u6b21\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u90fd\u662f \\(O(1)\\) \u3002

    Q\uff1a\u56fe\u201c\u94fe\u8868\u5b9a\u4e49\u4e0e\u5b58\u50a8\u65b9\u5f0f\u201d\u4e2d\uff0c\u6d45\u84dd\u8272\u7684\u5b58\u50a8\u8282\u70b9\u6307\u9488\u662f\u5360\u7528\u4e00\u5757\u5185\u5b58\u5730\u5740\u5417\uff1f\u8fd8\u662f\u548c\u8282\u70b9\u503c\u5404\u5360\u4e00\u534a\u5462\uff1f

    \u8be5\u793a\u610f\u56fe\u53ea\u662f\u5b9a\u6027\u8868\u793a\uff0c\u5b9a\u91cf\u8868\u793a\u9700\u8981\u6839\u636e\u5177\u4f53\u60c5\u51b5\u8fdb\u884c\u5206\u6790\u3002

    • \u4e0d\u540c\u7c7b\u578b\u7684\u8282\u70b9\u503c\u5360\u7528\u7684\u7a7a\u95f4\u662f\u4e0d\u540c\u7684\uff0c\u6bd4\u5982 int\u3001long\u3001double \u548c\u5b9e\u4f8b\u5bf9\u8c61\u7b49\u3002
    • \u6307\u9488\u53d8\u91cf\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u5927\u5c0f\u6839\u636e\u6240\u4f7f\u7528\u7684\u64cd\u4f5c\u7cfb\u7edf\u53ca\u7f16\u8bd1\u73af\u5883\u800c\u5b9a\uff0c\u5927\u591a\u4e3a 8 \u5b57\u8282\u6216 4 \u5b57\u8282\u3002

    Q\uff1a\u5728\u5217\u8868\u672b\u5c3e\u6dfb\u52a0\u5143\u7d20\u662f\u5426\u65f6\u65f6\u523b\u523b\u90fd\u4e3a \\(O(1)\\) \uff1f

    \u5982\u679c\u6dfb\u52a0\u5143\u7d20\u65f6\u8d85\u51fa\u5217\u8868\u957f\u5ea6\uff0c\u5219\u9700\u8981\u5148\u6269\u5bb9\u5217\u8868\u518d\u6dfb\u52a0\u3002\u7cfb\u7edf\u4f1a\u7533\u8bf7\u4e00\u5757\u65b0\u7684\u5185\u5b58\uff0c\u5e76\u5c06\u539f\u5217\u8868\u7684\u6240\u6709\u5143\u7d20\u642c\u8fd0\u8fc7\u53bb\uff0c\u8fd9\u65f6\u5019\u65f6\u95f4\u590d\u6742\u5ea6\u5c31\u4f1a\u662f \\(O(n)\\) \u3002

    Q\uff1a\u201c\u5217\u8868\u7684\u51fa\u73b0\u6781\u5927\u5730\u63d0\u9ad8\u4e86\u6570\u7ec4\u7684\u5b9e\u7528\u6027\uff0c\u4f46\u53ef\u80fd\u5bfc\u81f4\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u201d\uff0c\u8fd9\u91cc\u7684\u7a7a\u95f4\u6d6a\u8d39\u662f\u6307\u989d\u5916\u589e\u52a0\u7684\u53d8\u91cf\u5982\u5bb9\u91cf\u3001\u957f\u5ea6\u3001\u6269\u5bb9\u500d\u6570\u6240\u5360\u7684\u5185\u5b58\u5417\uff1f

    \u8fd9\u91cc\u7684\u7a7a\u95f4\u6d6a\u8d39\u4e3b\u8981\u6709\u4e24\u65b9\u9762\u542b\u4e49\uff1a\u4e00\u65b9\u9762\uff0c\u5217\u8868\u90fd\u4f1a\u8bbe\u5b9a\u4e00\u4e2a\u521d\u59cb\u957f\u5ea6\uff0c\u6211\u4eec\u4e0d\u4e00\u5b9a\u9700\u8981\u7528\u8fd9\u4e48\u591a\uff1b\u53e6\u4e00\u65b9\u9762\uff0c\u4e3a\u4e86\u9632\u6b62\u9891\u7e41\u6269\u5bb9\uff0c\u6269\u5bb9\u4e00\u822c\u4f1a\u4e58\u4ee5\u4e00\u4e2a\u7cfb\u6570\uff0c\u6bd4\u5982 \\(\\times 1.5\\) \u3002\u8fd9\u6837\u4e00\u6765\uff0c\u4e5f\u4f1a\u51fa\u73b0\u5f88\u591a\u7a7a\u4f4d\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u80fd\u5b8c\u5168\u586b\u6ee1\u5b83\u4eec\u3002

    Q\uff1a\u5728 Python \u4e2d\u521d\u59cb\u5316 n = [1, 2, 3] \u540e\uff0c\u8fd9 3 \u4e2a\u5143\u7d20\u7684\u5730\u5740\u662f\u76f8\u8fde\u7684\uff0c\u4f46\u662f\u521d\u59cb\u5316 m = [2, 1, 3] \u4f1a\u53d1\u73b0\u5b83\u4eec\u6bcf\u4e2a\u5143\u7d20\u7684 id \u5e76\u4e0d\u662f\u8fde\u7eed\u7684\uff0c\u800c\u662f\u5206\u522b\u8ddf n \u4e2d\u7684\u76f8\u540c\u3002\u8fd9\u4e9b\u5143\u7d20\u7684\u5730\u5740\u4e0d\u8fde\u7eed\uff0c\u90a3\u4e48 m \u8fd8\u662f\u6570\u7ec4\u5417\uff1f

    \u5047\u5982\u628a\u5217\u8868\u5143\u7d20\u6362\u6210\u94fe\u8868\u8282\u70b9 n = [n1, n2, n3, n4, n5] \uff0c\u901a\u5e38\u60c5\u51b5\u4e0b\u8fd9 5 \u4e2a\u8282\u70b9\u5bf9\u8c61\u4e5f\u5206\u6563\u5b58\u50a8\u5728\u5185\u5b58\u5404\u5904\u3002\u7136\u800c\uff0c\u7ed9\u5b9a\u4e00\u4e2a\u5217\u8868\u7d22\u5f15\uff0c\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u83b7\u53d6\u8282\u70b9\u5185\u5b58\u5730\u5740\uff0c\u4ece\u800c\u8bbf\u95ee\u5230\u5bf9\u5e94\u7684\u8282\u70b9\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u4e2d\u5b58\u50a8\u7684\u662f\u8282\u70b9\u7684\u5f15\u7528\uff0c\u800c\u975e\u8282\u70b9\u672c\u8eab\u3002

    \u4e0e\u8bb8\u591a\u8bed\u8a00\u4e0d\u540c\uff0cPython \u4e2d\u7684\u6570\u5b57\u4e5f\u88ab\u5305\u88c5\u4e3a\u5bf9\u8c61\uff0c\u5217\u8868\u4e2d\u5b58\u50a8\u7684\u4e0d\u662f\u6570\u5b57\u672c\u8eab\uff0c\u800c\u662f\u5bf9\u6570\u5b57\u7684\u5f15\u7528\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u4f1a\u53d1\u73b0\u4e24\u4e2a\u6570\u7ec4\u4e2d\u7684\u76f8\u540c\u6570\u5b57\u62e5\u6709\u540c\u4e00\u4e2a id \uff0c\u5e76\u4e14\u8fd9\u4e9b\u6570\u5b57\u7684\u5185\u5b58\u5730\u5740\u65e0\u987b\u8fde\u7eed\u3002

    Q\uff1aC++ STL \u91cc\u9762\u7684 std::list \u5df2\u7ecf\u5b9e\u73b0\u4e86\u53cc\u5411\u94fe\u8868\uff0c\u4f46\u597d\u50cf\u4e00\u4e9b\u7b97\u6cd5\u4e66\u4e0a\u4e0d\u600e\u4e48\u76f4\u63a5\u4f7f\u7528\u5b83\uff0c\u662f\u4e0d\u662f\u56e0\u4e3a\u6709\u4ec0\u4e48\u5c40\u9650\u6027\u5462\uff1f

    \u4e00\u65b9\u9762\uff0c\u6211\u4eec\u5f80\u5f80\u66f4\u9752\u7750\u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\u7b97\u6cd5\uff0c\u800c\u53ea\u5728\u5fc5\u8981\u65f6\u624d\u4f7f\u7528\u94fe\u8868\uff0c\u4e3b\u8981\u6709\u4e24\u4e2a\u539f\u56e0\u3002

    • \u7a7a\u95f4\u5f00\u9500\uff1a\u7531\u4e8e\u6bcf\u4e2a\u5143\u7d20\u9700\u8981\u4e24\u4e2a\u989d\u5916\u7684\u6307\u9488\uff08\u4e00\u4e2a\u7528\u4e8e\u524d\u4e00\u4e2a\u5143\u7d20\uff0c\u4e00\u4e2a\u7528\u4e8e\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u6240\u4ee5 std::list \u901a\u5e38\u6bd4 std::vector \u66f4\u5360\u7528\u7a7a\u95f4\u3002
    • \u7f13\u5b58\u4e0d\u53cb\u597d\uff1a\u7531\u4e8e\u6570\u636e\u4e0d\u662f\u8fde\u7eed\u5b58\u653e\u7684\uff0c\u56e0\u6b64 std::list \u5bf9\u7f13\u5b58\u7684\u5229\u7528\u7387\u8f83\u4f4e\u3002\u4e00\u822c\u60c5\u51b5\u4e0b\uff0cstd::vector \u7684\u6027\u80fd\u4f1a\u66f4\u597d\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5fc5\u8981\u4f7f\u7528\u94fe\u8868\u7684\u60c5\u51b5\u4e3b\u8981\u662f\u4e8c\u53c9\u6811\u548c\u56fe\u3002\u6808\u548c\u961f\u5217\u5f80\u5f80\u4f1a\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u7684 stack \u548c queue \uff0c\u800c\u975e\u94fe\u8868\u3002

    Q\uff1a\u521d\u59cb\u5316\u5217\u8868 res = [0] * self.size() \u64cd\u4f5c\uff0c\u4f1a\u5bfc\u81f4 res \u7684\u6bcf\u4e2a\u5143\u7d20\u5f15\u7528\u76f8\u540c\u7684\u5730\u5740\u5417\uff1f

    \u4e0d\u4f1a\u3002\u4f46\u4e8c\u7ef4\u6570\u7ec4\u4f1a\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u4f8b\u5982\u521d\u59cb\u5316\u4e8c\u7ef4\u5217\u8868 res = [[0] * self.size()] \uff0c\u5219\u591a\u6b21\u5f15\u7528\u4e86\u540c\u4e00\u4e2a\u5217\u8868 [0] \u3002

    "},{"location":"chapter_backtracking/","title":"\u7b2c 13 \u7ae0 \u00a0 \u56de\u6eaf","text":"

    Abstract

    \u6211\u4eec\u5982\u540c\u8ff7\u5bab\u4e2d\u7684\u63a2\u7d22\u8005\uff0c\u5728\u524d\u8fdb\u7684\u9053\u8def\u4e0a\u53ef\u80fd\u4f1a\u9047\u5230\u56f0\u96be\u3002

    \u56de\u6eaf\u7684\u529b\u91cf\u8ba9\u6211\u4eec\u80fd\u591f\u91cd\u65b0\u5f00\u59cb\uff0c\u4e0d\u65ad\u5c1d\u8bd5\uff0c\u6700\u7ec8\u627e\u5230\u901a\u5f80\u5149\u660e\u7684\u51fa\u53e3\u3002

    "},{"location":"chapter_backtracking/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 13.1 \u00a0 \u56de\u6eaf\u7b97\u6cd5
    • 13.2 \u00a0 \u5168\u6392\u5217\u95ee\u9898
    • 13.3 \u00a0 \u5b50\u96c6\u548c\u95ee\u9898
    • 13.4 \u00a0 N \u7687\u540e\u95ee\u9898
    • 13.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_backtracking/backtracking_algorithm/","title":"13.1 \u00a0 \u56de\u6eaf\u7b97\u6cd5","text":"

    \u56de\u6eaf\u7b97\u6cd5\uff08backtracking algorithm\uff09\u662f\u4e00\u79cd\u901a\u8fc7\u7a77\u4e3e\u6765\u89e3\u51b3\u95ee\u9898\u7684\u65b9\u6cd5\uff0c\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f\u4ece\u4e00\u4e2a\u521d\u59cb\u72b6\u6001\u51fa\u53d1\uff0c\u66b4\u529b\u641c\u7d22\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u5f53\u9047\u5230\u6b63\u786e\u7684\u89e3\u5219\u5c06\u5176\u8bb0\u5f55\uff0c\u76f4\u5230\u627e\u5230\u89e3\u6216\u8005\u5c1d\u8bd5\u4e86\u6240\u6709\u53ef\u80fd\u7684\u9009\u62e9\u90fd\u65e0\u6cd5\u627e\u5230\u89e3\u4e3a\u6b62\u3002

    \u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u91c7\u7528\u201c\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u201d\u6765\u904d\u5386\u89e3\u7a7a\u95f4\u3002\u5728\u201c\u4e8c\u53c9\u6811\u201d\u7ae0\u8282\u4e2d\uff0c\u6211\u4eec\u63d0\u5230\u524d\u5e8f\u3001\u4e2d\u5e8f\u548c\u540e\u5e8f\u904d\u5386\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5229\u7528\u524d\u5e8f\u904d\u5386\u6784\u9020\u4e00\u4e2a\u56de\u6eaf\u95ee\u9898\uff0c\u9010\u6b65\u4e86\u89e3\u56de\u6eaf\u7b97\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u3002

    \u4f8b\u9898\u4e00

    \u7ed9\u5b9a\u4e00\u68f5\u4e8c\u53c9\u6811\uff0c\u641c\u7d22\u5e76\u8bb0\u5f55\u6240\u6709\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\uff0c\u8bf7\u8fd4\u56de\u8282\u70b9\u5217\u8868\u3002

    \u5bf9\u4e8e\u6b64\u9898\uff0c\u6211\u4eec\u524d\u5e8f\u904d\u5386\u8fd9\u68f5\u6811\uff0c\u5e76\u5224\u65ad\u5f53\u524d\u8282\u70b9\u7684\u503c\u662f\u5426\u4e3a \\(7\\) \uff0c\u82e5\u662f\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u7684\u503c\u52a0\u5165\u7ed3\u679c\u5217\u8868 res \u4e4b\u4e2d\u3002\u76f8\u5173\u8fc7\u7a0b\u5b9e\u73b0\u5982\u56fe 13-1 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_i_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00\"\"\"\n    if root is None:\n        return\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(root)\n    pre_order(root.left)\n    pre_order(root.right)\n
    preorder_traversal_i_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr) {\n        return;\n    }\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(root);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n}\n
    preorder_traversal_i_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode root) {\n    if (root == null) {\n        return;\n    }\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(root);\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n}\n
    preorder_traversal_i_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) {\n        return;\n    }\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(root);\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n
    preorder_traversal_i_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunc preOrderI(root *TreeNode, res *[]*TreeNode) {\n    if root == nil {\n        return\n    }\n    if (root.Val).(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, root)\n    }\n    preOrderI(root.Left, res)\n    preOrderI(root.Right, res)\n}\n
    preorder_traversal_i_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(root)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n
    preorder_traversal_i_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunction preOrder(root, res) {\n    if (root === null) {\n        return;\n    }\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push(root);\n    }\n    preOrder(root.left, res);\n    preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunction preOrder(root: TreeNode | null, res: TreeNode[]): void {\n    if (root === null) {\n        return;\n    }\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push(root);\n    }\n    preOrder(root.left, res);\n    preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode? root, List<TreeNode> res) {\n  if (root == null) {\n    return;\n  }\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(root);\n  }\n  preOrder(root.left, res);\n  preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfn pre_order(res: &mut Vec<Rc<RefCell<TreeNode>>>, root: Option<Rc<RefCell<TreeNode>>>) {\n    if root.is_none() {\n        return;\n    }\n    if let Some(node) = root {\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(node.clone());\n        }\n        pre_order(res, node.borrow().left.clone());\n        pre_order(res, node.borrow().right.clone());\n    }\n}\n
    preorder_traversal_i_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode *root) {\n    if (root == NULL) {\n        return;\n    }\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res[resSize++] = root;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n}\n
    preorder_traversal_i_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) {\n        return\n    }\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(root)\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n}\n
    preorder_traversal_i_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_i_compact.zig
    [class]{}-[func]{preOrder}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 13-1 \u00a0 \u5728\u524d\u5e8f\u904d\u5386\u4e2d\u641c\u7d22\u8282\u70b9

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1311","title":"13.1.1 \u00a0 \u5c1d\u8bd5\u4e0e\u56de\u9000","text":"

    \u4e4b\u6240\u4ee5\u79f0\u4e4b\u4e3a\u56de\u6eaf\u7b97\u6cd5\uff0c\u662f\u56e0\u4e3a\u8be5\u7b97\u6cd5\u5728\u641c\u7d22\u89e3\u7a7a\u95f4\u65f6\u4f1a\u91c7\u7528\u201c\u5c1d\u8bd5\u201d\u4e0e\u201c\u56de\u9000\u201d\u7684\u7b56\u7565\u3002\u5f53\u7b97\u6cd5\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u9047\u5230\u67d0\u4e2a\u72b6\u6001\u65e0\u6cd5\u7ee7\u7eed\u524d\u8fdb\u6216\u65e0\u6cd5\u5f97\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u89e3\u65f6\uff0c\u5b83\u4f1a\u64a4\u9500\u4e0a\u4e00\u6b65\u7684\u9009\u62e9\uff0c\u9000\u56de\u5230\u4e4b\u524d\u7684\u72b6\u6001\uff0c\u5e76\u5c1d\u8bd5\u5176\u4ed6\u53ef\u80fd\u7684\u9009\u62e9\u3002

    \u5bf9\u4e8e\u4f8b\u9898\u4e00\uff0c\u8bbf\u95ee\u6bcf\u4e2a\u8282\u70b9\u90fd\u4ee3\u8868\u4e00\u6b21\u201c\u5c1d\u8bd5\u201d\uff0c\u800c\u8d8a\u8fc7\u53f6\u8282\u70b9\u6216\u8fd4\u56de\u7236\u8282\u70b9\u7684 return \u5219\u8868\u793a\u201c\u56de\u9000\u201d\u3002

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u56de\u9000\u5e76\u4e0d\u4ec5\u4ec5\u5305\u62ec\u51fd\u6570\u8fd4\u56de\u3002\u4e3a\u89e3\u91ca\u8fd9\u4e00\u70b9\uff0c\u6211\u4eec\u5bf9\u4f8b\u9898\u4e00\u7a0d\u4f5c\u62d3\u5c55\u3002

    \u4f8b\u9898\u4e8c

    \u5728\u4e8c\u53c9\u6811\u4e2d\u641c\u7d22\u6240\u6709\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\uff0c\u8bf7\u8fd4\u56de\u6839\u8282\u70b9\u5230\u8fd9\u4e9b\u8282\u70b9\u7684\u8def\u5f84\u3002

    \u5728\u4f8b\u9898\u4e00\u4ee3\u7801\u7684\u57fa\u7840\u4e0a\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u5217\u8868 path \u8bb0\u5f55\u8bbf\u95ee\u8fc7\u7684\u8282\u70b9\u8def\u5f84\u3002\u5f53\u8bbf\u95ee\u5230\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\u65f6\uff0c\u5219\u590d\u5236 path \u5e76\u6dfb\u52a0\u8fdb\u7ed3\u679c\u5217\u8868 res \u3002\u904d\u5386\u5b8c\u6210\u540e\uff0cres \u4e2d\u4fdd\u5b58\u7684\u5c31\u662f\u6240\u6709\u7684\u89e3\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_ii_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c\"\"\"\n    if root is None:\n        return\n    # \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(list(path))\n    pre_order(root.left)\n    pre_order(root.right)\n    # \u56de\u9000\n    path.pop()\n
    preorder_traversal_ii_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push_back(root);\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(path);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    path.pop_back();\n}\n
    preorder_traversal_ii_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode root) {\n    if (root == null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(new ArrayList<>(path));\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n    // \u56de\u9000\n    path.remove(path.size() - 1);\n}\n
    preorder_traversal_ii_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.Add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(new List<TreeNode>(path));\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n    // \u56de\u9000\n    path.RemoveAt(path.Count - 1);\n}\n
    preorder_traversal_ii_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunc preOrderII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {\n    if root == nil {\n        return\n    }\n    // \u5c1d\u8bd5\n    *path = append(*path, root)\n    if root.Val.(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, append([]*TreeNode{}, *path...))\n    }\n    preOrderII(root.Left, res, path)\n    preOrderII(root.Right, res, path)\n    // \u56de\u9000\n    *path = (*path)[:len(*path)-1]\n}\n
    preorder_traversal_ii_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(path)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n    // \u56de\u9000\n    path.removeLast()\n}\n
    preorder_traversal_ii_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunction preOrder(root, path, res) {\n    if (root === null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_ii_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunction preOrder(\n    root: TreeNode | null,\n    path: TreeNode[],\n    res: TreeNode[][]\n): void {\n    if (root === null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_ii_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(\n  TreeNode? root,\n  List<TreeNode> path,\n  List<List<TreeNode>> res,\n) {\n  if (root == null) {\n    return;\n  }\n\n  // \u5c1d\u8bd5\n  path.add(root);\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(List.from(path));\n  }\n  preOrder(root.left, path, res);\n  preOrder(root.right, path, res);\n  // \u56de\u9000\n  path.removeLast();\n}\n
    preorder_traversal_ii_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfn pre_order(\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n    path: &mut Vec<Rc<RefCell<TreeNode>>>,\n    root: Option<Rc<RefCell<TreeNode>>>,\n) {\n    if root.is_none() {\n        return;\n    }\n    if let Some(node) = root {\n        // \u5c1d\u8bd5\n        path.push(node.clone());\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(path.clone());\n        }\n        pre_order(res, path, node.borrow().left.clone());\n        pre_order(res, path, node.borrow().right.clone());\n        // \u56de\u9000\n        path.remove(path.len() - 1);\n    }\n}\n
    preorder_traversal_ii_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode *root) {\n    if (root == NULL) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path[pathSize++] = root;\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        for (int i = 0; i < pathSize; ++i) {\n            res[resSize][i] = path[i];\n        }\n        resSize++;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    pathSize--;\n}\n
    preorder_traversal_ii_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfun preOrder(root: TreeNode?) {\n    if (root == null) {\n        return\n    }\n    // \u5c1d\u8bd5\n    path!!.add(root)\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(path!!.toMutableList())\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n    // \u56de\u9000\n    path!!.removeAt(path!!.size - 1)\n}\n
    preorder_traversal_ii_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_ii_compact.zig
    [class]{}-[func]{preOrder}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5728\u6bcf\u6b21\u201c\u5c1d\u8bd5\u201d\u4e2d\uff0c\u6211\u4eec\u901a\u8fc7\u5c06\u5f53\u524d\u8282\u70b9\u6dfb\u52a0\u8fdb path \u6765\u8bb0\u5f55\u8def\u5f84\uff1b\u800c\u5728\u201c\u56de\u9000\u201d\u524d\uff0c\u6211\u4eec\u9700\u8981\u5c06\u8be5\u8282\u70b9\u4ece path \u4e2d\u5f39\u51fa\uff0c\u4ee5\u6062\u590d\u672c\u6b21\u5c1d\u8bd5\u4e4b\u524d\u7684\u72b6\u6001\u3002

    \u89c2\u5bdf\u56fe 13-2 \u6240\u793a\u7684\u8fc7\u7a0b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5c1d\u8bd5\u548c\u56de\u9000\u7406\u89e3\u4e3a\u201c\u524d\u8fdb\u201d\u4e0e\u201c\u64a4\u9500\u201d\uff0c\u4e24\u4e2a\u64cd\u4f5c\u4e92\u4e3a\u9006\u5411\u3002

    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 13-2 \u00a0 \u5c1d\u8bd5\u4e0e\u56de\u9000

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1312","title":"13.1.2 \u00a0 \u526a\u679d","text":"

    \u590d\u6742\u7684\u56de\u6eaf\u95ee\u9898\u901a\u5e38\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u7ea6\u675f\u6761\u4ef6\uff0c\u7ea6\u675f\u6761\u4ef6\u901a\u5e38\u53ef\u7528\u4e8e\u201c\u526a\u679d\u201d\u3002

    \u4f8b\u9898\u4e09

    \u5728\u4e8c\u53c9\u6811\u4e2d\u641c\u7d22\u6240\u6709\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\uff0c\u8bf7\u8fd4\u56de\u6839\u8282\u70b9\u5230\u8fd9\u4e9b\u8282\u70b9\u7684\u8def\u5f84\uff0c\u5e76\u8981\u6c42\u8def\u5f84\u4e2d\u4e0d\u5305\u542b\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\u3002

    \u4e3a\u4e86\u6ee1\u8db3\u4ee5\u4e0a\u7ea6\u675f\u6761\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u6dfb\u52a0\u526a\u679d\u64cd\u4f5c\uff1a\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u82e5\u9047\u5230\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\uff0c\u5219\u63d0\u524d\u8fd4\u56de\uff0c\u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_iii_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09\"\"\"\n    # \u526a\u679d\n    if root is None or root.val == 3:\n        return\n    # \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(list(path))\n    pre_order(root.left)\n    pre_order(root.right)\n    # \u56de\u9000\n    path.pop()\n
    preorder_traversal_iii_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode *root) {\n    // \u526a\u679d\n    if (root == nullptr || root->val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push_back(root);\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(path);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    path.pop_back();\n}\n
    preorder_traversal_iii_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode root) {\n    // \u526a\u679d\n    if (root == null || root.val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(new ArrayList<>(path));\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n    // \u56de\u9000\n    path.remove(path.size() - 1);\n}\n
    preorder_traversal_iii_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid PreOrder(TreeNode? root) {\n    // \u526a\u679d\n    if (root == null || root.val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.Add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(new List<TreeNode>(path));\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n    // \u56de\u9000\n    path.RemoveAt(path.Count - 1);\n}\n
    preorder_traversal_iii_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunc preOrderIII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {\n    // \u526a\u679d\n    if root == nil || root.Val == 3 {\n        return\n    }\n    // \u5c1d\u8bd5\n    *path = append(*path, root)\n    if root.Val.(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, append([]*TreeNode{}, *path...))\n    }\n    preOrderIII(root.Left, res, path)\n    preOrderIII(root.Right, res, path)\n    // \u56de\u9000\n    *path = (*path)[:len(*path)-1]\n}\n
    preorder_traversal_iii_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunc preOrder(root: TreeNode?) {\n    // \u526a\u679d\n    guard let root = root, root.val != 3 else {\n        return\n    }\n    // \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(path)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n    // \u56de\u9000\n    path.removeLast()\n}\n
    preorder_traversal_iii_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunction preOrder(root, path, res) {\n    // \u526a\u679d\n    if (root === null || root.val === 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_iii_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunction preOrder(\n    root: TreeNode | null,\n    path: TreeNode[],\n    res: TreeNode[][]\n): void {\n    // \u526a\u679d\n    if (root === null || root.val === 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_iii_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(\n  TreeNode? root,\n  List<TreeNode> path,\n  List<List<TreeNode>> res,\n) {\n  if (root == null || root.val == 3) {\n    return;\n  }\n\n  // \u5c1d\u8bd5\n  path.add(root);\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(List.from(path));\n  }\n  preOrder(root.left, path, res);\n  preOrder(root.right, path, res);\n  // \u56de\u9000\n  path.removeLast();\n}\n
    preorder_traversal_iii_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfn pre_order(\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n    path: &mut Vec<Rc<RefCell<TreeNode>>>,\n    root: Option<Rc<RefCell<TreeNode>>>,\n) {\n    // \u526a\u679d\n    if root.is_none() || root.as_ref().unwrap().borrow().val == 3 {\n        return;\n    }\n    if let Some(node) = root {\n        // \u5c1d\u8bd5\n        path.push(node.clone());\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(path.clone());\n        }\n        pre_order(res, path, node.borrow().left.clone());\n        pre_order(res, path, node.borrow().right.clone());\n        // \u56de\u9000\n        path.remove(path.len() - 1);\n    }\n}\n
    preorder_traversal_iii_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode *root) {\n    // \u526a\u679d\n    if (root == NULL || root->val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path[pathSize++] = root;\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        for (int i = 0; i < pathSize; i++) {\n            res[resSize][i] = path[i];\n        }\n        resSize++;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    pathSize--;\n}\n
    preorder_traversal_iii_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfun preOrder(root: TreeNode?) {\n    // \u526a\u679d\n    if (root == null || root._val == 3) {\n        return\n    }\n    // \u5c1d\u8bd5\n    path!!.add(root)\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(path!!.toMutableList())\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n    // \u56de\u9000\n    path!!.removeAt(path!!.size - 1)\n}\n
    preorder_traversal_iii_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_iii_compact.zig
    [class]{}-[func]{preOrder}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u201c\u526a\u679d\u201d\u662f\u4e00\u4e2a\u975e\u5e38\u5f62\u8c61\u7684\u540d\u8bcd\u3002\u5982\u56fe 13-3 \u6240\u793a\uff0c\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u201c\u526a\u6389\u201d\u4e86\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u641c\u7d22\u5206\u652f\uff0c\u907f\u514d\u8bb8\u591a\u65e0\u610f\u4e49\u7684\u5c1d\u8bd5\uff0c\u4ece\u800c\u63d0\u9ad8\u4e86\u641c\u7d22\u6548\u7387\u3002

    \u56fe 13-3 \u00a0 \u6839\u636e\u7ea6\u675f\u6761\u4ef6\u526a\u679d

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1313","title":"13.1.3 \u00a0 \u6846\u67b6\u4ee3\u7801","text":"

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c1d\u8bd5\u5c06\u56de\u6eaf\u7684\u201c\u5c1d\u8bd5\u3001\u56de\u9000\u3001\u526a\u679d\u201d\u7684\u4e3b\u4f53\u6846\u67b6\u63d0\u70bc\u51fa\u6765\uff0c\u63d0\u5347\u4ee3\u7801\u7684\u901a\u7528\u6027\u3002

    \u5728\u4ee5\u4e0b\u6846\u67b6\u4ee3\u7801\u4e2d\uff0cstate \u8868\u793a\u95ee\u9898\u7684\u5f53\u524d\u72b6\u6001\uff0cchoices \u8868\u793a\u5f53\u524d\u72b6\u6001\u4e0b\u53ef\u4ee5\u505a\u51fa\u7684\u9009\u62e9\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def backtrack(state: State, choices: list[choice], res: list[state]):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\u6846\u67b6\"\"\"\n    # \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if is_solution(state):\n        # \u8bb0\u5f55\u89e3\n        record_solution(state, res)\n        # \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice):\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice)\n            backtrack(state, choices, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice)\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State *state, vector<Choice *> &choices, vector<State *> &res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Choice choice : choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State state, List<Choice> choices, List<State> res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Choice choice : choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid Backtrack(State state, List<Choice> choices, List<State> res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (IsSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        RecordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (Choice choice in choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (IsValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            MakeChoice(state, choice);\n            Backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            UndoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunc backtrack(state *State, choices []Choice, res *[]State) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if isSolution(state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range choices {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            backtrack(state, choices, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunc backtrack(state: inout State, choices: [Choice], res: inout [State]) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if isSolution(state: state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state: state, res: &res)\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state: state, choice: choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state: &state, choice: choice)\n            backtrack(state: &state, choices: choices, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state: &state, choice: choice)\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunction backtrack(state, choices, res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let choice of choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunction backtrack(state: State, choices: Choice[], res: State[]): void {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let choice of choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State state, List<Choice>, List<State> res) {\n  // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n  if (isSolution(state)) {\n    // \u8bb0\u5f55\u89e3\n    recordSolution(state, res);\n    // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (Choice choice in choices) {\n    // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n    if (isValid(state, choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      makeChoice(state, choice);\n      backtrack(state, choices, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      undoChoice(state, choice);\n    }\n  }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfn backtrack(state: &mut State, choices: &Vec<Choice>, res: &mut Vec<State>) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if is_solution(state) {\n        // \u8bb0\u5f55\u89e3\n        record_solution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State *state, Choice *choices, int numChoices, State *res, int numRes) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res, numRes);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < numChoices; i++) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, &choices[i])) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, &choices[i]);\n            backtrack(state, choices, numChoices, res, numRes);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, &choices[i]);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfun backtrack(state: State?, choices: List<Choice?>, res: List<State?>?) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            backtrack(state, choices, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    \n
    \n

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u57fa\u4e8e\u6846\u67b6\u4ee3\u7801\u6765\u89e3\u51b3\u4f8b\u9898\u4e09\u3002\u72b6\u6001 state \u4e3a\u8282\u70b9\u904d\u5386\u8def\u5f84\uff0c\u9009\u62e9 choices \u4e3a\u5f53\u524d\u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u548c\u53f3\u5b50\u8282\u70b9\uff0c\u7ed3\u679c res \u662f\u8def\u5f84\u5217\u8868\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_iii_template.py
    def is_solution(state: list[TreeNode]) -> bool:\n    \"\"\"\u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3\"\"\"\n    return state and state[-1].val == 7\n\ndef record_solution(state: list[TreeNode], res: list[list[TreeNode]]):\n    \"\"\"\u8bb0\u5f55\u89e3\"\"\"\n    res.append(list(state))\n\ndef is_valid(state: list[TreeNode], choice: TreeNode) -> bool:\n    \"\"\"\u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5\"\"\"\n    return choice is not None and choice.val != 3\n\ndef make_choice(state: list[TreeNode], choice: TreeNode):\n    \"\"\"\u66f4\u65b0\u72b6\u6001\"\"\"\n    state.append(choice)\n\ndef undo_choice(state: list[TreeNode], choice: TreeNode):\n    \"\"\"\u6062\u590d\u72b6\u6001\"\"\"\n    state.pop()\n\ndef backtrack(\n    state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09\"\"\"\n    # \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if is_solution(state):\n        # \u8bb0\u5f55\u89e3\n        record_solution(state, res)\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice):\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice)\n
    preorder_traversal_iii_template.cpp
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(vector<TreeNode *> &state) {\n    return !state.empty() && state.back()->val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(vector<TreeNode *> &state, vector<vector<TreeNode *>> &res) {\n    res.push_back(state);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(vector<TreeNode *> &state, TreeNode *choice) {\n    return choice != nullptr && choice->val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(vector<TreeNode *> &state, TreeNode *choice) {\n    state.push_back(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(vector<TreeNode *> &state, TreeNode *choice) {\n    state.pop_back();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(vector<TreeNode *> &state, vector<TreeNode *> &choices, vector<vector<TreeNode *>> &res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (TreeNode *choice : choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            vector<TreeNode *> nextChoices{choice->left, choice->right};\n            backtrack(state, nextChoices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.java
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nboolean isSolution(List<TreeNode> state) {\n    return !state.isEmpty() && state.get(state.size() - 1).val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n    res.add(new ArrayList<>(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nboolean isValid(List<TreeNode> state, TreeNode choice) {\n    return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(List<TreeNode> state, TreeNode choice) {\n    state.add(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(List<TreeNode> state, TreeNode choice) {\n    state.remove(state.size() - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(List<TreeNode> state, List<TreeNode> choices, List<List<TreeNode>> res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (TreeNode choice : choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, Arrays.asList(choice.left, choice.right), res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.cs
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool IsSolution(List<TreeNode> state) {\n    return state.Count != 0 && state[^1].val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid RecordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n    res.Add(new List<TreeNode>(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool IsValid(List<TreeNode> state, TreeNode choice) {\n    return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid MakeChoice(List<TreeNode> state, TreeNode choice) {\n    state.Add(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid UndoChoice(List<TreeNode> state, TreeNode choice) {\n    state.RemoveAt(state.Count - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid Backtrack(List<TreeNode> state, List<TreeNode> choices, List<List<TreeNode>> res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (IsSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        RecordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (TreeNode choice in choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (IsValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            MakeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, [choice.left!, choice.right!], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            UndoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.go
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunc isSolution(state *[]*TreeNode) bool {\n    return len(*state) != 0 && (*state)[len(*state)-1].Val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunc recordSolution(state *[]*TreeNode, res *[][]*TreeNode) {\n    *res = append(*res, append([]*TreeNode{}, *state...))\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunc isValid(state *[]*TreeNode, choice *TreeNode) bool {\n    return choice != nil && choice.Val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunc makeChoice(state *[]*TreeNode, choice *TreeNode) {\n    *state = append(*state, choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunc undoChoice(state *[]*TreeNode, choice *TreeNode) {\n    *state = (*state)[:len(*state)-1]\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunc backtrackIII(state *[]*TreeNode, choices *[]*TreeNode, res *[][]*TreeNode) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if isSolution(state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range *choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            temp := make([]*TreeNode, 0)\n            temp = append(temp, choice.Left, choice.Right)\n            backtrackIII(state, &temp, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.swift
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunc isSolution(state: [TreeNode]) -> Bool {\n    !state.isEmpty && state.last!.val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunc recordSolution(state: [TreeNode], res: inout [[TreeNode]]) {\n    res.append(state)\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunc isValid(state: [TreeNode], choice: TreeNode?) -> Bool {\n    choice != nil && choice!.val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunc makeChoice(state: inout [TreeNode], choice: TreeNode) {\n    state.append(choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunc undoChoice(state: inout [TreeNode], choice: TreeNode) {\n    state.removeLast()\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunc backtrack(state: inout [TreeNode], choices: [TreeNode], res: inout [[TreeNode]]) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if isSolution(state: state) {\n        recordSolution(state: state, res: &res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state: state, choice: choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state: &state, choice: choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: [choice.left, choice.right].compactMap { $0 }, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state: &state, choice: choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.js
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunction isSolution(state) {\n    return state && state[state.length - 1]?.val === 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunction recordSolution(state, res) {\n    res.push([...state]);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunction isValid(state, choice) {\n    return choice !== null && choice.val !== 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunction makeChoice(state, choice) {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunction undoChoice(state) {\n    state.pop();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunction backtrack(state, choices, res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state);\n        }\n    }\n}\n
    preorder_traversal_iii_template.ts
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunction isSolution(state: TreeNode[]): boolean {\n    return state && state[state.length - 1]?.val === 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunction recordSolution(state: TreeNode[], res: TreeNode[][]): void {\n    res.push([...state]);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunction isValid(state: TreeNode[], choice: TreeNode): boolean {\n    return choice !== null && choice.val !== 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunction makeChoice(state: TreeNode[], choice: TreeNode): void {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunction undoChoice(state: TreeNode[]): void {\n    state.pop();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunction backtrack(\n    state: TreeNode[],\n    choices: TreeNode[],\n    res: TreeNode[][]\n): void {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state);\n        }\n    }\n}\n
    preorder_traversal_iii_template.dart
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(List<TreeNode> state) {\n  return state.isNotEmpty && state.last.val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n  res.add(List.from(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(List<TreeNode> state, TreeNode? choice) {\n  return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(List<TreeNode> state, TreeNode? choice) {\n  state.add(choice!);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(List<TreeNode> state, TreeNode? choice) {\n  state.removeLast();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(\n  List<TreeNode> state,\n  List<TreeNode?> choices,\n  List<List<TreeNode>> res,\n) {\n  // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n  if (isSolution(state)) {\n    // \u8bb0\u5f55\u89e3\n    recordSolution(state, res);\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (TreeNode? choice in choices) {\n    // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n    if (isValid(state, choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      makeChoice(state, choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, [choice!.left, choice.right], res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      undoChoice(state, choice);\n    }\n  }\n}\n
    preorder_traversal_iii_template.rs
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfn is_solution(state: &mut Vec<Rc<RefCell<TreeNode>>>) -> bool {\n    return !state.is_empty() && state.get(state.len() - 1).unwrap().borrow().val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfn record_solution(\n    state: &mut Vec<Rc<RefCell<TreeNode>>>,\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n) {\n    res.push(state.clone());\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfn is_valid(_: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) -> bool {\n    return choice.borrow().val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfn make_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfn undo_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, _: Rc<RefCell<TreeNode>>) {\n    state.remove(state.len() - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfn backtrack(\n    state: &mut Vec<Rc<RefCell<TreeNode>>>,\n    choices: &mut Vec<Rc<RefCell<TreeNode>>>,\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if is_solution(state) {\n        // \u8bb0\u5f55\u89e3\n        record_solution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice.clone()) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice.clone());\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(\n                state,\n                &mut vec![\n                    choice.borrow().left.clone().unwrap(),\n                    choice.borrow().right.clone().unwrap(),\n                ],\n                res,\n            );\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice.clone());\n        }\n    }\n}\n
    preorder_traversal_iii_template.c
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(void) {\n    return pathSize > 0 && path[pathSize - 1]->val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(void) {\n    for (int i = 0; i < pathSize; i++) {\n        res[resSize][i] = path[i];\n    }\n    resSize++;\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(TreeNode *choice) {\n    return choice != NULL && choice->val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(TreeNode *choice) {\n    path[pathSize++] = choice;\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(void) {\n    pathSize--;\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(TreeNode *choices[2]) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution()) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution();\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < 2; i++) {\n        TreeNode *choice = choices[i];\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            TreeNode *nextChoices[2] = {choice->left, choice->right};\n            backtrack(nextChoices);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice();\n        }\n    }\n}\n
    preorder_traversal_iii_template.kt
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfun isSolution(state: MutableList<TreeNode?>): Boolean {\n    return state.isNotEmpty() && state[state.size - 1]?._val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfun recordSolution(state: MutableList<TreeNode?>?, res: MutableList<MutableList<TreeNode?>?>) {\n    res.add(state!!.toMutableList())\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfun isValid(state: MutableList<TreeNode?>?, choice: TreeNode?): Boolean {\n    return choice != null && choice._val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfun makeChoice(state: MutableList<TreeNode?>, choice: TreeNode?) {\n    state.add(choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfun undoChoice(state: MutableList<TreeNode?>, choice: TreeNode?) {\n    state.removeLast()\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfun backtrack(\n    state: MutableList<TreeNode?>,\n    choices: MutableList<TreeNode?>,\n    res: MutableList<MutableList<TreeNode?>?>\n) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, mutableListOf(choice!!.left, choice.right), res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.rb
    [class]{}-[func]{is_solution}\n\n[class]{}-[func]{record_solution}\n\n[class]{}-[func]{is_valid}\n\n[class]{}-[func]{make_choice}\n\n[class]{}-[func]{undo_choice}\n\n[class]{}-[func]{backtrack}\n
    preorder_traversal_iii_template.zig
    [class]{}-[func]{isSolution}\n\n[class]{}-[func]{recordSolution}\n\n[class]{}-[func]{isValid}\n\n[class]{}-[func]{makeChoice}\n\n[class]{}-[func]{undoChoice}\n\n[class]{}-[func]{backtrack}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6839\u636e\u9898\u610f\uff0c\u6211\u4eec\u5728\u627e\u5230\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\u540e\u5e94\u8be5\u7ee7\u7eed\u641c\u7d22\uff0c\u56e0\u6b64\u9700\u8981\u5c06\u8bb0\u5f55\u89e3\u4e4b\u540e\u7684 return \u8bed\u53e5\u5220\u9664\u3002\u56fe 13-4 \u5bf9\u6bd4\u4e86\u4fdd\u7559\u6216\u5220\u9664 return \u8bed\u53e5\u7684\u641c\u7d22\u8fc7\u7a0b\u3002

    \u56fe 13-4 \u00a0 \u4fdd\u7559\u4e0e\u5220\u9664 return \u7684\u641c\u7d22\u8fc7\u7a0b\u5bf9\u6bd4

    \u76f8\u6bd4\u57fa\u4e8e\u524d\u5e8f\u904d\u5386\u7684\u4ee3\u7801\u5b9e\u73b0\uff0c\u57fa\u4e8e\u56de\u6eaf\u7b97\u6cd5\u6846\u67b6\u7684\u4ee3\u7801\u5b9e\u73b0\u867d\u7136\u663e\u5f97\u5570\u5506\uff0c\u4f46\u901a\u7528\u6027\u66f4\u597d\u3002\u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u56de\u6eaf\u95ee\u9898\u53ef\u4ee5\u5728\u8be5\u6846\u67b6\u4e0b\u89e3\u51b3\u3002\u6211\u4eec\u53ea\u9700\u6839\u636e\u5177\u4f53\u95ee\u9898\u6765\u5b9a\u4e49 state \u548c choices \uff0c\u5e76\u5b9e\u73b0\u6846\u67b6\u4e2d\u7684\u5404\u4e2a\u65b9\u6cd5\u5373\u53ef\u3002

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1314","title":"13.1.4 \u00a0 \u5e38\u7528\u672f\u8bed","text":"

    \u4e3a\u4e86\u66f4\u6e05\u6670\u5730\u5206\u6790\u7b97\u6cd5\u95ee\u9898\uff0c\u6211\u4eec\u603b\u7ed3\u4e00\u4e0b\u56de\u6eaf\u7b97\u6cd5\u4e2d\u5e38\u7528\u672f\u8bed\u7684\u542b\u4e49\uff0c\u5e76\u5bf9\u7167\u4f8b\u9898\u4e09\u7ed9\u51fa\u5bf9\u5e94\u793a\u4f8b\uff0c\u5982\u8868 13-1 \u6240\u793a\u3002

    \u8868 13-1 \u00a0 \u5e38\u89c1\u7684\u56de\u6eaf\u7b97\u6cd5\u672f\u8bed

    \u540d\u8bcd \u5b9a\u4e49 \u4f8b\u9898\u4e09 \u89e3\uff08solution\uff09 \u89e3\u662f\u6ee1\u8db3\u95ee\u9898\u7279\u5b9a\u6761\u4ef6\u7684\u7b54\u6848\uff0c\u53ef\u80fd\u6709\u4e00\u4e2a\u6216\u591a\u4e2a \u6839\u8282\u70b9\u5230\u8282\u70b9 \\(7\\) \u7684\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u6240\u6709\u8def\u5f84 \u7ea6\u675f\u6761\u4ef6\uff08constraint\uff09 \u7ea6\u675f\u6761\u4ef6\u662f\u95ee\u9898\u4e2d\u9650\u5236\u89e3\u7684\u53ef\u884c\u6027\u7684\u6761\u4ef6\uff0c\u901a\u5e38\u7528\u4e8e\u526a\u679d \u8def\u5f84\u4e2d\u4e0d\u5305\u542b\u8282\u70b9 \\(3\\) \u72b6\u6001\uff08state\uff09 \u72b6\u6001\u8868\u793a\u95ee\u9898\u5728\u67d0\u4e00\u65f6\u523b\u7684\u60c5\u51b5\uff0c\u5305\u62ec\u5df2\u7ecf\u505a\u51fa\u7684\u9009\u62e9 \u5f53\u524d\u5df2\u8bbf\u95ee\u7684\u8282\u70b9\u8def\u5f84\uff0c\u5373 path \u8282\u70b9\u5217\u8868 \u5c1d\u8bd5\uff08attempt\uff09 \u5c1d\u8bd5\u662f\u6839\u636e\u53ef\u7528\u9009\u62e9\u6765\u63a2\u7d22\u89e3\u7a7a\u95f4\u7684\u8fc7\u7a0b\uff0c\u5305\u62ec\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\uff0c\u68c0\u67e5\u662f\u5426\u4e3a\u89e3 \u9012\u5f52\u8bbf\u95ee\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\uff0c\u5c06\u8282\u70b9\u6dfb\u52a0\u8fdb path \uff0c\u5224\u65ad\u8282\u70b9\u7684\u503c\u662f\u5426\u4e3a \\(7\\) \u56de\u9000\uff08backtracking\uff09 \u56de\u9000\u6307\u9047\u5230\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u72b6\u6001\u65f6\uff0c\u64a4\u9500\u524d\u9762\u505a\u51fa\u7684\u9009\u62e9\uff0c\u56de\u5230\u4e0a\u4e00\u4e2a\u72b6\u6001 \u5f53\u8d8a\u8fc7\u53f6\u8282\u70b9\u3001\u7ed3\u675f\u8282\u70b9\u8bbf\u95ee\u3001\u9047\u5230\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\u65f6\u7ec8\u6b62\u641c\u7d22\uff0c\u51fd\u6570\u8fd4\u56de \u526a\u679d\uff08pruning\uff09 \u526a\u679d\u662f\u6839\u636e\u95ee\u9898\u7279\u6027\u548c\u7ea6\u675f\u6761\u4ef6\u907f\u514d\u65e0\u610f\u4e49\u7684\u641c\u7d22\u8def\u5f84\u7684\u65b9\u6cd5\uff0c\u53ef\u63d0\u9ad8\u641c\u7d22\u6548\u7387 \u5f53\u9047\u5230\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\u65f6\uff0c\u5219\u4e0d\u518d\u7ee7\u7eed\u641c\u7d22

    Tip

    \u95ee\u9898\u3001\u89e3\u3001\u72b6\u6001\u7b49\u6982\u5ff5\u662f\u901a\u7528\u7684\uff0c\u5728\u5206\u6cbb\u3001\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\u3001\u8d2a\u5fc3\u7b49\u7b97\u6cd5\u4e2d\u90fd\u6709\u6d89\u53ca\u3002

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1315","title":"13.1.5 \u00a0 \u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u56de\u6eaf\u7b97\u6cd5\u672c\u8d28\u4e0a\u662f\u4e00\u79cd\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u7b97\u6cd5\uff0c\u5b83\u5c1d\u8bd5\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\u76f4\u5230\u627e\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u89e3\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u4f18\u70b9\u5728\u4e8e\u80fd\u591f\u627e\u5230\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u800c\u4e14\u5728\u5408\u7406\u7684\u526a\u679d\u64cd\u4f5c\u4e0b\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u6548\u7387\u3002

    \u7136\u800c\uff0c\u5728\u5904\u7406\u5927\u89c4\u6a21\u6216\u8005\u590d\u6742\u95ee\u9898\u65f6\uff0c\u56de\u6eaf\u7b97\u6cd5\u7684\u8fd0\u884c\u6548\u7387\u53ef\u80fd\u96be\u4ee5\u63a5\u53d7\u3002

    • \u65f6\u95f4\uff1a\u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u9700\u8981\u904d\u5386\u72b6\u6001\u7a7a\u95f4\u7684\u6240\u6709\u53ef\u80fd\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u6307\u6570\u9636\u6216\u9636\u4e58\u9636\u3002
    • \u7a7a\u95f4\uff1a\u5728\u9012\u5f52\u8c03\u7528\u4e2d\u9700\u8981\u4fdd\u5b58\u5f53\u524d\u7684\u72b6\u6001\uff08\u4f8b\u5982\u8def\u5f84\u3001\u7528\u4e8e\u526a\u679d\u7684\u8f85\u52a9\u53d8\u91cf\u7b49\uff09\uff0c\u5f53\u6df1\u5ea6\u5f88\u5927\u65f6\uff0c\u7a7a\u95f4\u9700\u6c42\u53ef\u80fd\u4f1a\u53d8\u5f97\u5f88\u5927\u3002

    \u5373\u4fbf\u5982\u6b64\uff0c\u56de\u6eaf\u7b97\u6cd5\u4ecd\u7136\u662f\u67d0\u4e9b\u641c\u7d22\u95ee\u9898\u548c\u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\u7684\u6700\u4f73\u89e3\u51b3\u65b9\u6848\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u95ee\u9898\uff0c\u7531\u4e8e\u65e0\u6cd5\u9884\u6d4b\u54ea\u4e9b\u9009\u62e9\u53ef\u751f\u6210\u6709\u6548\u7684\u89e3\uff0c\u56e0\u6b64\u6211\u4eec\u5fc5\u987b\u5bf9\u6240\u6709\u53ef\u80fd\u7684\u9009\u62e9\u8fdb\u884c\u904d\u5386\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5173\u952e\u662f\u5982\u4f55\u4f18\u5316\u6548\u7387\uff0c\u5e38\u89c1\u7684\u6548\u7387\u4f18\u5316\u65b9\u6cd5\u6709\u4e24\u79cd\u3002

    • \u526a\u679d\uff1a\u907f\u514d\u641c\u7d22\u90a3\u4e9b\u80af\u5b9a\u4e0d\u4f1a\u4ea7\u751f\u89e3\u7684\u8def\u5f84\uff0c\u4ece\u800c\u8282\u7701\u65f6\u95f4\u548c\u7a7a\u95f4\u3002
    • \u542f\u53d1\u5f0f\u641c\u7d22\uff1a\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u5f15\u5165\u4e00\u4e9b\u7b56\u7565\u6216\u8005\u4f30\u8ba1\u503c\uff0c\u4ece\u800c\u4f18\u5148\u641c\u7d22\u6700\u6709\u53ef\u80fd\u4ea7\u751f\u6709\u6548\u89e3\u7684\u8def\u5f84\u3002
    "},{"location":"chapter_backtracking/backtracking_algorithm/#1316","title":"13.1.6 \u00a0 \u56de\u6eaf\u5178\u578b\u4f8b\u9898","text":"

    \u56de\u6eaf\u7b97\u6cd5\u53ef\u7528\u4e8e\u89e3\u51b3\u8bb8\u591a\u641c\u7d22\u95ee\u9898\u3001\u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\u548c\u7ec4\u5408\u4f18\u5316\u95ee\u9898\u3002

    \u641c\u7d22\u95ee\u9898\uff1a\u8fd9\u7c7b\u95ee\u9898\u7684\u76ee\u6807\u662f\u627e\u5230\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u7684\u89e3\u51b3\u65b9\u6848\u3002

    • \u5168\u6392\u5217\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u96c6\u5408\uff0c\u6c42\u51fa\u5176\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u7ec4\u5408\u3002
    • \u5b50\u96c6\u548c\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u96c6\u5408\u548c\u4e00\u4e2a\u76ee\u6807\u548c\uff0c\u627e\u5230\u96c6\u5408\u4e2d\u6240\u6709\u548c\u4e3a\u76ee\u6807\u548c\u7684\u5b50\u96c6\u3002
    • \u6c49\u8bfa\u5854\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e09\u6839\u67f1\u5b50\u548c\u4e00\u7cfb\u5217\u5927\u5c0f\u4e0d\u540c\u7684\u5706\u76d8\uff0c\u8981\u6c42\u5c06\u6240\u6709\u5706\u76d8\u4ece\u4e00\u6839\u67f1\u5b50\u79fb\u52a8\u5230\u53e6\u4e00\u6839\u67f1\u5b50\uff0c\u6bcf\u6b21\u53ea\u80fd\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\uff0c\u4e14\u4e0d\u80fd\u5c06\u5927\u5706\u76d8\u653e\u5728\u5c0f\u5706\u76d8\u4e0a\u3002

    \u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\uff1a\u8fd9\u7c7b\u95ee\u9898\u7684\u76ee\u6807\u662f\u627e\u5230\u6ee1\u8db3\u6240\u6709\u7ea6\u675f\u6761\u4ef6\u7684\u89e3\u3002

    • \\(n\\) \u7687\u540e\uff1a\u5728 \\(n \\times n\\) \u7684\u68cb\u76d8\u4e0a\u653e\u7f6e \\(n\\) \u4e2a\u7687\u540e\uff0c\u4f7f\u5f97\u5b83\u4eec\u4e92\u4e0d\u653b\u51fb\u3002
    • \u6570\u72ec\uff1a\u5728 \\(9 \\times 9\\) \u7684\u7f51\u683c\u4e2d\u586b\u5165\u6570\u5b57 \\(1\\) ~ \\(9\\) \uff0c\u4f7f\u5f97\u6bcf\u884c\u3001\u6bcf\u5217\u548c\u6bcf\u4e2a \\(3 \\times 3\\) \u5b50\u7f51\u683c\u4e2d\u7684\u6570\u5b57\u4e0d\u91cd\u590d\u3002
    • \u56fe\u7740\u8272\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u65e0\u5411\u56fe\uff0c\u7528\u6700\u5c11\u7684\u989c\u8272\u7ed9\u56fe\u7684\u6bcf\u4e2a\u9876\u70b9\u7740\u8272\uff0c\u4f7f\u5f97\u76f8\u90bb\u9876\u70b9\u989c\u8272\u4e0d\u540c\u3002

    \u7ec4\u5408\u4f18\u5316\u95ee\u9898\uff1a\u8fd9\u7c7b\u95ee\u9898\u7684\u76ee\u6807\u662f\u5728\u4e00\u4e2a\u7ec4\u5408\u7a7a\u95f4\u4e2d\u627e\u5230\u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u7684\u6700\u4f18\u89e3\u3002

    • 0-1 \u80cc\u5305\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u7269\u54c1\u548c\u4e00\u4e2a\u80cc\u5305\uff0c\u6bcf\u4e2a\u7269\u54c1\u6709\u4e00\u5b9a\u7684\u4ef7\u503c\u548c\u91cd\u91cf\uff0c\u8981\u6c42\u5728\u80cc\u5305\u5bb9\u91cf\u9650\u5236\u5185\uff0c\u9009\u62e9\u7269\u54c1\u4f7f\u5f97\u603b\u4ef7\u503c\u6700\u5927\u3002
    • \u65c5\u884c\u5546\u95ee\u9898\uff1a\u5728\u4e00\u4e2a\u56fe\u4e2d\uff0c\u4ece\u4e00\u4e2a\u70b9\u51fa\u53d1\uff0c\u8bbf\u95ee\u6240\u6709\u5176\u4ed6\u70b9\u6070\u597d\u4e00\u6b21\u540e\u8fd4\u56de\u8d77\u70b9\uff0c\u6c42\u6700\u77ed\u8def\u5f84\u3002
    • \u6700\u5927\u56e2\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u65e0\u5411\u56fe\uff0c\u627e\u5230\u6700\u5927\u7684\u5b8c\u5168\u5b50\u56fe\uff0c\u5373\u5b50\u56fe\u4e2d\u7684\u4efb\u610f\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u90fd\u6709\u8fb9\u76f8\u8fde\u3002

    \u8bf7\u6ce8\u610f\uff0c\u5bf9\u4e8e\u8bb8\u591a\u7ec4\u5408\u4f18\u5316\u95ee\u9898\uff0c\u56de\u6eaf\u4e0d\u662f\u6700\u4f18\u89e3\u51b3\u65b9\u6848\u3002

    • 0-1 \u80cc\u5305\u95ee\u9898\u901a\u5e38\u4f7f\u7528\u52a8\u6001\u89c4\u5212\u89e3\u51b3\uff0c\u4ee5\u8fbe\u5230\u66f4\u9ad8\u7684\u65f6\u95f4\u6548\u7387\u3002
    • \u65c5\u884c\u5546\u662f\u4e00\u4e2a\u8457\u540d\u7684 NP-Hard \u95ee\u9898\uff0c\u5e38\u7528\u89e3\u6cd5\u6709\u9057\u4f20\u7b97\u6cd5\u548c\u8681\u7fa4\u7b97\u6cd5\u7b49\u3002
    • \u6700\u5927\u56e2\u95ee\u9898\u662f\u56fe\u8bba\u4e2d\u7684\u4e00\u4e2a\u7ecf\u5178\u95ee\u9898\uff0c\u53ef\u7528\u8d2a\u5fc3\u7b97\u6cd5\u7b49\u542f\u53d1\u5f0f\u7b97\u6cd5\u6765\u89e3\u51b3\u3002
    "},{"location":"chapter_backtracking/n_queens_problem/","title":"13.4 \u00a0 n \u7687\u540e\u95ee\u9898","text":"

    Question

    \u6839\u636e\u56fd\u9645\u8c61\u68cb\u7684\u89c4\u5219\uff0c\u7687\u540e\u53ef\u4ee5\u653b\u51fb\u4e0e\u540c\u5904\u4e00\u884c\u3001\u4e00\u5217\u6216\u4e00\u6761\u659c\u7ebf\u4e0a\u7684\u68cb\u5b50\u3002\u7ed9\u5b9a \\(n\\) \u4e2a\u7687\u540e\u548c\u4e00\u4e2a \\(n \\times n\\) \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5bfb\u627e\u4f7f\u5f97\u6240\u6709\u7687\u540e\u4e4b\u95f4\u65e0\u6cd5\u76f8\u4e92\u653b\u51fb\u7684\u6446\u653e\u65b9\u6848\u3002

    \u5982\u56fe 13-15 \u6240\u793a\uff0c\u5f53 \\(n = 4\\) \u65f6\uff0c\u5171\u53ef\u4ee5\u627e\u5230\u4e24\u4e2a\u89e3\u3002\u4ece\u56de\u6eaf\u7b97\u6cd5\u7684\u89d2\u5ea6\u770b\uff0c\\(n \\times n\\) \u5927\u5c0f\u7684\u68cb\u76d8\u5171\u6709 \\(n^2\\) \u4e2a\u683c\u5b50\uff0c\u7ed9\u51fa\u4e86\u6240\u6709\u7684\u9009\u62e9 choices \u3002\u5728\u9010\u4e2a\u653e\u7f6e\u7687\u540e\u7684\u8fc7\u7a0b\u4e2d\uff0c\u68cb\u76d8\u72b6\u6001\u5728\u4e0d\u65ad\u5730\u53d8\u5316\uff0c\u6bcf\u4e2a\u65f6\u523b\u7684\u68cb\u76d8\u5c31\u662f\u72b6\u6001 state \u3002

    \u56fe 13-15 \u00a0 4 \u7687\u540e\u95ee\u9898\u7684\u89e3

    \u56fe 13-16 \u5c55\u793a\u4e86\u672c\u9898\u7684\u4e09\u4e2a\u7ea6\u675f\u6761\u4ef6\uff1a\u591a\u4e2a\u7687\u540e\u4e0d\u80fd\u5728\u540c\u4e00\u884c\u3001\u540c\u4e00\u5217\u3001\u540c\u4e00\u6761\u5bf9\u89d2\u7ebf\u4e0a\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u5bf9\u89d2\u7ebf\u5206\u4e3a\u4e3b\u5bf9\u89d2\u7ebf \\ \u548c\u6b21\u5bf9\u89d2\u7ebf / \u4e24\u79cd\u3002

    \u56fe 13-16 \u00a0 n \u7687\u540e\u95ee\u9898\u7684\u7ea6\u675f\u6761\u4ef6

    "},{"location":"chapter_backtracking/n_queens_problem/#1","title":"1. \u00a0 \u9010\u884c\u653e\u7f6e\u7b56\u7565","text":"

    \u7687\u540e\u7684\u6570\u91cf\u548c\u68cb\u76d8\u7684\u884c\u6570\u90fd\u4e3a \\(n\\) \uff0c\u56e0\u6b64\u6211\u4eec\u5bb9\u6613\u5f97\u5230\u4e00\u4e2a\u63a8\u8bba\uff1a\u68cb\u76d8\u6bcf\u884c\u90fd\u5141\u8bb8\u4e14\u53ea\u5141\u8bb8\u653e\u7f6e\u4e00\u4e2a\u7687\u540e\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u53d6\u9010\u884c\u653e\u7f6e\u7b56\u7565\uff1a\u4ece\u7b2c\u4e00\u884c\u5f00\u59cb\uff0c\u5728\u6bcf\u884c\u653e\u7f6e\u4e00\u4e2a\u7687\u540e\uff0c\u76f4\u81f3\u6700\u540e\u4e00\u884c\u7ed3\u675f\u3002

    \u56fe 13-17 \u6240\u793a\u4e3a \\(4\\) \u7687\u540e\u95ee\u9898\u7684\u9010\u884c\u653e\u7f6e\u8fc7\u7a0b\u3002\u53d7\u753b\u5e45\u9650\u5236\uff0c\u56fe 13-17 \u4ec5\u5c55\u5f00\u4e86\u7b2c\u4e00\u884c\u7684\u5176\u4e2d\u4e00\u4e2a\u641c\u7d22\u5206\u652f\uff0c\u5e76\u4e14\u5c06\u4e0d\u6ee1\u8db3\u5217\u7ea6\u675f\u548c\u5bf9\u89d2\u7ebf\u7ea6\u675f\u7684\u65b9\u6848\u90fd\u8fdb\u884c\u4e86\u526a\u679d\u3002

    \u56fe 13-17 \u00a0 \u9010\u884c\u653e\u7f6e\u7b56\u7565

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u9010\u884c\u653e\u7f6e\u7b56\u7565\u8d77\u5230\u4e86\u526a\u679d\u7684\u4f5c\u7528\uff0c\u5b83\u907f\u514d\u4e86\u540c\u4e00\u884c\u51fa\u73b0\u591a\u4e2a\u7687\u540e\u7684\u6240\u6709\u641c\u7d22\u5206\u652f\u3002

    "},{"location":"chapter_backtracking/n_queens_problem/#2","title":"2. \u00a0 \u5217\u4e0e\u5bf9\u89d2\u7ebf\u526a\u679d","text":"

    \u4e3a\u4e86\u6ee1\u8db3\u5217\u7ea6\u675f\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u5e03\u5c14\u578b\u6570\u7ec4 cols \u8bb0\u5f55\u6bcf\u4e00\u5217\u662f\u5426\u6709\u7687\u540e\u3002\u5728\u6bcf\u6b21\u51b3\u5b9a\u653e\u7f6e\u524d\uff0c\u6211\u4eec\u901a\u8fc7 cols \u5c06\u5df2\u6709\u7687\u540e\u7684\u5217\u8fdb\u884c\u526a\u679d\uff0c\u5e76\u5728\u56de\u6eaf\u4e2d\u52a8\u6001\u66f4\u65b0 cols \u7684\u72b6\u6001\u3002

    \u90a3\u4e48\uff0c\u5982\u4f55\u5904\u7406\u5bf9\u89d2\u7ebf\u7ea6\u675f\u5462\uff1f\u8bbe\u68cb\u76d8\u4e2d\u67d0\u4e2a\u683c\u5b50\u7684\u884c\u5217\u7d22\u5f15\u4e3a \\((row, col)\\) \uff0c\u9009\u5b9a\u77e9\u9635\u4e2d\u7684\u67d0\u6761\u4e3b\u5bf9\u89d2\u7ebf\uff0c\u6211\u4eec\u53d1\u73b0\u8be5\u5bf9\u89d2\u7ebf\u4e0a\u6240\u6709\u683c\u5b50\u7684\u884c\u7d22\u5f15\u51cf\u5217\u7d22\u5f15\u90fd\u76f8\u7b49\uff0c\u5373\u5bf9\u89d2\u7ebf\u4e0a\u6240\u6709\u683c\u5b50\u7684 \\(row - col\\) \u4e3a\u6052\u5b9a\u503c\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u4e24\u4e2a\u683c\u5b50\u6ee1\u8db3 \\(row_1 - col_1 = row_2 - col_2\\) \uff0c\u5219\u5b83\u4eec\u4e00\u5b9a\u5904\u5728\u540c\u4e00\u6761\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u3002\u5229\u7528\u8be5\u89c4\u5f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u501f\u52a9\u56fe 13-18 \u6240\u793a\u7684\u6570\u7ec4 diags1 \u8bb0\u5f55\u6bcf\u6761\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\u3002

    \u540c\u7406\uff0c\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u7684\u6240\u6709\u683c\u5b50\u7684 \\(row + col\\) \u662f\u6052\u5b9a\u503c\u3002\u6211\u4eec\u540c\u6837\u4e5f\u53ef\u4ee5\u501f\u52a9\u6570\u7ec4 diags2 \u6765\u5904\u7406\u6b21\u5bf9\u89d2\u7ebf\u7ea6\u675f\u3002

    \u56fe 13-18 \u00a0 \u5904\u7406\u5217\u7ea6\u675f\u548c\u5bf9\u89d2\u7ebf\u7ea6\u675f

    "},{"location":"chapter_backtracking/n_queens_problem/#3","title":"3. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u8bf7\u6ce8\u610f\uff0c\\(n\\) \u7ef4\u65b9\u9635\u4e2d \\(row - col\\) \u7684\u8303\u56f4\u662f \\([-n + 1, n - 1]\\) \uff0c\\(row + col\\) \u7684\u8303\u56f4\u662f \\([0, 2n - 2]\\) \uff0c\u6240\u4ee5\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\u7684\u6570\u91cf\u90fd\u4e3a \\(2n - 1\\) \uff0c\u5373\u6570\u7ec4 diags1 \u548c diags2 \u7684\u957f\u5ea6\u90fd\u4e3a \\(2n - 1\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig n_queens.py
    def backtrack(\n    row: int,\n    n: int,\n    state: list[list[str]],\n    res: list[list[list[str]]],\n    cols: list[bool],\n    diags1: list[bool],\n    diags2: list[bool],\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e\"\"\"\n    # \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n:\n        res.append([list(row) for row in state])\n        return\n    # \u904d\u5386\u6240\u6709\u5217\n    for col in range(n):\n        # \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        diag1 = row - col + n - 1\n        diag2 = row + col\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if not cols[col] and not diags1[diag1] and not diags2[diag2]:\n            # \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            cols[col] = diags1[diag1] = diags2[diag2] = True\n            # \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2)\n            # \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            cols[col] = diags1[diag1] = diags2[diag2] = False\n\ndef n_queens(n: int) -> list[list[list[str]]]:\n    \"\"\"\u6c42\u89e3 n \u7687\u540e\"\"\"\n    # \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    state = [[\"#\" for _ in range(n)] for _ in range(n)]\n    cols = [False] * n  # \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    diags1 = [False] * (2 * n - 1)  # \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    diags2 = [False] * (2 * n - 1)  # \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    res = []\n    backtrack(0, n, state, res, cols, diags1, diags2)\n\n    return res\n
    n_queens.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, vector<vector<string>> &state, vector<vector<vector<string>>> &res, vector<bool> &cols,\n               vector<bool> &diags1, vector<bool> &diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\";\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\";\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nvector<vector<vector<string>>> nQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    vector<vector<string>> state(n, vector<string>(n, \"#\"));\n    vector<bool> cols(n, false);           // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    vector<bool> diags1(2 * n - 1, false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    vector<bool> diags2(2 * n - 1, false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    vector<vector<vector<string>>> res;\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, List<List<String>> state, List<List<List<String>>> res,\n        boolean[] cols, boolean[] diags1, boolean[] diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        List<List<String>> copyState = new ArrayList<>();\n        for (List<String> sRow : state) {\n            copyState.add(new ArrayList<>(sRow));\n        }\n        res.add(copyState);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state.get(row).set(col, \"Q\");\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state.get(row).set(col, \"#\");\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<String>>> nQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    List<List<String>> state = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<String> row = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            row.add(\"#\");\n        }\n        state.add(row);\n    }\n    boolean[] cols = new boolean[n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    boolean[] diags1 = new boolean[2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    boolean[] diags2 = new boolean[2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    List<List<List<String>>> res = new ArrayList<>();\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid Backtrack(int row, int n, List<List<string>> state, List<List<List<string>>> res,\n        bool[] cols, bool[] diags1, bool[] diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        List<List<string>> copyState = [];\n        foreach (List<string> sRow in state) {\n            copyState.Add(new List<string>(sRow));\n        }\n        res.Add(copyState);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\";\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            Backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\";\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<string>>> NQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    List<List<string>> state = [];\n    for (int i = 0; i < n; i++) {\n        List<string> row = [];\n        for (int j = 0; j < n; j++) {\n            row.Add(\"#\");\n        }\n        state.Add(row);\n    }\n    bool[] cols = new bool[n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    bool[] diags1 = new bool[2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    bool[] diags2 = new bool[2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    List<List<List<string>>> res = [];\n\n    Backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunc backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        newState := make([][]string, len(*state))\n        for i, _ := range newState {\n            newState[i] = make([]string, len((*state)[0]))\n            copy(newState[i], (*state)[i])\n\n        }\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col := 0; col < n; col++ {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        diag1 := row - col + n - 1\n        diag2 := row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !(*cols)[col] && !(*diags1)[diag1] && !(*diags2)[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            (*state)[row][col] = \"Q\"\n            (*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = true, true, true\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row+1, n, state, res, cols, diags1, diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            (*state)[row][col] = \"#\"\n            (*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = false, false, false\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunc nQueens(n int) [][][]string {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    state := make([][]string, n)\n    for i := 0; i < n; i++ {\n        row := make([]string, n)\n        for i := 0; i < n; i++ {\n            row[i] = \"#\"\n        }\n        state[i] = row\n    }\n    // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    cols := make([]bool, n)\n    diags1 := make([]bool, 2*n-1)\n    diags2 := make([]bool, 2*n-1)\n    res := make([][][]string, 0)\n    backtrack(0, n, &state, &res, &cols, &diags1, &diags2)\n    return res\n}\n
    n_queens.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunc backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]], cols: inout [Bool], diags1: inout [Bool], diags2: inout [Bool]) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col in 0 ..< n {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        let diag1 = row - col + n - 1\n        let diag2 = row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !cols[col] && !diags1[diag1] && !diags2[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            cols[col] = true\n            diags1[diag1] = true\n            diags2[diag2] = true\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row: row + 1, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            cols[col] = false\n            diags1[diag1] = false\n            diags2[diag2] = false\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunc nQueens(n: Int) -> [[[String]]] {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    var state = Array(repeating: Array(repeating: \"#\", count: n), count: n)\n    var cols = Array(repeating: false, count: n) // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    var diags1 = Array(repeating: false, count: 2 * n - 1) // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    var diags2 = Array(repeating: false, count: 2 * n - 1) // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    var res: [[[String]]] = []\n\n    backtrack(row: 0, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)\n\n    return res\n}\n
    n_queens.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunction backtrack(row, n, state, res, cols, diags1, diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row === n) {\n        res.push(state.map((row) => row.slice()));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (let col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        const diag1 = row - col + n - 1;\n        const diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunction nQueens(n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    const state = Array.from({ length: n }, () => Array(n).fill('#'));\n    const cols = Array(n).fill(false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    const diags1 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const diags2 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const res = [];\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunction backtrack(\n    row: number,\n    n: number,\n    state: string[][],\n    res: string[][][],\n    cols: boolean[],\n    diags1: boolean[],\n    diags2: boolean[]\n): void {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row === n) {\n        res.push(state.map((row) => row.slice()));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (let col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        const diag1 = row - col + n - 1;\n        const diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunction nQueens(n: number): string[][][] {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    const state = Array.from({ length: n }, () => Array(n).fill('#'));\n    const cols = Array(n).fill(false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    const diags1 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const diags2 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const res: string[][][] = [];\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(\n  int row,\n  int n,\n  List<List<String>> state,\n  List<List<List<String>>> res,\n  List<bool> cols,\n  List<bool> diags1,\n  List<bool> diags2,\n) {\n  // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (row == n) {\n    List<List<String>> copyState = [];\n    for (List<String> sRow in state) {\n      copyState.add(List.from(sRow));\n    }\n    res.add(copyState);\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u5217\n  for (int col = 0; col < n; col++) {\n    // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n    int diag1 = row - col + n - 1;\n    int diag2 = row + col;\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n    if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n      // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n      state[row][col] = \"Q\";\n      cols[col] = true;\n      diags1[diag1] = true;\n      diags2[diag2] = true;\n      // \u653e\u7f6e\u4e0b\u4e00\u884c\n      backtrack(row + 1, n, state, res, cols, diags1, diags2);\n      // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n      state[row][col] = \"#\";\n      cols[col] = false;\n      diags1[diag1] = false;\n      diags2[diag2] = false;\n    }\n  }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<String>>> nQueens(int n) {\n  // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n  List<List<String>> state = List.generate(n, (index) => List.filled(n, \"#\"));\n  List<bool> cols = List.filled(n, false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n  List<bool> diags1 = List.filled(2 * n - 1, false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n  List<bool> diags2 = List.filled(2 * n - 1, false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n  List<List<List<String>>> res = [];\n\n  backtrack(0, n, state, res, cols, diags1, diags2);\n\n  return res;\n}\n
    n_queens.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfn backtrack(\n    row: usize,\n    n: usize,\n    state: &mut Vec<Vec<String>>,\n    res: &mut Vec<Vec<Vec<String>>>,\n    cols: &mut [bool],\n    diags1: &mut [bool],\n    diags2: &mut [bool],\n) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        let mut copy_state: Vec<Vec<String>> = Vec::new();\n        for s_row in state.clone() {\n            copy_state.push(s_row);\n        }\n        res.push(copy_state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col in 0..n {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        let diag1 = row + n - 1 - col;\n        let diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !cols[col] && !diags1[diag1] && !diags2[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state.get_mut(row).unwrap()[col] = \"Q\".into();\n            (cols[col], diags1[diag1], diags2[diag2]) = (true, true, true);\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state.get_mut(row).unwrap()[col] = \"#\".into();\n            (cols[col], diags1[diag1], diags2[diag2]) = (false, false, false);\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    let mut state: Vec<Vec<String>> = Vec::new();\n    for _ in 0..n {\n        let mut row: Vec<String> = Vec::new();\n        for _ in 0..n {\n            row.push(\"#\".into());\n        }\n        state.push(row);\n    }\n    let mut cols = vec![false; n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    let mut diags1 = vec![false; 2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    let mut diags2 = vec![false; 2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    let mut res: Vec<Vec<Vec<String>>> = Vec::new();\n\n    backtrack(\n        0,\n        n,\n        &mut state,\n        &mut res,\n        &mut cols,\n        &mut diags1,\n        &mut diags2,\n    );\n\n    res\n}\n
    n_queens.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, char state[MAX_SIZE][MAX_SIZE], char ***res, int *resSize, bool cols[MAX_SIZE],\n               bool diags1[2 * MAX_SIZE - 1], bool diags2[2 * MAX_SIZE - 1]) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        res[*resSize] = (char **)malloc(sizeof(char *) * n);\n        for (int i = 0; i < n; ++i) {\n            res[*resSize][i] = (char *)malloc(sizeof(char) * (n + 1));\n            strcpy(res[*resSize][i], state[i]);\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, resSize, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nchar ***nQueens(int n, int *returnSize) {\n    char state[MAX_SIZE][MAX_SIZE];\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            state[i][j] = '#';\n        }\n        state[i][n] = '\\0';\n    }\n    bool cols[MAX_SIZE] = {false};           // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    bool diags1[2 * MAX_SIZE - 1] = {false}; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    bool diags2[2 * MAX_SIZE - 1] = {false}; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n\n    char ***res = (char ***)malloc(sizeof(char **) * MAX_SIZE);\n    *returnSize = 0;\n    backtrack(0, n, state, res, returnSize, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfun backtrack(\n    row: Int,\n    n: Int,\n    state: MutableList<MutableList<String>>,\n    res: MutableList<MutableList<MutableList<String>>?>,\n    cols: BooleanArray,\n    diags1: BooleanArray,\n    diags2: BooleanArray\n) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        val copyState = mutableListOf<MutableList<String>>()\n        for (sRow in state) {\n            copyState.add(sRow.toMutableList())\n        }\n        res.add(copyState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (col in 0..<n) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        val diag1 = row - col + n - 1\n        val diag2 = row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            diags2[diag2] = true\n            diags1[diag1] = diags2[diag2]\n            cols[col] = diags1[diag1]\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            diags2[diag2] = false\n            diags1[diag1] = diags2[diag2]\n            cols[col] = diags1[diag1]\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfun nQueens(n: Int): MutableList<MutableList<MutableList<String>>?> {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    val state = mutableListOf<MutableList<String>>()\n    for (i in 0..<n) {\n        val row = mutableListOf<String>()\n        for (j in 0..<n) {\n            row.add(\"#\")\n        }\n        state.add(row)\n    }\n    val cols = BooleanArray(n) // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    val diags1 = BooleanArray(2 * n - 1) // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    val diags2 = BooleanArray(2 * n - 1) // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    val res = mutableListOf<MutableList<MutableList<String>>?>()\n\n    backtrack(0, n, state, res, cols, diags1, diags2)\n\n    return res\n}\n
    n_queens.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{n_queens}\n
    n_queens.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{nQueens}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u9010\u884c\u653e\u7f6e \\(n\\) \u6b21\uff0c\u8003\u8651\u5217\u7ea6\u675f\uff0c\u5219\u4ece\u7b2c\u4e00\u884c\u5230\u6700\u540e\u4e00\u884c\u5206\u522b\u6709 \\(n\\)\u3001\\(n-1\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \u4e2a\u9009\u62e9\uff0c\u4f7f\u7528 \\(O(n!)\\) \u65f6\u95f4\u3002\u5f53\u8bb0\u5f55\u89e3\u65f6\uff0c\u9700\u8981\u590d\u5236\u77e9\u9635 state \u5e76\u6dfb\u52a0\u8fdb res \uff0c\u590d\u5236\u64cd\u4f5c\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002\u56e0\u6b64\uff0c\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n! \\cdot n^2)\\) \u3002\u5b9e\u9645\u4e0a\uff0c\u6839\u636e\u5bf9\u89d2\u7ebf\u7ea6\u675f\u7684\u526a\u679d\u4e5f\u80fd\u591f\u5927\u5e45\u7f29\u5c0f\u641c\u7d22\u7a7a\u95f4\uff0c\u56e0\u800c\u641c\u7d22\u6548\u7387\u5f80\u5f80\u4f18\u4e8e\u4ee5\u4e0a\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    \u6570\u7ec4 state \u4f7f\u7528 \\(O(n^2)\\) \u7a7a\u95f4\uff0c\u6570\u7ec4 cols\u3001diags1 \u548c diags2 \u7686\u4f7f\u7528 \\(O(n)\\) \u7a7a\u95f4\u3002\u6700\u5927\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002\u56e0\u6b64\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_backtracking/permutations_problem/","title":"13.2 \u00a0 \u5168\u6392\u5217\u95ee\u9898","text":"

    \u5168\u6392\u5217\u95ee\u9898\u662f\u56de\u6eaf\u7b97\u6cd5\u7684\u4e00\u4e2a\u5178\u578b\u5e94\u7528\u3002\u5b83\u7684\u5b9a\u4e49\u662f\u5728\u7ed9\u5b9a\u4e00\u4e2a\u96c6\u5408\uff08\u5982\u4e00\u4e2a\u6570\u7ec4\u6216\u5b57\u7b26\u4e32\uff09\u7684\u60c5\u51b5\u4e0b\uff0c\u627e\u51fa\u5176\u4e2d\u5143\u7d20\u7684\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u3002

    \u8868 13-2 \u5217\u4e3e\u4e86\u51e0\u4e2a\u793a\u4f8b\u6570\u636e\uff0c\u5305\u62ec\u8f93\u5165\u6570\u7ec4\u548c\u5bf9\u5e94\u7684\u6240\u6709\u6392\u5217\u3002

    \u8868 13-2 \u00a0 \u5168\u6392\u5217\u793a\u4f8b

    \u8f93\u5165\u6570\u7ec4 \u6240\u6709\u6392\u5217 \\([1]\\) \\([1]\\) \\([1, 2]\\) \\([1, 2], [2, 1]\\) \\([1, 2, 3]\\) \\([1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]\\)"},{"location":"chapter_backtracking/permutations_problem/#1321","title":"13.2.1 \u00a0 \u65e0\u76f8\u7b49\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u8f93\u5165\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\uff0c\u5176\u4e2d\u4e0d\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u8fd4\u56de\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u3002

    \u4ece\u56de\u6eaf\u7b97\u6cd5\u7684\u89d2\u5ea6\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u751f\u6210\u6392\u5217\u7684\u8fc7\u7a0b\u60f3\u8c61\u6210\u4e00\u7cfb\u5217\u9009\u62e9\u7684\u7ed3\u679c\u3002\u5047\u8bbe\u8f93\u5165\u6570\u7ec4\u4e3a \\([1, 2, 3]\\) \uff0c\u5982\u679c\u6211\u4eec\u5148\u9009\u62e9 \\(1\\) \uff0c\u518d\u9009\u62e9 \\(3\\) \uff0c\u6700\u540e\u9009\u62e9 \\(2\\) \uff0c\u5219\u83b7\u5f97\u6392\u5217 \\([1, 3, 2]\\) \u3002\u56de\u9000\u8868\u793a\u64a4\u9500\u4e00\u4e2a\u9009\u62e9\uff0c\u4e4b\u540e\u7ee7\u7eed\u5c1d\u8bd5\u5176\u4ed6\u9009\u62e9\u3002

    \u4ece\u56de\u6eaf\u4ee3\u7801\u7684\u89d2\u5ea6\u770b\uff0c\u5019\u9009\u96c6\u5408 choices \u662f\u8f93\u5165\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\uff0c\u72b6\u6001 state \u662f\u76f4\u81f3\u76ee\u524d\u5df2\u88ab\u9009\u62e9\u7684\u5143\u7d20\u3002\u8bf7\u6ce8\u610f\uff0c\u6bcf\u4e2a\u5143\u7d20\u53ea\u5141\u8bb8\u88ab\u9009\u62e9\u4e00\u6b21\uff0c\u56e0\u6b64 state \u4e2d\u7684\u6240\u6709\u5143\u7d20\u90fd\u5e94\u8be5\u662f\u552f\u4e00\u7684\u3002

    \u5982\u56fe 13-5 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u641c\u7d22\u8fc7\u7a0b\u5c55\u5f00\u6210\u4e00\u68f5\u9012\u5f52\u6811\uff0c\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u5f53\u524d\u72b6\u6001 state \u3002\u4ece\u6839\u8282\u70b9\u5f00\u59cb\uff0c\u7ecf\u8fc7\u4e09\u8f6e\u9009\u62e9\u540e\u5230\u8fbe\u53f6\u8282\u70b9\uff0c\u6bcf\u4e2a\u53f6\u8282\u70b9\u90fd\u5bf9\u5e94\u4e00\u4e2a\u6392\u5217\u3002

    \u56fe 13-5 \u00a0 \u5168\u6392\u5217\u7684\u9012\u5f52\u6811

    "},{"location":"chapter_backtracking/permutations_problem/#1","title":"1. \u00a0 \u91cd\u590d\u9009\u62e9\u526a\u679d","text":"

    \u4e3a\u4e86\u5b9e\u73b0\u6bcf\u4e2a\u5143\u7d20\u53ea\u88ab\u9009\u62e9\u4e00\u6b21\uff0c\u6211\u4eec\u8003\u8651\u5f15\u5165\u4e00\u4e2a\u5e03\u5c14\u578b\u6570\u7ec4 selected \uff0c\u5176\u4e2d selected[i] \u8868\u793a choices[i] \u662f\u5426\u5df2\u88ab\u9009\u62e9\uff0c\u5e76\u57fa\u4e8e\u5b83\u5b9e\u73b0\u4ee5\u4e0b\u526a\u679d\u64cd\u4f5c\u3002

    • \u5728\u505a\u51fa\u9009\u62e9 choice[i] \u540e\uff0c\u6211\u4eec\u5c31\u5c06 selected[i] \u8d4b\u503c\u4e3a \\(\\text{True}\\) \uff0c\u4ee3\u8868\u5b83\u5df2\u88ab\u9009\u62e9\u3002
    • \u904d\u5386\u9009\u62e9\u5217\u8868 choices \u65f6\uff0c\u8df3\u8fc7\u6240\u6709\u5df2\u88ab\u9009\u62e9\u7684\u8282\u70b9\uff0c\u5373\u526a\u679d\u3002

    \u5982\u56fe 13-6 \u6240\u793a\uff0c\u5047\u8bbe\u6211\u4eec\u7b2c\u4e00\u8f6e\u9009\u62e9 1 \uff0c\u7b2c\u4e8c\u8f6e\u9009\u62e9 3 \uff0c\u7b2c\u4e09\u8f6e\u9009\u62e9 2 \uff0c\u5219\u9700\u8981\u5728\u7b2c\u4e8c\u8f6e\u526a\u6389\u5143\u7d20 1 \u7684\u5206\u652f\uff0c\u5728\u7b2c\u4e09\u8f6e\u526a\u6389\u5143\u7d20 1 \u548c\u5143\u7d20 3 \u7684\u5206\u652f\u3002

    \u56fe 13-6 \u00a0 \u5168\u6392\u5217\u526a\u679d\u793a\u4f8b

    \u89c2\u5bdf\u56fe 13-6 \u53d1\u73b0\uff0c\u8be5\u526a\u679d\u64cd\u4f5c\u5c06\u641c\u7d22\u7a7a\u95f4\u5927\u5c0f\u4ece \\(O(n^n)\\) \u51cf\u5c0f\u81f3 \\(O(n!)\\) \u3002

    "},{"location":"chapter_backtracking/permutations_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u60f3\u6e05\u695a\u4ee5\u4e0a\u4fe1\u606f\u4e4b\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5728\u6846\u67b6\u4ee3\u7801\u4e2d\u505a\u201c\u5b8c\u5f62\u586b\u7a7a\u201d\u4e86\u3002\u4e3a\u4e86\u7f29\u77ed\u6574\u4f53\u4ee3\u7801\uff0c\u6211\u4eec\u4e0d\u5355\u72ec\u5b9e\u73b0\u6846\u67b6\u4ee3\u7801\u4e2d\u7684\u5404\u4e2a\u51fd\u6570\uff0c\u800c\u662f\u5c06\u5b83\u4eec\u5c55\u5f00\u5728 backtrack() \u51fd\u6570\u4e2d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig permutations_i.py
    def backtrack(\n    state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I\"\"\"\n    # \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(state) == len(choices):\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i, choice in enumerate(choices):\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if not selected[i]:\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = True\n            state.append(choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = False\n            state.pop()\n\ndef permutations_i(nums: list[int]) -> list[list[int]]:\n    \"\"\"\u5168\u6392\u5217 I\"\"\"\n    res = []\n    backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res)\n    return res\n
    permutations_i.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(vector<int> &state, const vector<int> &choices, vector<bool> &selected, vector<vector<int>> &res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.size()) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.size(); i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push_back(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop_back();\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nvector<vector<int>> permutationsI(vector<int> nums) {\n    vector<int> state;\n    vector<bool> selected(nums.size(), false);\n    vector<vector<int>> res;\n    backtrack(state, nums, selected, res);\n    return res;\n}\n
    permutations_i.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(List<Integer> state, int[] choices, boolean[] selected, List<List<Integer>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.length) {\n        res.add(new ArrayList<Integer>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.size() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<Integer>> permutationsI(int[] nums) {\n    List<List<Integer>> res = new ArrayList<List<Integer>>();\n    backtrack(new ArrayList<Integer>(), nums, new boolean[nums.length], res);\n    return res;\n}\n
    permutations_i.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid Backtrack(List<int> state, int[] choices, bool[] selected, List<List<int>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.Count == choices.Length) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.Length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.Add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.RemoveAt(state.Count - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<int>> PermutationsI(int[] nums) {\n    List<List<int>> res = [];\n    Backtrack([], nums, new bool[nums.Length], res);\n    return res;\n}\n
    permutations_i.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunc backtrackI(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(*state) == len(*choices) {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i := 0; i < len(*choices); i++ {\n        choice := (*choices)[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !(*selected)[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            (*selected)[i] = true\n            *state = append(*state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrackI(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            (*selected)[i] = false\n            *state = (*state)[:len(*state)-1]\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfunc permutationsI(nums []int) [][]int {\n    res := make([][]int, 0)\n    state := make([]int, 0)\n    selected := make([]bool, len(nums))\n    backtrackI(&state, &nums, &selected, &res)\n    return res\n}\n
    permutations_i.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunc backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.count == choices.count {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i, choice) in choices.enumerated() {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !selected[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true\n            state.append(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: choices, selected: &selected, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeLast()\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfunc permutationsI(nums: [Int]) -> [[Int]] {\n    var state: [Int] = []\n    var selected = Array(repeating: false, count: nums.count)\n    var res: [[Int]] = []\n    backtrack(state: &state, choices: nums, selected: &selected, res: &res)\n    return res\n}\n
    permutations_i.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunction backtrack(state, choices, selected, res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 I */\nfunction permutationsI(nums) {\n    const res = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_i.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunction backtrack(\n    state: number[],\n    choices: number[],\n    selected: boolean[],\n    res: number[][]\n): void {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 I */\nfunction permutationsI(nums: number[]): number[][] {\n    const res: number[][] = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_i.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(\n  List<int> state,\n  List<int> choices,\n  List<bool> selected,\n  List<List<int>> res,\n) {\n  // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (state.length == choices.length) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int i = 0; i < choices.length; i++) {\n    int choice = choices[i];\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n    if (!selected[i]) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      selected[i] = true;\n      state.add(choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, choices, selected, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      selected[i] = false;\n      state.removeLast();\n    }\n  }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<int>> permutationsI(List<int> nums) {\n  List<List<int>> res = [];\n  backtrack([], nums, List.filled(nums.length, false), res);\n  return res;\n}\n
    permutations_i.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfn backtrack(mut state: Vec<i32>, choices: &[i32], selected: &mut [bool], res: &mut Vec<Vec<i32>>) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.len() == choices.len() {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in 0..choices.len() {\n        let choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !selected[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state.clone(), choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.len() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfn permutations_i(nums: &mut [i32]) -> Vec<Vec<i32>> {\n    let mut res = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    backtrack(Vec::new(), nums, &mut vec![false; nums.len()], &mut res);\n    res\n}\n
    permutations_i.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (stateSize == choicesSize) {\n        res[*resSize] = (int *)malloc(choicesSize * sizeof(int));\n        for (int i = 0; i < choicesSize; i++) {\n            res[*resSize][i] = state[i];\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choicesSize; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state[stateSize] = choice;\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nint **permutationsI(int *nums, int numsSize, int *returnSize) {\n    int *state = (int *)malloc(numsSize * sizeof(int));\n    bool *selected = (bool *)malloc(numsSize * sizeof(bool));\n    for (int i = 0; i < numsSize; i++) {\n        selected[i] = false;\n    }\n    int **res = (int **)malloc(MAX_SIZE * sizeof(int *));\n    *returnSize = 0;\n\n    backtrack(state, 0, nums, numsSize, selected, res, returnSize);\n\n    free(state);\n    free(selected);\n\n    return res;\n}\n
    permutations_i.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfun backtrack(\n    state: MutableList<Int>,\n    choices: IntArray,\n    selected: BooleanArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size == choices.size) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i in choices.indices) {\n        val choice = choices[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true\n            state.add(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeAt(state.size - 1)\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfun permutationsI(nums: IntArray): MutableList<MutableList<Int>?> {\n    val res = mutableListOf<MutableList<Int>?>()\n    backtrack(mutableListOf(), nums, BooleanArray(nums.size), res)\n    return res\n}\n
    permutations_i.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutations_i}\n
    permutations_i.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutationsI}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_backtracking/permutations_problem/#1322","title":"13.2.2 \u00a0 \u8003\u8651\u76f8\u7b49\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u8f93\u5165\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\uff0c\u6570\u7ec4\u4e2d\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u8fd4\u56de\u6240\u6709\u4e0d\u91cd\u590d\u7684\u6392\u5217\u3002

    \u5047\u8bbe\u8f93\u5165\u6570\u7ec4\u4e3a \\([1, 1, 2]\\) \u3002\u4e3a\u4e86\u65b9\u4fbf\u533a\u5206\u4e24\u4e2a\u91cd\u590d\u5143\u7d20 \\(1\\) \uff0c\u6211\u4eec\u5c06\u7b2c\u4e8c\u4e2a \\(1\\) \u8bb0\u4e3a \\(\\hat{1}\\) \u3002

    \u5982\u56fe 13-7 \u6240\u793a\uff0c\u4e0a\u8ff0\u65b9\u6cd5\u751f\u6210\u7684\u6392\u5217\u6709\u4e00\u534a\u662f\u91cd\u590d\u7684\u3002

    \u56fe 13-7 \u00a0 \u91cd\u590d\u6392\u5217

    \u90a3\u4e48\u5982\u4f55\u53bb\u9664\u91cd\u590d\u7684\u6392\u5217\u5462\uff1f\u6700\u76f4\u63a5\u5730\uff0c\u8003\u8651\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408\uff0c\u76f4\u63a5\u5bf9\u6392\u5217\u7ed3\u679c\u8fdb\u884c\u53bb\u91cd\u3002\u7136\u800c\u8fd9\u6837\u505a\u4e0d\u591f\u4f18\u96c5\uff0c\u56e0\u4e3a\u751f\u6210\u91cd\u590d\u6392\u5217\u7684\u641c\u7d22\u5206\u652f\u6ca1\u6709\u5fc5\u8981\uff0c\u5e94\u5f53\u63d0\u524d\u8bc6\u522b\u5e76\u526a\u679d\uff0c\u8fd9\u6837\u53ef\u4ee5\u8fdb\u4e00\u6b65\u63d0\u5347\u7b97\u6cd5\u6548\u7387\u3002

    "},{"location":"chapter_backtracking/permutations_problem/#1_1","title":"1. \u00a0 \u76f8\u7b49\u5143\u7d20\u526a\u679d","text":"

    \u89c2\u5bdf\u56fe 13-8 \uff0c\u5728\u7b2c\u4e00\u8f6e\u4e2d\uff0c\u9009\u62e9 \\(1\\) \u6216\u9009\u62e9 \\(\\hat{1}\\) \u662f\u7b49\u4ef7\u7684\uff0c\u5728\u8fd9\u4e24\u4e2a\u9009\u62e9\u4e4b\u4e0b\u751f\u6210\u7684\u6240\u6709\u6392\u5217\u90fd\u662f\u91cd\u590d\u7684\u3002\u56e0\u6b64\u5e94\u8be5\u628a \\(\\hat{1}\\) \u526a\u679d\u3002

    \u540c\u7406\uff0c\u5728\u7b2c\u4e00\u8f6e\u9009\u62e9 \\(2\\) \u4e4b\u540e\uff0c\u7b2c\u4e8c\u8f6e\u9009\u62e9\u4e2d\u7684 \\(1\\) \u548c \\(\\hat{1}\\) \u4e5f\u4f1a\u4ea7\u751f\u91cd\u590d\u5206\u652f\uff0c\u56e0\u6b64\u4e5f\u5e94\u5c06\u7b2c\u4e8c\u8f6e\u7684 \\(\\hat{1}\\) \u526a\u679d\u3002

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u6211\u4eec\u7684\u76ee\u6807\u662f\u5728\u67d0\u4e00\u8f6e\u9009\u62e9\u4e2d\uff0c\u4fdd\u8bc1\u591a\u4e2a\u76f8\u7b49\u7684\u5143\u7d20\u4ec5\u88ab\u9009\u62e9\u4e00\u6b21\u3002

    \u56fe 13-8 \u00a0 \u91cd\u590d\u6392\u5217\u526a\u679d

    "},{"location":"chapter_backtracking/permutations_problem/#2_1","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5728\u4e0a\u4e00\u9898\u7684\u4ee3\u7801\u7684\u57fa\u7840\u4e0a\uff0c\u6211\u4eec\u8003\u8651\u5728\u6bcf\u4e00\u8f6e\u9009\u62e9\u4e2d\u5f00\u542f\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408 duplicated \uff0c\u7528\u4e8e\u8bb0\u5f55\u8be5\u8f6e\u4e2d\u5df2\u7ecf\u5c1d\u8bd5\u8fc7\u7684\u5143\u7d20\uff0c\u5e76\u5c06\u91cd\u590d\u5143\u7d20\u526a\u679d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig permutations_ii.py
    def backtrack(\n    state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II\"\"\"\n    # \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(state) == len(choices):\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    duplicated = set[int]()\n    for i, choice in enumerate(choices):\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if not selected[i] and choice not in duplicated:\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice)  # \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = True\n            state.append(choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = False\n            state.pop()\n\ndef permutations_ii(nums: list[int]) -> list[list[int]]:\n    \"\"\"\u5168\u6392\u5217 II\"\"\"\n    res = []\n    backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res)\n    return res\n
    permutations_ii.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(vector<int> &state, const vector<int> &choices, vector<bool> &selected, vector<vector<int>> &res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.size()) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    unordered_set<int> duplicated;\n    for (int i = 0; i < choices.size(); i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && duplicated.find(choice) == duplicated.end()) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.emplace(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push_back(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop_back();\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nvector<vector<int>> permutationsII(vector<int> nums) {\n    vector<int> state;\n    vector<bool> selected(nums.size(), false);\n    vector<vector<int>> res;\n    backtrack(state, nums, selected, res);\n    return res;\n}\n
    permutations_ii.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(List<Integer> state, int[] choices, boolean[] selected, List<List<Integer>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.length) {\n        res.add(new ArrayList<Integer>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    Set<Integer> duplicated = new HashSet<Integer>();\n    for (int i = 0; i < choices.length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.size() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<Integer>> permutationsII(int[] nums) {\n    List<List<Integer>> res = new ArrayList<List<Integer>>();\n    backtrack(new ArrayList<Integer>(), nums, new boolean[nums.length], res);\n    return res;\n}\n
    permutations_ii.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid Backtrack(List<int> state, int[] choices, bool[] selected, List<List<int>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.Count == choices.Length) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    HashSet<int> duplicated = [];\n    for (int i = 0; i < choices.Length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.Contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.Add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.Add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.RemoveAt(state.Count - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<int>> PermutationsII(int[] nums) {\n    List<List<int>> res = [];\n    Backtrack([], nums, new bool[nums.Length], res);\n    return res;\n}\n
    permutations_ii.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunc backtrackII(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(*state) == len(*choices) {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    duplicated := make(map[int]struct{}, 0)\n    for i := 0; i < len(*choices); i++ {\n        choice := (*choices)[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if _, ok := duplicated[choice]; !ok && !(*selected)[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            duplicated[choice] = struct{}{}\n            (*selected)[i] = true\n            *state = append(*state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrackI(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            (*selected)[i] = false\n            *state = (*state)[:len(*state)-1]\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfunc permutationsII(nums []int) [][]int {\n    res := make([][]int, 0)\n    state := make([]int, 0)\n    selected := make([]bool, len(nums))\n    backtrackII(&state, &nums, &selected, &res)\n    return res\n}\n
    permutations_ii.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunc backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.count == choices.count {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    var duplicated: Set<Int> = []\n    for (i, choice) in choices.enumerated() {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if !selected[i], !duplicated.contains(choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.insert(choice) // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true\n            state.append(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: choices, selected: &selected, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeLast()\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfunc permutationsII(nums: [Int]) -> [[Int]] {\n    var state: [Int] = []\n    var selected = Array(repeating: false, count: nums.count)\n    var res: [[Int]] = []\n    backtrack(state: &state, choices: nums, selected: &selected, res: &res)\n    return res\n}\n
    permutations_ii.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunction backtrack(state, choices, selected, res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    const duplicated = new Set();\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.has(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 II */\nfunction permutationsII(nums) {\n    const res = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_ii.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunction backtrack(\n    state: number[],\n    choices: number[],\n    selected: boolean[],\n    res: number[][]\n): void {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    const duplicated = new Set();\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.has(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 II */\nfunction permutationsII(nums: number[]): number[][] {\n    const res: number[][] = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_ii.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(\n  List<int> state,\n  List<int> choices,\n  List<bool> selected,\n  List<List<int>> res,\n) {\n  // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (state.length == choices.length) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  Set<int> duplicated = {};\n  for (int i = 0; i < choices.length; i++) {\n    int choice = choices[i];\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n    if (!selected[i] && !duplicated.contains(choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n      selected[i] = true;\n      state.add(choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, choices, selected, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      selected[i] = false;\n      state.removeLast();\n    }\n  }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<int>> permutationsII(List<int> nums) {\n  List<List<int>> res = [];\n  backtrack([], nums, List.filled(nums.length, false), res);\n  return res;\n}\n
    permutations_ii.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfn backtrack(mut state: Vec<i32>, choices: &[i32], selected: &mut [bool], res: &mut Vec<Vec<i32>>) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.len() == choices.len() {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    let mut duplicated = HashSet::<i32>::new();\n    for i in 0..choices.len() {\n        let choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if !selected[i] && !duplicated.contains(&choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.insert(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state.clone(), choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.len() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfn permutations_ii(nums: &mut [i32]) -> Vec<Vec<i32>> {\n    let mut res = Vec::new();\n    backtrack(Vec::new(), nums, &mut vec![false; nums.len()], &mut res);\n    res\n}\n
    permutations_ii.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (stateSize == choicesSize) {\n        res[*resSize] = (int *)malloc(choicesSize * sizeof(int));\n        for (int i = 0; i < choicesSize; i++) {\n            res[*resSize][i] = state[i];\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    bool duplicated[MAX_SIZE] = {false};\n    for (int i = 0; i < choicesSize; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated[choice]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated[choice] = true; // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state[stateSize] = choice;\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nint **permutationsII(int *nums, int numsSize, int *returnSize) {\n    int *state = (int *)malloc(numsSize * sizeof(int));\n    bool *selected = (bool *)malloc(numsSize * sizeof(bool));\n    for (int i = 0; i < numsSize; i++) {\n        selected[i] = false;\n    }\n    int **res = (int **)malloc(MAX_SIZE * sizeof(int *));\n    *returnSize = 0;\n\n    backtrack(state, 0, nums, numsSize, selected, res, returnSize);\n\n    free(state);\n    free(selected);\n\n    return res;\n}\n
    permutations_ii.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfun backtrack(\n    state: MutableList<Int>,\n    choices: IntArray,\n    selected: BooleanArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size == choices.size) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    val duplicated = HashSet<Int>()\n    for (i in choices.indices) {\n        val choice = choices[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice) // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true\n            state.add(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeAt(state.size - 1)\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfun permutationsII(nums: IntArray): MutableList<MutableList<Int>?> {\n    val res = mutableListOf<MutableList<Int>?>()\n    backtrack(mutableListOf(), nums, BooleanArray(nums.size), res)\n    return res\n}\n
    permutations_ii.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutations_ii}\n
    permutations_ii.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutationsII}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5047\u8bbe\u5143\u7d20\u4e24\u4e24\u4e4b\u95f4\u4e92\u4e0d\u76f8\u540c\uff0c\u5219 \\(n\\) \u4e2a\u5143\u7d20\u5171\u6709 \\(n!\\) \u79cd\u6392\u5217\uff08\u9636\u4e58\uff09\uff1b\u5728\u8bb0\u5f55\u7ed3\u679c\u65f6\uff0c\u9700\u8981\u590d\u5236\u957f\u5ea6\u4e3a \\(n\\) \u7684\u5217\u8868\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n!n)\\) \u3002

    \u6700\u5927\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002selected \u4f7f\u7528 \\(O(n)\\) \u7a7a\u95f4\u3002\u540c\u4e00\u65f6\u523b\u6700\u591a\u5171\u6709 \\(n\\) \u4e2a duplicated \uff0c\u4f7f\u7528 \\(O(n^2)\\) \u7a7a\u95f4\u3002\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_backtracking/permutations_problem/#3","title":"3. \u00a0 \u4e24\u79cd\u526a\u679d\u5bf9\u6bd4","text":"

    \u8bf7\u6ce8\u610f\uff0c\u867d\u7136 selected \u548c duplicated \u90fd\u7528\u4e8e\u526a\u679d\uff0c\u4f46\u4e24\u8005\u7684\u76ee\u6807\u4e0d\u540c\u3002

    • \u91cd\u590d\u9009\u62e9\u526a\u679d\uff1a\u6574\u4e2a\u641c\u7d22\u8fc7\u7a0b\u4e2d\u53ea\u6709\u4e00\u4e2a selected \u3002\u5b83\u8bb0\u5f55\u7684\u662f\u5f53\u524d\u72b6\u6001\u4e2d\u5305\u542b\u54ea\u4e9b\u5143\u7d20\uff0c\u5176\u4f5c\u7528\u662f\u907f\u514d\u67d0\u4e2a\u5143\u7d20\u5728 state \u4e2d\u91cd\u590d\u51fa\u73b0\u3002
    • \u76f8\u7b49\u5143\u7d20\u526a\u679d\uff1a\u6bcf\u8f6e\u9009\u62e9\uff08\u6bcf\u4e2a\u8c03\u7528\u7684 backtrack \u51fd\u6570\uff09\u90fd\u5305\u542b\u4e00\u4e2a duplicated \u3002\u5b83\u8bb0\u5f55\u7684\u662f\u5728\u672c\u8f6e\u904d\u5386\uff08for \u5faa\u73af\uff09\u4e2d\u54ea\u4e9b\u5143\u7d20\u5df2\u88ab\u9009\u62e9\u8fc7\uff0c\u5176\u4f5c\u7528\u662f\u4fdd\u8bc1\u76f8\u7b49\u5143\u7d20\u53ea\u88ab\u9009\u62e9\u4e00\u6b21\u3002

    \u56fe 13-9 \u5c55\u793a\u4e86\u4e24\u4e2a\u526a\u679d\u6761\u4ef6\u7684\u751f\u6548\u8303\u56f4\u3002\u6ce8\u610f\uff0c\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u4e00\u4e2a\u9009\u62e9\uff0c\u4ece\u6839\u8282\u70b9\u5230\u53f6\u8282\u70b9\u7684\u8def\u5f84\u4e0a\u7684\u5404\u4e2a\u8282\u70b9\u6784\u6210\u4e00\u4e2a\u6392\u5217\u3002

    \u56fe 13-9 \u00a0 \u4e24\u79cd\u526a\u679d\u6761\u4ef6\u7684\u4f5c\u7528\u8303\u56f4

    "},{"location":"chapter_backtracking/subset_sum_problem/","title":"13.3 \u00a0 \u5b50\u96c6\u548c\u95ee\u9898","text":""},{"location":"chapter_backtracking/subset_sum_problem/#1331","title":"13.3.1 \u00a0 \u65e0\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6b63\u6574\u6570\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u76ee\u6807\u6b63\u6574\u6570 target \uff0c\u8bf7\u627e\u51fa\u6240\u6709\u53ef\u80fd\u7684\u7ec4\u5408\uff0c\u4f7f\u5f97\u7ec4\u5408\u4e2d\u7684\u5143\u7d20\u548c\u7b49\u4e8e target \u3002\u7ed9\u5b9a\u6570\u7ec4\u65e0\u91cd\u590d\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u53ef\u4ee5\u88ab\u9009\u53d6\u591a\u6b21\u3002\u8bf7\u4ee5\u5217\u8868\u5f62\u5f0f\u8fd4\u56de\u8fd9\u4e9b\u7ec4\u5408\uff0c\u5217\u8868\u4e2d\u4e0d\u5e94\u5305\u542b\u91cd\u590d\u7ec4\u5408\u3002

    \u4f8b\u5982\uff0c\u8f93\u5165\u96c6\u5408 \\(\\{3, 4, 5\\}\\) \u548c\u76ee\u6807\u6574\u6570 \\(9\\) \uff0c\u89e3\u4e3a \\(\\{3, 3, 3\\}, \\{4, 5\\}\\) \u3002\u9700\u8981\u6ce8\u610f\u4ee5\u4e0b\u4e24\u70b9\u3002

    • \u8f93\u5165\u96c6\u5408\u4e2d\u7684\u5143\u7d20\u53ef\u4ee5\u88ab\u65e0\u9650\u6b21\u91cd\u590d\u9009\u53d6\u3002
    • \u5b50\u96c6\u4e0d\u533a\u5206\u5143\u7d20\u987a\u5e8f\uff0c\u6bd4\u5982 \\(\\{4, 5\\}\\) \u548c \\(\\{5, 4\\}\\) \u662f\u540c\u4e00\u4e2a\u5b50\u96c6\u3002
    "},{"location":"chapter_backtracking/subset_sum_problem/#1","title":"1. \u00a0 \u53c2\u8003\u5168\u6392\u5217\u89e3\u6cd5","text":"

    \u7c7b\u4f3c\u4e8e\u5168\u6392\u5217\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u5b50\u96c6\u7684\u751f\u6210\u8fc7\u7a0b\u60f3\u8c61\u6210\u4e00\u7cfb\u5217\u9009\u62e9\u7684\u7ed3\u679c\uff0c\u5e76\u5728\u9009\u62e9\u8fc7\u7a0b\u4e2d\u5b9e\u65f6\u66f4\u65b0\u201c\u5143\u7d20\u548c\u201d\uff0c\u5f53\u5143\u7d20\u548c\u7b49\u4e8e target \u65f6\uff0c\u5c31\u5c06\u5b50\u96c6\u8bb0\u5f55\u81f3\u7ed3\u679c\u5217\u8868\u3002

    \u800c\u4e0e\u5168\u6392\u5217\u95ee\u9898\u4e0d\u540c\u7684\u662f\uff0c\u672c\u9898\u96c6\u5408\u4e2d\u7684\u5143\u7d20\u53ef\u4ee5\u88ab\u65e0\u9650\u6b21\u9009\u53d6\uff0c\u56e0\u6b64\u65e0\u987b\u501f\u52a9 selected \u5e03\u5c14\u5217\u8868\u6765\u8bb0\u5f55\u5143\u7d20\u662f\u5426\u5df2\u88ab\u9009\u62e9\u3002\u6211\u4eec\u53ef\u4ee5\u5bf9\u5168\u6392\u5217\u4ee3\u7801\u8fdb\u884c\u5c0f\u5e45\u4fee\u6539\uff0c\u521d\u6b65\u5f97\u5230\u89e3\u9898\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_i_naive.py
    def backtrack(\n    state: list[int],\n    target: int,\n    total: int,\n    choices: list[int],\n    res: list[list[int]],\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in range(len(choices)):\n        # \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_i_naive(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    total = 0  # \u5b50\u96c6\u548c\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res)\n    return res\n
    subset_sum_i_naive.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(vector<int> &state, int target, int total, vector<int> &choices, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (size_t i = 0; i < choices.size(); i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nvector<vector<int>> subsetSumINaive(vector<int> &nums, int target) {\n    vector<int> state;       // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0;           // \u5b50\u96c6\u548c\n    vector<vector<int>> res; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(List<Integer> state, int target, int total, int[] choices, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<Integer>> subsetSumINaive(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0; // \u5b50\u96c6\u548c\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid Backtrack(List<int> state, int target, int total, int[] choices, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.Length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<int>> SubsetSumINaive(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0; // \u5b50\u96c6\u548c\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrackSubsetSumINaive(total, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == total {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i := 0; i < len(*choices); i++ {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total+(*choices)[i] > target {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumINaive(total+(*choices)[i], target, state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunc subsetSumINaive(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    total := 0              // \u5b50\u96c6\u548c\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumINaive(total, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_i_naive.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrack(state: inout [Int], target: Int, total: Int, choices: [Int], res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in choices.indices {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target, total: total + choices[i], choices: choices, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunc subsetSumINaive(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let total = 0 // \u5b50\u96c6\u548c\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, total: total, choices: nums, res: &res)\n    return res\n}\n
    subset_sum_i_naive.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(state, target, total, choices, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total === target) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunction subsetSumINaive(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    const total = 0; // \u5b50\u96c6\u548c\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(\n    state: number[],\n    target: number,\n    total: number,\n    choices: number[],\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total === target) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunction subsetSumINaive(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    const total = 0; // \u5b50\u96c6\u548c\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(\n  List<int> state,\n  int target,\n  int total,\n  List<int> choices,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (total == target) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int i = 0; i < choices.length; i++) {\n    // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n    if (total + choices[i] > target) {\n      continue;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target, total + choices[i], choices, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<int>> subsetSumINaive(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  int total = 0; // \u5143\u7d20\u548c\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, total, nums, res);\n  return res;\n}\n
    subset_sum_i_naive.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    total: i32,\n    choices: &[i32],\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in 0..choices.len() {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfn subset_sum_i_naive(nums: &[i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let total = 0; // \u5b50\u96c6\u548c\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, &mut res);\n    res\n}\n
    subset_sum_i_naive.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(int target, int total, int *choices, int choicesSize) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        for (int i = 0; i < stateSize; i++) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choicesSize; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state[stateSize++] = choices[i];\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target, total + choices[i], choices, choicesSize);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nvoid subsetSumINaive(int *nums, int numsSize, int target) {\n    resSize = 0; // \u521d\u59cb\u5316\u89e3\u7684\u6570\u91cf\u4e3a0\n    backtrack(target, 0, nums, numsSize);\n}\n
    subset_sum_i_naive.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    total: Int,\n    choices: IntArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i in choices.indices) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfun subsetSumINaive(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    val total = 0 // \u5b50\u96c6\u548c\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res)\n    return res\n}\n
    subset_sum_i_naive.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_i_naive}\n
    subset_sum_i_naive.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumINaive}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5411\u4ee5\u4e0a\u4ee3\u7801\u8f93\u5165\u6570\u7ec4 \\([3, 4, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \uff0c\u8f93\u51fa\u7ed3\u679c\u4e3a \\([3, 3, 3], [4, 5], [5, 4]\\) \u3002\u867d\u7136\u6210\u529f\u627e\u51fa\u4e86\u6240\u6709\u548c\u4e3a \\(9\\) \u7684\u5b50\u96c6\uff0c\u4f46\u5176\u4e2d\u5b58\u5728\u91cd\u590d\u7684\u5b50\u96c6 \\([4, 5]\\) \u548c \\([5, 4]\\) \u3002

    \u8fd9\u662f\u56e0\u4e3a\u641c\u7d22\u8fc7\u7a0b\u662f\u533a\u5206\u9009\u62e9\u987a\u5e8f\u7684\uff0c\u7136\u800c\u5b50\u96c6\u4e0d\u533a\u5206\u9009\u62e9\u987a\u5e8f\u3002\u5982\u56fe 13-10 \u6240\u793a\uff0c\u5148\u9009 \\(4\\) \u540e\u9009 \\(5\\) \u4e0e\u5148\u9009 \\(5\\) \u540e\u9009 \\(4\\) \u662f\u4e0d\u540c\u7684\u5206\u652f\uff0c\u4f46\u5bf9\u5e94\u540c\u4e00\u4e2a\u5b50\u96c6\u3002

    \u56fe 13-10 \u00a0 \u5b50\u96c6\u641c\u7d22\u4e0e\u8d8a\u754c\u526a\u679d

    \u4e3a\u4e86\u53bb\u9664\u91cd\u590d\u5b50\u96c6\uff0c\u4e00\u79cd\u76f4\u63a5\u7684\u601d\u8def\u662f\u5bf9\u7ed3\u679c\u5217\u8868\u8fdb\u884c\u53bb\u91cd\u3002\u4f46\u8fd9\u4e2a\u65b9\u6cd5\u6548\u7387\u5f88\u4f4e\uff0c\u6709\u4e24\u65b9\u9762\u539f\u56e0\u3002

    • \u5f53\u6570\u7ec4\u5143\u7d20\u8f83\u591a\uff0c\u5c24\u5176\u662f\u5f53 target \u8f83\u5927\u65f6\uff0c\u641c\u7d22\u8fc7\u7a0b\u4f1a\u4ea7\u751f\u5927\u91cf\u7684\u91cd\u590d\u5b50\u96c6\u3002
    • \u6bd4\u8f83\u5b50\u96c6\uff08\u6570\u7ec4\uff09\u7684\u5f02\u540c\u975e\u5e38\u8017\u65f6\uff0c\u9700\u8981\u5148\u6392\u5e8f\u6570\u7ec4\uff0c\u518d\u6bd4\u8f83\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u5143\u7d20\u7684\u5f02\u540c\u3002
    "},{"location":"chapter_backtracking/subset_sum_problem/#2","title":"2. \u00a0 \u91cd\u590d\u5b50\u96c6\u526a\u679d","text":"

    \u6211\u4eec\u8003\u8651\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u901a\u8fc7\u526a\u679d\u8fdb\u884c\u53bb\u91cd\u3002\u89c2\u5bdf\u56fe 13-11 \uff0c\u91cd\u590d\u5b50\u96c6\u662f\u5728\u4ee5\u4e0d\u540c\u987a\u5e8f\u9009\u62e9\u6570\u7ec4\u5143\u7d20\u65f6\u4ea7\u751f\u7684\uff0c\u4f8b\u5982\u4ee5\u4e0b\u60c5\u51b5\u3002

    1. \u5f53\u7b2c\u4e00\u8f6e\u548c\u7b2c\u4e8c\u8f6e\u5206\u522b\u9009\u62e9 \\(3\\) \u548c \\(4\\) \u65f6\uff0c\u4f1a\u751f\u6210\u5305\u542b\u8fd9\u4e24\u4e2a\u5143\u7d20\u7684\u6240\u6709\u5b50\u96c6\uff0c\u8bb0\u4e3a \\([3, 4, \\dots]\\) \u3002
    2. \u4e4b\u540e\uff0c\u5f53\u7b2c\u4e00\u8f6e\u9009\u62e9 \\(4\\) \u65f6\uff0c\u5219\u7b2c\u4e8c\u8f6e\u5e94\u8be5\u8df3\u8fc7 \\(3\\) \uff0c\u56e0\u4e3a\u8be5\u9009\u62e9\u4ea7\u751f\u7684\u5b50\u96c6 \\([4, 3, \\dots]\\) \u548c\u7b2c 1. \u6b65\u4e2d\u751f\u6210\u7684\u5b50\u96c6\u5b8c\u5168\u91cd\u590d\u3002

    \u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u4e00\u5c42\u7684\u9009\u62e9\u90fd\u662f\u4ece\u5de6\u5230\u53f3\u88ab\u9010\u4e2a\u5c1d\u8bd5\u7684\uff0c\u56e0\u6b64\u8d8a\u9760\u53f3\u7684\u5206\u652f\u88ab\u526a\u6389\u7684\u8d8a\u591a\u3002

    1. \u524d\u4e24\u8f6e\u9009\u62e9 \\(3\\) \u548c \\(5\\) \uff0c\u751f\u6210\u5b50\u96c6 \\([3, 5, \\dots]\\) \u3002
    2. \u524d\u4e24\u8f6e\u9009\u62e9 \\(4\\) \u548c \\(5\\) \uff0c\u751f\u6210\u5b50\u96c6 \\([4, 5, \\dots]\\) \u3002
    3. \u82e5\u7b2c\u4e00\u8f6e\u9009\u62e9 \\(5\\) \uff0c\u5219\u7b2c\u4e8c\u8f6e\u5e94\u8be5\u8df3\u8fc7 \\(3\\) \u548c \\(4\\) \uff0c\u56e0\u4e3a\u5b50\u96c6 \\([5, 3, \\dots]\\) \u548c \\([5, 4, \\dots]\\) \u4e0e\u7b2c 1. \u6b65\u548c\u7b2c 2. \u6b65\u4e2d\u63cf\u8ff0\u7684\u5b50\u96c6\u5b8c\u5168\u91cd\u590d\u3002

    \u56fe 13-11 \u00a0 \u4e0d\u540c\u9009\u62e9\u987a\u5e8f\u5bfc\u81f4\u7684\u91cd\u590d\u5b50\u96c6

    \u603b\u7ed3\u6765\u770b\uff0c\u7ed9\u5b9a\u8f93\u5165\u6570\u7ec4 \\([x_1, x_2, \\dots, x_n]\\) \uff0c\u8bbe\u641c\u7d22\u8fc7\u7a0b\u4e2d\u7684\u9009\u62e9\u5e8f\u5217\u4e3a \\([x_{i_1}, x_{i_2}, \\dots, x_{i_m}]\\) \uff0c\u5219\u8be5\u9009\u62e9\u5e8f\u5217\u9700\u8981\u6ee1\u8db3 \\(i_1 \\leq i_2 \\leq \\dots \\leq i_m\\) \uff0c\u4e0d\u6ee1\u8db3\u8be5\u6761\u4ef6\u7684\u9009\u62e9\u5e8f\u5217\u90fd\u4f1a\u9020\u6210\u91cd\u590d\uff0c\u5e94\u5f53\u526a\u679d\u3002

    "},{"location":"chapter_backtracking/subset_sum_problem/#3","title":"3. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u4e3a\u5b9e\u73b0\u8be5\u526a\u679d\uff0c\u6211\u4eec\u521d\u59cb\u5316\u53d8\u91cf start \uff0c\u7528\u4e8e\u6307\u793a\u904d\u5386\u8d77\u59cb\u70b9\u3002\u5f53\u505a\u51fa\u9009\u62e9 \\(x_{i}\\) \u540e\uff0c\u8bbe\u5b9a\u4e0b\u4e00\u8f6e\u4ece\u7d22\u5f15 \\(i\\) \u5f00\u59cb\u904d\u5386\u3002\u8fd9\u6837\u505a\u5c31\u53ef\u4ee5\u8ba9\u9009\u62e9\u5e8f\u5217\u6ee1\u8db3 \\(i_1 \\leq i_2 \\leq \\dots \\leq i_m\\) \uff0c\u4ece\u800c\u4fdd\u8bc1\u5b50\u96c6\u552f\u4e00\u3002

    \u9664\u6b64\u4e4b\u5916\uff0c\u6211\u4eec\u8fd8\u5bf9\u4ee3\u7801\u8fdb\u884c\u4e86\u4ee5\u4e0b\u4e24\u9879\u4f18\u5316\u3002

    • \u5728\u5f00\u542f\u641c\u7d22\u524d\uff0c\u5148\u5c06\u6570\u7ec4 nums \u6392\u5e8f\u3002\u5728\u904d\u5386\u6240\u6709\u9009\u62e9\u65f6\uff0c\u5f53\u5b50\u96c6\u548c\u8d85\u8fc7 target \u65f6\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\uff0c\u56e0\u4e3a\u540e\u8fb9\u7684\u5143\u7d20\u66f4\u5927\uff0c\u5176\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target \u3002
    • \u7701\u53bb\u5143\u7d20\u548c\u53d8\u91cf total \uff0c\u901a\u8fc7\u5728 target \u4e0a\u6267\u884c\u51cf\u6cd5\u6765\u7edf\u8ba1\u5143\u7d20\u548c\uff0c\u5f53 target \u7b49\u4e8e \\(0\\) \u65f6\u8bb0\u5f55\u89e3\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_i.py
    def backtrack(\n    state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    # \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in range(start, len(choices)):\n        # \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        # \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0:\n            break\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_i(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c I\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort()  # \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start = 0  # \u904d\u5386\u8d77\u59cb\u70b9\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n
    subset_sum_i.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(vector<int> &state, int target, vector<int> &choices, int start, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.size(); i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nvector<vector<int>> subsetSumI(vector<int> &nums, int target) {\n    vector<int> state;              // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort(nums.begin(), nums.end()); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                  // \u904d\u5386\u8d77\u59cb\u70b9\n    vector<vector<int>> res;        // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(List<Integer> state, int target, int[] choices, int start, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<Integer>> subsetSumI(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Arrays.sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid Backtrack(List<int> state, int target, int[] choices, int start, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.Length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<int>> SubsetSumI(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Array.Sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrackSubsetSumI(start, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i := start; i < len(*choices); i++ {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target-(*choices)[i] < 0 {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumI(i, target-(*choices)[i], state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunc subsetSumI(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort.Ints(nums)         // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start := 0              // \u904d\u5386\u8d77\u59cb\u70b9\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumI(start, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_i.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in choices.indices.dropFirst(start) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target - choices[i], choices: choices, start: i, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunc subsetSumI(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let nums = nums.sorted() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, choices: nums, start: start, res: &res)\n    return res\n}\n
    subset_sum_i.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(state, target, choices, start, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunction subsetSumI(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(\n    state: number[],\n    target: number,\n    choices: number[],\n    start: number,\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunction subsetSumI(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(\n  List<int> state,\n  int target,\n  List<int> choices,\n  int start,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (target == 0) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n  for (int i = start; i < choices.length; i++) {\n    // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n    // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n    if (target - choices[i] < 0) {\n      break;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target - choices[i], choices, i, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<int>> subsetSumI(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n  int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, nums, start, res);\n  return res;\n}\n
    subset_sum_i.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    choices: &[i32],\n    start: usize,\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in start..choices.len() {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfn subset_sum_i(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, &mut res);\n    res\n}\n
    subset_sum_i.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(int target, int *choices, int choicesSize, int start) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        for (int i = 0; i < stateSize; ++i) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choicesSize; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state[stateSize] = choices[i];\n        stateSize++;\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target - choices[i], choices, choicesSize, i);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nvoid subsetSumI(int *nums, int numsSize, int target) {\n    qsort(nums, numsSize, sizeof(int), cmp); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                           // \u904d\u5386\u8d77\u59cb\u70b9\n    backtrack(target, nums, numsSize, start);\n}\n
    subset_sum_i.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    choices: IntArray,\n    start: Int,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (i in start..<choices.size) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfun subsetSumI(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    val start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n}\n
    subset_sum_i.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_i}\n
    subset_sum_i.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumI}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 13-12 \u6240\u793a\u4e3a\u5c06\u6570\u7ec4 \\([3, 4, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \u8f93\u5165\u4ee5\u4e0a\u4ee3\u7801\u540e\u7684\u6574\u4f53\u56de\u6eaf\u8fc7\u7a0b\u3002

    \u56fe 13-12 \u00a0 \u5b50\u96c6\u548c I \u56de\u6eaf\u8fc7\u7a0b

    "},{"location":"chapter_backtracking/subset_sum_problem/#1332","title":"13.3.2 \u00a0 \u8003\u8651\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6b63\u6574\u6570\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u76ee\u6807\u6b63\u6574\u6570 target \uff0c\u8bf7\u627e\u51fa\u6240\u6709\u53ef\u80fd\u7684\u7ec4\u5408\uff0c\u4f7f\u5f97\u7ec4\u5408\u4e2d\u7684\u5143\u7d20\u548c\u7b49\u4e8e target \u3002\u7ed9\u5b9a\u6570\u7ec4\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u53ea\u53ef\u88ab\u9009\u62e9\u4e00\u6b21\u3002\u8bf7\u4ee5\u5217\u8868\u5f62\u5f0f\u8fd4\u56de\u8fd9\u4e9b\u7ec4\u5408\uff0c\u5217\u8868\u4e2d\u4e0d\u5e94\u5305\u542b\u91cd\u590d\u7ec4\u5408\u3002

    \u76f8\u6bd4\u4e8e\u4e0a\u9898\uff0c\u672c\u9898\u7684\u8f93\u5165\u6570\u7ec4\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u8fd9\u5f15\u5165\u4e86\u65b0\u7684\u95ee\u9898\u3002\u4f8b\u5982\uff0c\u7ed9\u5b9a\u6570\u7ec4 \\([4, \\hat{4}, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \uff0c\u5219\u73b0\u6709\u4ee3\u7801\u7684\u8f93\u51fa\u7ed3\u679c\u4e3a \\([4, 5], [\\hat{4}, 5]\\) \uff0c\u51fa\u73b0\u4e86\u91cd\u590d\u5b50\u96c6\u3002

    \u9020\u6210\u8fd9\u79cd\u91cd\u590d\u7684\u539f\u56e0\u662f\u76f8\u7b49\u5143\u7d20\u5728\u67d0\u8f6e\u4e2d\u88ab\u591a\u6b21\u9009\u62e9\u3002\u5728\u56fe 13-13 \u4e2d\uff0c\u7b2c\u4e00\u8f6e\u5171\u6709\u4e09\u4e2a\u9009\u62e9\uff0c\u5176\u4e2d\u4e24\u4e2a\u90fd\u4e3a \\(4\\) \uff0c\u4f1a\u4ea7\u751f\u4e24\u4e2a\u91cd\u590d\u7684\u641c\u7d22\u5206\u652f\uff0c\u4ece\u800c\u8f93\u51fa\u91cd\u590d\u5b50\u96c6\uff1b\u540c\u7406\uff0c\u7b2c\u4e8c\u8f6e\u7684\u4e24\u4e2a \\(4\\) \u4e5f\u4f1a\u4ea7\u751f\u91cd\u590d\u5b50\u96c6\u3002

    \u56fe 13-13 \u00a0 \u76f8\u7b49\u5143\u7d20\u5bfc\u81f4\u7684\u91cd\u590d\u5b50\u96c6

    "},{"location":"chapter_backtracking/subset_sum_problem/#1_1","title":"1. \u00a0 \u76f8\u7b49\u5143\u7d20\u526a\u679d","text":"

    \u4e3a\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u9700\u8981\u9650\u5236\u76f8\u7b49\u5143\u7d20\u5728\u6bcf\u4e00\u8f6e\u4e2d\u53ea\u80fd\u88ab\u9009\u62e9\u4e00\u6b21\u3002\u5b9e\u73b0\u65b9\u5f0f\u6bd4\u8f83\u5de7\u5999\uff1a\u7531\u4e8e\u6570\u7ec4\u662f\u5df2\u6392\u5e8f\u7684\uff0c\u56e0\u6b64\u76f8\u7b49\u5143\u7d20\u90fd\u662f\u76f8\u90bb\u7684\u3002\u8fd9\u610f\u5473\u7740\u5728\u67d0\u8f6e\u9009\u62e9\u4e2d\uff0c\u82e5\u5f53\u524d\u5143\u7d20\u4e0e\u5176\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u5219\u8bf4\u660e\u5b83\u5df2\u7ecf\u88ab\u9009\u62e9\u8fc7\uff0c\u56e0\u6b64\u76f4\u63a5\u8df3\u8fc7\u5f53\u524d\u5143\u7d20\u3002

    \u4e0e\u6b64\u540c\u65f6\uff0c\u672c\u9898\u89c4\u5b9a\u6bcf\u4e2a\u6570\u7ec4\u5143\u7d20\u53ea\u80fd\u88ab\u9009\u62e9\u4e00\u6b21\u3002\u5e78\u8fd0\u7684\u662f\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u5229\u7528\u53d8\u91cf start \u6765\u6ee1\u8db3\u8be5\u7ea6\u675f\uff1a\u5f53\u505a\u51fa\u9009\u62e9 \\(x_{i}\\) \u540e\uff0c\u8bbe\u5b9a\u4e0b\u4e00\u8f6e\u4ece\u7d22\u5f15 \\(i + 1\\) \u5f00\u59cb\u5411\u540e\u904d\u5386\u3002\u8fd9\u6837\u65e2\u80fd\u53bb\u9664\u91cd\u590d\u5b50\u96c6\uff0c\u4e5f\u80fd\u907f\u514d\u91cd\u590d\u9009\u62e9\u5143\u7d20\u3002

    "},{"location":"chapter_backtracking/subset_sum_problem/#2_1","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_ii.py
    def backtrack(\n    state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    # \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    # \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in range(start, len(choices)):\n        # \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        # \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0:\n            break\n        # \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start and choices[i] == choices[i - 1]:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_ii(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c II\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort()  # \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start = 0  # \u904d\u5386\u8d77\u59cb\u70b9\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n
    subset_sum_ii.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(vector<int> &state, int target, vector<int> &choices, int start, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.size(); i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nvector<vector<int>> subsetSumII(vector<int> &nums, int target) {\n    vector<int> state;              // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort(nums.begin(), nums.end()); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                  // \u904d\u5386\u8d77\u59cb\u70b9\n    vector<vector<int>> res;        // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(List<Integer> state, int target, int[] choices, int start, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<Integer>> subsetSumII(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Arrays.sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid Backtrack(List<int> state, int target, int[] choices, int start, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.Length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<int>> SubsetSumII(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Array.Sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunc backtrackSubsetSumII(start, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i := start; i < len(*choices); i++ {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target-(*choices)[i] < 0 {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start && (*choices)[i] == (*choices)[i-1] {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumII(i+1, target-(*choices)[i], state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunc subsetSumII(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort.Ints(nums)         // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start := 0              // \u904d\u5386\u8d77\u59cb\u70b9\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumII(start, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_ii.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunc backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in choices.indices.dropFirst(start) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start, choices[i] == choices[i - 1] {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target - choices[i], choices: choices, start: i + 1, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunc subsetSumII(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let nums = nums.sorted() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, choices: nums, start: start, res: &res)\n    return res\n}\n
    subset_sum_ii.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunction backtrack(state, target, choices, start, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] === choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunction subsetSumII(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunction backtrack(\n    state: number[],\n    target: number,\n    choices: number[],\n    start: number,\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] === choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunction subsetSumII(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(\n  List<int> state,\n  int target,\n  List<int> choices,\n  int start,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (target == 0) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n  // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n  for (int i = start; i < choices.length; i++) {\n    // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n    // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n    if (target - choices[i] < 0) {\n      break;\n    }\n    // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n    if (i > start && choices[i] == choices[i - 1]) {\n      continue;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target - choices[i], choices, i + 1, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<int>> subsetSumII(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n  int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, nums, start, res);\n  return res;\n}\n
    subset_sum_ii.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    choices: &[i32],\n    start: usize,\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in start..choices.len() {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start && choices[i] == choices[i - 1] {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfn subset_sum_ii(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, &mut res);\n    res\n}\n
    subset_sum_ii.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(int target, int *choices, int choicesSize, int start) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        for (int i = 0; i < stateSize; i++) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choicesSize; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\n        if (target - choices[i] < 0) {\n            continue;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state[stateSize] = choices[i];\n        stateSize++;\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target - choices[i], choices, choicesSize, i + 1);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nvoid subsetSumII(int *nums, int numsSize, int target) {\n    // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    qsort(nums, numsSize, sizeof(int), cmp);\n    // \u5f00\u59cb\u56de\u6eaf\n    backtrack(target, nums, numsSize, 0);\n}\n
    subset_sum_ii.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    choices: IntArray,\n    start: Int,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (i in start..<choices.size) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfun subsetSumII(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    val start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n}\n
    subset_sum_ii.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_ii}\n
    subset_sum_ii.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumII}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 13-14 \u5c55\u793a\u4e86\u6570\u7ec4 \\([4, 4, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \u7684\u56de\u6eaf\u8fc7\u7a0b\uff0c\u5171\u5305\u542b\u56db\u79cd\u526a\u679d\u64cd\u4f5c\u3002\u8bf7\u4f60\u5c06\u56fe\u793a\u4e0e\u4ee3\u7801\u6ce8\u91ca\u76f8\u7ed3\u5408\uff0c\u7406\u89e3\u6574\u4e2a\u641c\u7d22\u8fc7\u7a0b\uff0c\u4ee5\u53ca\u6bcf\u79cd\u526a\u679d\u64cd\u4f5c\u662f\u5982\u4f55\u5de5\u4f5c\u7684\u3002

    \u56fe 13-14 \u00a0 \u5b50\u96c6\u548c II \u56de\u6eaf\u8fc7\u7a0b

    "},{"location":"chapter_backtracking/summary/","title":"13.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_backtracking/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u56de\u6eaf\u7b97\u6cd5\u672c\u8d28\u662f\u7a77\u4e3e\u6cd5\uff0c\u901a\u8fc7\u5bf9\u89e3\u7a7a\u95f4\u8fdb\u884c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u6765\u5bfb\u627e\u7b26\u5408\u6761\u4ef6\u7684\u89e3\u3002\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u9047\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u89e3\u5219\u8bb0\u5f55\uff0c\u76f4\u81f3\u627e\u5230\u6240\u6709\u89e3\u6216\u904d\u5386\u5b8c\u6210\u540e\u7ed3\u675f\u3002
    • \u56de\u6eaf\u7b97\u6cd5\u7684\u641c\u7d22\u8fc7\u7a0b\u5305\u62ec\u5c1d\u8bd5\u4e0e\u56de\u9000\u4e24\u4e2a\u90e8\u5206\u3002\u5b83\u901a\u8fc7\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u6765\u5c1d\u8bd5\u5404\u79cd\u9009\u62e9\uff0c\u5f53\u9047\u5230\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u60c5\u51b5\u65f6\uff0c\u5219\u64a4\u9500\u4e0a\u4e00\u6b65\u7684\u9009\u62e9\uff0c\u9000\u56de\u5230\u4e4b\u524d\u7684\u72b6\u6001\uff0c\u5e76\u7ee7\u7eed\u5c1d\u8bd5\u5176\u4ed6\u9009\u62e9\u3002\u5c1d\u8bd5\u4e0e\u56de\u9000\u662f\u4e24\u4e2a\u65b9\u5411\u76f8\u53cd\u7684\u64cd\u4f5c\u3002
    • \u56de\u6eaf\u95ee\u9898\u901a\u5e38\u5305\u542b\u591a\u4e2a\u7ea6\u675f\u6761\u4ef6\uff0c\u5b83\u4eec\u53ef\u7528\u4e8e\u5b9e\u73b0\u526a\u679d\u64cd\u4f5c\u3002\u526a\u679d\u53ef\u4ee5\u63d0\u524d\u7ed3\u675f\u4e0d\u5fc5\u8981\u7684\u641c\u7d22\u5206\u652f\uff0c\u5927\u5e45\u63d0\u5347\u641c\u7d22\u6548\u7387\u3002
    • \u56de\u6eaf\u7b97\u6cd5\u4e3b\u8981\u53ef\u7528\u4e8e\u89e3\u51b3\u641c\u7d22\u95ee\u9898\u548c\u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\u3002\u7ec4\u5408\u4f18\u5316\u95ee\u9898\u867d\u7136\u53ef\u4ee5\u7528\u56de\u6eaf\u7b97\u6cd5\u89e3\u51b3\uff0c\u4f46\u5f80\u5f80\u5b58\u5728\u6548\u7387\u66f4\u9ad8\u6216\u6548\u679c\u66f4\u597d\u7684\u89e3\u6cd5\u3002
    • \u5168\u6392\u5217\u95ee\u9898\u65e8\u5728\u641c\u7d22\u7ed9\u5b9a\u96c6\u5408\u5143\u7d20\u7684\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u3002\u6211\u4eec\u501f\u52a9\u4e00\u4e2a\u6570\u7ec4\u6765\u8bb0\u5f55\u6bcf\u4e2a\u5143\u7d20\u662f\u5426\u88ab\u9009\u62e9\uff0c\u526a\u6389\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\u7684\u641c\u7d22\u5206\u652f\uff0c\u786e\u4fdd\u6bcf\u4e2a\u5143\u7d20\u53ea\u88ab\u9009\u62e9\u4e00\u6b21\u3002
    • \u5728\u5168\u6392\u5217\u95ee\u9898\u4e2d\uff0c\u5982\u679c\u96c6\u5408\u4e2d\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff0c\u5219\u6700\u7ec8\u7ed3\u679c\u4f1a\u51fa\u73b0\u91cd\u590d\u6392\u5217\u3002\u6211\u4eec\u9700\u8981\u7ea6\u675f\u76f8\u7b49\u5143\u7d20\u5728\u6bcf\u8f6e\u4e2d\u53ea\u80fd\u88ab\u9009\u62e9\u4e00\u6b21\uff0c\u8fd9\u901a\u5e38\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408\u6765\u5b9e\u73b0\u3002
    • \u5b50\u96c6\u548c\u95ee\u9898\u7684\u76ee\u6807\u662f\u5728\u7ed9\u5b9a\u96c6\u5408\u4e2d\u627e\u5230\u548c\u4e3a\u76ee\u6807\u503c\u7684\u6240\u6709\u5b50\u96c6\u3002\u96c6\u5408\u4e0d\u533a\u5206\u5143\u7d20\u987a\u5e8f\uff0c\u800c\u641c\u7d22\u8fc7\u7a0b\u4f1a\u8f93\u51fa\u6240\u6709\u987a\u5e8f\u7684\u7ed3\u679c\uff0c\u4ea7\u751f\u91cd\u590d\u5b50\u96c6\u3002\u6211\u4eec\u5728\u56de\u6eaf\u524d\u5c06\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c\u5e76\u8bbe\u7f6e\u4e00\u4e2a\u53d8\u91cf\u6765\u6307\u793a\u6bcf\u4e00\u8f6e\u7684\u904d\u5386\u8d77\u59cb\u70b9\uff0c\u4ece\u800c\u5c06\u751f\u6210\u91cd\u590d\u5b50\u96c6\u7684\u641c\u7d22\u5206\u652f\u8fdb\u884c\u526a\u679d\u3002
    • \u5bf9\u4e8e\u5b50\u96c6\u548c\u95ee\u9898\uff0c\u6570\u7ec4\u4e2d\u7684\u76f8\u7b49\u5143\u7d20\u4f1a\u4ea7\u751f\u91cd\u590d\u96c6\u5408\u3002\u6211\u4eec\u5229\u7528\u6570\u7ec4\u5df2\u6392\u5e8f\u7684\u524d\u7f6e\u6761\u4ef6\uff0c\u901a\u8fc7\u5224\u65ad\u76f8\u90bb\u5143\u7d20\u662f\u5426\u76f8\u7b49\u5b9e\u73b0\u526a\u679d\uff0c\u4ece\u800c\u786e\u4fdd\u76f8\u7b49\u5143\u7d20\u5728\u6bcf\u8f6e\u4e2d\u53ea\u80fd\u88ab\u9009\u4e2d\u4e00\u6b21\u3002
    • \\(n\\) \u7687\u540e\u95ee\u9898\u65e8\u5728\u5bfb\u627e\u5c06 \\(n\\) \u4e2a\u7687\u540e\u653e\u7f6e\u5230 \\(n \\times n\\) \u5c3a\u5bf8\u68cb\u76d8\u4e0a\u7684\u65b9\u6848\uff0c\u8981\u6c42\u6240\u6709\u7687\u540e\u4e24\u4e24\u4e4b\u95f4\u65e0\u6cd5\u653b\u51fb\u5bf9\u65b9\u3002\u8be5\u95ee\u9898\u7684\u7ea6\u675f\u6761\u4ef6\u6709\u884c\u7ea6\u675f\u3001\u5217\u7ea6\u675f\u3001\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\u7ea6\u675f\u3002\u4e3a\u6ee1\u8db3\u884c\u7ea6\u675f\uff0c\u6211\u4eec\u91c7\u7528\u6309\u884c\u653e\u7f6e\u7684\u7b56\u7565\uff0c\u4fdd\u8bc1\u6bcf\u4e00\u884c\u653e\u7f6e\u4e00\u4e2a\u7687\u540e\u3002
    • \u5217\u7ea6\u675f\u548c\u5bf9\u89d2\u7ebf\u7ea6\u675f\u7684\u5904\u7406\u65b9\u5f0f\u7c7b\u4f3c\u3002\u5bf9\u4e8e\u5217\u7ea6\u675f\uff0c\u6211\u4eec\u5229\u7528\u4e00\u4e2a\u6570\u7ec4\u6765\u8bb0\u5f55\u6bcf\u4e00\u5217\u662f\u5426\u6709\u7687\u540e\uff0c\u4ece\u800c\u6307\u793a\u9009\u4e2d\u7684\u683c\u5b50\u662f\u5426\u5408\u6cd5\u3002\u5bf9\u4e8e\u5bf9\u89d2\u7ebf\u7ea6\u675f\uff0c\u6211\u4eec\u501f\u52a9\u4e24\u4e2a\u6570\u7ec4\u6765\u5206\u522b\u8bb0\u5f55\u8be5\u4e3b\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u5b58\u5728\u7687\u540e\uff1b\u96be\u70b9\u5728\u4e8e\u627e\u5904\u5728\u5230\u540c\u4e00\u4e3b\uff08\u526f\uff09\u5bf9\u89d2\u7ebf\u4e0a\u683c\u5b50\u6ee1\u8db3\u7684\u884c\u5217\u7d22\u5f15\u89c4\u5f8b\u3002
    "},{"location":"chapter_backtracking/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u600e\u4e48\u7406\u89e3\u56de\u6eaf\u548c\u9012\u5f52\u7684\u5173\u7cfb\uff1f

    \u603b\u7684\u6765\u770b\uff0c\u56de\u6eaf\u662f\u4e00\u79cd\u201c\u7b97\u6cd5\u7b56\u7565\u201d\uff0c\u800c\u9012\u5f52\u66f4\u50cf\u662f\u4e00\u4e2a\u201c\u5de5\u5177\u201d\u3002

    • \u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\u3002\u7136\u800c\uff0c\u56de\u6eaf\u662f\u9012\u5f52\u7684\u5e94\u7528\u573a\u666f\u4e4b\u4e00\uff0c\u662f\u9012\u5f52\u5728\u641c\u7d22\u95ee\u9898\u4e2d\u7684\u5e94\u7528\u3002
    • \u9012\u5f52\u7684\u7ed3\u6784\u4f53\u73b0\u4e86\u201c\u5b50\u95ee\u9898\u5206\u89e3\u201d\u7684\u89e3\u9898\u8303\u5f0f\uff0c\u5e38\u7528\u4e8e\u89e3\u51b3\u5206\u6cbb\u3001\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\uff08\u8bb0\u5fc6\u5316\u9012\u5f52\uff09\u7b49\u95ee\u9898\u3002
    "},{"location":"chapter_computational_complexity/","title":"\u7b2c 2 \u7ae0 \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    Abstract

    \u590d\u6742\u5ea6\u5206\u6790\u72b9\u5982\u6d69\u701a\u7684\u7b97\u6cd5\u5b87\u5b99\u4e2d\u7684\u65f6\u7a7a\u5411\u5bfc\u3002

    \u5b83\u5e26\u9886\u6211\u4eec\u5728\u65f6\u95f4\u4e0e\u7a7a\u95f4\u8fd9\u4e24\u4e2a\u7ef4\u5ea6\u4e0a\u6df1\u5165\u63a2\u7d22\uff0c\u5bfb\u627e\u66f4\u4f18\u96c5\u7684\u89e3\u51b3\u65b9\u6848\u3002

    "},{"location":"chapter_computational_complexity/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 2.1 \u00a0 \u7b97\u6cd5\u6548\u7387\u8bc4\u4f30
    • 2.2 \u00a0 \u8fed\u4ee3\u4e0e\u9012\u5f52
    • 2.3 \u00a0 \u65f6\u95f4\u590d\u6742\u5ea6
    • 2.4 \u00a0 \u7a7a\u95f4\u590d\u6742\u5ea6
    • 2.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/","title":"2.2 \u00a0 \u8fed\u4ee3\u4e0e\u9012\u5f52","text":"

    \u5728\u7b97\u6cd5\u4e2d\uff0c\u91cd\u590d\u6267\u884c\u67d0\u4e2a\u4efb\u52a1\u662f\u5f88\u5e38\u89c1\u7684\uff0c\u5b83\u4e0e\u590d\u6742\u5ea6\u5206\u6790\u606f\u606f\u76f8\u5173\u3002\u56e0\u6b64\uff0c\u5728\u4ecb\u7ecd\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e4b\u524d\uff0c\u6211\u4eec\u5148\u6765\u4e86\u89e3\u5982\u4f55\u5728\u7a0b\u5e8f\u4e2d\u5b9e\u73b0\u91cd\u590d\u6267\u884c\u4efb\u52a1\uff0c\u5373\u4e24\u79cd\u57fa\u672c\u7684\u7a0b\u5e8f\u63a7\u5236\u7ed3\u6784\uff1a\u8fed\u4ee3\u3001\u9012\u5f52\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#221","title":"2.2.1 \u00a0 \u8fed\u4ee3","text":"

    \u8fed\u4ee3\uff08iteration\uff09\u662f\u4e00\u79cd\u91cd\u590d\u6267\u884c\u67d0\u4e2a\u4efb\u52a1\u7684\u63a7\u5236\u7ed3\u6784\u3002\u5728\u8fed\u4ee3\u4e2d\uff0c\u7a0b\u5e8f\u4f1a\u5728\u6ee1\u8db3\u4e00\u5b9a\u7684\u6761\u4ef6\u4e0b\u91cd\u590d\u6267\u884c\u67d0\u6bb5\u4ee3\u7801\uff0c\u76f4\u5230\u8fd9\u4e2a\u6761\u4ef6\u4e0d\u518d\u6ee1\u8db3\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1-for","title":"1. \u00a0 for \u5faa\u73af","text":"

    for \u5faa\u73af\u662f\u6700\u5e38\u89c1\u7684\u8fed\u4ee3\u5f62\u5f0f\u4e4b\u4e00\uff0c\u9002\u5408\u5728\u9884\u5148\u77e5\u9053\u8fed\u4ee3\u6b21\u6570\u65f6\u4f7f\u7528\u3002

    \u4ee5\u4e0b\u51fd\u6570\u57fa\u4e8e for \u5faa\u73af\u5b9e\u73b0\u4e86\u6c42\u548c \\(1 + 2 + \\dots + n\\) \uff0c\u6c42\u548c\u7ed3\u679c\u4f7f\u7528\u53d8\u91cf res \u8bb0\u5f55\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cPython \u4e2d range(a, b) \u5bf9\u5e94\u7684\u533a\u95f4\u662f\u201c\u5de6\u95ed\u53f3\u5f00\u201d\u7684\uff0c\u5bf9\u5e94\u7684\u904d\u5386\u8303\u56f4\u4e3a \\(a, a + 1, \\dots, b-1\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def for_loop(n: int) -> int:\n    \"\"\"for \u5faa\u73af\"\"\"\n    res = 0\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        res += i\n    return res\n
    iteration.cpp
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.java
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.cs
    /* for \u5faa\u73af */\nint ForLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.go
    /* for \u5faa\u73af */\nfunc forLoop(n int) int {\n    res := 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        res += i\n    }\n    return res\n}\n
    iteration.swift
    /* for \u5faa\u73af */\nfunc forLoop(n: Int) -> Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        res += i\n    }\n    return res\n}\n
    iteration.js
    /* for \u5faa\u73af */\nfunction forLoop(n) {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.ts
    /* for \u5faa\u73af */\nfunction forLoop(n: number): number {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.dart
    /* for \u5faa\u73af */\nint forLoop(int n) {\n  int res = 0;\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    res += i;\n  }\n  return res;\n}\n
    iteration.rs
    /* for \u5faa\u73af */\nfn for_loop(n: i32) -> i32 {\n    let mut res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1..=n {\n        res += i;\n    }\n    res\n}\n
    iteration.c
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.kt
    /* for \u5faa\u73af */\nfun forLoop(n: Int): Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        res += i\n    }\n    return res\n}\n
    iteration.rb
    ### for \u5faa\u73af ###\ndef for_loop(n)\n  res = 0\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for i in 1..n\n    res += i\n  end\n\n  res\nend\n
    iteration.zig
    // for \u5faa\u73af\nfn forLoop(n: usize) i32 {\n    var res: i32 = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        res = res + @as(i32, @intCast(i));\n    }\n    return res;\n} \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-1 \u662f\u8be5\u6c42\u548c\u51fd\u6570\u7684\u6d41\u7a0b\u6846\u56fe\u3002

    \u56fe 2-1 \u00a0 \u6c42\u548c\u51fd\u6570\u7684\u6d41\u7a0b\u6846\u56fe

    \u6b64\u6c42\u548c\u51fd\u6570\u7684\u64cd\u4f5c\u6570\u91cf\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u6210\u6b63\u6bd4\uff0c\u6216\u8005\u8bf4\u6210\u201c\u7ebf\u6027\u5173\u7cfb\u201d\u3002\u5b9e\u9645\u4e0a\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u63cf\u8ff0\u7684\u5c31\u662f\u8fd9\u4e2a\u201c\u7ebf\u6027\u5173\u7cfb\u201d\u3002\u76f8\u5173\u5185\u5bb9\u5c06\u4f1a\u5728\u4e0b\u4e00\u8282\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2-while","title":"2. \u00a0 while \u5faa\u73af","text":"

    \u4e0e for \u5faa\u73af\u7c7b\u4f3c\uff0cwhile \u5faa\u73af\u4e5f\u662f\u4e00\u79cd\u5b9e\u73b0\u8fed\u4ee3\u7684\u65b9\u6cd5\u3002\u5728 while \u5faa\u73af\u4e2d\uff0c\u7a0b\u5e8f\u6bcf\u8f6e\u90fd\u4f1a\u5148\u68c0\u67e5\u6761\u4ef6\uff0c\u5982\u679c\u6761\u4ef6\u4e3a\u771f\uff0c\u5219\u7ee7\u7eed\u6267\u884c\uff0c\u5426\u5219\u5c31\u7ed3\u675f\u5faa\u73af\u3002

    \u4e0b\u9762\u6211\u4eec\u7528 while \u5faa\u73af\u6765\u5b9e\u73b0\u6c42\u548c \\(1 + 2 + \\dots + n\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop(n: int) -> int:\n    \"\"\"while \u5faa\u73af\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n:\n        res += i\n        i += 1  # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af */\nint WhileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af */\nfunc whileLoop(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af */\nfunc whileLoop(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i\n        i += 1 // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af */\nfunction whileLoop(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af */\nfunction whileLoop(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while (i <= n) {\n    res += i;\n    i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af */\nfn while_loop(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af */\nfun whileLoop(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i\n        i++ // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af ###\ndef while_loop(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while i <= n\n    res += i\n    i += 1 # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  end\n\n  res\nend\n
    iteration.zig
    // while \u5faa\u73af\nfn whileLoop(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += @intCast(i);\n        i += 1;\n    }\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    while \u5faa\u73af\u6bd4 for \u5faa\u73af\u7684\u81ea\u7531\u5ea6\u66f4\u9ad8\u3002\u5728 while \u5faa\u73af\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u81ea\u7531\u5730\u8bbe\u8ba1\u6761\u4ef6\u53d8\u91cf\u7684\u521d\u59cb\u5316\u548c\u66f4\u65b0\u6b65\u9aa4\u3002

    \u4f8b\u5982\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u6761\u4ef6\u53d8\u91cf \\(i\\) \u6bcf\u8f6e\u8fdb\u884c\u4e24\u6b21\u66f4\u65b0\uff0c\u8fd9\u79cd\u60c5\u51b5\u5c31\u4e0d\u592a\u65b9\u4fbf\u7528 for \u5faa\u73af\u5b9e\u73b0\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop_ii(n: int) -> int:\n    \"\"\"while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n:\n        res += i\n        # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint WhileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1; \n        i *= 2;\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while (i <= n) {\n    res += i;\n    // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i++;\n    i *= 2;\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfn while_loop_ii(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfun whileLoopII(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09###\ndef while_loop_ii(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while i <= n\n    res += i\n    # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i += 1\n    i *= 2\n  end\n\n  res\nend\n
    iteration.zig
    //  while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\nfn whileLoopII(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += @intCast(i);\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u603b\u7684\u6765\u8bf4\uff0cfor \u5faa\u73af\u7684\u4ee3\u7801\u66f4\u52a0\u7d27\u51d1\uff0cwhile \u5faa\u73af\u66f4\u52a0\u7075\u6d3b\uff0c\u4e24\u8005\u90fd\u53ef\u4ee5\u5b9e\u73b0\u8fed\u4ee3\u7ed3\u6784\u3002\u9009\u62e9\u4f7f\u7528\u54ea\u4e00\u4e2a\u5e94\u8be5\u6839\u636e\u7279\u5b9a\u95ee\u9898\u7684\u9700\u6c42\u6765\u51b3\u5b9a\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3","title":"3. \u00a0 \u5d4c\u5957\u5faa\u73af","text":"

    \u6211\u4eec\u53ef\u4ee5\u5728\u4e00\u4e2a\u5faa\u73af\u7ed3\u6784\u5185\u5d4c\u5957\u53e6\u4e00\u4e2a\u5faa\u73af\u7ed3\u6784\uff0c\u4e0b\u9762\u4ee5 for \u5faa\u73af\u4e3a\u4f8b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def nested_for_loop(n: int) -> str:\n    \"\"\"\u53cc\u5c42 for \u5faa\u73af\"\"\"\n    res = \"\"\n    # \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        # \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in range(1, n + 1):\n            res += f\"({i}, {j}), \"\n    return res\n
    iteration.cpp
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring nestedForLoop(int n) {\n    ostringstream res;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; ++j) {\n            res << \"(\" << i << \", \" << j << \"), \";\n        }\n    }\n    return res.str();\n}\n
    iteration.java
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n    StringBuilder res = new StringBuilder();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.append(\"(\" + i + \", \" + j + \"), \");\n        }\n    }\n    return res.toString();\n}\n
    iteration.cs
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring NestedForLoop(int n) {\n    StringBuilder res = new();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.Append($\"({i}, {j}), \");\n        }\n    }\n    return res.ToString();\n}\n
    iteration.go
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n int) string {\n    res := \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= n; j++ {\n            // \u5faa\u73af j = 1, 2, ..., n-1, n\n            res += fmt.Sprintf(\"(%d, %d), \", i, j)\n        }\n    }\n    return res\n}\n
    iteration.swift
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n: Int) -> String {\n    var res = \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1 ... n {\n            res.append(\"(\\(i), \\(j)), \")\n        }\n    }\n    return res\n}\n
    iteration.js
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n) {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.ts
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n: number): string {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.dart
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n  String res = \"\";\n  // \u5faa\u73af i = 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    // \u5faa\u73af j = 1, 2, ..., n-1, n\n    for (int j = 1; j <= n; j++) {\n      res += \"($i, $j), \";\n    }\n  }\n  return res;\n}\n
    iteration.rs
    /* \u53cc\u5c42 for \u5faa\u73af */\nfn nested_for_loop(n: i32) -> String {\n    let mut res = vec![];\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1..=n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1..=n {\n            res.push(format!(\"({}, {}), \", i, j));\n        }\n    }\n    res.join(\"\")\n}\n
    iteration.c
    /* \u53cc\u5c42 for \u5faa\u73af */\nchar *nestedForLoop(int n) {\n    // n * n \u4e3a\u5bf9\u5e94\u70b9\u6570\u91cf\uff0c\"(i, j), \" \u5bf9\u5e94\u5b57\u7b26\u4e32\u957f\u6700\u5927\u4e3a 6+10*2\uff0c\u52a0\u4e0a\u6700\u540e\u4e00\u4e2a\u7a7a\u5b57\u7b26 \\0 \u7684\u989d\u5916\u7a7a\u95f4\n    int size = n * n * 26 + 1;\n    char *res = malloc(size * sizeof(char));\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            char tmp[26];\n            snprintf(tmp, sizeof(tmp), \"(%d, %d), \", i, j);\n            strncat(res, tmp, size - strlen(res) - 1);\n        }\n    }\n    return res;\n}\n
    iteration.kt
    /* \u53cc\u5c42 for \u5faa\u73af */\nfun nestedForLoop(n: Int): String {\n    val res = StringBuilder()\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (j in 1..n) {\n            res.append(\" ($i, $j), \")\n        }\n    }\n    return res.toString()\n}\n
    iteration.rb
    ### \u53cc\u5c42 for \u5faa\u73af ###\ndef nested_for_loop(n)\n  res = \"\"\n\n  # \u5faa\u73af i = 1, 2, ..., n-1, n\n  for i in 1..n\n    # \u5faa\u73af j = 1, 2, ..., n-1, n\n    for j in 1..n\n      res += \"(#{i}, #{j}), \"\n    end\n  end\n\n  res\nend\n
    iteration.zig
    // \u53cc\u5c42 for \u5faa\u73af\nfn nestedForLoop(allocator: Allocator, n: usize) ![]const u8 {\n    var res = std.ArrayList(u8).init(allocator);\n    defer res.deinit();\n    var buffer: [20]u8 = undefined;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (1..n+1) |j| {\n            var _str = try std.fmt.bufPrint(&buffer, \"({d}, {d}), \", .{i, j});\n            try res.appendSlice(_str);\n        }\n    }\n    return res.toOwnedSlice();\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-2 \u662f\u8be5\u5d4c\u5957\u5faa\u73af\u7684\u6d41\u7a0b\u6846\u56fe\u3002

    \u56fe 2-2 \u00a0 \u5d4c\u5957\u5faa\u73af\u7684\u6d41\u7a0b\u6846\u56fe

    \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u7684\u64cd\u4f5c\u6570\u91cf\u4e0e \\(n^2\\) \u6210\u6b63\u6bd4\uff0c\u6216\u8005\u8bf4\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u548c\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u6210\u201c\u5e73\u65b9\u5173\u7cfb\u201d\u3002

    \u6211\u4eec\u53ef\u4ee5\u7ee7\u7eed\u6dfb\u52a0\u5d4c\u5957\u5faa\u73af\uff0c\u6bcf\u4e00\u6b21\u5d4c\u5957\u90fd\u662f\u4e00\u6b21\u201c\u5347\u7ef4\u201d\uff0c\u5c06\u4f1a\u4f7f\u65f6\u95f4\u590d\u6742\u5ea6\u63d0\u9ad8\u81f3\u201c\u7acb\u65b9\u5173\u7cfb\u201d\u201c\u56db\u6b21\u65b9\u5173\u7cfb\u201d\uff0c\u4ee5\u6b64\u7c7b\u63a8\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#222","title":"2.2.2 \u00a0 \u9012\u5f52","text":"

    \u9012\u5f52\uff08recursion\uff09\u662f\u4e00\u79cd\u7b97\u6cd5\u7b56\u7565\uff0c\u901a\u8fc7\u51fd\u6570\u8c03\u7528\u81ea\u8eab\u6765\u89e3\u51b3\u95ee\u9898\u3002\u5b83\u4e3b\u8981\u5305\u542b\u4e24\u4e2a\u9636\u6bb5\u3002

    1. \u9012\uff1a\u7a0b\u5e8f\u4e0d\u65ad\u6df1\u5165\u5730\u8c03\u7528\u81ea\u8eab\uff0c\u901a\u5e38\u4f20\u5165\u66f4\u5c0f\u6216\u66f4\u7b80\u5316\u7684\u53c2\u6570\uff0c\u76f4\u5230\u8fbe\u5230\u201c\u7ec8\u6b62\u6761\u4ef6\u201d\u3002
    2. \u5f52\uff1a\u89e6\u53d1\u201c\u7ec8\u6b62\u6761\u4ef6\u201d\u540e\uff0c\u7a0b\u5e8f\u4ece\u6700\u6df1\u5c42\u7684\u9012\u5f52\u51fd\u6570\u5f00\u59cb\u9010\u5c42\u8fd4\u56de\uff0c\u6c47\u805a\u6bcf\u4e00\u5c42\u7684\u7ed3\u679c\u3002

    \u800c\u4ece\u5b9e\u73b0\u7684\u89d2\u5ea6\u770b\uff0c\u9012\u5f52\u4ee3\u7801\u4e3b\u8981\u5305\u542b\u4e09\u4e2a\u8981\u7d20\u3002

    1. \u7ec8\u6b62\u6761\u4ef6\uff1a\u7528\u4e8e\u51b3\u5b9a\u4ec0\u4e48\u65f6\u5019\u7531\u201c\u9012\u201d\u8f6c\u201c\u5f52\u201d\u3002
    2. \u9012\u5f52\u8c03\u7528\uff1a\u5bf9\u5e94\u201c\u9012\u201d\uff0c\u51fd\u6570\u8c03\u7528\u81ea\u8eab\uff0c\u901a\u5e38\u8f93\u5165\u66f4\u5c0f\u6216\u66f4\u7b80\u5316\u7684\u53c2\u6570\u3002
    3. \u8fd4\u56de\u7ed3\u679c\uff1a\u5bf9\u5e94\u201c\u5f52\u201d\uff0c\u5c06\u5f53\u524d\u9012\u5f52\u5c42\u7ea7\u7684\u7ed3\u679c\u8fd4\u56de\u81f3\u4e0a\u4e00\u5c42\u3002

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u6211\u4eec\u53ea\u9700\u8c03\u7528\u51fd\u6570 recur(n) \uff0c\u5c31\u53ef\u4ee5\u5b8c\u6210 \\(1 + 2 + \\dots + n\\) \u7684\u8ba1\u7b97\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def recur(n: int) -> int:\n    \"\"\"\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 1:\n        return 1\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res = recur(n - 1)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n
    recursion.cpp
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.java
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.cs
    /* \u9012\u5f52 */\nint Recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = Recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.go
    /* \u9012\u5f52 */\nfunc recur(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res := recur(n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.swift
    /* \u9012\u5f52 */\nfunc recur(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n: n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.js
    /* \u9012\u5f52 */\nfunction recur(n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.ts
    /* \u9012\u5f52 */\nfunction recur(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.dart
    /* \u9012\u5f52 */\nint recur(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 1) return 1;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  int res = recur(n - 1);\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  return n + res;\n}\n
    recursion.rs
    /* \u9012\u5f52 */\nfn recur(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    n + res\n}\n
    recursion.c
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.kt
    /* \u9012\u5f52 */\nfun recur(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    val res = recur(n - 1)\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.rb
    ### \u9012\u5f52 ###\ndef recur(n)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return 1 if n == 1\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  res = recur(n - 1)\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  n + res\nend\n
    recursion.zig
    // \u9012\u5f52\u51fd\u6570\nfn recur(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1) {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var res: i32 = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-3 \u5c55\u793a\u4e86\u8be5\u51fd\u6570\u7684\u9012\u5f52\u8fc7\u7a0b\u3002

    \u56fe 2-3 \u00a0 \u6c42\u548c\u51fd\u6570\u7684\u9012\u5f52\u8fc7\u7a0b

    \u867d\u7136\u4ece\u8ba1\u7b97\u89d2\u5ea6\u770b\uff0c\u8fed\u4ee3\u4e0e\u9012\u5f52\u53ef\u4ee5\u5f97\u5230\u76f8\u540c\u7684\u7ed3\u679c\uff0c\u4f46\u5b83\u4eec\u4ee3\u8868\u4e86\u4e24\u79cd\u5b8c\u5168\u4e0d\u540c\u7684\u601d\u8003\u548c\u89e3\u51b3\u95ee\u9898\u7684\u8303\u5f0f\u3002

    • \u8fed\u4ee3\uff1a\u201c\u81ea\u4e0b\u800c\u4e0a\u201d\u5730\u89e3\u51b3\u95ee\u9898\u3002\u4ece\u6700\u57fa\u7840\u7684\u6b65\u9aa4\u5f00\u59cb\uff0c\u7136\u540e\u4e0d\u65ad\u91cd\u590d\u6216\u7d2f\u52a0\u8fd9\u4e9b\u6b65\u9aa4\uff0c\u76f4\u5230\u4efb\u52a1\u5b8c\u6210\u3002
    • \u9012\u5f52\uff1a\u201c\u81ea\u4e0a\u800c\u4e0b\u201d\u5730\u89e3\u51b3\u95ee\u9898\u3002\u5c06\u539f\u95ee\u9898\u5206\u89e3\u4e3a\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u8fd9\u4e9b\u5b50\u95ee\u9898\u548c\u539f\u95ee\u9898\u5177\u6709\u76f8\u540c\u7684\u5f62\u5f0f\u3002\u63a5\u4e0b\u6765\u5c06\u5b50\u95ee\u9898\u7ee7\u7eed\u5206\u89e3\u4e3a\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u76f4\u5230\u57fa\u672c\u60c5\u51b5\u65f6\u505c\u6b62\uff08\u57fa\u672c\u60c5\u51b5\u7684\u89e3\u662f\u5df2\u77e5\u7684\uff09\u3002

    \u4ee5\u4e0a\u8ff0\u6c42\u548c\u51fd\u6570\u4e3a\u4f8b\uff0c\u8bbe\u95ee\u9898 \\(f(n) = 1 + 2 + \\dots + n\\) \u3002

    • \u8fed\u4ee3\uff1a\u5728\u5faa\u73af\u4e2d\u6a21\u62df\u6c42\u548c\u8fc7\u7a0b\uff0c\u4ece \\(1\\) \u904d\u5386\u5230 \\(n\\) \uff0c\u6bcf\u8f6e\u6267\u884c\u6c42\u548c\u64cd\u4f5c\uff0c\u5373\u53ef\u6c42\u5f97 \\(f(n)\\) \u3002
    • \u9012\u5f52\uff1a\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u5b50\u95ee\u9898 \\(f(n) = n + f(n-1)\\) \uff0c\u4e0d\u65ad\uff08\u9012\u5f52\u5730\uff09\u5206\u89e3\u4e0b\u53bb\uff0c\u76f4\u81f3\u57fa\u672c\u60c5\u51b5 \\(f(1) = 1\\) \u65f6\u7ec8\u6b62\u3002
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1","title":"1. \u00a0 \u8c03\u7528\u6808","text":"

    \u9012\u5f52\u51fd\u6570\u6bcf\u6b21\u8c03\u7528\u81ea\u8eab\u65f6\uff0c\u7cfb\u7edf\u90fd\u4f1a\u4e3a\u65b0\u5f00\u542f\u7684\u51fd\u6570\u5206\u914d\u5185\u5b58\uff0c\u4ee5\u5b58\u50a8\u5c40\u90e8\u53d8\u91cf\u3001\u8c03\u7528\u5730\u5740\u548c\u5176\u4ed6\u4fe1\u606f\u7b49\u3002\u8fd9\u5c06\u5bfc\u81f4\u4e24\u65b9\u9762\u7684\u7ed3\u679c\u3002

    • \u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u6570\u636e\u90fd\u5b58\u50a8\u5728\u79f0\u4e3a\u201c\u6808\u5e27\u7a7a\u95f4\u201d\u7684\u5185\u5b58\u533a\u57df\u4e2d\uff0c\u76f4\u81f3\u51fd\u6570\u8fd4\u56de\u540e\u624d\u4f1a\u88ab\u91ca\u653e\u3002\u56e0\u6b64\uff0c\u9012\u5f52\u901a\u5e38\u6bd4\u8fed\u4ee3\u66f4\u52a0\u8017\u8d39\u5185\u5b58\u7a7a\u95f4\u3002
    • \u9012\u5f52\u8c03\u7528\u51fd\u6570\u4f1a\u4ea7\u751f\u989d\u5916\u7684\u5f00\u9500\u3002\u56e0\u6b64\u9012\u5f52\u901a\u5e38\u6bd4\u5faa\u73af\u7684\u65f6\u95f4\u6548\u7387\u66f4\u4f4e\u3002

    \u5982\u56fe 2-4 \u6240\u793a\uff0c\u5728\u89e6\u53d1\u7ec8\u6b62\u6761\u4ef6\u524d\uff0c\u540c\u65f6\u5b58\u5728 \\(n\\) \u4e2a\u672a\u8fd4\u56de\u7684\u9012\u5f52\u51fd\u6570\uff0c\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \u3002

    \u56fe 2-4 \u00a0 \u9012\u5f52\u8c03\u7528\u6df1\u5ea6

    \u5728\u5b9e\u9645\u4e2d\uff0c\u7f16\u7a0b\u8bed\u8a00\u5141\u8bb8\u7684\u9012\u5f52\u6df1\u5ea6\u901a\u5e38\u662f\u6709\u9650\u7684\uff0c\u8fc7\u6df1\u7684\u9012\u5f52\u53ef\u80fd\u5bfc\u81f4\u6808\u6ea2\u51fa\u9519\u8bef\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2","title":"2. \u00a0 \u5c3e\u9012\u5f52","text":"

    \u6709\u8da3\u7684\u662f\uff0c\u5982\u679c\u51fd\u6570\u5728\u8fd4\u56de\u524d\u7684\u6700\u540e\u4e00\u6b65\u624d\u8fdb\u884c\u9012\u5f52\u8c03\u7528\uff0c\u5219\u8be5\u51fd\u6570\u53ef\u4ee5\u88ab\u7f16\u8bd1\u5668\u6216\u89e3\u91ca\u5668\u4f18\u5316\uff0c\u4f7f\u5176\u5728\u7a7a\u95f4\u6548\u7387\u4e0a\u4e0e\u8fed\u4ee3\u76f8\u5f53\u3002\u8fd9\u79cd\u60c5\u51b5\u88ab\u79f0\u4e3a\u5c3e\u9012\u5f52\uff08tail recursion\uff09\u3002

    • \u666e\u901a\u9012\u5f52\uff1a\u5f53\u51fd\u6570\u8fd4\u56de\u5230\u4e0a\u4e00\u5c42\u7ea7\u7684\u51fd\u6570\u540e\uff0c\u9700\u8981\u7ee7\u7eed\u6267\u884c\u4ee3\u7801\uff0c\u56e0\u6b64\u7cfb\u7edf\u9700\u8981\u4fdd\u5b58\u4e0a\u4e00\u5c42\u8c03\u7528\u7684\u4e0a\u4e0b\u6587\u3002
    • \u5c3e\u9012\u5f52\uff1a\u9012\u5f52\u8c03\u7528\u662f\u51fd\u6570\u8fd4\u56de\u524d\u7684\u6700\u540e\u4e00\u4e2a\u64cd\u4f5c\uff0c\u8fd9\u610f\u5473\u7740\u51fd\u6570\u8fd4\u56de\u5230\u4e0a\u4e00\u5c42\u7ea7\u540e\uff0c\u65e0\u987b\u7ee7\u7eed\u6267\u884c\u5176\u4ed6\u64cd\u4f5c\uff0c\u56e0\u6b64\u7cfb\u7edf\u65e0\u987b\u4fdd\u5b58\u4e0a\u4e00\u5c42\u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u3002

    \u4ee5\u8ba1\u7b97 \\(1 + 2 + \\dots + n\\) \u4e3a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u7ed3\u679c\u53d8\u91cf res \u8bbe\u4e3a\u51fd\u6570\u53c2\u6570\uff0c\u4ece\u800c\u5b9e\u73b0\u5c3e\u9012\u5f52\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def tail_recur(n, res):\n    \"\"\"\u5c3e\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 0:\n        return res\n    # \u5c3e\u9012\u5f52\u8c03\u7528\n    return tail_recur(n - 1, res + n)\n
    recursion.cpp
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.java
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.cs
    /* \u5c3e\u9012\u5f52 */\nint TailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return TailRecur(n - 1, res + n);\n}\n
    recursion.go
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n int, res int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n-1, res+n)\n}\n
    recursion.swift
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n: Int, res: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n: n - 1, res: res + n)\n}\n
    recursion.js
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n, res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.ts
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n: number, res: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.dart
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 0) return res;\n  // \u5c3e\u9012\u5f52\u8c03\u7528\n  return tailRecur(n - 1, res + n);\n}\n
    recursion.rs
    /* \u5c3e\u9012\u5f52 */\nfn tail_recur(n: i32, res: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    tail_recur(n - 1, res + n)\n}\n
    recursion.c
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.kt
    /* \u5c3e\u9012\u5f52 */\ntailrec fun tailRecur(n: Int, res: Int): Int {\n    // \u6dfb\u52a0 tailrec \u5173\u952e\u8bcd\uff0c\u4ee5\u5f00\u542f\u5c3e\u9012\u5f52\u4f18\u5316\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n)\n}\n
    recursion.rb
    ### \u5c3e\u9012\u5f52 ###\ndef tail_recur(n, res)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return res if n == 0\n  # \u5c3e\u9012\u5f52\u8c03\u7528\n  tail_recur(n - 1, res + n)\nend\n
    recursion.zig
    // \u5c3e\u9012\u5f52\u51fd\u6570\nfn tailRecur(n: i32, res: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0) {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5c3e\u9012\u5f52\u7684\u6267\u884c\u8fc7\u7a0b\u5982\u56fe 2-5 \u6240\u793a\u3002\u5bf9\u6bd4\u666e\u901a\u9012\u5f52\u548c\u5c3e\u9012\u5f52\uff0c\u4e24\u8005\u7684\u6c42\u548c\u64cd\u4f5c\u7684\u6267\u884c\u70b9\u662f\u4e0d\u540c\u7684\u3002

    • \u666e\u901a\u9012\u5f52\uff1a\u6c42\u548c\u64cd\u4f5c\u662f\u5728\u201c\u5f52\u201d\u7684\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\uff0c\u6bcf\u5c42\u8fd4\u56de\u540e\u90fd\u8981\u518d\u6267\u884c\u4e00\u6b21\u6c42\u548c\u64cd\u4f5c\u3002
    • \u5c3e\u9012\u5f52\uff1a\u6c42\u548c\u64cd\u4f5c\u662f\u5728\u201c\u9012\u201d\u7684\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\uff0c\u201c\u5f52\u201d\u7684\u8fc7\u7a0b\u53ea\u9700\u5c42\u5c42\u8fd4\u56de\u3002

    \u56fe 2-5 \u00a0 \u5c3e\u9012\u5f52\u8fc7\u7a0b

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u8bb8\u591a\u7f16\u8bd1\u5668\u6216\u89e3\u91ca\u5668\u5e76\u4e0d\u652f\u6301\u5c3e\u9012\u5f52\u4f18\u5316\u3002\u4f8b\u5982\uff0cPython \u9ed8\u8ba4\u4e0d\u652f\u6301\u5c3e\u9012\u5f52\u4f18\u5316\uff0c\u56e0\u6b64\u5373\u4f7f\u51fd\u6570\u662f\u5c3e\u9012\u5f52\u5f62\u5f0f\uff0c\u4ecd\u7136\u53ef\u80fd\u4f1a\u9047\u5230\u6808\u6ea2\u51fa\u95ee\u9898\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3_1","title":"3. \u00a0 \u9012\u5f52\u6811","text":"

    \u5f53\u5904\u7406\u4e0e\u201c\u5206\u6cbb\u201d\u76f8\u5173\u7684\u7b97\u6cd5\u95ee\u9898\u65f6\uff0c\u9012\u5f52\u5f80\u5f80\u6bd4\u8fed\u4ee3\u7684\u601d\u8def\u66f4\u52a0\u76f4\u89c2\u3001\u4ee3\u7801\u66f4\u52a0\u6613\u8bfb\u3002\u4ee5\u201c\u6590\u6ce2\u90a3\u5951\u6570\u5217\u201d\u4e3a\u4f8b\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6590\u6ce2\u90a3\u5951\u6570\u5217 \\(0, 1, 1, 2, 3, 5, 8, 13, \\dots\\) \uff0c\u6c42\u8be5\u6570\u5217\u7684\u7b2c \\(n\\) \u4e2a\u6570\u5b57\u3002

    \u8bbe\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u7b2c \\(n\\) \u4e2a\u6570\u5b57\u4e3a \\(f(n)\\) \uff0c\u6613\u5f97\u4e24\u4e2a\u7ed3\u8bba\u3002

    • \u6570\u5217\u7684\u524d\u4e24\u4e2a\u6570\u5b57\u4e3a \\(f(1) = 0\\) \u548c \\(f(2) = 1\\) \u3002
    • \u6570\u5217\u4e2d\u7684\u6bcf\u4e2a\u6570\u5b57\u662f\u524d\u4e24\u4e2a\u6570\u5b57\u7684\u548c\uff0c\u5373 \\(f(n) = f(n - 1) + f(n - 2)\\) \u3002

    \u6309\u7167\u9012\u63a8\u5173\u7cfb\u8fdb\u884c\u9012\u5f52\u8c03\u7528\uff0c\u5c06\u524d\u4e24\u4e2a\u6570\u5b57\u4f5c\u4e3a\u7ec8\u6b62\u6761\u4ef6\uff0c\u4fbf\u53ef\u5199\u51fa\u9012\u5f52\u4ee3\u7801\u3002\u8c03\u7528 fib(n) \u5373\u53ef\u5f97\u5230\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u7b2c \\(n\\) \u4e2a\u6570\u5b57\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def fib(n: int) -> int:\n    \"\"\"\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 or n == 2:\n        return n - 1\n    # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res = fib(n - 1) + fib(n - 2)\n    # \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n
    recursion.cpp
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.java
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.cs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint Fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = Fib(n - 1) + Fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.go
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res := fib(n-1) + fib(n-2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.swift
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n: n - 1) + fib(n: n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.js
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.ts
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.dart
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  if (n == 1 || n == 2) return n - 1;\n  // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  int res = fib(n - 1) + fib(n - 2);\n  // \u8fd4\u56de\u7ed3\u679c f(n)\n  return res;\n}\n
    recursion.rs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfn fib(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c\n    res\n}\n
    recursion.c
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.kt
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfun fib(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    val res = fib(n - 1) + fib(n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.rb
    ### \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 ###\ndef fib(n)\n  # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  return n - 1 if n == 1 || n == 2\n  # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  res = fib(n - 1) + fib(n - 2)\n  # \u8fd4\u56de\u7ed3\u679c f(n)\n  res\nend\n
    recursion.zig
    // \u6590\u6ce2\u90a3\u5951\u6570\u5217\nfn fib(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 or n == 2) {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    var res: i32 = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u4ee5\u4e0a\u4ee3\u7801\uff0c\u6211\u4eec\u5728\u51fd\u6570\u5185\u9012\u5f52\u8c03\u7528\u4e86\u4e24\u4e2a\u51fd\u6570\uff0c\u8fd9\u610f\u5473\u7740\u4ece\u4e00\u4e2a\u8c03\u7528\u4ea7\u751f\u4e86\u4e24\u4e2a\u8c03\u7528\u5206\u652f\u3002\u5982\u56fe 2-6 \u6240\u793a\uff0c\u8fd9\u6837\u4e0d\u65ad\u9012\u5f52\u8c03\u7528\u4e0b\u53bb\uff0c\u6700\u7ec8\u5c06\u4ea7\u751f\u4e00\u68f5\u5c42\u6570\u4e3a \\(n\\) \u7684\u9012\u5f52\u6811\uff08recursion tree\uff09\u3002

    \u56fe 2-6 \u00a0 \u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u9012\u5f52\u6811

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u9012\u5f52\u4f53\u73b0\u4e86\u201c\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u66f4\u5c0f\u5b50\u95ee\u9898\u201d\u7684\u601d\u7ef4\u8303\u5f0f\uff0c\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u81f3\u5173\u91cd\u8981\u3002

    • \u4ece\u7b97\u6cd5\u89d2\u5ea6\u770b\uff0c\u641c\u7d22\u3001\u6392\u5e8f\u3001\u56de\u6eaf\u3001\u5206\u6cbb\u3001\u52a8\u6001\u89c4\u5212\u7b49\u8bb8\u591a\u91cd\u8981\u7b97\u6cd5\u7b56\u7565\u76f4\u63a5\u6216\u95f4\u63a5\u5730\u5e94\u7528\u4e86\u8fd9\u79cd\u601d\u7ef4\u65b9\u5f0f\u3002
    • \u4ece\u6570\u636e\u7ed3\u6784\u89d2\u5ea6\u770b\uff0c\u9012\u5f52\u5929\u7136\u9002\u5408\u5904\u7406\u94fe\u8868\u3001\u6811\u548c\u56fe\u7684\u76f8\u5173\u95ee\u9898\uff0c\u56e0\u4e3a\u5b83\u4eec\u975e\u5e38\u9002\u5408\u7528\u5206\u6cbb\u601d\u60f3\u8fdb\u884c\u5206\u6790\u3002
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#223","title":"2.2.3 \u00a0 \u4e24\u8005\u5bf9\u6bd4","text":"

    \u603b\u7ed3\u4ee5\u4e0a\u5185\u5bb9\uff0c\u5982\u8868 2-1 \u6240\u793a\uff0c\u8fed\u4ee3\u548c\u9012\u5f52\u5728\u5b9e\u73b0\u3001\u6027\u80fd\u548c\u9002\u7528\u6027\u4e0a\u6709\u6240\u4e0d\u540c\u3002

    \u8868 2-1 \u00a0 \u8fed\u4ee3\u4e0e\u9012\u5f52\u7279\u70b9\u5bf9\u6bd4

    \u8fed\u4ee3 \u9012\u5f52 \u5b9e\u73b0\u65b9\u5f0f \u5faa\u73af\u7ed3\u6784 \u51fd\u6570\u8c03\u7528\u81ea\u8eab \u65f6\u95f4\u6548\u7387 \u6548\u7387\u901a\u5e38\u8f83\u9ad8\uff0c\u65e0\u51fd\u6570\u8c03\u7528\u5f00\u9500 \u6bcf\u6b21\u51fd\u6570\u8c03\u7528\u90fd\u4f1a\u4ea7\u751f\u5f00\u9500 \u5185\u5b58\u4f7f\u7528 \u901a\u5e38\u4f7f\u7528\u56fa\u5b9a\u5927\u5c0f\u7684\u5185\u5b58\u7a7a\u95f4 \u7d2f\u79ef\u51fd\u6570\u8c03\u7528\u53ef\u80fd\u4f7f\u7528\u5927\u91cf\u7684\u6808\u5e27\u7a7a\u95f4 \u9002\u7528\u95ee\u9898 \u9002\u7528\u4e8e\u7b80\u5355\u5faa\u73af\u4efb\u52a1\uff0c\u4ee3\u7801\u76f4\u89c2\u3001\u53ef\u8bfb\u6027\u597d \u9002\u7528\u4e8e\u5b50\u95ee\u9898\u5206\u89e3\uff0c\u5982\u6811\u3001\u56fe\u3001\u5206\u6cbb\u3001\u56de\u6eaf\u7b49\uff0c\u4ee3\u7801\u7ed3\u6784\u7b80\u6d01\u3001\u6e05\u6670

    Tip

    \u5982\u679c\u611f\u89c9\u4ee5\u4e0b\u5185\u5bb9\u7406\u89e3\u56f0\u96be\uff0c\u53ef\u4ee5\u5728\u8bfb\u5b8c\u201c\u6808\u201d\u7ae0\u8282\u540e\u518d\u6765\u590d\u4e60\u3002

    \u90a3\u4e48\uff0c\u8fed\u4ee3\u548c\u9012\u5f52\u5177\u6709\u4ec0\u4e48\u5185\u5728\u8054\u7cfb\u5462\uff1f\u4ee5\u4e0a\u8ff0\u9012\u5f52\u51fd\u6570\u4e3a\u4f8b\uff0c\u6c42\u548c\u64cd\u4f5c\u5728\u9012\u5f52\u7684\u201c\u5f52\u201d\u9636\u6bb5\u8fdb\u884c\u3002\u8fd9\u610f\u5473\u7740\u6700\u521d\u88ab\u8c03\u7528\u7684\u51fd\u6570\u5b9e\u9645\u4e0a\u662f\u6700\u540e\u5b8c\u6210\u5176\u6c42\u548c\u64cd\u4f5c\u7684\uff0c\u8fd9\u79cd\u5de5\u4f5c\u673a\u5236\u4e0e\u6808\u7684\u201c\u5148\u5165\u540e\u51fa\u201d\u539f\u5219\u5f02\u66f2\u540c\u5de5\u3002

    \u4e8b\u5b9e\u4e0a\uff0c\u201c\u8c03\u7528\u6808\u201d\u548c\u201c\u6808\u5e27\u7a7a\u95f4\u201d\u8fd9\u7c7b\u9012\u5f52\u672f\u8bed\u5df2\u7ecf\u6697\u793a\u4e86\u9012\u5f52\u4e0e\u6808\u4e4b\u95f4\u7684\u5bc6\u5207\u5173\u7cfb\u3002

    1. \u9012\uff1a\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u7cfb\u7edf\u4f1a\u5728\u201c\u8c03\u7528\u6808\u201d\u4e0a\u4e3a\u8be5\u51fd\u6570\u5206\u914d\u65b0\u7684\u6808\u5e27\uff0c\u7528\u4e8e\u5b58\u50a8\u51fd\u6570\u7684\u5c40\u90e8\u53d8\u91cf\u3001\u53c2\u6570\u3001\u8fd4\u56de\u5730\u5740\u7b49\u6570\u636e\u3002
    2. \u5f52\uff1a\u5f53\u51fd\u6570\u5b8c\u6210\u6267\u884c\u5e76\u8fd4\u56de\u65f6\uff0c\u5bf9\u5e94\u7684\u6808\u5e27\u4f1a\u88ab\u4ece\u201c\u8c03\u7528\u6808\u201d\u4e0a\u79fb\u9664\uff0c\u6062\u590d\u4e4b\u524d\u51fd\u6570\u7684\u6267\u884c\u73af\u5883\u3002

    \u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u8c03\u7528\u6808\u7684\u884c\u4e3a\uff0c\u4ece\u800c\u5c06\u9012\u5f52\u8f6c\u5316\u4e3a\u8fed\u4ee3\u5f62\u5f0f\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def for_loop_recur(n: int) -> int:\n    \"\"\"\u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\"\"\"\n    # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack = []\n    res = 0\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in range(n, 0, -1):\n        # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while stack:\n        # \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    # res = 1+2+3+...+n\n    return res\n
    recursion.cpp
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack<int> stack;\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.empty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.top();\n        stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.java
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<Integer> stack = new Stack<>();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.isEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.cs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint ForLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<int> stack = new();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.Push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.Count > 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.go
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n int) int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack := list.New()\n    res := 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i := n; i > 0; i-- {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.PushBack(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    for stack.Len() != 0 {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Back().Value.(int)\n        stack.Remove(stack.Back())\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.swift
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n: Int) -> Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [Int] = []\n    var res = 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1 ... n).reversed() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.isEmpty {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.removeLast()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.js
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    const stack = [];\n    let res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.ts
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n: number): number {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808 \n    const stack: number[] = [];\n    let res: number = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.dart
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n  // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  List<int> stack = [];\n  int res = 0;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for (int i = n; i > 0; i--) {\n    // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack.add(i);\n  }\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while (!stack.isEmpty) {\n    // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n    res += stack.removeLast();\n  }\n  // res = 1+2+3+...+n\n  return res;\n}\n
    recursion.rs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfn for_loop_recur(n: i32) -> i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    let mut stack = Vec::new();\n    let mut res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1..=n).rev() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.is_empty() {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop().unwrap();\n    }\n    // res = 1+2+3+...+n\n    res\n}\n
    recursion.c
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    int stack[1000]; // \u501f\u52a9\u4e00\u4e2a\u5927\u6570\u7ec4\u6765\u6a21\u62df\u6808\n    int top = -1;    // \u6808\u9876\u7d22\u5f15\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack[1 + top++] = i;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (top >= 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack[top--];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.kt
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfun forLoopRecur(n: Int): Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    val stack = Stack<Int>()\n    var res = 0\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    for (i in n downTo 0) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i)\n    }\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    while (stack.isNotEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.rb
    ### \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 ###\ndef for_loop_recur(n)\n  # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  stack = []\n  res = 0\n\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for i in n.downto(0)\n    # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack << i\n  end\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while !stack.empty?\n    res += stack.pop\n  end\n\n  # res = 1+2+3+...+n\n  res\nend\n
    recursion.zig
    // \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\nfn forLoopRecur(comptime n: i32) i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [n]i32 = undefined;\n    var res: i32 = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var i: usize = n;\n    while (i > 0) {\n        stack[i - 1] = @intCast(i);\n        i -= 1;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    var index: usize = n;\n    while (index > 0) {\n        index -= 1;\n        res += stack[index];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u4ee5\u4e0a\u4ee3\u7801\uff0c\u5f53\u9012\u5f52\u8f6c\u5316\u4e3a\u8fed\u4ee3\u540e\uff0c\u4ee3\u7801\u53d8\u5f97\u66f4\u52a0\u590d\u6742\u4e86\u3002\u5c3d\u7ba1\u8fed\u4ee3\u548c\u9012\u5f52\u5728\u5f88\u591a\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4e92\u76f8\u8f6c\u5316\uff0c\u4f46\u4e0d\u4e00\u5b9a\u503c\u5f97\u8fd9\u6837\u505a\uff0c\u6709\u4ee5\u4e0b\u4e24\u70b9\u539f\u56e0\u3002

    • \u8f6c\u5316\u540e\u7684\u4ee3\u7801\u53ef\u80fd\u66f4\u52a0\u96be\u4ee5\u7406\u89e3\uff0c\u53ef\u8bfb\u6027\u66f4\u5dee\u3002
    • \u5bf9\u4e8e\u67d0\u4e9b\u590d\u6742\u95ee\u9898\uff0c\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\u7684\u884c\u4e3a\u53ef\u80fd\u975e\u5e38\u56f0\u96be\u3002

    \u603b\u4e4b\uff0c\u9009\u62e9\u8fed\u4ee3\u8fd8\u662f\u9012\u5f52\u53d6\u51b3\u4e8e\u7279\u5b9a\u95ee\u9898\u7684\u6027\u8d28\u3002\u5728\u7f16\u7a0b\u5b9e\u8df5\u4e2d\uff0c\u6743\u8861\u4e24\u8005\u7684\u4f18\u52a3\u5e76\u6839\u636e\u60c5\u5883\u9009\u62e9\u5408\u9002\u7684\u65b9\u6cd5\u81f3\u5173\u91cd\u8981\u3002

    "},{"location":"chapter_computational_complexity/performance_evaluation/","title":"2.1 \u00a0 \u7b97\u6cd5\u6548\u7387\u8bc4\u4f30","text":"

    \u5728\u7b97\u6cd5\u8bbe\u8ba1\u4e2d\uff0c\u6211\u4eec\u5148\u540e\u8ffd\u6c42\u4ee5\u4e0b\u4e24\u4e2a\u5c42\u9762\u7684\u76ee\u6807\u3002

    1. \u627e\u5230\u95ee\u9898\u89e3\u6cd5\uff1a\u7b97\u6cd5\u9700\u8981\u5728\u89c4\u5b9a\u7684\u8f93\u5165\u8303\u56f4\u5185\u53ef\u9760\u5730\u6c42\u5f97\u95ee\u9898\u7684\u6b63\u786e\u89e3\u3002
    2. \u5bfb\u6c42\u6700\u4f18\u89e3\u6cd5\uff1a\u540c\u4e00\u4e2a\u95ee\u9898\u53ef\u80fd\u5b58\u5728\u591a\u79cd\u89e3\u6cd5\uff0c\u6211\u4eec\u5e0c\u671b\u627e\u5230\u5c3d\u53ef\u80fd\u9ad8\u6548\u7684\u7b97\u6cd5\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5728\u80fd\u591f\u89e3\u51b3\u95ee\u9898\u7684\u524d\u63d0\u4e0b\uff0c\u7b97\u6cd5\u6548\u7387\u5df2\u6210\u4e3a\u8861\u91cf\u7b97\u6cd5\u4f18\u52a3\u7684\u4e3b\u8981\u8bc4\u4ef7\u6307\u6807\uff0c\u5b83\u5305\u62ec\u4ee5\u4e0b\u4e24\u4e2a\u7ef4\u5ea6\u3002

    • \u65f6\u95f4\u6548\u7387\uff1a\u7b97\u6cd5\u8fd0\u884c\u901f\u5ea6\u7684\u5feb\u6162\u3002
    • \u7a7a\u95f4\u6548\u7387\uff1a\u7b97\u6cd5\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u7684\u5927\u5c0f\u3002

    \u7b80\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u7684\u76ee\u6807\u662f\u8bbe\u8ba1\u201c\u65e2\u5feb\u53c8\u7701\u201d\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u3002\u800c\u6709\u6548\u5730\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u81f3\u5173\u91cd\u8981\uff0c\u56e0\u4e3a\u53ea\u6709\u8fd9\u6837\uff0c\u6211\u4eec\u624d\u80fd\u5c06\u5404\u79cd\u7b97\u6cd5\u8fdb\u884c\u5bf9\u6bd4\uff0c\u8fdb\u800c\u6307\u5bfc\u7b97\u6cd5\u8bbe\u8ba1\u4e0e\u4f18\u5316\u8fc7\u7a0b\u3002

    \u6548\u7387\u8bc4\u4f30\u65b9\u6cd5\u4e3b\u8981\u5206\u4e3a\u4e24\u79cd\uff1a\u5b9e\u9645\u6d4b\u8bd5\u3001\u7406\u8bba\u4f30\u7b97\u3002

    "},{"location":"chapter_computational_complexity/performance_evaluation/#211","title":"2.1.1 \u00a0 \u5b9e\u9645\u6d4b\u8bd5","text":"

    \u5047\u8bbe\u6211\u4eec\u73b0\u5728\u6709\u7b97\u6cd5 A \u548c\u7b97\u6cd5 B \uff0c\u5b83\u4eec\u90fd\u80fd\u89e3\u51b3\u540c\u4e00\u95ee\u9898\uff0c\u73b0\u5728\u9700\u8981\u5bf9\u6bd4\u8fd9\u4e24\u4e2a\u7b97\u6cd5\u7684\u6548\u7387\u3002\u6700\u76f4\u63a5\u7684\u65b9\u6cd5\u662f\u627e\u4e00\u53f0\u8ba1\u7b97\u673a\uff0c\u8fd0\u884c\u8fd9\u4e24\u4e2a\u7b97\u6cd5\uff0c\u5e76\u76d1\u63a7\u8bb0\u5f55\u5b83\u4eec\u7684\u8fd0\u884c\u65f6\u95f4\u548c\u5185\u5b58\u5360\u7528\u60c5\u51b5\u3002\u8fd9\u79cd\u8bc4\u4f30\u65b9\u5f0f\u80fd\u591f\u53cd\u6620\u771f\u5b9e\u60c5\u51b5\uff0c\u4f46\u4e5f\u5b58\u5728\u8f83\u5927\u7684\u5c40\u9650\u6027\u3002

    \u4e00\u65b9\u9762\uff0c\u96be\u4ee5\u6392\u9664\u6d4b\u8bd5\u73af\u5883\u7684\u5e72\u6270\u56e0\u7d20\u3002\u786c\u4ef6\u914d\u7f6e\u4f1a\u5f71\u54cd\u7b97\u6cd5\u7684\u6027\u80fd\u3002\u6bd4\u5982\u5728\u67d0\u53f0\u8ba1\u7b97\u673a\u4e2d\uff0c\u7b97\u6cd5 A \u7684\u8fd0\u884c\u65f6\u95f4\u6bd4\u7b97\u6cd5 B \u77ed\uff1b\u4f46\u5728\u53e6\u4e00\u53f0\u914d\u7f6e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u4e2d\uff0c\u53ef\u80fd\u5f97\u5230\u76f8\u53cd\u7684\u6d4b\u8bd5\u7ed3\u679c\u3002\u8fd9\u610f\u5473\u7740\u6211\u4eec\u9700\u8981\u5728\u5404\u79cd\u673a\u5668\u4e0a\u8fdb\u884c\u6d4b\u8bd5\uff0c\u7edf\u8ba1\u5e73\u5747\u6548\u7387\uff0c\u800c\u8fd9\u662f\u4e0d\u73b0\u5b9e\u7684\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5c55\u5f00\u5b8c\u6574\u6d4b\u8bd5\u975e\u5e38\u8017\u8d39\u8d44\u6e90\u3002\u968f\u7740\u8f93\u5165\u6570\u636e\u91cf\u7684\u53d8\u5316\uff0c\u7b97\u6cd5\u4f1a\u8868\u73b0\u51fa\u4e0d\u540c\u7684\u6548\u7387\u3002\u4f8b\u5982\uff0c\u5728\u8f93\u5165\u6570\u636e\u91cf\u8f83\u5c0f\u65f6\uff0c\u7b97\u6cd5 A \u7684\u8fd0\u884c\u65f6\u95f4\u6bd4\u7b97\u6cd5 B \u77ed\uff1b\u800c\u5728\u8f93\u5165\u6570\u636e\u91cf\u8f83\u5927\u65f6\uff0c\u6d4b\u8bd5\u7ed3\u679c\u53ef\u80fd\u6070\u6070\u76f8\u53cd\u3002\u56e0\u6b64\uff0c\u4e3a\u4e86\u5f97\u5230\u6709\u8bf4\u670d\u529b\u7684\u7ed3\u8bba\uff0c\u6211\u4eec\u9700\u8981\u6d4b\u8bd5\u5404\u79cd\u89c4\u6a21\u7684\u8f93\u5165\u6570\u636e\uff0c\u800c\u8fd9\u9700\u8981\u8017\u8d39\u5927\u91cf\u7684\u8ba1\u7b97\u8d44\u6e90\u3002

    "},{"location":"chapter_computational_complexity/performance_evaluation/#212","title":"2.1.2 \u00a0 \u7406\u8bba\u4f30\u7b97","text":"

    \u7531\u4e8e\u5b9e\u9645\u6d4b\u8bd5\u5177\u6709\u8f83\u5927\u7684\u5c40\u9650\u6027\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u8003\u8651\u4ec5\u901a\u8fc7\u4e00\u4e9b\u8ba1\u7b97\u6765\u8bc4\u4f30\u7b97\u6cd5\u7684\u6548\u7387\u3002\u8fd9\u79cd\u4f30\u7b97\u65b9\u6cd5\u88ab\u79f0\u4e3a\u6e10\u8fd1\u590d\u6742\u5ea6\u5206\u6790\uff08asymptotic complexity analysis\uff09\uff0c\u7b80\u79f0\u590d\u6742\u5ea6\u5206\u6790\u3002

    \u590d\u6742\u5ea6\u5206\u6790\u80fd\u591f\u4f53\u73b0\u7b97\u6cd5\u8fd0\u884c\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u8d44\u6e90\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u5b83\u63cf\u8ff0\u4e86\u968f\u7740\u8f93\u5165\u6570\u636e\u5927\u5c0f\u7684\u589e\u52a0\uff0c\u7b97\u6cd5\u6267\u884c\u6240\u9700\u65f6\u95f4\u548c\u7a7a\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u3002\u8fd9\u4e2a\u5b9a\u4e49\u6709\u4e9b\u62d7\u53e3\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5176\u5206\u4e3a\u4e09\u4e2a\u91cd\u70b9\u6765\u7406\u89e3\u3002

    • \u201c\u65f6\u95f4\u548c\u7a7a\u95f4\u8d44\u6e90\u201d\u5206\u522b\u5bf9\u5e94\u65f6\u95f4\u590d\u6742\u5ea6\uff08time complexity\uff09\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\uff08space complexity\uff09\u3002
    • \u201c\u968f\u7740\u8f93\u5165\u6570\u636e\u5927\u5c0f\u7684\u589e\u52a0\u201d\u610f\u5473\u7740\u590d\u6742\u5ea6\u53cd\u6620\u4e86\u7b97\u6cd5\u8fd0\u884c\u6548\u7387\u4e0e\u8f93\u5165\u6570\u636e\u4f53\u91cf\u4e4b\u95f4\u7684\u5173\u7cfb\u3002
    • \u201c\u65f6\u95f4\u548c\u7a7a\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u201d\u8868\u793a\u590d\u6742\u5ea6\u5206\u6790\u5173\u6ce8\u7684\u4e0d\u662f\u8fd0\u884c\u65f6\u95f4\u6216\u5360\u7528\u7a7a\u95f4\u7684\u5177\u4f53\u503c\uff0c\u800c\u662f\u65f6\u95f4\u6216\u7a7a\u95f4\u589e\u957f\u7684\u201c\u5feb\u6162\u201d\u3002

    \u590d\u6742\u5ea6\u5206\u6790\u514b\u670d\u4e86\u5b9e\u9645\u6d4b\u8bd5\u65b9\u6cd5\u7684\u5f0a\u7aef\uff0c\u4f53\u73b0\u5728\u4ee5\u4e0b\u4e24\u4e2a\u65b9\u9762\u3002

    • \u5b83\u72ec\u7acb\u4e8e\u6d4b\u8bd5\u73af\u5883\uff0c\u5206\u6790\u7ed3\u679c\u9002\u7528\u4e8e\u6240\u6709\u8fd0\u884c\u5e73\u53f0\u3002
    • \u5b83\u53ef\u4ee5\u4f53\u73b0\u4e0d\u540c\u6570\u636e\u91cf\u4e0b\u7684\u7b97\u6cd5\u6548\u7387\uff0c\u5c24\u5176\u662f\u5728\u5927\u6570\u636e\u91cf\u4e0b\u7684\u7b97\u6cd5\u6027\u80fd\u3002

    Tip

    \u5982\u679c\u4f60\u4ecd\u5bf9\u590d\u6742\u5ea6\u7684\u6982\u5ff5\u611f\u5230\u56f0\u60d1\uff0c\u65e0\u987b\u62c5\u5fc3\uff0c\u6211\u4eec\u4f1a\u5728\u540e\u7eed\u7ae0\u8282\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u3002

    \u590d\u6742\u5ea6\u5206\u6790\u4e3a\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u628a\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u7684\u201c\u6807\u5c3a\u201d\uff0c\u4f7f\u6211\u4eec\u53ef\u4ee5\u8861\u91cf\u6267\u884c\u67d0\u4e2a\u7b97\u6cd5\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u8d44\u6e90\uff0c\u5bf9\u6bd4\u4e0d\u540c\u7b97\u6cd5\u4e4b\u95f4\u7684\u6548\u7387\u3002

    \u590d\u6742\u5ea6\u662f\u4e2a\u6570\u5b66\u6982\u5ff5\uff0c\u5bf9\u4e8e\u521d\u5b66\u8005\u53ef\u80fd\u6bd4\u8f83\u62bd\u8c61\uff0c\u5b66\u4e60\u96be\u5ea6\u76f8\u5bf9\u8f83\u9ad8\u3002\u4ece\u8fd9\u4e2a\u89d2\u5ea6\u770b\uff0c\u590d\u6742\u5ea6\u5206\u6790\u53ef\u80fd\u4e0d\u592a\u9002\u5408\u4f5c\u4e3a\u6700\u5148\u4ecb\u7ecd\u7684\u5185\u5bb9\u3002\u7136\u800c\uff0c\u5f53\u6211\u4eec\u8ba8\u8bba\u67d0\u4e2a\u6570\u636e\u7ed3\u6784\u6216\u7b97\u6cd5\u7684\u7279\u70b9\u65f6\uff0c\u96be\u4ee5\u907f\u514d\u8981\u5206\u6790\u5176\u8fd0\u884c\u901f\u5ea6\u548c\u7a7a\u95f4\u4f7f\u7528\u60c5\u51b5\u3002

    \u7efc\u4e0a\u6240\u8ff0\uff0c\u5efa\u8bae\u4f60\u5728\u6df1\u5165\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u4e4b\u524d\uff0c\u5148\u5bf9\u590d\u6742\u5ea6\u5206\u6790\u5efa\u7acb\u521d\u6b65\u7684\u4e86\u89e3\uff0c\u4ee5\u4fbf\u80fd\u591f\u5b8c\u6210\u7b80\u5355\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u5206\u6790\u3002

    "},{"location":"chapter_computational_complexity/space_complexity/","title":"2.4 \u00a0 \u7a7a\u95f4\u590d\u6742\u5ea6","text":"

    \u7a7a\u95f4\u590d\u6742\u5ea6\uff08space complexity\uff09\u7528\u4e8e\u8861\u91cf\u7b97\u6cd5\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u968f\u7740\u6570\u636e\u91cf\u53d8\u5927\u65f6\u7684\u589e\u957f\u8d8b\u52bf\u3002\u8fd9\u4e2a\u6982\u5ff5\u4e0e\u65f6\u95f4\u590d\u6742\u5ea6\u975e\u5e38\u7c7b\u4f3c\uff0c\u53ea\u9700\u5c06\u201c\u8fd0\u884c\u65f6\u95f4\u201d\u66ff\u6362\u4e3a\u201c\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u201d\u3002

    "},{"location":"chapter_computational_complexity/space_complexity/#241","title":"2.4.1 \u00a0 \u7b97\u6cd5\u76f8\u5173\u7a7a\u95f4","text":"

    \u7b97\u6cd5\u5728\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f7f\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u4e3b\u8981\u5305\u62ec\u4ee5\u4e0b\u51e0\u79cd\u3002

    • \u8f93\u5165\u7a7a\u95f4\uff1a\u7528\u4e8e\u5b58\u50a8\u7b97\u6cd5\u7684\u8f93\u5165\u6570\u636e\u3002
    • \u6682\u5b58\u7a7a\u95f4\uff1a\u7528\u4e8e\u5b58\u50a8\u7b97\u6cd5\u5728\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u53d8\u91cf\u3001\u5bf9\u8c61\u3001\u51fd\u6570\u4e0a\u4e0b\u6587\u7b49\u6570\u636e\u3002
    • \u8f93\u51fa\u7a7a\u95f4\uff1a\u7528\u4e8e\u5b58\u50a8\u7b97\u6cd5\u7684\u8f93\u51fa\u6570\u636e\u3002

    \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u7edf\u8ba1\u8303\u56f4\u662f\u201c\u6682\u5b58\u7a7a\u95f4\u201d\u52a0\u4e0a\u201c\u8f93\u51fa\u7a7a\u95f4\u201d\u3002

    \u6682\u5b58\u7a7a\u95f4\u53ef\u4ee5\u8fdb\u4e00\u6b65\u5212\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\u3002

    • \u6682\u5b58\u6570\u636e\uff1a\u7528\u4e8e\u4fdd\u5b58\u7b97\u6cd5\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u5404\u79cd\u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u7b49\u3002
    • \u6808\u5e27\u7a7a\u95f4\uff1a\u7528\u4e8e\u4fdd\u5b58\u8c03\u7528\u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u6570\u636e\u3002\u7cfb\u7edf\u5728\u6bcf\u6b21\u8c03\u7528\u51fd\u6570\u65f6\u90fd\u4f1a\u5728\u6808\u9876\u90e8\u521b\u5efa\u4e00\u4e2a\u6808\u5e27\uff0c\u51fd\u6570\u8fd4\u56de\u540e\uff0c\u6808\u5e27\u7a7a\u95f4\u4f1a\u88ab\u91ca\u653e\u3002
    • \u6307\u4ee4\u7a7a\u95f4\uff1a\u7528\u4e8e\u4fdd\u5b58\u7f16\u8bd1\u540e\u7684\u7a0b\u5e8f\u6307\u4ee4\uff0c\u5728\u5b9e\u9645\u7edf\u8ba1\u4e2d\u901a\u5e38\u5ffd\u7565\u4e0d\u8ba1\u3002

    \u5728\u5206\u6790\u4e00\u6bb5\u7a0b\u5e8f\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u7edf\u8ba1\u6682\u5b58\u6570\u636e\u3001\u6808\u5e27\u7a7a\u95f4\u548c\u8f93\u51fa\u6570\u636e\u4e09\u90e8\u5206\uff0c\u5982\u56fe 2-15 \u6240\u793a\u3002

    \u56fe 2-15 \u00a0 \u7b97\u6cd5\u4f7f\u7528\u7684\u76f8\u5173\u7a7a\u95f4

    \u76f8\u5173\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class Node:\n    \"\"\"\u7c7b\"\"\"\n    def __init__(self, x: int):\n        self.val: int = x              # \u8282\u70b9\u503c\n        self.next: Node | None = None  # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\ndef function() -> int:\n    \"\"\"\u51fd\u6570\"\"\"\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n\ndef algorithm(n) -> int:  # \u8f93\u5165\u6570\u636e\n    A = 0                 # \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff0c\u4e00\u822c\u7528\u5927\u5199\u5b57\u6bcd\u8868\u793a\uff09\n    b = 0                 # \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    node = Node(0)        # \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    c = function()        # \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return A + b + c      # \u8f93\u51fa\u6570\u636e\n
    /* \u7ed3\u6784\u4f53 */\nstruct Node {\n    int val;\n    Node *next;\n    Node(int x) : val(x), next(nullptr) {}\n};\n\n/* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint algorithm(int n) {        // \u8f93\u5165\u6570\u636e\n    const int a = 0;          // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    Node* node = new Node(0); // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    int c = func();           // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    int val;\n    Node next;\n    Node(int x) { val = x; }\n}\n\n/* \u51fd\u6570 */\nint function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint algorithm(int n) {        // \u8f93\u5165\u6570\u636e\n    final int a = 0;          // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    Node node = new Node(0);  // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    int c = function();       // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node(int x) {\n    int val = x;\n    Node next;\n}\n\n/* \u51fd\u6570 */\nint Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint Algorithm(int n) {        // \u8f93\u5165\u6570\u636e\n    const int a = 0;          // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    Node node = new(0);       // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    int c = Function();       // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7ed3\u6784\u4f53 */\ntype node struct {\n    val  int\n    next *node\n}\n\n/* \u521b\u5efa node \u7ed3\u6784\u4f53  */\nfunc newNode(val int) *node {\n    return &node{val: val}\n}\n\n/* \u51fd\u6570 */\nfunc function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\nfunc algorithm(n int) int { // \u8f93\u5165\u6570\u636e\n    const a = 0             // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    b := 0                  // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    newNode(0)              // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    c := function()         // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c        // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    var val: Int\n    var next: Node?\n\n    init(x: Int) {\n        val = x\n    }\n}\n\n/* \u51fd\u6570 */\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\nfunc algorithm(n: Int) -> Int { // \u8f93\u5165\u6570\u636e\n    let a = 0             // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    var b = 0             // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    let node = Node(x: 0) // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    let c = function()    // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c      // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    val;\n    next;\n    constructor(val) {\n        this.val = val === undefined ? 0 : val; // \u8282\u70b9\u503c\n        this.next = null;                       // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n\n/* \u51fd\u6570 */\nfunction constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\nfunction algorithm(n) {       // \u8f93\u5165\u6570\u636e\n    const a = 0;              // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    let b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    const node = new Node(0); // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    const c = constFunc();    // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    val: number;\n    next: Node | null;\n    constructor(val?: number) {\n        this.val = val === undefined ? 0 : val; // \u8282\u70b9\u503c\n        this.next = null;                       // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n\n/* \u51fd\u6570 */\nfunction constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\nfunction algorithm(n: number): number { // \u8f93\u5165\u6570\u636e\n    const a = 0;                        // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    let b = 0;                          // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    const node = new Node(0);           // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    const c = constFunc();              // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;                   // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n  int val;\n  Node next;\n  Node(this.val, [this.next]);\n}\n\n/* \u51fd\u6570 */\nint function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n  return 0;\n}\n\nint algorithm(int n) {  // \u8f93\u5165\u6570\u636e\n  const int a = 0;      // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n  int b = 0;            // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n  Node node = Node(0);  // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n  int c = function();   // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n  return a + b + c;     // \u8f93\u51fa\u6570\u636e\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* \u7ed3\u6784\u4f53 */\nstruct Node {\n    val: i32,\n    next: Option<Rc<RefCell<Node>>>,\n}\n\n/* \u521b\u5efa Node \u7ed3\u6784\u4f53 */\nimpl Node {\n    fn new(val: i32) -> Self {\n        Self { val: val, next: None }\n    }\n}\n\n/* \u51fd\u6570 */\nfn function() -> i32 {      \n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nfn algorithm(n: i32) -> i32 {       // \u8f93\u5165\u6570\u636e\n    const a: i32 = 0;               // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    let mut b = 0;                  // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    let node = Node::new(0);        // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    let c = function();             // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;               // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint algorithm(int n) { // \u8f93\u5165\u6570\u636e\n    const int a = 0;   // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;         // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    int c = func();    // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;  // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node(var _val: Int) {\n    var next: Node? = null\n}\n\n/* \u51fd\u6570 */\nfun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\nfun algorithm(n: Int): Int { // \u8f93\u5165\u6570\u636e\n    val a = 0                // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    var b = 0                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    val node = Node(0)       // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    val c = function()       // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c         // \u8f93\u51fa\u6570\u636e\n}\n
    ### \u7c7b ###\nclass Node\n    attr_accessor :val      # \u8282\u70b9\u503c\n    attr_accessor :next     # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\n    def initialize(x)\n        @val = x\n    end\nend\n\n### \u51fd\u6570 ###\ndef function\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    0\nend\n\n### \u7b97\u6cd5 ###\ndef algorithm(n)        # \u8f93\u5165\u6570\u636e\n    a = 0               # \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    b = 0               # \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    node = Node.new(0)  # \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    c = function        # \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    a + b + c           # \u8f93\u51fa\u6570\u636e\nend\n
    \n
    "},{"location":"chapter_computational_complexity/space_complexity/#242","title":"2.4.2 \u00a0 \u63a8\u7b97\u65b9\u6cd5","text":"

    \u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u63a8\u7b97\u65b9\u6cd5\u4e0e\u65f6\u95f4\u590d\u6742\u5ea6\u5927\u81f4\u76f8\u540c\uff0c\u53ea\u9700\u5c06\u7edf\u8ba1\u5bf9\u8c61\u4ece\u201c\u64cd\u4f5c\u6570\u91cf\u201d\u8f6c\u4e3a\u201c\u4f7f\u7528\u7a7a\u95f4\u5927\u5c0f\u201d\u3002

    \u800c\u4e0e\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u540c\u7684\u662f\uff0c\u6211\u4eec\u901a\u5e38\u53ea\u5173\u6ce8\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u3002\u8fd9\u662f\u56e0\u4e3a\u5185\u5b58\u7a7a\u95f4\u662f\u4e00\u9879\u786c\u6027\u8981\u6c42\uff0c\u6211\u4eec\u5fc5\u987b\u786e\u4fdd\u5728\u6240\u6709\u8f93\u5165\u6570\u636e\u4e0b\u90fd\u6709\u8db3\u591f\u7684\u5185\u5b58\u7a7a\u95f4\u9884\u7559\u3002

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4e2d\u7684\u201c\u6700\u5dee\u201d\u6709\u4e24\u5c42\u542b\u4e49\u3002

    1. \u4ee5\u6700\u5dee\u8f93\u5165\u6570\u636e\u4e3a\u51c6\uff1a\u5f53 \\(n < 10\\) \u65f6\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff1b\u4f46\u5f53 \\(n > 10\\) \u65f6\uff0c\u521d\u59cb\u5316\u7684\u6570\u7ec4 nums \u5360\u7528 \\(O(n)\\) \u7a7a\u95f4\uff0c\u56e0\u6b64\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002
    2. \u4ee5\u7b97\u6cd5\u8fd0\u884c\u4e2d\u7684\u5cf0\u503c\u5185\u5b58\u4e3a\u51c6\uff1a\u4f8b\u5982\uff0c\u7a0b\u5e8f\u5728\u6267\u884c\u6700\u540e\u4e00\u884c\u4e4b\u524d\uff0c\u5360\u7528 \\(O(1)\\) \u7a7a\u95f4\uff1b\u5f53\u521d\u59cb\u5316\u6570\u7ec4 nums \u65f6\uff0c\u7a0b\u5e8f\u5360\u7528 \\(O(n)\\) \u7a7a\u95f4\uff0c\u56e0\u6b64\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def algorithm(n: int):\n    a = 0               # O(1)\n    b = [0] * 10000     # O(1)\n    if n > 10:\n        nums = [0] * n  # O(n)\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    vector<int> b(10000);    // O(1)\n    if (n > 10)\n        vector<int> nums(n); // O(n)\n}\n
    void algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10)\n        int[] nums = new int[n]; // O(n)\n}\n
    void Algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10) {\n        int[] nums = new int[n]; // O(n)\n    }\n}\n
    func algorithm(n int) {\n    a := 0                      // O(1)\n    b := make([]int, 10000)     // O(1)\n    var nums []int\n    if n > 10 {\n        nums := make([]int, n)  // O(n)\n    }\n    fmt.Println(a, b, nums)\n}\n
    func algorithm(n: Int) {\n    let a = 0 // O(1)\n    let b = Array(repeating: 0, count: 10000) // O(1)\n    if n > 10 {\n        let nums = Array(repeating: 0, count: n) // O(n)\n    }\n}\n
    function algorithm(n) {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    function algorithm(n: number): void {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    void algorithm(int n) {\n  int a = 0;                            // O(1)\n  List<int> b = List.filled(10000, 0);  // O(1)\n  if (n > 10) {\n    List<int> nums = List.filled(n, 0); // O(n)\n  }\n}\n
    fn algorithm(n: i32) {\n    let a = 0;                              // O(1)\n    let b = [0; 10000];                     // O(1)\n    if n > 10 {\n        let nums = vec![0; n as usize];     // O(n)\n    }\n}\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    int b[10000];            // O(1)\n    if (n > 10)\n        int nums[n] = {0};   // O(n)\n}\n
    fun algorithm(n: Int) {\n    val a = 0                    // O(1)\n    val b = IntArray(10000)      // O(1)\n    if (n > 10) {\n        val nums = IntArray(n)   // O(n)\n    }\n}\n
    def algorithm(n)\n    a = 0                           # O(1)\n    b = Array.new(10000)            # O(1)\n    nums = Array.new(n) if n > 10   # O(n)\nend\n
    \n

    \u5728\u9012\u5f52\u51fd\u6570\u4e2d\uff0c\u9700\u8981\u6ce8\u610f\u7edf\u8ba1\u6808\u5e27\u7a7a\u95f4\u3002\u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def function() -> int:\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n\ndef loop(n: int):\n    \"\"\"\u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1)\"\"\"\n    for _ in range(n):\n        function()\n\ndef recur(n: int):\n    \"\"\"\u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\"\"\"\n    if n == 1:\n        return\n    return recur(n - 1)\n
    int func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid Loop(int n) {\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nint Recur(int n) {\n    if (n == 1) return 1;\n    return Recur(n - 1);\n}\n
    func function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunc loop(n int) {\n    for i := 0; i < n; i++ {\n        function()\n    }\n}\n\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunc recur(n int) {\n    if n == 1 {\n        return\n    }\n    recur(n - 1)\n}\n
    @discardableResult\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunc loop(n: Int) {\n    for _ in 0 ..< n {\n        function()\n    }\n}\n\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunc recur(n: Int) {\n    if n == 1 {\n        return\n    }\n    recur(n: n - 1)\n}\n
    function constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunction loop(n) {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunction recur(n) {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    function constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunction loop(n: number): void {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunction recur(n: number): void {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n  for (int i = 0; i < n; i++) {\n    function();\n  }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n  if (n == 1) return;\n  return recur(n - 1);\n}\n
    fn function() -> i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfn loop(n: i32) {\n    for i in 0..n {\n        function();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfn recur(n: i32) {\n    if n == 1 {\n        return;\n    }\n    recur(n - 1);\n}\n
    int func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    fun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfun loop(n: Int) {\n    for (i in 0..<n) {\n        function()\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfun recur(n: Int) {\n    if (n == 1) return\n    return recur(n - 1)\n}\n
    def function\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    0\nend\n\n### \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) ###\ndef loop(n)\n    (0...n).each { function }\nend\n\n### \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) ###\ndef recur(n)\n    return if n == 1\n    recur(n - 1)\nend\n
    \n

    \u51fd\u6570 loop() \u548c recur() \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n)\\) \uff0c\u4f46\u7a7a\u95f4\u590d\u6742\u5ea6\u4e0d\u540c\u3002

    • \u51fd\u6570 loop() \u5728\u5faa\u73af\u4e2d\u8c03\u7528\u4e86 \\(n\\) \u6b21 function() \uff0c\u6bcf\u8f6e\u4e2d\u7684 function() \u90fd\u8fd4\u56de\u5e76\u91ca\u653e\u4e86\u6808\u5e27\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(1)\\) \u3002
    • \u9012\u5f52\u51fd\u6570 recur() \u5728\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u540c\u65f6\u5b58\u5728 \\(n\\) \u4e2a\u672a\u8fd4\u56de\u7684 recur() \uff0c\u4ece\u800c\u5360\u7528 \\(O(n)\\) \u7684\u6808\u5e27\u7a7a\u95f4\u3002
    "},{"location":"chapter_computational_complexity/space_complexity/#243","title":"2.4.3 \u00a0 \u5e38\u89c1\u7c7b\u578b","text":"

    \u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u56fe 2-16 \u5c55\u793a\u4e86\u5e38\u89c1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u7c7b\u578b\uff08\u4ece\u4f4e\u5230\u9ad8\u6392\u5217\uff09\u3002

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n^2) < O(2^n) \\newline \\text{\u5e38\u6570\u9636} < \\text{\u5bf9\u6570\u9636} < \\text{\u7ebf\u6027\u9636} < \\text{\u5e73\u65b9\u9636} < \\text{\u6307\u6570\u9636} \\end{aligned} \\]

    \u56fe 2-16 \u00a0 \u5e38\u89c1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u7c7b\u578b

    "},{"location":"chapter_computational_complexity/space_complexity/#1-o1","title":"1. \u00a0 \u5e38\u6570\u9636 \\(O(1)\\)","text":"

    \u5e38\u6570\u9636\u5e38\u89c1\u4e8e\u6570\u91cf\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\u7684\u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728\u5faa\u73af\u4e2d\u521d\u59cb\u5316\u53d8\u91cf\u6216\u8c03\u7528\u51fd\u6570\u800c\u5360\u7528\u7684\u5185\u5b58\uff0c\u5728\u8fdb\u5165\u4e0b\u4e00\u5faa\u73af\u540e\u5c31\u4f1a\u88ab\u91ca\u653e\uff0c\u56e0\u6b64\u4e0d\u4f1a\u7d2f\u79ef\u5360\u7528\u7a7a\u95f4\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(1)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def function() -> int:\n    \"\"\"\u51fd\u6570\"\"\"\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n\ndef constant(n: int):\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    a = 0\n    nums = [0] * 10000\n    node = ListNode(0)\n    # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        c = 0\n    # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        function()\n
    space_complexity.cpp
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    vector<int> nums(10000);\n    ListNode node(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.java
    /* \u51fd\u6570 */\nint function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    final int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n
    space_complexity.cs
    /* \u51fd\u6570 */\nint Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid Constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n
    space_complexity.go
    /* \u51fd\u6570 */\nfunc function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc spaceConstant(n int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0\n    b := 0\n    nums := make([]int, 10000)\n    node := newNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    var c int\n    for i := 0; i < n; i++ {\n        c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i := 0; i < n; i++ {\n        function()\n    }\n    b += 0\n    c += 0\n    nums[0] = 0\n    node.val = 0\n}\n
    space_complexity.swift
    /* \u51fd\u6570 */\n@discardableResult\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    let a = 0\n    var b = 0\n    let nums = Array(repeating: 0, count: 10000)\n    let node = ListNode(x: 0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        let c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        function()\n    }\n}\n
    space_complexity.js
    /* \u51fd\u6570 */\nfunction constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.ts
    /* \u51fd\u6570 */\nfunction constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n: number): void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.dart
    /* \u51fd\u6570 */\nint function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n  // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  final int a = 0;\n  int b = 0;\n  List<int> nums = List.filled(10000, 0);\n  ListNode node = ListNode(0);\n  // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    int c = 0;\n  }\n  // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    function();\n  }\n}\n
    space_complexity.rs
    /* \u51fd\u6570 */\nfn function() -> i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\n#[allow(unused)]\nfn constant(n: i32) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const A: i32 = 0;\n    let b = 0;\n    let nums = vec![0; 10000];\n    let node = ListNode::new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        let c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        function();\n    }\n}\n
    space_complexity.c
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    int nums[1000];\n    ListNode *node = newListNode(0);\n    free(node);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.kt
    /* \u51fd\u6570 */\nfun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfun constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    val a = 0\n    var b = 0\n    val nums = Array(10000) { 0 }\n    val node = ListNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        val c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        function()\n    }\n}\n
    space_complexity.rb
    ### \u51fd\u6570 ###\ndef function\n  # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  0\nend\n\n### \u5e38\u6570\u9636 ###\ndef constant(n)\n  # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  a = 0\n  nums = [0] * 10000\n  node = ListNode.new\n\n  # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { c = 0 }\n  # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { function }\nend\n
    space_complexity.zig
    // \u51fd\u6570\nfn function() i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n// \u5e38\u6570\u9636\nfn constant(n: i32) void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a: i32 = 0;\n    var b: i32 = 0;\n    var nums = [_]i32{0}**10000;\n    var node = inc.ListNode(i32){.val = 0};\n    var i: i32 = 0;\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    while (i < n) : (i += 1) {\n        var c: i32 = 0;\n        _ = c;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    i = 0;\n    while (i < n) : (i += 1) {\n        _ = function();\n    }\n    _ = a;\n    _ = b;\n    _ = nums;\n    _ = node;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_computational_complexity/space_complexity/#2-on","title":"2. \u00a0 \u7ebf\u6027\u9636 \\(O(n)\\)","text":"

    \u7ebf\u6027\u9636\u5e38\u89c1\u4e8e\u5143\u7d20\u6570\u91cf\u4e0e \\(n\\) \u6210\u6b63\u6bd4\u7684\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u7b49\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear(n: int):\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    nums = [0] * n\n    # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    hmap = dict[int, str]()\n    for i in range(n):\n        hmap[i] = str(i)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<int> nums(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<ListNode> nodes;\n    for (int i = 0; i < n; i++) {\n        nodes.push_back(ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    unordered_map<int, string> map;\n    for (int i = 0; i < n; i++) {\n        map[i] = to_string(i);\n    }\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        nodes.add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Map<Integer, String> map = new HashMap<>();\n    for (int i = 0; i < n; i++) {\n        map.put(i, String.valueOf(i));\n    }\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636 */\nvoid Linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = [];\n    for (int i = 0; i < n; i++) {\n        nodes.Add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Dictionary<int, string> map = [];\n    for (int i = 0; i < n; i++) {\n        map.Add(i, i.ToString());\n    }\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc spaceLinear(n int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    _ = make([]int, n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes []*node\n    for i := 0; i < n; i++ {\n        nodes = append(nodes, newNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    m := make(map[int]string, n)\n    for i := 0; i < n; i++ {\n        m[i] = strconv.Itoa(i)\n    }\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let nums = Array(repeating: 0, count: n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let nodes = (0 ..< n).map { ListNode(x: $0) }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let map = Dictionary(uniqueKeysWithValues: (0 ..< n).map { ($0, \"\\($0)\") })\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes: ListNode[] = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n  // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n  List<int> nums = List.filled(n, 0);\n  // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  List<ListNode> nodes = [];\n  for (var i = 0; i < n; i++) {\n    nodes.add(ListNode(i));\n  }\n  // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  Map<int, String> map = HashMap();\n  for (var i = 0; i < n; i++) {\n    map.putIfAbsent(i, () => i.toString());\n  }\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636 */\n#[allow(unused)]\nfn linear(n: i32) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nums = vec![0; n as usize];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nodes = Vec::new();\n    for i in 0..n {\n        nodes.push(ListNode::new(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut map = HashMap::new();\n    for i in 0..n {\n        map.insert(i, i.to_string());\n    }\n}\n
    space_complexity.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int *nums = malloc(sizeof(int) * n);\n    free(nums);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    ListNode **nodes = malloc(sizeof(ListNode *) * n);\n    for (int i = 0; i < n; i++) {\n        nodes[i] = newListNode(i);\n    }\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(nodes[i]);\n    }\n    free(nodes);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    HashTable *h = NULL;\n    for (int i = 0; i < n; i++) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = i;\n        tmp->val = i;\n        HASH_ADD_INT(h, key, tmp);\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    HashTable *curr, *tmp;\n    HASH_ITER(hh, h, curr, tmp) {\n        HASH_DEL(h, curr);\n        free(curr);\n    }\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    val nums = Array(n) { 0 }\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val nodes = mutableListOf<ListNode>()\n    for (i in 0..<n) {\n        nodes.add(ListNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val map = mutableMapOf<Int, String>()\n    for (i in 0..<n) {\n        map[i] = i.toString()\n    }\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  nums = Array.new(n, 0)\n\n  # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  hmap = {}\n  for i in 0...n\n    hmap[i] = i.to_s\n  end\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(comptime n: i32) !void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    var nums = [_]i32{0}**n;\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        try nodes.append(i);\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var map = std.AutoArrayHashMap(i32, []const u8).init(std.heap.page_allocator);\n    defer map.deinit();\n    var j: i32 = 0;\n    while (j < n) : (j += 1) {\n        const string = try std.fmt.allocPrint(std.heap.page_allocator, \"{d}\", .{j});\n        defer std.heap.page_allocator.free(string);\n        try map.put(i, string);\n    }\n    _ = nums;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 2-17 \u6240\u793a\uff0c\u6b64\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u5373\u540c\u65f6\u5b58\u5728 \\(n\\) \u4e2a\u672a\u8fd4\u56de\u7684 linear_recur() \u51fd\u6570\uff0c\u4f7f\u7528 \\(O(n)\\) \u5927\u5c0f\u7684\u6808\u5e27\u7a7a\u95f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear_recur(n: int):\n    \"\"\"\u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    print(\"\u9012\u5f52 n =\", n)\n    if n == 1:\n        return\n    linear_recur(n - 1)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    cout << \"\u9012\u5f52 n = \" << n << endl;\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    System.out.println(\"\u9012\u5f52 n = \" + n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid LinearRecur(int n) {\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n);\n    if (n == 1) return;\n    LinearRecur(n - 1);\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceLinearRecur(n int) {\n    fmt.Println(\"\u9012\u5f52 n =\", n)\n    if n == 1 {\n        return\n    }\n    spaceLinearRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc linearRecur(n: Int) {\n    print(\"\u9012\u5f52 n = \\(n)\")\n    if n == 1 {\n        return\n    }\n    linearRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n) {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n: number): void {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n  print('\u9012\u5f52 n = $n');\n  if (n == 1) return;\n  linearRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn linear_recur(n: i32) {\n    println!(\"\u9012\u5f52 n = {}\", n);\n    if n == 1 {\n        return;\n    };\n    linear_recur(n - 1);\n}\n
    space_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    printf(\"\u9012\u5f52 n = %d\\r\\n\", n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun linearRecur(n: Int) {\n    println(\"\u9012\u5f52 n = $n\")\n    if (n == 1)\n        return\n    linearRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef linear_recur(n)\n  puts \"\u9012\u5f52 n = #{n}\"\n  return if n == 1\n  linear_recur(n - 1)\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn linearRecur(comptime n: i32) void {\n    std.debug.print(\"\u9012\u5f52 n = {}\\n\", .{n});\n    if (n == 1) return;\n    linearRecur(n - 1);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-17 \u00a0 \u9012\u5f52\u51fd\u6570\u4ea7\u751f\u7684\u7ebf\u6027\u9636\u7a7a\u95f4\u590d\u6742\u5ea6

    "},{"location":"chapter_computational_complexity/space_complexity/#3-on2","title":"3. \u00a0 \u5e73\u65b9\u9636 \\(O(n^2)\\)","text":"

    \u5e73\u65b9\u9636\u5e38\u89c1\u4e8e\u77e9\u9635\u548c\u56fe\uff0c\u5143\u7d20\u6570\u91cf\u4e0e \\(n\\) \u6210\u5e73\u65b9\u5173\u7cfb\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic(n: int):\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    num_matrix = [[0] * n for _ in range(n)]\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    vector<vector<int>> numMatrix;\n    for (int i = 0; i < n; i++) {\n        vector<int> tmp;\n        for (int j = 0; j < n; j++) {\n            tmp.push_back(0);\n        }\n        numMatrix.push_back(tmp);\n    }\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[][] numMatrix = new int[n][n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<Integer>> numList = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<Integer> tmp = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            tmp.add(0);\n        }\n        numList.add(tmp);\n    }\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636 */\nvoid Quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[,] numMatrix = new int[n, n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<int>> numList = [];\n    for (int i = 0; i < n; i++) {\n        List<int> tmp = [];\n        for (int j = 0; j < n; j++) {\n            tmp.Add(0);\n        }\n        numList.Add(tmp);\n    }\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc spaceQuadratic(n int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    numMatrix := make([][]int, n)\n    for i := 0; i < n; i++ {\n        numMatrix[i] = make([]int, n)\n    }\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let numList = Array(repeating: Array(repeating: 0, count: n), count: n)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): void {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n  // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numMatrix = List.generate(n, (_) => List.filled(n, 0));\n  // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numList = [];\n  for (var i = 0; i < n; i++) {\n    List<int> tmp = [];\n    for (int j = 0; j < n; j++) {\n      tmp.add(0);\n    }\n    numList.add(tmp);\n  }\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636 */\n#[allow(unused)]\nfn quadratic(n: i32) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let num_matrix = vec![vec![0; n as usize]; n as usize];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let mut num_list = Vec::new();\n    for i in 0..n {\n        let mut tmp = Vec::new();\n        for j in 0..n {\n            tmp.push(0);\n        }\n        num_list.push(tmp);\n    }\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int **numMatrix = malloc(sizeof(int *) * n);\n    for (int i = 0; i < n; i++) {\n        int *tmp = malloc(sizeof(int) * n);\n        for (int j = 0; j < n; j++) {\n            tmp[j] = 0;\n        }\n        numMatrix[i] = tmp;\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(numMatrix[i]);\n    }\n    free(numMatrix);\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numMatrix = arrayOfNulls<Array<Int>?>(n)\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numList = mutableListOf<MutableList<Int>>()\n    for (i in 0..<n) {\n        val tmp = mutableListOf<Int>()\n        for (j in 0..<n) {\n            tmp.add(0)\n        }\n        numList.add(tmp)\n    }\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  Array.new(n) { Array.new(n, 0) }\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) !void {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    var nodes = std.ArrayList(std.ArrayList(i32)).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        var tmp = std.ArrayList(i32).init(std.heap.page_allocator);\n        defer tmp.deinit();\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            try tmp.append(0);\n        }\n        try nodes.append(tmp);\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 2-18 \u6240\u793a\uff0c\u8be5\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u5728\u6bcf\u4e2a\u9012\u5f52\u51fd\u6570\u4e2d\u90fd\u521d\u59cb\u5316\u4e86\u4e00\u4e2a\u6570\u7ec4\uff0c\u957f\u5ea6\u5206\u522b\u4e3a \\(n\\)\u3001\\(n-1\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \uff0c\u5e73\u5747\u957f\u5ea6\u4e3a \\(n / 2\\) \uff0c\u56e0\u6b64\u603b\u4f53\u5360\u7528 \\(O(n^2)\\) \u7a7a\u95f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic_recur(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 0:\n        return 0\n    # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    nums = [0] * n\n    return quadratic_recur(n - 1)\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    vector<int> nums(n);\n    cout << \"\u9012\u5f52 n = \" << n << \" \u4e2d\u7684 nums \u957f\u5ea6 = \" << nums.size() << endl;\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    int[] nums = new int[n];\n    System.out.println(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.length);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint QuadraticRecur(int n) {\n    if (n <= 0) return 0;\n    int[] nums = new int[n];\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.Length);\n    return QuadraticRecur(n - 1);\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceQuadraticRecur(n int) int {\n    if n <= 0 {\n        return 0\n    }\n    nums := make([]int, n)\n    fmt.Printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d \\n\", n, len(nums))\n    return spaceQuadraticRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\n@discardableResult\nfunc quadraticRecur(n: Int) -> Int {\n    if n <= 0 {\n        return 0\n    }\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = Array(repeating: 0, count: n)\n    print(\"\u9012\u5f52 n = \\(n) \u4e2d\u7684 nums \u957f\u5ea6 = \\(nums.count)\")\n    return quadraticRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n) {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n: number): number {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n  if (n <= 0) return 0;\n  List<int> nums = List.filled(n, 0);\n  print('\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}');\n  return quadraticRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn quadratic_recur(n: i32) -> i32 {\n    if n <= 0 {\n        return 0;\n    };\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = vec![0; n as usize];\n    println!(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\", n, nums.len());\n    return quadratic_recur(n - 1);\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    int *nums = malloc(sizeof(int) * n);\n    printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d\\r\\n\", n, n);\n    int res = quadraticRecur(n - 1);\n    free(nums);\n    return res;\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\ntailrec fun quadraticRecur(n: Int): Int {\n    if (n <= 0)\n        return 0\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    val nums = Array(n) { 0 }\n    println(\"\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.size}\")\n    return quadraticRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef quadratic_recur(n)\n  return 0 unless n > 0\n\n  # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n  nums = Array.new(n, 0)\n  quadratic_recur(n - 1)\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn quadraticRecur(comptime n: i32) i32 {\n    if (n <= 0) return 0;\n    var nums = [_]i32{0}**n;\n    std.debug.print(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\\n\", .{n, nums.len});\n    return quadraticRecur(n - 1);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-18 \u00a0 \u9012\u5f52\u51fd\u6570\u4ea7\u751f\u7684\u5e73\u65b9\u9636\u7a7a\u95f4\u590d\u6742\u5ea6

    "},{"location":"chapter_computational_complexity/space_complexity/#4-o2n","title":"4. \u00a0 \u6307\u6570\u9636 \\(O(2^n)\\)","text":"

    \u6307\u6570\u9636\u5e38\u89c1\u4e8e\u4e8c\u53c9\u6811\u3002\u89c2\u5bdf\u56fe 2-19 \uff0c\u5c42\u6570\u4e3a \\(n\\) \u7684\u201c\u6ee1\u4e8c\u53c9\u6811\u201d\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(2^n - 1\\) \uff0c\u5360\u7528 \\(O(2^n)\\) \u7a7a\u95f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def build_tree(n: int) -> TreeNode | None:\n    \"\"\"\u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\"\"\"\n    if n == 0:\n        return None\n    root = TreeNode(0)\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n    return root\n
    space_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return nullptr;\n    TreeNode *root = new TreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.java
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode buildTree(int n) {\n    if (n == 0)\n        return null;\n    TreeNode root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? BuildTree(int n) {\n    if (n == 0) return null;\n    TreeNode root = new(0) {\n        left = BuildTree(n - 1),\n        right = BuildTree(n - 1)\n    };\n    return root;\n}\n
    space_complexity.go
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n int) *TreeNode {\n    if n == 0 {\n        return nil\n    }\n    root := NewTreeNode(0)\n    root.Left = buildTree(n - 1)\n    root.Right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n: Int) -> TreeNode? {\n    if n == 0 {\n        return nil\n    }\n    let root = TreeNode(x: 0)\n    root.left = buildTree(n: n - 1)\n    root.right = buildTree(n: n - 1)\n    return root\n}\n
    space_complexity.js
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n) {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n: number): TreeNode | null {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? buildTree(int n) {\n  if (n == 0) return null;\n  TreeNode root = TreeNode(0);\n  root.left = buildTree(n - 1);\n  root.right = buildTree(n - 1);\n  return root;\n}\n
    space_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfn build_tree(n: i32) -> Option<Rc<RefCell<TreeNode>>> {\n    if n == 0 {\n        return None;\n    };\n    let root = TreeNode::new(0);\n    root.borrow_mut().left = build_tree(n - 1);\n    root.borrow_mut().right = build_tree(n - 1);\n    return Some(root);\n}\n
    space_complexity.c
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return NULL;\n    TreeNode *root = newTreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfun buildTree(n: Int): TreeNode? {\n    if (n == 0)\n        return null\n    val root = TreeNode(0)\n    root.left = buildTree(n - 1)\n    root.right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09###\ndef build_tree(n)\n  return if n == 0\n\n  TreeNode.new.tap do |root|\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n  end\nend\n
    space_complexity.zig
    // \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\nfn buildTree(mem_allocator: std.mem.Allocator, n: i32) !?*inc.TreeNode(i32) {\n    if (n == 0) return null;\n    const root = try mem_allocator.create(inc.TreeNode(i32));\n    root.init(0);\n    root.left = try buildTree(mem_allocator, n - 1);\n    root.right = try buildTree(mem_allocator, n - 1);\n    return root;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-19 \u00a0 \u6ee1\u4e8c\u53c9\u6811\u4ea7\u751f\u7684\u6307\u6570\u9636\u7a7a\u95f4\u590d\u6742\u5ea6

    "},{"location":"chapter_computational_complexity/space_complexity/#5-olog-n","title":"5. \u00a0 \u5bf9\u6570\u9636 \\(O(\\log n)\\)","text":"

    \u5bf9\u6570\u9636\u5e38\u89c1\u4e8e\u5206\u6cbb\u7b97\u6cd5\u3002\u4f8b\u5982\u5f52\u5e76\u6392\u5e8f\uff0c\u8f93\u5165\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\uff0c\u6bcf\u8f6e\u9012\u5f52\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5904\u5212\u5206\u4e3a\u4e24\u534a\uff0c\u5f62\u6210\u9ad8\u5ea6\u4e3a \\(\\log n\\) \u7684\u9012\u5f52\u6811\uff0c\u4f7f\u7528 \\(O(\\log n)\\) \u6808\u5e27\u7a7a\u95f4\u3002

    \u518d\u4f8b\u5982\u5c06\u6570\u5b57\u8f6c\u5316\u4e3a\u5b57\u7b26\u4e32\uff0c\u8f93\u5165\u4e00\u4e2a\u6b63\u6574\u6570 \\(n\\) \uff0c\u5b83\u7684\u4f4d\u6570\u4e3a \\(\\lfloor \\log_{10} n \\rfloor + 1\\) \uff0c\u5373\u5bf9\u5e94\u5b57\u7b26\u4e32\u957f\u5ea6\u4e3a \\(\\lfloor \\log_{10} n \\rfloor + 1\\) \uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log_{10} n + 1) = O(\\log n)\\) \u3002

    "},{"location":"chapter_computational_complexity/space_complexity/#244","title":"2.4.4 \u00a0 \u6743\u8861\u65f6\u95f4\u4e0e\u7a7a\u95f4","text":"

    \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5e0c\u671b\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u80fd\u8fbe\u5230\u6700\u4f18\u3002\u7136\u800c\u5728\u5b9e\u9645\u60c5\u51b5\u4e2d\uff0c\u540c\u65f6\u4f18\u5316\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u975e\u5e38\u56f0\u96be\u3002

    \u964d\u4f4e\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u9700\u8981\u4ee5\u63d0\u5347\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a\u4ee3\u4ef7\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002\u6211\u4eec\u5c06\u727a\u7272\u5185\u5b58\u7a7a\u95f4\u6765\u63d0\u5347\u7b97\u6cd5\u8fd0\u884c\u901f\u5ea6\u7684\u601d\u8def\u79f0\u4e3a\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\uff1b\u53cd\u4e4b\uff0c\u5219\u79f0\u4e3a\u201c\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4\u201d\u3002

    \u9009\u62e9\u54ea\u79cd\u601d\u8def\u53d6\u51b3\u4e8e\u6211\u4eec\u66f4\u770b\u91cd\u54ea\u4e2a\u65b9\u9762\u3002\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u65f6\u95f4\u6bd4\u7a7a\u95f4\u66f4\u5b9d\u8d35\uff0c\u56e0\u6b64\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\u901a\u5e38\u662f\u66f4\u5e38\u7528\u7684\u7b56\u7565\u3002\u5f53\u7136\uff0c\u5728\u6570\u636e\u91cf\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u63a7\u5236\u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u975e\u5e38\u91cd\u8981\u3002

    "},{"location":"chapter_computational_complexity/summary/","title":"2.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_computational_complexity/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"

    \u7b97\u6cd5\u6548\u7387\u8bc4\u4f30

    • \u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u662f\u8861\u91cf\u7b97\u6cd5\u4f18\u52a3\u7684\u4e24\u4e2a\u4e3b\u8981\u8bc4\u4ef7\u6307\u6807\u3002
    • \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5b9e\u9645\u6d4b\u8bd5\u6765\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\uff0c\u4f46\u96be\u4ee5\u6d88\u9664\u6d4b\u8bd5\u73af\u5883\u7684\u5f71\u54cd\uff0c\u4e14\u4f1a\u8017\u8d39\u5927\u91cf\u8ba1\u7b97\u8d44\u6e90\u3002
    • \u590d\u6742\u5ea6\u5206\u6790\u53ef\u4ee5\u6d88\u9664\u5b9e\u9645\u6d4b\u8bd5\u7684\u5f0a\u7aef\uff0c\u5206\u6790\u7ed3\u679c\u9002\u7528\u4e8e\u6240\u6709\u8fd0\u884c\u5e73\u53f0\uff0c\u5e76\u4e14\u80fd\u591f\u63ed\u793a\u7b97\u6cd5\u5728\u4e0d\u540c\u6570\u636e\u89c4\u6a21\u4e0b\u7684\u6548\u7387\u3002

    \u65f6\u95f4\u590d\u6742\u5ea6

    • \u65f6\u95f4\u590d\u6742\u5ea6\u7528\u4e8e\u8861\u91cf\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u968f\u6570\u636e\u91cf\u589e\u957f\u7684\u8d8b\u52bf\uff0c\u53ef\u4ee5\u6709\u6548\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u53ef\u80fd\u5931\u6548\uff0c\u5982\u5728\u8f93\u5165\u7684\u6570\u636e\u91cf\u8f83\u5c0f\u6216\u65f6\u95f4\u590d\u6742\u5ea6\u76f8\u540c\u65f6\uff0c\u65e0\u6cd5\u7cbe\u786e\u5bf9\u6bd4\u7b97\u6cd5\u6548\u7387\u7684\u4f18\u52a3\u3002
    • \u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4f7f\u7528\u5927 \\(O\\) \u7b26\u53f7\u8868\u793a\uff0c\u5bf9\u5e94\u51fd\u6570\u6e10\u8fd1\u4e0a\u754c\uff0c\u53cd\u6620\u5f53 \\(n\\) \u8d8b\u5411\u6b63\u65e0\u7a77\u65f6\uff0c\u64cd\u4f5c\u6570\u91cf \\(T(n)\\) \u7684\u589e\u957f\u7ea7\u522b\u3002
    • \u63a8\u7b97\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u4e3a\u4e24\u6b65\uff0c\u9996\u5148\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf\uff0c\u7136\u540e\u5224\u65ad\u6e10\u8fd1\u4e0a\u754c\u3002
    • \u5e38\u89c1\u65f6\u95f4\u590d\u6742\u5ea6\u4ece\u4f4e\u5230\u9ad8\u6392\u5217\u6709 \\(O(1)\\)\u3001\\(O(\\log n)\\)\u3001\\(O(n)\\)\u3001\\(O(n \\log n)\\)\u3001\\(O(n^2)\\)\u3001\\(O(2^n)\\) \u548c \\(O(n!)\\) \u7b49\u3002
    • \u67d0\u4e9b\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u975e\u56fa\u5b9a\uff0c\u800c\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u6709\u5173\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u4e3a\u6700\u5dee\u3001\u6700\u4f73\u3001\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u51e0\u4e4e\u4e0d\u7528\uff0c\u56e0\u4e3a\u8f93\u5165\u6570\u636e\u4e00\u822c\u9700\u8981\u6ee1\u8db3\u4e25\u683c\u6761\u4ef6\u624d\u80fd\u8fbe\u5230\u6700\u4f73\u60c5\u51b5\u3002
    • \u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u53cd\u6620\u7b97\u6cd5\u5728\u968f\u673a\u6570\u636e\u8f93\u5165\u4e0b\u7684\u8fd0\u884c\u6548\u7387\uff0c\u6700\u63a5\u8fd1\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u7b97\u6cd5\u6027\u80fd\u3002\u8ba1\u7b97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u9700\u8981\u7edf\u8ba1\u8f93\u5165\u6570\u636e\u5206\u5e03\u4ee5\u53ca\u7efc\u5408\u540e\u7684\u6570\u5b66\u671f\u671b\u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6

    • \u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u4f5c\u7528\u7c7b\u4f3c\u4e8e\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u7528\u4e8e\u8861\u91cf\u7b97\u6cd5\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u968f\u6570\u636e\u91cf\u589e\u957f\u7684\u8d8b\u52bf\u3002
    • \u7b97\u6cd5\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u76f8\u5173\u5185\u5b58\u7a7a\u95f4\u53ef\u5206\u4e3a\u8f93\u5165\u7a7a\u95f4\u3001\u6682\u5b58\u7a7a\u95f4\u3001\u8f93\u51fa\u7a7a\u95f4\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u8f93\u5165\u7a7a\u95f4\u4e0d\u7eb3\u5165\u7a7a\u95f4\u590d\u6742\u5ea6\u8ba1\u7b97\u3002\u6682\u5b58\u7a7a\u95f4\u53ef\u5206\u4e3a\u6682\u5b58\u6570\u636e\u3001\u6808\u5e27\u7a7a\u95f4\u548c\u6307\u4ee4\u7a7a\u95f4\uff0c\u5176\u4e2d\u6808\u5e27\u7a7a\u95f4\u901a\u5e38\u4ec5\u5728\u9012\u5f52\u51fd\u6570\u4e2d\u5f71\u54cd\u7a7a\u95f4\u590d\u6742\u5ea6\u3002
    • \u6211\u4eec\u901a\u5e38\u53ea\u5173\u6ce8\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5373\u7edf\u8ba1\u7b97\u6cd5\u5728\u6700\u5dee\u8f93\u5165\u6570\u636e\u548c\u6700\u5dee\u8fd0\u884c\u65f6\u523b\u4e0b\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u3002
    • \u5e38\u89c1\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece\u4f4e\u5230\u9ad8\u6392\u5217\u6709 \\(O(1)\\)\u3001\\(O(\\log n)\\)\u3001\\(O(n)\\)\u3001\\(O(n^2)\\) \u548c \\(O(2^n)\\) \u7b49\u3002
    "},{"location":"chapter_computational_complexity/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u5c3e\u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u5417\uff1f

    \u7406\u8bba\u4e0a\uff0c\u5c3e\u9012\u5f52\u51fd\u6570\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f18\u5316\u81f3 \\(O(1)\\) \u3002\u4e0d\u8fc7\u7edd\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\uff08\u4f8b\u5982 Java\u3001Python\u3001C++\u3001Go\u3001C# \u7b49\uff09\u4e0d\u652f\u6301\u81ea\u52a8\u4f18\u5316\u5c3e\u9012\u5f52\uff0c\u56e0\u6b64\u901a\u5e38\u8ba4\u4e3a\u7a7a\u95f4\u590d\u6742\u5ea6\u662f \\(O(n)\\) \u3002

    Q\uff1a\u51fd\u6570\u548c\u65b9\u6cd5\u8fd9\u4e24\u4e2a\u672f\u8bed\u7684\u533a\u522b\u662f\u4ec0\u4e48\uff1f

    \u51fd\u6570\uff08function\uff09\u53ef\u4ee5\u88ab\u72ec\u7acb\u6267\u884c\uff0c\u6240\u6709\u53c2\u6570\u90fd\u4ee5\u663e\u5f0f\u4f20\u9012\u3002\u65b9\u6cd5\uff08method\uff09\u4e0e\u4e00\u4e2a\u5bf9\u8c61\u5173\u8054\uff0c\u88ab\u9690\u5f0f\u4f20\u9012\u7ed9\u8c03\u7528\u5b83\u7684\u5bf9\u8c61\uff0c\u80fd\u591f\u5bf9\u7c7b\u7684\u5b9e\u4f8b\u4e2d\u5305\u542b\u7684\u6570\u636e\u8fdb\u884c\u64cd\u4f5c\u3002

    \u4e0b\u9762\u4ee5\u51e0\u79cd\u5e38\u89c1\u7684\u7f16\u7a0b\u8bed\u8a00\u4e3a\u4f8b\u6765\u8bf4\u660e\u3002

    • C \u8bed\u8a00\u662f\u8fc7\u7a0b\u5f0f\u7f16\u7a0b\u8bed\u8a00\uff0c\u6ca1\u6709\u9762\u5411\u5bf9\u8c61\u7684\u6982\u5ff5\uff0c\u6240\u4ee5\u53ea\u6709\u51fd\u6570\u3002\u4f46\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa\u7ed3\u6784\u4f53\uff08struct\uff09\u6765\u6a21\u62df\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff0c\u4e0e\u7ed3\u6784\u4f53\u76f8\u5173\u8054\u7684\u51fd\u6570\u5c31\u76f8\u5f53\u4e8e\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u65b9\u6cd5\u3002
    • Java \u548c C# \u662f\u9762\u5411\u5bf9\u8c61\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u4ee3\u7801\u5757\uff08\u65b9\u6cd5\uff09\u901a\u5e38\u4f5c\u4e3a\u67d0\u4e2a\u7c7b\u7684\u4e00\u90e8\u5206\u3002\u9759\u6001\u65b9\u6cd5\u7684\u884c\u4e3a\u7c7b\u4f3c\u4e8e\u51fd\u6570\uff0c\u56e0\u4e3a\u5b83\u88ab\u7ed1\u5b9a\u5728\u7c7b\u4e0a\uff0c\u4e0d\u80fd\u8bbf\u95ee\u7279\u5b9a\u7684\u5b9e\u4f8b\u53d8\u91cf\u3002
    • C++ \u548c Python \u65e2\u652f\u6301\u8fc7\u7a0b\u5f0f\u7f16\u7a0b\uff08\u51fd\u6570\uff09\uff0c\u4e5f\u652f\u6301\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08\u65b9\u6cd5\uff09\u3002

    Q\uff1a\u56fe\u89e3\u201c\u5e38\u89c1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u7c7b\u578b\u201d\u53cd\u6620\u7684\u662f\u5426\u662f\u5360\u7528\u7a7a\u95f4\u7684\u7edd\u5bf9\u5927\u5c0f\uff1f

    \u4e0d\u662f\uff0c\u8be5\u56fe\u5c55\u793a\u7684\u662f\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5176\u53cd\u6620\u7684\u662f\u589e\u957f\u8d8b\u52bf\uff0c\u800c\u4e0d\u662f\u5360\u7528\u7a7a\u95f4\u7684\u7edd\u5bf9\u5927\u5c0f\u3002

    \u5047\u8bbe\u53d6 \\(n = 8\\) \uff0c\u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0\u6bcf\u6761\u66f2\u7ebf\u7684\u503c\u4e0e\u51fd\u6570\u5bf9\u5e94\u4e0d\u4e0a\u3002\u8fd9\u662f\u56e0\u4e3a\u6bcf\u6761\u66f2\u7ebf\u90fd\u5305\u542b\u4e00\u4e2a\u5e38\u6570\u9879\uff0c\u7528\u4e8e\u5c06\u53d6\u503c\u8303\u56f4\u538b\u7f29\u5230\u4e00\u4e2a\u89c6\u89c9\u8212\u9002\u7684\u8303\u56f4\u5185\u3002

    \u5728\u5b9e\u9645\u4e2d\uff0c\u56e0\u4e3a\u6211\u4eec\u901a\u5e38\u4e0d\u77e5\u9053\u6bcf\u4e2a\u65b9\u6cd5\u7684\u201c\u5e38\u6570\u9879\u201d\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff0c\u6240\u4ee5\u4e00\u822c\u65e0\u6cd5\u4ec5\u51ed\u590d\u6742\u5ea6\u6765\u9009\u62e9 \\(n = 8\\) \u4e4b\u4e0b\u7684\u6700\u4f18\u89e3\u6cd5\u3002\u4f46\u5bf9\u4e8e \\(n = 8^5\\) \u5c31\u5f88\u597d\u9009\u4e86\uff0c\u8fd9\u65f6\u589e\u957f\u8d8b\u52bf\u5df2\u7ecf\u5360\u4e3b\u5bfc\u4e86\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/","title":"2.3 \u00a0 \u65f6\u95f4\u590d\u6742\u5ea6","text":"

    \u8fd0\u884c\u65f6\u95f4\u53ef\u4ee5\u76f4\u89c2\u4e14\u51c6\u786e\u5730\u53cd\u6620\u7b97\u6cd5\u7684\u6548\u7387\u3002\u5982\u679c\u6211\u4eec\u60f3\u51c6\u786e\u9884\u4f30\u4e00\u6bb5\u4ee3\u7801\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u5e94\u8be5\u5982\u4f55\u64cd\u4f5c\u5462\uff1f

    1. \u786e\u5b9a\u8fd0\u884c\u5e73\u53f0\uff0c\u5305\u62ec\u786c\u4ef6\u914d\u7f6e\u3001\u7f16\u7a0b\u8bed\u8a00\u3001\u7cfb\u7edf\u73af\u5883\u7b49\uff0c\u8fd9\u4e9b\u56e0\u7d20\u90fd\u4f1a\u5f71\u54cd\u4ee3\u7801\u7684\u8fd0\u884c\u6548\u7387\u3002
    2. \u8bc4\u4f30\u5404\u79cd\u8ba1\u7b97\u64cd\u4f5c\u6240\u9700\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u4f8b\u5982\u52a0\u6cd5\u64cd\u4f5c + \u9700\u8981 1 ns \uff0c\u4e58\u6cd5\u64cd\u4f5c * \u9700\u8981 10 ns \uff0c\u6253\u5370\u64cd\u4f5c print() \u9700\u8981 5 ns \u7b49\u3002
    3. \u7edf\u8ba1\u4ee3\u7801\u4e2d\u6240\u6709\u7684\u8ba1\u7b97\u64cd\u4f5c\uff0c\u5e76\u5c06\u6240\u6709\u64cd\u4f5c\u7684\u6267\u884c\u65f6\u95f4\u6c42\u548c\uff0c\u4ece\u800c\u5f97\u5230\u8fd0\u884c\u65f6\u95f4\u3002

    \u4f8b\u5982\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\ndef algorithm(n: int):\n    a = 2      # 1 ns\n    a = a + 1  # 1 ns\n    a = a * 2  # 10 ns\n    # \u5faa\u73af n \u6b21\n    for _ in range(n):  # 1 ns\n        print(0)        # 5 ns\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        cout << 0 << endl;         // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        System.out.println(0);     // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid Algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        Console.WriteLine(0);      // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunc algorithm(n int) {\n    a := 2     // 1 ns\n    a = a + 1  // 1 ns\n    a = a * 2  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for i := 0; i < n; i++ {  // 1 ns\n        fmt.Println(a)        // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunc algorithm(n: Int) {\n    var a = 2 // 1 ns\n    a = a + 1 // 1 ns\n    a = a * 2 // 10 ns\n    // \u5faa\u73af n \u6b21\n    for _ in 0 ..< n { // 1 ns\n        print(0) // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunction algorithm(n) {\n    var a = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++) { // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        console.log(0); // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunction algorithm(n: number): void {\n    var a: number = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++) { // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        console.log(0); // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n  int a = 2; // 1 ns\n  a = a + 1; // 1 ns\n  a = a * 2; // 10 ns\n  // \u5faa\u73af n \u6b21\n  for (int i = 0; i < n; i++) { // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n    print(0); // 5 ns\n  }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfn algorithm(n: i32) {\n    let mut a = 2;      // 1 ns\n    a = a + 1;          // 1 ns\n    a = a * 2;          // 10 ns\n    // \u5faa\u73af n \u6b21\n    for _ in 0..n {     // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        println!(\"{}\", 0);  // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {   // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        printf(\"%d\", 0);            // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfun algorithm(n: Int) {\n    var a = 2 // 1 ns\n    a = a + 1 // 1 ns\n    a = a * 2 // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (i in 0..<n) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        println(0)      // 5 ns\n    }\n}\n
    # \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\ndef algorithm(n)\n    a = 2       # 1 ns\n    a = a + 1   # 1 ns\n    a = a * 2   # 10 ns\n    # \u5faa\u73af n \u6b21\n    (0...n).each do # 1 ns\n        puts 0      # 5 ns\n    end\nend\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfn algorithm(n: usize) void {\n    var a: i32 = 2; // 1 ns\n    a += 1; // 1 ns\n    a *= 2; // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (0..n) |_| { // 1 ns\n        std.debug.print(\"{}\\n\", .{0}); // 5 ns\n    }\n}\n

    \u6839\u636e\u4ee5\u4e0a\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5f97\u5230\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u95f4\u4e3a \\((6n + 12)\\) ns \uff1a

    \\[ 1 + 1 + 10 + (1 + 5) \\times n = 6n + 12 \\]

    \u4f46\u5b9e\u9645\u4e0a\uff0c\u7edf\u8ba1\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u95f4\u65e2\u4e0d\u5408\u7406\u4e5f\u4e0d\u73b0\u5b9e\u3002\u9996\u5148\uff0c\u6211\u4eec\u4e0d\u5e0c\u671b\u5c06\u9884\u4f30\u65f6\u95f4\u548c\u8fd0\u884c\u5e73\u53f0\u7ed1\u5b9a\uff0c\u56e0\u4e3a\u7b97\u6cd5\u9700\u8981\u5728\u5404\u79cd\u4e0d\u540c\u7684\u5e73\u53f0\u4e0a\u8fd0\u884c\u3002\u5176\u6b21\uff0c\u6211\u4eec\u5f88\u96be\u83b7\u77e5\u6bcf\u79cd\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u8fd9\u7ed9\u9884\u4f30\u8fc7\u7a0b\u5e26\u6765\u4e86\u6781\u5927\u7684\u96be\u5ea6\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#231","title":"2.3.1 \u00a0 \u7edf\u8ba1\u65f6\u95f4\u589e\u957f\u8d8b\u52bf","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u7edf\u8ba1\u7684\u4e0d\u662f\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\uff0c\u800c\u662f\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u968f\u7740\u6570\u636e\u91cf\u53d8\u5927\u65f6\u7684\u589e\u957f\u8d8b\u52bf\u3002

    \u201c\u65f6\u95f4\u589e\u957f\u8d8b\u52bf\u201d\u8fd9\u4e2a\u6982\u5ff5\u6bd4\u8f83\u62bd\u8c61\uff0c\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u4f8b\u5b50\u6765\u52a0\u4ee5\u7406\u89e3\u3002\u5047\u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u7ed9\u5b9a\u4e09\u4e2a\u7b97\u6cd5 A\u3001B \u548c C \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_A(n: int):\n    print(0)\n# \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\ndef algorithm_B(n: int):\n    for _ in range(n):\n        print(0)\n# \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_C(n: int):\n    for _ in range(1000000):\n        print(0)\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_A(int n) {\n    cout << 0 << endl;\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        cout << 0 << endl;\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        cout << 0 << endl;\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_A(int n) {\n    System.out.println(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        System.out.println(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        System.out.println(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid AlgorithmA(int n) {\n    Console.WriteLine(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid AlgorithmB(int n) {\n    for (int i = 0; i < n; i++) {\n        Console.WriteLine(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid AlgorithmC(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        Console.WriteLine(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithm_A(n int) {\n    fmt.Println(0)\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunc algorithm_B(n int) {\n    for i := 0; i < n; i++ {\n        fmt.Println(0)\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithm_C(n int) {\n    for i := 0; i < 1000000; i++ {\n        fmt.Println(0)\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithmA(n: Int) {\n    print(0)\n}\n\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunc algorithmB(n: Int) {\n    for _ in 0 ..< n {\n        print(0)\n    }\n}\n\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithmC(n: Int) {\n    for _ in 0 ..< 1_000_000 {\n        print(0)\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_A(n) {\n    console.log(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunction algorithm_B(n) {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_C(n) {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_A(n: number): void {\n    console.log(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunction algorithm_B(n: number): void {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_C(n: number): void {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithmA(int n) {\n  print(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithmB(int n) {\n  for (int i = 0; i < n; i++) {\n    print(0);\n  }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithmC(int n) {\n  for (int i = 0; i < 1000000; i++) {\n    print(0);\n  }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_A(n: i32) {\n    println!(\"{}\", 0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfn algorithm_B(n: i32) {\n    for _ in 0..n {\n        println!(\"{}\", 0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_C(n: i32) {\n    for _ in 0..1000000 {\n        println!(\"{}\", 0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_A(int n) {\n    printf(\"%d\", 0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        printf(\"%d\", 0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        printf(\"%d\", 0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfun algoritm_A(n: Int) {\n    println(0)\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfun algorithm_B(n: Int) {\n    for (i in 0..<n){\n        println(0)\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfun algorithm_C(n: Int) {\n    for (i in 0..<1000000) {\n        println(0)\n    }\n}\n
    # \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_A(n)\n    puts 0\nend\n\n# \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\ndef algorithm_B(n)\n    (0...n).each { puts 0 }\nend\n\n# \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_C(n)\n    (0...1_000_000).each { puts 0 }\nend\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_A(n: usize) void {\n    _ = n;\n    std.debug.print(\"{}\\n\", .{0});\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfn algorithm_B(n: i32) void {\n    for (0..n) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_C(n: i32) void {\n    _ = n;\n    for (0..1000000) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n

    \u56fe 2-7 \u5c55\u793a\u4e86\u4ee5\u4e0a\u4e09\u4e2a\u7b97\u6cd5\u51fd\u6570\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    • \u7b97\u6cd5 A \u53ea\u6709 \\(1\\) \u4e2a\u6253\u5370\u64cd\u4f5c\uff0c\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u4e0d\u968f\u7740 \\(n\\) \u589e\u5927\u800c\u589e\u957f\u3002\u6211\u4eec\u79f0\u6b64\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\u201c\u5e38\u6570\u9636\u201d\u3002
    • \u7b97\u6cd5 B \u4e2d\u7684\u6253\u5370\u64cd\u4f5c\u9700\u8981\u5faa\u73af \\(n\\) \u6b21\uff0c\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u968f\u7740 \\(n\\) \u589e\u5927\u5448\u7ebf\u6027\u589e\u957f\u3002\u6b64\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u88ab\u79f0\u4e3a\u201c\u7ebf\u6027\u9636\u201d\u3002
    • \u7b97\u6cd5 C \u4e2d\u7684\u6253\u5370\u64cd\u4f5c\u9700\u8981\u5faa\u73af \\(1000000\\) \u6b21\uff0c\u867d\u7136\u8fd0\u884c\u65f6\u95f4\u5f88\u957f\uff0c\u4f46\u5b83\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\u3002\u56e0\u6b64 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u548c A \u76f8\u540c\uff0c\u4ecd\u4e3a\u201c\u5e38\u6570\u9636\u201d\u3002

    \u56fe 2-7 \u00a0 \u7b97\u6cd5 A\u3001B \u548c C \u7684\u65f6\u95f4\u589e\u957f\u8d8b\u52bf

    \u76f8\u8f83\u4e8e\u76f4\u63a5\u7edf\u8ba1\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u6709\u54ea\u4e9b\u7279\u70b9\u5462\uff1f

    • \u65f6\u95f4\u590d\u6742\u5ea6\u80fd\u591f\u6709\u6548\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u3002\u4f8b\u5982\uff0c\u7b97\u6cd5 B \u7684\u8fd0\u884c\u65f6\u95f4\u5448\u7ebf\u6027\u589e\u957f\uff0c\u5728 \\(n > 1\\) \u65f6\u6bd4\u7b97\u6cd5 A \u66f4\u6162\uff0c\u5728 \\(n > 1000000\\) \u65f6\u6bd4\u7b97\u6cd5 C \u66f4\u6162\u3002\u4e8b\u5b9e\u4e0a\uff0c\u53ea\u8981\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u8db3\u591f\u5927\uff0c\u590d\u6742\u5ea6\u4e3a\u201c\u5e38\u6570\u9636\u201d\u7684\u7b97\u6cd5\u4e00\u5b9a\u4f18\u4e8e\u201c\u7ebf\u6027\u9636\u201d\u7684\u7b97\u6cd5\uff0c\u8fd9\u6b63\u662f\u65f6\u95f4\u589e\u957f\u8d8b\u52bf\u7684\u542b\u4e49\u3002
    • \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u63a8\u7b97\u65b9\u6cd5\u66f4\u7b80\u4fbf\u3002\u663e\u7136\uff0c\u8fd0\u884c\u5e73\u53f0\u548c\u8ba1\u7b97\u64cd\u4f5c\u7c7b\u578b\u90fd\u4e0e\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u65e0\u5173\u3002\u56e0\u6b64\u5728\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5355\u5730\u5c06\u6240\u6709\u8ba1\u7b97\u64cd\u4f5c\u7684\u6267\u884c\u65f6\u95f4\u89c6\u4e3a\u76f8\u540c\u7684\u201c\u5355\u4f4d\u65f6\u95f4\u201d\uff0c\u4ece\u800c\u5c06\u201c\u8ba1\u7b97\u64cd\u4f5c\u8fd0\u884c\u65f6\u95f4\u7edf\u8ba1\u201d\u7b80\u5316\u4e3a\u201c\u8ba1\u7b97\u64cd\u4f5c\u6570\u91cf\u7edf\u8ba1\u201d\uff0c\u8fd9\u6837\u4e00\u6765\u4f30\u7b97\u96be\u5ea6\u5c31\u5927\u5927\u964d\u4f4e\u4e86\u3002
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u5b58\u5728\u4e00\u5b9a\u7684\u5c40\u9650\u6027\u3002\u4f8b\u5982\uff0c\u5c3d\u7ba1\u7b97\u6cd5 A \u548c C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u76f8\u540c\uff0c\u4f46\u5b9e\u9645\u8fd0\u884c\u65f6\u95f4\u5dee\u522b\u5f88\u5927\u3002\u540c\u6837\uff0c\u5c3d\u7ba1\u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u6bd4 C \u9ad8\uff0c\u4f46\u5728\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u8f83\u5c0f\u65f6\uff0c\u7b97\u6cd5 B \u660e\u663e\u4f18\u4e8e\u7b97\u6cd5 C \u3002\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5f88\u96be\u4ec5\u51ed\u65f6\u95f4\u590d\u6742\u5ea6\u5224\u65ad\u7b97\u6cd5\u6548\u7387\u7684\u9ad8\u4f4e\u3002\u5f53\u7136\uff0c\u5c3d\u7ba1\u5b58\u5728\u4e0a\u8ff0\u95ee\u9898\uff0c\u590d\u6742\u5ea6\u5206\u6790\u4ecd\u7136\u662f\u8bc4\u5224\u7b97\u6cd5\u6548\u7387\u6700\u6709\u6548\u4e14\u5e38\u7528\u7684\u65b9\u6cd5\u3002
    "},{"location":"chapter_computational_complexity/time_complexity/#232","title":"2.3.2 \u00a0 \u51fd\u6570\u6e10\u8fd1\u4e0a\u754c","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u8f93\u5165\u5927\u5c0f\u4e3a \\(n\\) \u7684\u51fd\u6570\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def algorithm(n: int):\n    a = 1      # +1\n    a = a + 1  # +1\n    a = a * 2  # +1\n    # \u5faa\u73af n \u6b21\n    for i in range(n):  # +1\n        print(0)        # +1\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        cout << 0 << endl;    // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        System.out.println(0);    // +1\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {   // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        Console.WriteLine(0);   // +1\n    }\n}\n
    func algorithm(n int) {\n    a := 1      // +1\n    a = a + 1   // +1\n    a = a * 2   // +1\n    // \u5faa\u73af n \u6b21\n    for i := 0; i < n; i++ {   // +1\n        fmt.Println(a)         // +1\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +1\n    a = a + 1 // +1\n    a = a * 2 // +1\n    // \u5faa\u73af n \u6b21\n    for _ in 0 ..< n { // +1\n        print(0) // +1\n    }\n}\n
    function algorithm(n) {\n    var a = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++){ // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        console.log(0); // +1\n    }\n}\n
    function algorithm(n: number): void{\n    var a: number = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++){ // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        console.log(0); // +1\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +1\n  a = a + 1; // +1\n  a = a * 2; // +1\n  // \u5faa\u73af n \u6b21\n  for (int i = 0; i < n; i++) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n    print(0); // +1\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;   // +1\n    a = a + 1;      // +1\n    a = a * 2;      // +1\n\n    // \u5faa\u73af n \u6b21\n    for _ in 0..n { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        println!(\"{}\", 0); // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {   // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        printf(\"%d\", 0);            // +1\n    }\n}\n
    fun algorithm(n: Int) {\n    var a = 1 // +1\n    a = a + 1 // +1\n    a = a * 2 // +1\n    // \u5faa\u73af n \u6b21\n    for (i in 0..<n) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        println(0) // +1\n    }\n}\n
    def algorithm(n)\n    a = 1       # +1\n    a = a + 1   # +1\n    a = a * 2   # +1\n    # \u5faa\u73af n \u6b21\n    (0...n).each do # +1\n        puts 0      # +1\n    end\nend\n
    fn algorithm(n: usize) void {\n    var a: i32 = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // \u5faa\u73af n \u6b21\n    for (0..n) |_| { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        std.debug.print(\"{}\\n\", .{0}); // +1\n    }\n}\n

    \u8bbe\u7b97\u6cd5\u7684\u64cd\u4f5c\u6570\u91cf\u662f\u4e00\u4e2a\u5173\u4e8e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u7684\u51fd\u6570\uff0c\u8bb0\u4e3a \\(T(n)\\) \uff0c\u5219\u4ee5\u4e0a\u51fd\u6570\u7684\u64cd\u4f5c\u6570\u91cf\u4e3a\uff1a

    \\[ T(n) = 3 + 2n \\]

    \\(T(n)\\) \u662f\u4e00\u6b21\u51fd\u6570\uff0c\u8bf4\u660e\u5176\u8fd0\u884c\u65f6\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u662f\u7ebf\u6027\u7684\uff0c\u56e0\u6b64\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u9636\u3002

    \u6211\u4eec\u5c06\u7ebf\u6027\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u8bb0\u4e3a \\(O(n)\\) \uff0c\u8fd9\u4e2a\u6570\u5b66\u7b26\u53f7\u79f0\u4e3a\u5927 \\(O\\) \u8bb0\u53f7\uff08big-\\(O\\) notation\uff09\uff0c\u8868\u793a\u51fd\u6570 \\(T(n)\\) \u7684\u6e10\u8fd1\u4e0a\u754c\uff08asymptotic upper bound\uff09\u3002

    \u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u672c\u8d28\u4e0a\u662f\u8ba1\u7b97\u201c\u64cd\u4f5c\u6570\u91cf \\(T(n)\\)\u201d\u7684\u6e10\u8fd1\u4e0a\u754c\uff0c\u5b83\u5177\u6709\u660e\u786e\u7684\u6570\u5b66\u5b9a\u4e49\u3002

    \u51fd\u6570\u6e10\u8fd1\u4e0a\u754c

    \u82e5\u5b58\u5728\u6b63\u5b9e\u6570 \\(c\\) \u548c\u5b9e\u6570 \\(n_0\\) \uff0c\u4f7f\u5f97\u5bf9\u4e8e\u6240\u6709\u7684 \\(n > n_0\\) \uff0c\u5747\u6709 \\(T(n) \\leq c \\cdot f(n)\\) \uff0c\u5219\u53ef\u8ba4\u4e3a \\(f(n)\\) \u7ed9\u51fa\u4e86 \\(T(n)\\) \u7684\u4e00\u4e2a\u6e10\u8fd1\u4e0a\u754c\uff0c\u8bb0\u4e3a \\(T(n) = O(f(n))\\) \u3002

    \u5982\u56fe 2-8 \u6240\u793a\uff0c\u8ba1\u7b97\u6e10\u8fd1\u4e0a\u754c\u5c31\u662f\u5bfb\u627e\u4e00\u4e2a\u51fd\u6570 \\(f(n)\\) \uff0c\u4f7f\u5f97\u5f53 \\(n\\) \u8d8b\u5411\u4e8e\u65e0\u7a77\u5927\u65f6\uff0c\\(T(n)\\) \u548c \\(f(n)\\) \u5904\u4e8e\u76f8\u540c\u7684\u589e\u957f\u7ea7\u522b\uff0c\u4ec5\u76f8\u5dee\u4e00\u4e2a\u5e38\u6570\u9879 \\(c\\) \u7684\u500d\u6570\u3002

    \u56fe 2-8 \u00a0 \u51fd\u6570\u7684\u6e10\u8fd1\u4e0a\u754c

    "},{"location":"chapter_computational_complexity/time_complexity/#233","title":"2.3.3 \u00a0 \u63a8\u7b97\u65b9\u6cd5","text":"

    \u6e10\u8fd1\u4e0a\u754c\u7684\u6570\u5b66\u5473\u513f\u6709\u70b9\u91cd\uff0c\u5982\u679c\u4f60\u611f\u89c9\u6ca1\u6709\u5b8c\u5168\u7406\u89e3\uff0c\u4e5f\u65e0\u987b\u62c5\u5fc3\u3002\u6211\u4eec\u53ef\u4ee5\u5148\u638c\u63e1\u63a8\u7b97\u65b9\u6cd5\uff0c\u5728\u4e0d\u65ad\u7684\u5b9e\u8df5\u4e2d\uff0c\u5c31\u53ef\u4ee5\u9010\u6e10\u9886\u609f\u5176\u6570\u5b66\u610f\u4e49\u3002

    \u6839\u636e\u5b9a\u4e49\uff0c\u786e\u5b9a \\(f(n)\\) \u4e4b\u540e\uff0c\u6211\u4eec\u4fbf\u53ef\u5f97\u5230\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(f(n))\\) \u3002\u90a3\u4e48\u5982\u4f55\u786e\u5b9a\u6e10\u8fd1\u4e0a\u754c \\(f(n)\\) \u5462\uff1f\u603b\u4f53\u5206\u4e3a\u4e24\u6b65\uff1a\u9996\u5148\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf\uff0c\u7136\u540e\u5224\u65ad\u6e10\u8fd1\u4e0a\u754c\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#1","title":"1. \u00a0 \u7b2c\u4e00\u6b65\uff1a\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf","text":"

    \u9488\u5bf9\u4ee3\u7801\uff0c\u9010\u884c\u4ece\u4e0a\u5230\u4e0b\u8ba1\u7b97\u5373\u53ef\u3002\u7136\u800c\uff0c\u7531\u4e8e\u4e0a\u8ff0 \\(c \\cdot f(n)\\) \u4e2d\u7684\u5e38\u6570\u9879 \\(c\\) \u53ef\u4ee5\u53d6\u4efb\u610f\u5927\u5c0f\uff0c\u56e0\u6b64\u64cd\u4f5c\u6570\u91cf \\(T(n)\\) \u4e2d\u7684\u5404\u79cd\u7cfb\u6570\u3001\u5e38\u6570\u9879\u90fd\u53ef\u4ee5\u5ffd\u7565\u3002\u6839\u636e\u6b64\u539f\u5219\uff0c\u53ef\u4ee5\u603b\u7ed3\u51fa\u4ee5\u4e0b\u8ba1\u6570\u7b80\u5316\u6280\u5de7\u3002

    1. \u5ffd\u7565 \\(T(n)\\) \u4e2d\u7684\u5e38\u6570\u9879\u3002\u56e0\u4e3a\u5b83\u4eec\u90fd\u4e0e \\(n\\) \u65e0\u5173\uff0c\u6240\u4ee5\u5bf9\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u4ea7\u751f\u5f71\u54cd\u3002
    2. \u7701\u7565\u6240\u6709\u7cfb\u6570\u3002\u4f8b\u5982\uff0c\u5faa\u73af \\(2n\\) \u6b21\u3001\\(5n + 1\\) \u6b21\u7b49\uff0c\u90fd\u53ef\u4ee5\u7b80\u5316\u8bb0\u4e3a \\(n\\) \u6b21\uff0c\u56e0\u4e3a \\(n\\) \u524d\u9762\u7684\u7cfb\u6570\u5bf9\u65f6\u95f4\u590d\u6742\u5ea6\u6ca1\u6709\u5f71\u54cd\u3002
    3. \u5faa\u73af\u5d4c\u5957\u65f6\u4f7f\u7528\u4e58\u6cd5\u3002\u603b\u64cd\u4f5c\u6570\u91cf\u7b49\u4e8e\u5916\u5c42\u5faa\u73af\u548c\u5185\u5c42\u5faa\u73af\u64cd\u4f5c\u6570\u91cf\u4e4b\u79ef\uff0c\u6bcf\u4e00\u5c42\u5faa\u73af\u4f9d\u7136\u53ef\u4ee5\u5206\u522b\u5957\u7528\u7b2c 1. \u70b9\u548c\u7b2c 2. \u70b9\u7684\u6280\u5de7\u3002

    \u7ed9\u5b9a\u4e00\u4e2a\u51fd\u6570\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u4e0a\u8ff0\u6280\u5de7\u6765\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def algorithm(n: int):\n    a = 1      # +0\uff08\u6280\u5de7 1\uff09\n    a = a + n  # +0\uff08\u6280\u5de7 1\uff09\n    # +n\uff08\u6280\u5de7 2\uff09\n    for i in range(5 * n + 1):\n        print(0)\n    # +n*n\uff08\u6280\u5de7 3\uff09\n    for i in range(2 * n):\n        for j in range(n + 1):\n            print(0)\n
    void algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        cout << 0 << endl;\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            cout << 0 << endl;\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        System.out.println(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            System.out.println(0);\n        }\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        Console.WriteLine(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            Console.WriteLine(0);\n        }\n    }\n}\n
    func algorithm(n int) {\n    a := 1     // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for i := 0; i < 5 * n + 1; i++ {\n        fmt.Println(0)\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for i := 0; i < 2 * n; i++ {\n        for j := 0; j < n + 1; j++ {\n            fmt.Println(0)\n        }\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for _ in 0 ..< (5 * n + 1) {\n        print(0)\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for _ in 0 ..< (2 * n) {\n        for _ in 0 ..< (n + 1) {\n            print(0)\n        }\n    }\n}\n
    function algorithm(n) {\n    let a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    function algorithm(n: number): void {\n    let a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +0\uff08\u6280\u5de7 1\uff09\n  a = a + n; // +0\uff08\u6280\u5de7 1\uff09\n  // +n\uff08\u6280\u5de7 2\uff09\n  for (int i = 0; i < 5 * n + 1; i++) {\n    print(0);\n  }\n  // +n*n\uff08\u6280\u5de7 3\uff09\n  for (int i = 0; i < 2 * n; i++) {\n    for (int j = 0; j < n + 1; j++) {\n      print(0);\n    }\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;     // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;        // +0\uff08\u6280\u5de7 1\uff09\n\n    // +n\uff08\u6280\u5de7 2\uff09\n    for i in 0..(5 * n + 1) {\n        println!(\"{}\", 0);\n    }\n\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for i in 0..(2 * n) {\n        for j in 0..(n + 1) {\n            println!(\"{}\", 0);\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        printf(\"%d\", 0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            printf(\"%d\", 0);\n        }\n    }\n}\n
    fun algorithm(n: Int) {\n    var a = 1   // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n   // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (i in 0..<5 * n + 1) {\n        println(0)\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (i in 0..<2 * n) {\n        for (j in 0..<n + 1) {\n            println(0)\n        }\n    }\n}\n
    def algorithm(n)\n    a = 1       # +0\uff08\u6280\u5de7 1\uff09\n    a = a + n   # +0\uff08\u6280\u5de7 1\uff09\n    # +n\uff08\u6280\u5de7 2\uff09\n    (0...(5 * n + 1)).each do { puts 0 }\n    # +n*n\uff08\u6280\u5de7 3\uff09\n    (0...(2 * n)).each do\n        (0...(n + 1)).each do { puts 0 }\n    end\nend\n
    fn algorithm(n: usize) void {\n    var a: i32 = 1;     // +0\uff08\u6280\u5de7 1\uff09\n    a = a + @as(i32, @intCast(n));        // +0\uff08\u6280\u5de7 1\uff09\n\n    // +n\uff08\u6280\u5de7 2\uff09\n    for(0..(5 * n + 1)) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for(0..(2 * n)) |_| {\n        for(0..(n + 1)) |_| {\n            std.debug.print(\"{}\\n\", .{0});\n        }\n    }\n}\n

    \u4ee5\u4e0b\u516c\u5f0f\u5c55\u793a\u4e86\u4f7f\u7528\u4e0a\u8ff0\u6280\u5de7\u524d\u540e\u7684\u7edf\u8ba1\u7ed3\u679c\uff0c\u4e24\u8005\u63a8\u7b97\u51fa\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n^2)\\) \u3002

    \\[ \\begin{aligned} T(n) & = 2n(n + 1) + (5n + 1) + 2 & \\text{\u5b8c\u6574\u7edf\u8ba1 (-.-|||)} \\newline & = 2n^2 + 7n + 3 \\newline T(n) & = n^2 + n & \\text{\u5077\u61d2\u7edf\u8ba1 (o.O)} \\end{aligned} \\]"},{"location":"chapter_computational_complexity/time_complexity/#2","title":"2. \u00a0 \u7b2c\u4e8c\u6b65\uff1a\u5224\u65ad\u6e10\u8fd1\u4e0a\u754c","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\u7531 \\(T(n)\\) \u4e2d\u6700\u9ad8\u9636\u7684\u9879\u6765\u51b3\u5b9a\u3002\u8fd9\u662f\u56e0\u4e3a\u5728 \\(n\\) \u8d8b\u4e8e\u65e0\u7a77\u5927\u65f6\uff0c\u6700\u9ad8\u9636\u7684\u9879\u5c06\u53d1\u6325\u4e3b\u5bfc\u4f5c\u7528\uff0c\u5176\u4ed6\u9879\u7684\u5f71\u54cd\u90fd\u53ef\u4ee5\u5ffd\u7565\u3002

    \u8868 2-2 \u5c55\u793a\u4e86\u4e00\u4e9b\u4f8b\u5b50\uff0c\u5176\u4e2d\u4e00\u4e9b\u5938\u5f20\u7684\u503c\u662f\u4e3a\u4e86\u5f3a\u8c03\u201c\u7cfb\u6570\u65e0\u6cd5\u64bc\u52a8\u9636\u6570\u201d\u8fd9\u4e00\u7ed3\u8bba\u3002\u5f53 \\(n\\) \u8d8b\u4e8e\u65e0\u7a77\u5927\u65f6\uff0c\u8fd9\u4e9b\u5e38\u6570\u53d8\u5f97\u65e0\u8db3\u8f7b\u91cd\u3002

    \u8868 2-2 \u00a0 \u4e0d\u540c\u64cd\u4f5c\u6570\u91cf\u5bf9\u5e94\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u64cd\u4f5c\u6570\u91cf \\(T(n)\\) \u65f6\u95f4\u590d\u6742\u5ea6 \\(O(f(n))\\) \\(100000\\) \\(O(1)\\) \\(3n + 2\\) \\(O(n)\\) \\(2n^2 + 3n + 2\\) \\(O(n^2)\\) \\(n^3 + 10000n^2\\) \\(O(n^3)\\) \\(2^n + 10000n^{10000}\\) \\(O(2^n)\\)"},{"location":"chapter_computational_complexity/time_complexity/#234","title":"2.3.4 \u00a0 \u5e38\u89c1\u7c7b\u578b","text":"

    \u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u5e38\u89c1\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7c7b\u578b\u5982\u56fe 2-9 \u6240\u793a\uff08\u6309\u7167\u4ece\u4f4e\u5230\u9ad8\u7684\u987a\u5e8f\u6392\u5217\uff09\u3002

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n \\log n) < O(n^2) < O(2^n) < O(n!) \\newline \\text{\u5e38\u6570\u9636} < \\text{\u5bf9\u6570\u9636} < \\text{\u7ebf\u6027\u9636} < \\text{\u7ebf\u6027\u5bf9\u6570\u9636} < \\text{\u5e73\u65b9\u9636} < \\text{\u6307\u6570\u9636} < \\text{\u9636\u4e58\u9636} \\end{aligned} \\]

    \u56fe 2-9 \u00a0 \u5e38\u89c1\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7c7b\u578b

    "},{"location":"chapter_computational_complexity/time_complexity/#1-o1","title":"1. \u00a0 \u5e38\u6570\u9636 \\(O(1)\\)","text":"

    \u5e38\u6570\u9636\u7684\u64cd\u4f5c\u6570\u91cf\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\uff0c\u5373\u4e0d\u968f\u7740 \\(n\\) \u7684\u53d8\u5316\u800c\u53d8\u5316\u3002

    \u5728\u4ee5\u4e0b\u51fd\u6570\u4e2d\uff0c\u5c3d\u7ba1\u64cd\u4f5c\u6570\u91cf size \u53ef\u80fd\u5f88\u5927\uff0c\u4f46\u7531\u4e8e\u5176\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(1)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def constant(n: int) -> int:\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    count = 0\n    size = 100000\n    for _ in range(size):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u5e38\u6570\u9636 */\nint Constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u5e38\u6570\u9636 */\nfunc constant(n int) int {\n    count := 0\n    size := 100000\n    for i := 0; i < size; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e38\u6570\u9636 */\nfunc constant(n: Int) -> Int {\n    var count = 0\n    let size = 100_000\n    for _ in 0 ..< size {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u5e38\u6570\u9636 */\nfunction constant(n: number): number {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n  int count = 0;\n  int size = 100000;\n  for (var i = 0; i < size; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e38\u6570\u9636 */\nfn constant(n: i32) -> i32 {\n    _ = n;\n    let mut count = 0;\n    let size = 100_000;\n    for _ in 0..size {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    int i = 0;\n    for (int i = 0; i < size; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e38\u6570\u9636 */\nfun constant(n: Int): Int {\n    var count = 0\n    val size = 100000\n    for (i in 0..<size)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u5e38\u6570\u9636 ###\ndef constant(n)\n  count = 0\n  size = 100000\n\n  (0...size).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u5e38\u6570\u9636\nfn constant(n: i32) i32 {\n    _ = n;\n    var count: i32 = 0;\n    const size: i32 = 100_000;\n    var i: i32 = 0;\n    while(i<size) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_computational_complexity/time_complexity/#2-on","title":"2. \u00a0 \u7ebf\u6027\u9636 \\(O(n)\\)","text":"

    \u7ebf\u6027\u9636\u7684\u64cd\u4f5c\u6570\u91cf\u76f8\u5bf9\u4e8e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u4ee5\u7ebf\u6027\u7ea7\u522b\u589e\u957f\u3002\u7ebf\u6027\u9636\u901a\u5e38\u51fa\u73b0\u5728\u5355\u5c42\u5faa\u73af\u4e2d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    count = 0\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636 */\nint Linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc linear(n int) int {\n    count := 0\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) -> Int {\n    var count = 0\n    for _ in 0 ..< n {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): number {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n  int count = 0;\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636 */\nfn linear(n: i32) -> i32 {\n    let mut count = 0;\n    for _ in 0..n {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int): Int {\n    var count = 0\n    for (i in 0..<n)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  count = 0\n  (0...n).each { count += 1 }\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u904d\u5386\u6570\u7ec4\u548c\u904d\u5386\u94fe\u8868\u7b49\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u6570\u7ec4\u6216\u94fe\u8868\u7684\u957f\u5ea6\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def array_traversal(nums: list[int]) -> int:\n    \"\"\"\u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for num in nums:\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(vector<int> &nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint ArrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    foreach (int num in nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums []int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for range nums {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums: [Int]) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums: number[]): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(List<int> nums) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for (var _num in nums) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfn array_traversal(nums: &[i32]) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int *nums, int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfun arrayTraversal(nums: IntArray): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (num in nums) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09###\ndef array_traversal(nums)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for num in nums\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\nfn arrayTraversal(nums: []i32) i32 {\n    var count: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (nums) |_| {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u9700\u6839\u636e\u8f93\u5165\u6570\u636e\u7684\u7c7b\u578b\u6765\u5177\u4f53\u786e\u5b9a\u3002\u6bd4\u5982\u5728\u7b2c\u4e00\u4e2a\u793a\u4f8b\u4e2d\uff0c\u53d8\u91cf \\(n\\) \u4e3a\u8f93\u5165\u6570\u636e\u5927\u5c0f\uff1b\u5728\u7b2c\u4e8c\u4e2a\u793a\u4f8b\u4e2d\uff0c\u6570\u7ec4\u957f\u5ea6 \\(n\\) \u4e3a\u6570\u636e\u5927\u5c0f\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#3-on2","title":"3. \u00a0 \u5e73\u65b9\u9636 \\(O(n^2)\\)","text":"

    \u5e73\u65b9\u9636\u7684\u64cd\u4f5c\u6570\u91cf\u76f8\u5bf9\u4e8e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u4ee5\u5e73\u65b9\u7ea7\u522b\u589e\u957f\u3002\u5e73\u65b9\u9636\u901a\u5e38\u51fa\u73b0\u5728\u5d4c\u5957\u5faa\u73af\u4e2d\uff0c\u5916\u5c42\u5faa\u73af\u548c\u5185\u5c42\u5faa\u73af\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n)\\) \uff0c\u56e0\u6b64\u603b\u4f53\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def quadratic(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i in range(n):\n        for j in range(n):\n            count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636 */\nint Quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i := 0; i < n; i++ {\n        for j := 0; j < n; j++ {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0 ..< n {\n        for _ in 0 ..< n {\n            count += 1\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for (int i = 0; i < n; i++) {\n    for (int j = 0; j < n; j++) {\n      count++;\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636 */\nfn quadratic(n: i32) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0..n {\n        for _ in 0..n {\n            count += 1;\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (i in 0..<n) {\n        for (j in 0..<n) {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for i in 0...n\n    for j in 0...n\n      count += 1\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            count += 1;\n        }\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-10 \u5bf9\u6bd4\u4e86\u5e38\u6570\u9636\u3001\u7ebf\u6027\u9636\u548c\u5e73\u65b9\u9636\u4e09\u79cd\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    \u56fe 2-10 \u00a0 \u5e38\u6570\u9636\u3001\u7ebf\u6027\u9636\u548c\u5e73\u65b9\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u4ee5\u5192\u6ce1\u6392\u5e8f\u4e3a\u4f8b\uff0c\u5916\u5c42\u5faa\u73af\u6267\u884c \\(n - 1\\) \u6b21\uff0c\u5185\u5c42\u5faa\u73af\u6267\u884c \\(n-1\\)\u3001\\(n-2\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \u6b21\uff0c\u5e73\u5747\u4e3a \\(n / 2\\) \u6b21\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O((n - 1) n / 2) = O(n^2)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def bubble_sort(nums: list[int]) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\"\"\"\n    count = 0  # \u8ba1\u6570\u5668\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(len(nums) - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp: int = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3  # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(vector<int> &nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int[] nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint BubbleSort(int[] nums) {\n    int count = 0;  // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums []int) int {\n    count := 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp := nums[j]\n                nums[j] = nums[j+1]\n                nums[j+1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums: inout [Int]) -> Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums) {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums: number[]): number {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(List<int> nums) {\n  int count = 0; // \u8ba1\u6570\u5668\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (var i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (var j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      }\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfn bubble_sort(nums: &mut [i32]) -> i32 {\n    let mut count = 0; // \u8ba1\u6570\u5668\n\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int *nums, int n) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = n - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfun bubbleSort(nums: IntArray): Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09###\ndef bubble_sort(nums)\n  count = 0  # \u8ba1\u6570\u5668\n\n  # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for i in (nums.length - 1).downto(0)\n    # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for j in 0...i\n      if nums[j] > nums[j + 1]\n        # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        tmp = nums[j]\n        nums[j] = nums[j + 1]\n        nums[j + 1] = tmp\n        count += 3 # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      end\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\nfn bubbleSort(nums: []i32) i32 {\n    var count: i32 = 0;  // \u8ba1\u6570\u5668 \n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: i32 = @as(i32, @intCast(nums.len)) - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_computational_complexity/time_complexity/#4-o2n","title":"4. \u00a0 \u6307\u6570\u9636 \\(O(2^n)\\)","text":"

    \u751f\u7269\u5b66\u7684\u201c\u7ec6\u80de\u5206\u88c2\u201d\u662f\u6307\u6570\u9636\u589e\u957f\u7684\u5178\u578b\u4f8b\u5b50\uff1a\u521d\u59cb\u72b6\u6001\u4e3a \\(1\\) \u4e2a\u7ec6\u80de\uff0c\u5206\u88c2\u4e00\u8f6e\u540e\u53d8\u4e3a \\(2\\) \u4e2a\uff0c\u5206\u88c2\u4e24\u8f6e\u540e\u53d8\u4e3a \\(4\\) \u4e2a\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u5206\u88c2 \\(n\\) \u8f6e\u540e\u6709 \\(2^n\\) \u4e2a\u7ec6\u80de\u3002

    \u56fe 2-11 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6a21\u62df\u4e86\u7ec6\u80de\u5206\u88c2\u7684\u8fc7\u7a0b\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exponential(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    base = 1\n    # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in range(n):\n        for _ in range(base):\n            count += 1\n        base *= 2\n    # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Exponential(int n) {\n    int count = 0, bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc exponential(n int) int {\n    count, base := 0, 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for i := 0; i < n; i++ {\n        for j := 0; j < base; j++ {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc exponential(n: Int) -> Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0 ..< n {\n        for _ in 0 ..< base {\n            count += 1\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n) {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n: number): number {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n  int count = 0, base = 1;\n  // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  for (var i = 0; i < n; i++) {\n    for (var j = 0; j < base; j++) {\n      count++;\n    }\n    base *= 2;\n  }\n  // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  return count;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn exponential(n: i32) -> i32 {\n    let mut count = 0;\n    let mut base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0..n {\n        for _ in 0..base {\n            count += 1\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    count\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0;\n    int bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun exponential(n: Int): Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (i in 0..<n) {\n        for (j in 0..<base) {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef exponential(n)\n  count, base = 0, 1\n\n  # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  (0...n).each do\n    (0...base).each { count += 1 }\n    base *= 2\n  end\n\n  # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  count\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn exponential(n: i32) i32 {\n    var count: i32 = 0;\n    var bas: i32 = 1;\n    var i: i32 = 0;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < bas) : (j += 1) {\n            count += 1;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-11 \u00a0 \u6307\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u5728\u5b9e\u9645\u7b97\u6cd5\u4e2d\uff0c\u6307\u6570\u9636\u5e38\u51fa\u73b0\u4e8e\u9012\u5f52\u51fd\u6570\u4e2d\u3002\u4f8b\u5982\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u5176\u9012\u5f52\u5730\u4e00\u5206\u4e3a\u4e8c\uff0c\u7ecf\u8fc7 \\(n\\) \u6b21\u5206\u88c2\u540e\u505c\u6b62\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exp_recur(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 1:\n        return 1\n    return exp_recur(n - 1) + exp_recur(n - 1) + 1\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint ExpRecur(int n) {\n    if (n == 1) return 1;\n    return ExpRecur(n - 1) + ExpRecur(n - 1) + 1;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc expRecur(n int) int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n-1) + expRecur(n-1) + 1\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc expRecur(n: Int) -> Int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n: n - 1) + expRecur(n: n - 1) + 1\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n) {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n: number): number {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n  if (n == 1) return 1;\n  return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn exp_recur(n: i32) -> i32 {\n    if n == 1 {\n        return 1;\n    }\n    exp_recur(n - 1) + exp_recur(n - 1) + 1\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun expRecur(n: Int): Int {\n    if (n == 1) {\n        return 1\n    }\n    return expRecur(n - 1) + expRecur(n - 1) + 1\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef exp_recur(n)\n  return 1 if n == 1\n  exp_recur(n - 1) + exp_recur(n - 1) + 1\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn expRecur(n: i32) i32 {\n    if (n == 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6307\u6570\u9636\u589e\u957f\u975e\u5e38\u8fc5\u901f\uff0c\u5728\u7a77\u4e3e\u6cd5\uff08\u66b4\u529b\u641c\u7d22\u3001\u56de\u6eaf\u7b49\uff09\u4e2d\u6bd4\u8f83\u5e38\u89c1\u3002\u5bf9\u4e8e\u6570\u636e\u89c4\u6a21\u8f83\u5927\u7684\u95ee\u9898\uff0c\u6307\u6570\u9636\u662f\u4e0d\u53ef\u63a5\u53d7\u7684\uff0c\u901a\u5e38\u9700\u8981\u4f7f\u7528\u52a8\u6001\u89c4\u5212\u6216\u8d2a\u5fc3\u7b97\u6cd5\u7b49\u6765\u89e3\u51b3\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#5-olog-n","title":"5. \u00a0 \u5bf9\u6570\u9636 \\(O(\\log n)\\)","text":"

    \u4e0e\u6307\u6570\u9636\u76f8\u53cd\uff0c\u5bf9\u6570\u9636\u53cd\u6620\u4e86\u201c\u6bcf\u8f6e\u7f29\u51cf\u5230\u4e00\u534a\u201d\u7684\u60c5\u51b5\u3002\u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u7531\u4e8e\u6bcf\u8f6e\u7f29\u51cf\u5230\u4e00\u534a\uff0c\u56e0\u6b64\u5faa\u73af\u6b21\u6570\u662f \\(\\log_2 n\\) \uff0c\u5373 \\(2^n\\) \u7684\u53cd\u51fd\u6570\u3002

    \u56fe 2-12 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6a21\u62df\u4e86\u201c\u6bcf\u8f6e\u7f29\u51cf\u5230\u4e00\u534a\u201d\u7684\u8fc7\u7a0b\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log_2 n)\\) \uff0c\u7b80\u8bb0\u4e3a \\(O(\\log n)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def logarithmic(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    while n > 1:\n        n = n / 2\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n /= 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc logarithmic(n int) int {\n    count := 0\n    for n > 1 {\n        n = n / 2\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc logarithmic(n: Int) -> Int {\n    var count = 0\n    var n = n\n    while n > 1 {\n        n = n / 2\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n) {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n: number): number {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n  int count = 0;\n  while (n > 1) {\n    n = n ~/ 2;\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn logarithmic(mut n: i32) -> i32 {\n    let mut count = 0;\n    while n > 1 {\n        n = n / 2;\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun logarithmic(n: Int): Int {\n    var n1 = n\n    var count = 0\n    while (n1 > 1) {\n        n1 /= 2\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef logarithmic(n)\n  count = 0\n\n  while n > 1\n    n /= 2\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn logarithmic(n: i32) i32 {\n    var count: i32 = 0;\n    var n_var = n;\n    while (n_var > 1)\n    {\n        n_var = n_var / 2;\n        count +=1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-12 \u00a0 \u5bf9\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u4e0e\u6307\u6570\u9636\u7c7b\u4f3c\uff0c\u5bf9\u6570\u9636\u4e5f\u5e38\u51fa\u73b0\u4e8e\u9012\u5f52\u51fd\u6570\u4e2d\u3002\u4ee5\u4e0b\u4ee3\u7801\u5f62\u6210\u4e86\u4e00\u68f5\u9ad8\u5ea6\u4e3a \\(\\log_2 n\\) \u7684\u9012\u5f52\u6811\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def log_recur(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 1:\n        return 0\n    return log_recur(n / 2) + 1\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint LogRecur(int n) {\n    if (n <= 1) return 0;\n    return LogRecur(n / 2) + 1;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc logRecur(n int) int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n/2) + 1\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc logRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n: n / 2) + 1\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n) {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n: number): number {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n  if (n <= 1) return 0;\n  return logRecur(n ~/ 2) + 1;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 0;\n    }\n    log_recur(n / 2) + 1\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun logRecur(n: Int): Int {\n    if (n <= 1)\n        return 0\n    return logRecur(n / 2) + 1\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef log_recur(n)\n  return 0 unless n > 1\n  log_recur(n / 2) + 1\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn logRecur(n: i32) i32 {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5bf9\u6570\u9636\u5e38\u51fa\u73b0\u4e8e\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u7b97\u6cd5\u4e2d\uff0c\u4f53\u73b0\u4e86\u201c\u4e00\u5206\u4e3a\u591a\u201d\u548c\u201c\u5316\u7e41\u4e3a\u7b80\u201d\u7684\u7b97\u6cd5\u601d\u60f3\u3002\u5b83\u589e\u957f\u7f13\u6162\uff0c\u662f\u4ec5\u6b21\u4e8e\u5e38\u6570\u9636\u7684\u7406\u60f3\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    \\(O(\\log n)\\) \u7684\u5e95\u6570\u662f\u591a\u5c11\uff1f

    \u51c6\u786e\u6765\u8bf4\uff0c\u201c\u4e00\u5206\u4e3a \\(m\\)\u201d\u5bf9\u5e94\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(\\log_m n)\\) \u3002\u800c\u901a\u8fc7\u5bf9\u6570\u6362\u5e95\u516c\u5f0f\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5177\u6709\u4e0d\u540c\u5e95\u6570\u3001\u76f8\u7b49\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a

    \\[ O(\\log_m n) = O(\\log_k n / \\log_k m) = O(\\log_k n) \\]

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5e95\u6570 \\(m\\) \u53ef\u4ee5\u5728\u4e0d\u5f71\u54cd\u590d\u6742\u5ea6\u7684\u524d\u63d0\u4e0b\u8f6c\u6362\u3002\u56e0\u6b64\u6211\u4eec\u901a\u5e38\u4f1a\u7701\u7565\u5e95\u6570 \\(m\\) \uff0c\u5c06\u5bf9\u6570\u9636\u76f4\u63a5\u8bb0\u4e3a \\(O(\\log n)\\) \u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#6-on-log-n","title":"6. \u00a0 \u7ebf\u6027\u5bf9\u6570\u9636 \\(O(n \\log n)\\)","text":"

    \u7ebf\u6027\u5bf9\u6570\u9636\u5e38\u51fa\u73b0\u4e8e\u5d4c\u5957\u5faa\u73af\u4e2d\uff0c\u4e24\u5c42\u5faa\u73af\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u522b\u4e3a \\(O(\\log n)\\) \u548c \\(O(n)\\) \u3002\u76f8\u5173\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear_log_recur(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u5bf9\u6570\u9636\"\"\"\n    if n <= 1:\n        return 1\n    count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2)\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint LinearLogRecur(int n) {\n    if (n <= 1) return 1;\n    int count = LinearLogRecur(n / 2) + LinearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n int) int {\n    if n <= 1 {\n        return 1\n    }\n    count := linearLogRecur(n/2) + linearLogRecur(n/2)\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 1\n    }\n    var count = linearLogRecur(n: n / 2) + linearLogRecur(n: n / 2)\n    for _ in stride(from: 0, to: n, by: 1) {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n) {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n: number): number {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n  if (n <= 1) return 1;\n  int count = linearLogRecur(n ~/ 2) + linearLogRecur(n ~/ 2);\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfn linear_log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 1;\n    }\n    let mut count = linear_log_recur(n / 2) + linear_log_recur(n / 2);\n    for _ in 0..n as i32 {\n        count += 1;\n    }\n    return count;\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfun linearLogRecur(n: Int): Int {\n    if (n <= 1)\n        return 1\n    var count = linearLogRecur(n / 2) + linearLogRecur(n / 2)\n    for (i in 0..<n) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u5bf9\u6570\u9636 ###\ndef linear_log_recur(n)\n  return 1 unless n > 1\n\n  count = linear_log_recur(n / 2) + linear_log_recur(n / 2)\n  (0...n).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u5bf9\u6570\u9636\nfn linearLogRecur(n: i32) i32 {\n    if (n <= 1) return 1;\n    var count: i32 = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-13 \u5c55\u793a\u4e86\u7ebf\u6027\u5bf9\u6570\u9636\u7684\u751f\u6210\u65b9\u5f0f\u3002\u4e8c\u53c9\u6811\u7684\u6bcf\u4e00\u5c42\u7684\u64cd\u4f5c\u603b\u6570\u90fd\u4e3a \\(n\\) \uff0c\u6811\u5171\u6709 \\(\\log_2 n + 1\\) \u5c42\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    \u56fe 2-13 \u00a0 \u7ebf\u6027\u5bf9\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u4e3b\u6d41\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u4e3a \\(O(n \\log n)\\) \uff0c\u4f8b\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u3001\u5806\u6392\u5e8f\u7b49\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#7-on","title":"7. \u00a0 \u9636\u4e58\u9636 \\(O(n!)\\)","text":"

    \u9636\u4e58\u9636\u5bf9\u5e94\u6570\u5b66\u4e0a\u7684\u201c\u5168\u6392\u5217\u201d\u95ee\u9898\u3002\u7ed9\u5b9a \\(n\\) \u4e2a\u4e92\u4e0d\u91cd\u590d\u7684\u5143\u7d20\uff0c\u6c42\u5176\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u65b9\u6848\uff0c\u65b9\u6848\u6570\u91cf\u4e3a\uff1a

    \\[ n! = n \\times (n - 1) \\times (n - 2) \\times \\dots \\times 2 \\times 1 \\]

    \u9636\u4e58\u901a\u5e38\u4f7f\u7528\u9012\u5f52\u5b9e\u73b0\u3002\u5982\u56fe 2-14 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff0c\u7b2c\u4e00\u5c42\u5206\u88c2\u51fa \\(n\\) \u4e2a\uff0c\u7b2c\u4e8c\u5c42\u5206\u88c2\u51fa \\(n - 1\\) \u4e2a\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u7b2c \\(n\\) \u5c42\u65f6\u505c\u6b62\u5206\u88c2\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def factorial_recur(n: int) -> int:\n    \"\"\"\u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 0:\n        return 1\n    count = 0\n    # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in range(n):\n        count += factorial_recur(n - 1)\n    return count\n
    time_complexity.cpp
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint FactorialRecur(int n) {\n    if (n == 0) return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += FactorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n int) int {\n    if n == 0 {\n        return 1\n    }\n    count := 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for i := 0; i < n; i++ {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n: Int) -> Int {\n    if n == 0 {\n        return 1\n    }\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0 ..< n {\n        count += factorialRecur(n: n - 1)\n    }\n    return count\n}\n
    time_complexity.js
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n) {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n: number): number {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n  if (n == 0) return 1;\n  int count = 0;\n  // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  for (var i = 0; i < n; i++) {\n    count += factorialRecur(n - 1);\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn factorial_recur(n: i32) -> i32 {\n    if n == 0 {\n        return 1;\n    }\n    let mut count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0..n {\n        count += factorial_recur(n - 1);\n    }\n    count\n}\n
    time_complexity.c
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun factorialRecur(n: Int): Int {\n    if (n == 0)\n        return 1\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (i in 0..<n) {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef factorial_recur(n)\n  return 1 if n == 0\n\n  count = 0\n  # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  (0...n).each { count += factorial_recur(n - 1) }\n\n  count\nend\n
    time_complexity.zig
    // \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn factorialRecur(n: i32) i32 {\n    if (n == 0) return 1;\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    while (i < n) : (i += 1) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-14 \u00a0 \u9636\u4e58\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u8bf7\u6ce8\u610f\uff0c\u56e0\u4e3a\u5f53 \\(n \\geq 4\\) \u65f6\u6052\u6709 \\(n! > 2^n\\) \uff0c\u6240\u4ee5\u9636\u4e58\u9636\u6bd4\u6307\u6570\u9636\u589e\u957f\u5f97\u66f4\u5feb\uff0c\u5728 \\(n\\) \u8f83\u5927\u65f6\u4e5f\u662f\u4e0d\u53ef\u63a5\u53d7\u7684\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#235","title":"2.3.5 \u00a0 \u6700\u5dee\u3001\u6700\u4f73\u3001\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6","text":"

    \u7b97\u6cd5\u7684\u65f6\u95f4\u6548\u7387\u5f80\u5f80\u4e0d\u662f\u56fa\u5b9a\u7684\uff0c\u800c\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u6709\u5173\u3002\u5047\u8bbe\u8f93\u5165\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4 nums \uff0c\u5176\u4e2d nums \u7531\u4ece \\(1\\) \u81f3 \\(n\\) \u7684\u6570\u5b57\u7ec4\u6210\uff0c\u6bcf\u4e2a\u6570\u5b57\u53ea\u51fa\u73b0\u4e00\u6b21\uff1b\u4f46\u5143\u7d20\u987a\u5e8f\u662f\u968f\u673a\u6253\u4e71\u7684\uff0c\u4efb\u52a1\u76ee\u6807\u662f\u8fd4\u56de\u5143\u7d20 \\(1\\) \u7684\u7d22\u5f15\u3002\u6211\u4eec\u53ef\u4ee5\u5f97\u51fa\u4ee5\u4e0b\u7ed3\u8bba\u3002

    • \u5f53 nums = [?, ?, ..., 1] \uff0c\u5373\u5f53\u672b\u5c3e\u5143\u7d20\u662f \\(1\\) \u65f6\uff0c\u9700\u8981\u5b8c\u6574\u904d\u5386\u6570\u7ec4\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u3002
    • \u5f53 nums = [1, ?, ?, ...] \uff0c\u5373\u5f53\u9996\u4e2a\u5143\u7d20\u4e3a \\(1\\) \u65f6\uff0c\u65e0\u8bba\u6570\u7ec4\u591a\u957f\u90fd\u4e0d\u9700\u8981\u7ee7\u7eed\u904d\u5386\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 \\(\\Omega(1)\\) \u3002

    \u201c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u201d\u5bf9\u5e94\u51fd\u6570\u6e10\u8fd1\u4e0a\u754c\uff0c\u4f7f\u7528\u5927 \\(O\\) \u8bb0\u53f7\u8868\u793a\u3002\u76f8\u5e94\u5730\uff0c\u201c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u201d\u5bf9\u5e94\u51fd\u6570\u6e10\u8fd1\u4e0b\u754c\uff0c\u7528 \\(\\Omega\\) \u8bb0\u53f7\u8868\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig worst_best_time_complexity.py
    def random_numbers(n: int) -> list[int]:\n    \"\"\"\u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71\"\"\"\n    # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n    nums = [i for i in range(1, n + 1)]\n    # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    random.shuffle(nums)\n    return nums\n\ndef find_one(nums: list[int]) -> int:\n    \"\"\"\u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\"\"\"\n    for i in range(len(nums)):\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1:\n            return i\n    return -1\n
    worst_best_time_complexity.cpp
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nvector<int> randomNumbers(int n) {\n    vector<int> nums(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u4f7f\u7528\u7cfb\u7edf\u65f6\u95f4\u751f\u6210\u968f\u673a\u79cd\u5b50\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    shuffle(nums.begin(), nums.end(), default_random_engine(seed));\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(vector<int> &nums) {\n    for (int i = 0; i < nums.size(); i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.java
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] randomNumbers(int n) {\n    Integer[] nums = new Integer[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    Collections.shuffle(Arrays.asList(nums));\n    // Integer[] -> int[]\n    int[] res = new int[n];\n    for (int i = 0; i < n; i++) {\n        res[i] = nums[i];\n    }\n    return res;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int[] nums) {\n    for (int i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.cs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] RandomNumbers(int n) {\n    int[] nums = new int[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = 0; i < nums.Length; i++) {\n        int index = new Random().Next(i, nums.Length);\n        (nums[i], nums[index]) = (nums[index], nums[i]);\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint FindOne(int[] nums) {\n    for (int i = 0; i < nums.Length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.go
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n int) []int {\n    nums := make([]int, n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for i := 0; i < n; i++ {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    rand.Shuffle(len(nums), func(i, j int) {\n        nums[i], nums[j] = nums[j], nums[i]\n    })\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums []int) int {\n    for i := 0; i < len(nums); i++ {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.swift
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n: Int) -> [Int] {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    var nums = Array(1 ... n)\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums: [Int]) -> Int {\n    for i in nums.indices {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.js
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n) {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums) {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.ts
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n: number): number[] {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums: number[]): number {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.dart
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nList<int> randomNumbers(int n) {\n  final nums = List.filled(n, 0);\n  // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n  for (var i = 0; i < n; i++) {\n    nums[i] = i + 1;\n  }\n  // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle();\n\n  return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(List<int> nums) {\n  for (var i = 0; i < nums.length; i++) {\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    if (nums[i] == 1) return i;\n  }\n\n  return -1;\n}\n
    worst_best_time_complexity.rs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfn random_numbers(n: i32) -> Vec<i32> {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    let mut nums = (1..=n).collect::<Vec<i32>>();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle(&mut thread_rng());\n    nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfn find_one(nums: &[i32]) -> Option<usize> {\n    for i in 0..nums.len() {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return Some(i);\n        }\n    }\n    None\n}\n
    worst_best_time_complexity.c
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint *randomNumbers(int n) {\n    // \u5206\u914d\u5806\u533a\u5185\u5b58\uff08\u521b\u5efa\u4e00\u7ef4\u53ef\u53d8\u957f\u6570\u7ec4\uff1a\u6570\u7ec4\u4e2d\u5143\u7d20\u6570\u91cf\u4e3a n \uff0c\u5143\u7d20\u7c7b\u578b\u4e3a int \uff09\n    int *nums = (int *)malloc(n * sizeof(int));\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = n - 1; i > 0; i--) {\n        int j = rand() % (i + 1);\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int *nums, int n) {\n    for (int i = 0; i < n; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.kt
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfun randomNumbers(n: Int): Array<Int?> {\n    val nums = IntArray(n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (i in 0..<n) {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    val res = arrayOfNulls<Int>(n)\n    for (i in 0..<n) {\n        res[i] = nums[i]\n    }\n    return res\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfun findOne(nums: Array<Int?>): Int {\n    for (i in nums.indices) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i\n    }\n    return -1\n}\n
    worst_best_time_complexity.rb
    ### \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71 ###\ndef random_numbers(n)\n  # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n  nums = Array.new(n) { |i| i + 1 }\n  # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle!\nend\n\n### \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 ###\ndef find_one(nums)\n  for i in 0...nums.length\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    return i if nums[i] == 1\n  end\n\n  -1\nend\n
    worst_best_time_complexity.zig
    // \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71\nfn randomNumbers(comptime n: usize) [n]i32 {\n    var nums: [n]i32 = undefined;\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (&nums, 0..) |*num, i| {\n        num.* = @as(i32, @intCast(i)) + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    const rand = std.crypto.random;\n    rand.shuffle(i32, &nums);\n    return nums;\n}\n\n// \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\nfn findOne(nums: []i32) i32 {\n    for (nums, 0..) |num, i| {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (num == 1) return @intCast(i);\n    }\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6211\u4eec\u5728\u5b9e\u9645\u4e2d\u5f88\u5c11\u4f7f\u7528\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u56e0\u4e3a\u901a\u5e38\u53ea\u6709\u5728\u5f88\u5c0f\u6982\u7387\u4e0b\u624d\u80fd\u8fbe\u5230\uff0c\u53ef\u80fd\u4f1a\u5e26\u6765\u4e00\u5b9a\u7684\u8bef\u5bfc\u6027\u3002\u800c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u66f4\u4e3a\u5b9e\u7528\uff0c\u56e0\u4e3a\u5b83\u7ed9\u51fa\u4e86\u4e00\u4e2a\u6548\u7387\u5b89\u5168\u503c\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u653e\u5fc3\u5730\u4f7f\u7528\u7b97\u6cd5\u3002

    \u4ece\u4e0a\u8ff0\u793a\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u53ea\u51fa\u73b0\u4e8e\u201c\u7279\u6b8a\u7684\u6570\u636e\u5206\u5e03\u201d\uff0c\u8fd9\u4e9b\u60c5\u51b5\u7684\u51fa\u73b0\u6982\u7387\u53ef\u80fd\u5f88\u5c0f\uff0c\u5e76\u4e0d\u80fd\u771f\u5b9e\u5730\u53cd\u6620\u7b97\u6cd5\u8fd0\u884c\u6548\u7387\u3002\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f53\u73b0\u7b97\u6cd5\u5728\u968f\u673a\u8f93\u5165\u6570\u636e\u4e0b\u7684\u8fd0\u884c\u6548\u7387\uff0c\u7528 \\(\\Theta\\) \u8bb0\u53f7\u6765\u8868\u793a\u3002

    \u5bf9\u4e8e\u90e8\u5206\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5355\u5730\u63a8\u7b97\u51fa\u968f\u673a\u6570\u636e\u5206\u5e03\u4e0b\u7684\u5e73\u5747\u60c5\u51b5\u3002\u6bd4\u5982\u4e0a\u8ff0\u793a\u4f8b\uff0c\u7531\u4e8e\u8f93\u5165\u6570\u7ec4\u662f\u88ab\u6253\u4e71\u7684\uff0c\u56e0\u6b64\u5143\u7d20 \\(1\\) \u51fa\u73b0\u5728\u4efb\u610f\u7d22\u5f15\u7684\u6982\u7387\u90fd\u662f\u76f8\u7b49\u7684\uff0c\u90a3\u4e48\u7b97\u6cd5\u7684\u5e73\u5747\u5faa\u73af\u6b21\u6570\u5c31\u662f\u6570\u7ec4\u957f\u5ea6\u7684\u4e00\u534a \\(n / 2\\) \uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(\\Theta(n / 2) = \\Theta(n)\\) \u3002

    \u4f46\u5bf9\u4e8e\u8f83\u4e3a\u590d\u6742\u7684\u7b97\u6cd5\uff0c\u8ba1\u7b97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u5f80\u5f80\u6bd4\u8f83\u56f0\u96be\uff0c\u56e0\u4e3a\u5f88\u96be\u5206\u6790\u51fa\u5728\u6570\u636e\u5206\u5e03\u4e0b\u7684\u6574\u4f53\u6570\u5b66\u671f\u671b\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u901a\u5e38\u4f7f\u7528\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4f5c\u4e3a\u7b97\u6cd5\u6548\u7387\u7684\u8bc4\u5224\u6807\u51c6\u3002

    \u4e3a\u4ec0\u4e48\u5f88\u5c11\u770b\u5230 \\(\\Theta\\) \u7b26\u53f7\uff1f

    \u53ef\u80fd\u7531\u4e8e \\(O\\) \u7b26\u53f7\u8fc7\u4e8e\u6717\u6717\u4e0a\u53e3\uff0c\u56e0\u6b64\u6211\u4eec\u5e38\u5e38\u4f7f\u7528\u5b83\u6765\u8868\u793a\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u4f46\u4ece\u4e25\u683c\u610f\u4e49\u4e0a\u8bb2\uff0c\u8fd9\u79cd\u505a\u6cd5\u5e76\u4e0d\u89c4\u8303\u3002\u5728\u672c\u4e66\u548c\u5176\u4ed6\u8d44\u6599\u4e2d\uff0c\u82e5\u9047\u5230\u7c7b\u4f3c\u201c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\)\u201d\u7684\u8868\u8ff0\uff0c\u8bf7\u5c06\u5176\u76f4\u63a5\u7406\u89e3\u4e3a \\(\\Theta(n)\\) \u3002

    "},{"location":"chapter_data_structure/","title":"\u7b2c 3 \u7ae0 \u00a0 \u6570\u636e\u7ed3\u6784","text":"

    Abstract

    \u6570\u636e\u7ed3\u6784\u5982\u540c\u4e00\u526f\u7a33\u56fa\u800c\u591a\u6837\u7684\u6846\u67b6\u3002

    \u5b83\u4e3a\u6570\u636e\u7684\u6709\u5e8f\u7ec4\u7ec7\u63d0\u4f9b\u4e86\u84dd\u56fe\uff0c\u7b97\u6cd5\u5f97\u4ee5\u5728\u6b64\u57fa\u7840\u4e0a\u751f\u52a8\u8d77\u6765\u3002

    "},{"location":"chapter_data_structure/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 3.1 \u00a0 \u6570\u636e\u7ed3\u6784\u5206\u7c7b
    • 3.2 \u00a0 \u57fa\u672c\u6570\u636e\u7c7b\u578b
    • 3.3 \u00a0 \u6570\u5b57\u7f16\u7801 *
    • 3.4 \u00a0 \u5b57\u7b26\u7f16\u7801 *
    • 3.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_data_structure/basic_data_types/","title":"3.2 \u00a0 \u57fa\u672c\u6570\u636e\u7c7b\u578b","text":"

    \u5f53\u8c08\u53ca\u8ba1\u7b97\u673a\u4e2d\u7684\u6570\u636e\u65f6\uff0c\u6211\u4eec\u4f1a\u60f3\u5230\u6587\u672c\u3001\u56fe\u7247\u3001\u89c6\u9891\u3001\u8bed\u97f3\u30013D \u6a21\u578b\u7b49\u5404\u79cd\u5f62\u5f0f\u3002\u5c3d\u7ba1\u8fd9\u4e9b\u6570\u636e\u7684\u7ec4\u7ec7\u5f62\u5f0f\u5404\u5f02\uff0c\u4f46\u5b83\u4eec\u90fd\u7531\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6784\u6210\u3002

    \u57fa\u672c\u6570\u636e\u7c7b\u578b\u662f CPU \u53ef\u4ee5\u76f4\u63a5\u8fdb\u884c\u8fd0\u7b97\u7684\u7c7b\u578b\uff0c\u5728\u7b97\u6cd5\u4e2d\u76f4\u63a5\u88ab\u4f7f\u7528\uff0c\u4e3b\u8981\u5305\u62ec\u4ee5\u4e0b\u51e0\u79cd\u3002

    • \u6574\u6570\u7c7b\u578b byte\u3001short\u3001int\u3001long \u3002
    • \u6d6e\u70b9\u6570\u7c7b\u578b float\u3001double \uff0c\u7528\u4e8e\u8868\u793a\u5c0f\u6570\u3002
    • \u5b57\u7b26\u7c7b\u578b char \uff0c\u7528\u4e8e\u8868\u793a\u5404\u79cd\u8bed\u8a00\u7684\u5b57\u6bcd\u3001\u6807\u70b9\u7b26\u53f7\u751a\u81f3\u8868\u60c5\u7b26\u53f7\u7b49\u3002
    • \u5e03\u5c14\u7c7b\u578b bool \uff0c\u7528\u4e8e\u8868\u793a\u201c\u662f\u201d\u4e0e\u201c\u5426\u201d\u5224\u65ad\u3002

    \u57fa\u672c\u6570\u636e\u7c7b\u578b\u4ee5\u4e8c\u8fdb\u5236\u7684\u5f62\u5f0f\u5b58\u50a8\u5728\u8ba1\u7b97\u673a\u4e2d\u3002\u4e00\u4e2a\u4e8c\u8fdb\u5236\u4f4d\u5373\u4e3a \\(1\\) \u6bd4\u7279\u3002\u5728\u7edd\u5927\u591a\u6570\u73b0\u4ee3\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\\(1\\) \u5b57\u8282\uff08byte\uff09\u7531 \\(8\\) \u6bd4\u7279\uff08bit\uff09\u7ec4\u6210\u3002

    \u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u53d6\u503c\u8303\u56f4\u53d6\u51b3\u4e8e\u5176\u5360\u7528\u7684\u7a7a\u95f4\u5927\u5c0f\u3002\u4e0b\u9762\u4ee5 Java \u4e3a\u4f8b\u3002

    • \u6574\u6570\u7c7b\u578b byte \u5360\u7528 \\(1\\) \u5b57\u8282 = \\(8\\) \u6bd4\u7279 \uff0c\u53ef\u4ee5\u8868\u793a \\(2^{8}\\) \u4e2a\u6570\u5b57\u3002
    • \u6574\u6570\u7c7b\u578b int \u5360\u7528 \\(4\\) \u5b57\u8282 = \\(32\\) \u6bd4\u7279 \uff0c\u53ef\u4ee5\u8868\u793a \\(2^{32}\\) \u4e2a\u6570\u5b57\u3002

    \u8868 3-1 \u5217\u4e3e\u4e86 Java \u4e2d\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5360\u7528\u7a7a\u95f4\u3001\u53d6\u503c\u8303\u56f4\u548c\u9ed8\u8ba4\u503c\u3002\u6b64\u8868\u683c\u65e0\u987b\u6b7b\u8bb0\u786c\u80cc\uff0c\u5927\u81f4\u7406\u89e3\u5373\u53ef\uff0c\u9700\u8981\u65f6\u53ef\u4ee5\u901a\u8fc7\u67e5\u8868\u6765\u56de\u5fc6\u3002

    \u8868 3-1 \u00a0 \u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5360\u7528\u7a7a\u95f4\u548c\u53d6\u503c\u8303\u56f4

    \u7c7b\u578b \u7b26\u53f7 \u5360\u7528\u7a7a\u95f4 \u6700\u5c0f\u503c \u6700\u5927\u503c \u9ed8\u8ba4\u503c \u6574\u6570 byte 1 \u5b57\u8282 \\(-2^7\\) (\\(-128\\)) \\(2^7 - 1\\) (\\(127\\)) \\(0\\) short 2 \u5b57\u8282 \\(-2^{15}\\) \\(2^{15} - 1\\) \\(0\\) int 4 \u5b57\u8282 \\(-2^{31}\\) \\(2^{31} - 1\\) \\(0\\) long 8 \u5b57\u8282 \\(-2^{63}\\) \\(2^{63} - 1\\) \\(0\\) \u6d6e\u70b9\u6570 float 4 \u5b57\u8282 \\(1.175 \\times 10^{-38}\\) \\(3.403 \\times 10^{38}\\) \\(0.0\\text{f}\\) double 8 \u5b57\u8282 \\(2.225 \\times 10^{-308}\\) \\(1.798 \\times 10^{308}\\) \\(0.0\\) \u5b57\u7b26 char 2 \u5b57\u8282 \\(0\\) \\(2^{16} - 1\\) \\(0\\) \u5e03\u5c14 bool 1 \u5b57\u8282 \\(\\text{false}\\) \\(\\text{true}\\) \\(\\text{false}\\)

    \u8bf7\u6ce8\u610f\uff0c\u8868 3-1 \u9488\u5bf9\u7684\u662f Java \u7684\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u60c5\u51b5\u3002\u6bcf\u79cd\u7f16\u7a0b\u8bed\u8a00\u90fd\u6709\u5404\u81ea\u7684\u6570\u636e\u7c7b\u578b\u5b9a\u4e49\uff0c\u5b83\u4eec\u7684\u5360\u7528\u7a7a\u95f4\u3001\u53d6\u503c\u8303\u56f4\u548c\u9ed8\u8ba4\u503c\u53ef\u80fd\u4f1a\u6709\u6240\u4e0d\u540c\u3002

    • \u5728 Python \u4e2d\uff0c\u6574\u6570\u7c7b\u578b int \u53ef\u4ee5\u662f\u4efb\u610f\u5927\u5c0f\uff0c\u53ea\u53d7\u9650\u4e8e\u53ef\u7528\u5185\u5b58\uff1b\u6d6e\u70b9\u6570 float \u662f\u53cc\u7cbe\u5ea6 64 \u4f4d\uff1b\u6ca1\u6709 char \u7c7b\u578b\uff0c\u5355\u4e2a\u5b57\u7b26\u5b9e\u9645\u4e0a\u662f\u957f\u5ea6\u4e3a 1 \u7684\u5b57\u7b26\u4e32 str \u3002
    • C \u548c C++ \u672a\u660e\u786e\u89c4\u5b9a\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5927\u5c0f\uff0c\u800c\u56e0\u5b9e\u73b0\u548c\u5e73\u53f0\u5404\u5f02\u3002\u8868 3-1 \u9075\u5faa LP64 \u6570\u636e\u6a21\u578b\uff0c\u5176\u7528\u4e8e\u5305\u62ec Linux \u548c macOS \u5728\u5185\u7684 Unix 64 \u4f4d\u64cd\u4f5c\u7cfb\u7edf\u3002
    • \u5b57\u7b26 char \u7684\u5927\u5c0f\u5728 C \u548c C++ \u4e2d\u4e3a 1 \u5b57\u8282\uff0c\u5728\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4e2d\u53d6\u51b3\u4e8e\u7279\u5b9a\u7684\u5b57\u7b26\u7f16\u7801\u65b9\u6cd5\uff0c\u8be6\u89c1\u201c\u5b57\u7b26\u7f16\u7801\u201d\u7ae0\u8282\u3002
    • \u5373\u4f7f\u8868\u793a\u5e03\u5c14\u91cf\u4ec5\u9700 1 \u4f4d\uff08\\(0\\) \u6216 \\(1\\)\uff09\uff0c\u5b83\u5728\u5185\u5b58\u4e2d\u901a\u5e38\u4e5f\u5b58\u50a8\u4e3a 1 \u5b57\u8282\u3002\u8fd9\u662f\u56e0\u4e3a\u73b0\u4ee3\u8ba1\u7b97\u673a CPU \u901a\u5e38\u5c06 1 \u5b57\u8282\u4f5c\u4e3a\u6700\u5c0f\u5bfb\u5740\u5185\u5b58\u5355\u5143\u3002

    \u90a3\u4e48\uff0c\u57fa\u672c\u6570\u636e\u7c7b\u578b\u4e0e\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u6709\u4ec0\u4e48\u8054\u7cfb\u5462\uff1f\u6211\u4eec\u77e5\u9053\uff0c\u6570\u636e\u7ed3\u6784\u662f\u5728\u8ba1\u7b97\u673a\u4e2d\u7ec4\u7ec7\u4e0e\u5b58\u50a8\u6570\u636e\u7684\u65b9\u5f0f\u3002\u8fd9\u53e5\u8bdd\u7684\u4e3b\u8bed\u662f\u201c\u7ed3\u6784\u201d\u800c\u975e\u201c\u6570\u636e\u201d\u3002

    \u5982\u679c\u60f3\u8868\u793a\u201c\u4e00\u6392\u6570\u5b57\u201d\uff0c\u6211\u4eec\u81ea\u7136\u4f1a\u60f3\u5230\u4f7f\u7528\u6570\u7ec4\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u7684\u7ebf\u6027\u7ed3\u6784\u53ef\u4ee5\u8868\u793a\u6570\u5b57\u7684\u76f8\u90bb\u5173\u7cfb\u548c\u987a\u5e8f\u5173\u7cfb\uff0c\u4f46\u81f3\u4e8e\u5b58\u50a8\u7684\u5185\u5bb9\u662f\u6574\u6570 int\u3001\u5c0f\u6570 float \u8fd8\u662f\u5b57\u7b26 char \uff0c\u5219\u4e0e\u201c\u6570\u636e\u7ed3\u6784\u201d\u65e0\u5173\u3002

    \u6362\u53e5\u8bdd\u8bf4\uff0c\u57fa\u672c\u6570\u636e\u7c7b\u578b\u63d0\u4f9b\u4e86\u6570\u636e\u7684\u201c\u5185\u5bb9\u7c7b\u578b\u201d\uff0c\u800c\u6570\u636e\u7ed3\u6784\u63d0\u4f9b\u4e86\u6570\u636e\u7684\u201c\u7ec4\u7ec7\u65b9\u5f0f\u201d\u3002\u4f8b\u5982\u4ee5\u4e0b\u4ee3\u7801\uff0c\u6211\u4eec\u7528\u76f8\u540c\u7684\u6570\u636e\u7ed3\u6784\uff08\u6570\u7ec4\uff09\u6765\u5b58\u50a8\u4e0e\u8868\u793a\u4e0d\u540c\u7684\u57fa\u672c\u6570\u636e\u7c7b\u578b\uff0c\u5305\u62ec int\u3001float\u3001char\u3001bool \u7b49\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nnumbers: list[int] = [0] * 5\ndecimals: list[float] = [0.0] * 5\n# Python \u7684\u5b57\u7b26\u5b9e\u9645\u4e0a\u662f\u957f\u5ea6\u4e3a 1 \u7684\u5b57\u7b26\u4e32\ncharacters: list[str] = ['0'] * 5\nbools: list[bool] = [False] * 5\n# Python \u7684\u5217\u8868\u53ef\u4ee5\u81ea\u7531\u5b58\u50a8\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u5bf9\u8c61\u5f15\u7528\ndata = [0, 0.0, 'a', False, ListNode(0)]\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint numbers[5];\nfloat decimals[5];\nchar characters[5];\nbool bools[5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nboolean[] bools = new boolean[5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nbool[] bools = new bool[5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nvar numbers = [5]int{}\nvar decimals = [5]float64{}\nvar characters = [5]byte{}\nvar bools = [5]bool{}\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nlet numbers = Array(repeating: 0, count: 5)\nlet decimals = Array(repeating: 0.0, count: 5)\nlet characters: [Character] = Array(repeating: \"a\", count: 5)\nlet bools = Array(repeating: false, count: 5)\n
    // JavaScript \u7684\u6570\u7ec4\u53ef\u4ee5\u81ea\u7531\u5b58\u50a8\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u5bf9\u8c61\nconst array = [0, 0.0, 'a', false];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nconst numbers: number[] = [];\nconst characters: string[] = [];\nconst bools: boolean[] = [];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nList<int> numbers = List.filled(5, 0);\nList<double> decimals = List.filled(5, 0.0);\nList<String> characters = List.filled(5, 'a');\nList<bool> bools = List.filled(5, false);\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nlet numbers: Vec<i32> = vec![0; 5];\nlet decimals: Vec<f32> = vec![0.0; 5];\nlet characters: Vec<char> = vec!['0'; 5];\nlet bools: Vec<bool> = vec![false; 5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint numbers[10];\nfloat decimals[10];\nchar characters[10];\nbool bools[10];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nval numbers = IntArray(5)\nval decinals = FloatArray(5)\nval characters = CharArray(5)\nval bools = BooleanArray(5)\n
    # Ruby \u7684\u5217\u8868\u53ef\u4ee5\u81ea\u7531\u5b58\u50a8\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u5bf9\u8c61\u5f15\u7528\ndata = [0, 0.0, 'a', false, ListNode(0)]\n
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_data_structure/character_encoding/","title":"3.4 \u00a0 \u5b57\u7b26\u7f16\u7801 *","text":"

    \u5728\u8ba1\u7b97\u673a\u4e2d\uff0c\u6240\u6709\u6570\u636e\u90fd\u662f\u4ee5\u4e8c\u8fdb\u5236\u6570\u7684\u5f62\u5f0f\u5b58\u50a8\u7684\uff0c\u5b57\u7b26 char \u4e5f\u4e0d\u4f8b\u5916\u3002\u4e3a\u4e86\u8868\u793a\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u5efa\u7acb\u4e00\u5957\u201c\u5b57\u7b26\u96c6\u201d\uff0c\u89c4\u5b9a\u6bcf\u4e2a\u5b57\u7b26\u548c\u4e8c\u8fdb\u5236\u6570\u4e4b\u95f4\u7684\u4e00\u4e00\u5bf9\u5e94\u5173\u7cfb\u3002\u6709\u4e86\u5b57\u7b26\u96c6\u4e4b\u540e\uff0c\u8ba1\u7b97\u673a\u5c31\u53ef\u4ee5\u901a\u8fc7\u67e5\u8868\u5b8c\u6210\u4e8c\u8fdb\u5236\u6570\u5230\u5b57\u7b26\u7684\u8f6c\u6362\u3002

    "},{"location":"chapter_data_structure/character_encoding/#341-ascii","title":"3.4.1 \u00a0 ASCII \u5b57\u7b26\u96c6","text":"

    ASCII \u7801\u662f\u6700\u65e9\u51fa\u73b0\u7684\u5b57\u7b26\u96c6\uff0c\u5176\u5168\u79f0\u4e3a American Standard Code for Information Interchange\uff08\u7f8e\u56fd\u6807\u51c6\u4fe1\u606f\u4ea4\u6362\u4ee3\u7801\uff09\u3002\u5b83\u4f7f\u7528 7 \u4f4d\u4e8c\u8fdb\u5236\u6570\uff08\u4e00\u4e2a\u5b57\u8282\u7684\u4f4e 7 \u4f4d\uff09\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u6700\u591a\u80fd\u591f\u8868\u793a 128 \u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u3002\u5982\u56fe 3-6 \u6240\u793a\uff0cASCII \u7801\u5305\u62ec\u82f1\u6587\u5b57\u6bcd\u7684\u5927\u5c0f\u5199\u3001\u6570\u5b57 0 ~ 9\u3001\u4e00\u4e9b\u6807\u70b9\u7b26\u53f7\uff0c\u4ee5\u53ca\u4e00\u4e9b\u63a7\u5236\u5b57\u7b26\uff08\u5982\u6362\u884c\u7b26\u548c\u5236\u8868\u7b26\uff09\u3002

    \u56fe 3-6 \u00a0 ASCII \u7801

    \u7136\u800c\uff0cASCII \u7801\u4ec5\u80fd\u591f\u8868\u793a\u82f1\u6587\u3002\u968f\u7740\u8ba1\u7b97\u673a\u7684\u5168\u7403\u5316\uff0c\u8bde\u751f\u4e86\u4e00\u79cd\u80fd\u591f\u8868\u793a\u66f4\u591a\u8bed\u8a00\u7684 EASCII \u5b57\u7b26\u96c6\u3002\u5b83\u5728 ASCII \u7684 7 \u4f4d\u57fa\u7840\u4e0a\u6269\u5c55\u5230 8 \u4f4d\uff0c\u80fd\u591f\u8868\u793a 256 \u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u3002

    \u5728\u4e16\u754c\u8303\u56f4\u5185\uff0c\u9646\u7eed\u51fa\u73b0\u4e86\u4e00\u6279\u9002\u7528\u4e8e\u4e0d\u540c\u5730\u533a\u7684 EASCII \u5b57\u7b26\u96c6\u3002\u8fd9\u4e9b\u5b57\u7b26\u96c6\u7684\u524d 128 \u4e2a\u5b57\u7b26\u7edf\u4e00\u4e3a ASCII \u7801\uff0c\u540e 128 \u4e2a\u5b57\u7b26\u5b9a\u4e49\u4e0d\u540c\uff0c\u4ee5\u9002\u5e94\u4e0d\u540c\u8bed\u8a00\u7684\u9700\u6c42\u3002

    "},{"location":"chapter_data_structure/character_encoding/#342-gbk","title":"3.4.2 \u00a0 GBK \u5b57\u7b26\u96c6","text":"

    \u540e\u6765\u4eba\u4eec\u53d1\u73b0\uff0cEASCII \u7801\u4ecd\u7136\u65e0\u6cd5\u6ee1\u8db3\u8bb8\u591a\u8bed\u8a00\u7684\u5b57\u7b26\u6570\u91cf\u8981\u6c42\u3002\u6bd4\u5982\u6c49\u5b57\u6709\u8fd1\u5341\u4e07\u4e2a\uff0c\u5149\u65e5\u5e38\u4f7f\u7528\u7684\u5c31\u6709\u51e0\u5343\u4e2a\u3002\u4e2d\u56fd\u56fd\u5bb6\u6807\u51c6\u603b\u5c40\u4e8e 1980 \u5e74\u53d1\u5e03\u4e86 GB2312 \u5b57\u7b26\u96c6\uff0c\u5176\u6536\u5f55\u4e86 6763 \u4e2a\u6c49\u5b57\uff0c\u57fa\u672c\u6ee1\u8db3\u4e86\u6c49\u5b57\u7684\u8ba1\u7b97\u673a\u5904\u7406\u9700\u8981\u3002

    \u7136\u800c\uff0cGB2312 \u65e0\u6cd5\u5904\u7406\u90e8\u5206\u7f55\u89c1\u5b57\u548c\u7e41\u4f53\u5b57\u3002GBK \u5b57\u7b26\u96c6\u662f\u5728 GB2312 \u7684\u57fa\u7840\u4e0a\u6269\u5c55\u5f97\u5230\u7684\uff0c\u5b83\u5171\u6536\u5f55\u4e86 21886 \u4e2a\u6c49\u5b57\u3002\u5728 GBK \u7684\u7f16\u7801\u65b9\u6848\u4e2d\uff0cASCII \u5b57\u7b26\u4f7f\u7528\u4e00\u4e2a\u5b57\u8282\u8868\u793a\uff0c\u6c49\u5b57\u4f7f\u7528\u4e24\u4e2a\u5b57\u8282\u8868\u793a\u3002

    "},{"location":"chapter_data_structure/character_encoding/#343-unicode","title":"3.4.3 \u00a0 Unicode \u5b57\u7b26\u96c6","text":"

    \u968f\u7740\u8ba1\u7b97\u673a\u6280\u672f\u7684\u84ec\u52c3\u53d1\u5c55\uff0c\u5b57\u7b26\u96c6\u4e0e\u7f16\u7801\u6807\u51c6\u767e\u82b1\u9f50\u653e\uff0c\u800c\u8fd9\u5e26\u6765\u4e86\u8bb8\u591a\u95ee\u9898\u3002\u4e00\u65b9\u9762\uff0c\u8fd9\u4e9b\u5b57\u7b26\u96c6\u4e00\u822c\u53ea\u5b9a\u4e49\u4e86\u7279\u5b9a\u8bed\u8a00\u7684\u5b57\u7b26\uff0c\u65e0\u6cd5\u5728\u591a\u8bed\u8a00\u73af\u5883\u4e0b\u6b63\u5e38\u5de5\u4f5c\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u540c\u4e00\u79cd\u8bed\u8a00\u5b58\u5728\u591a\u79cd\u5b57\u7b26\u96c6\u6807\u51c6\uff0c\u5982\u679c\u4e24\u53f0\u8ba1\u7b97\u673a\u4f7f\u7528\u7684\u662f\u4e0d\u540c\u7684\u7f16\u7801\u6807\u51c6\uff0c\u5219\u5728\u4fe1\u606f\u4f20\u9012\u65f6\u5c31\u4f1a\u51fa\u73b0\u4e71\u7801\u3002

    \u90a3\u4e2a\u65f6\u4ee3\u7684\u7814\u7a76\u4eba\u5458\u5c31\u5728\u60f3\uff1a\u5982\u679c\u63a8\u51fa\u4e00\u4e2a\u8db3\u591f\u5b8c\u6574\u7684\u5b57\u7b26\u96c6\uff0c\u5c06\u4e16\u754c\u8303\u56f4\u5185\u7684\u6240\u6709\u8bed\u8a00\u548c\u7b26\u53f7\u90fd\u6536\u5f55\u5176\u4e2d\uff0c\u4e0d\u5c31\u53ef\u4ee5\u89e3\u51b3\u8de8\u8bed\u8a00\u73af\u5883\u548c\u4e71\u7801\u95ee\u9898\u4e86\u5417\uff1f\u5728\u8fd9\u79cd\u60f3\u6cd5\u7684\u9a71\u52a8\u4e0b\uff0c\u4e00\u4e2a\u5927\u800c\u5168\u7684\u5b57\u7b26\u96c6 Unicode \u5e94\u8fd0\u800c\u751f\u3002

    Unicode \u7684\u4e2d\u6587\u540d\u79f0\u4e3a\u201c\u7edf\u4e00\u7801\u201d\uff0c\u7406\u8bba\u4e0a\u80fd\u5bb9\u7eb3 100 \u591a\u4e07\u4e2a\u5b57\u7b26\u3002\u5b83\u81f4\u529b\u4e8e\u5c06\u5168\u7403\u8303\u56f4\u5185\u7684\u5b57\u7b26\u7eb3\u5165\u7edf\u4e00\u7684\u5b57\u7b26\u96c6\u4e4b\u4e2d\uff0c\u63d0\u4f9b\u4e00\u79cd\u901a\u7528\u7684\u5b57\u7b26\u96c6\u6765\u5904\u7406\u548c\u663e\u793a\u5404\u79cd\u8bed\u8a00\u6587\u5b57\uff0c\u51cf\u5c11\u56e0\u4e3a\u7f16\u7801\u6807\u51c6\u4e0d\u540c\u800c\u4ea7\u751f\u7684\u4e71\u7801\u95ee\u9898\u3002

    \u81ea 1991 \u5e74\u53d1\u5e03\u4ee5\u6765\uff0cUnicode \u4e0d\u65ad\u6269\u5145\u65b0\u7684\u8bed\u8a00\u4e0e\u5b57\u7b26\u3002\u622a\u81f3 2022 \u5e74 9 \u6708\uff0cUnicode \u5df2\u7ecf\u5305\u542b 149186 \u4e2a\u5b57\u7b26\uff0c\u5305\u62ec\u5404\u79cd\u8bed\u8a00\u7684\u5b57\u7b26\u3001\u7b26\u53f7\u751a\u81f3\u8868\u60c5\u7b26\u53f7\u7b49\u3002\u5728\u5e9e\u5927\u7684 Unicode \u5b57\u7b26\u96c6\u4e2d\uff0c\u5e38\u7528\u7684\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\uff0c\u6709\u4e9b\u751f\u50fb\u7684\u5b57\u7b26\u5360\u7528 3 \u5b57\u8282\u751a\u81f3 4 \u5b57\u8282\u3002

    Unicode \u662f\u4e00\u79cd\u901a\u7528\u5b57\u7b26\u96c6\uff0c\u672c\u8d28\u4e0a\u662f\u7ed9\u6bcf\u4e2a\u5b57\u7b26\u5206\u914d\u4e00\u4e2a\u7f16\u53f7\uff08\u79f0\u4e3a\u201c\u7801\u70b9\u201d\uff09\uff0c\u4f46\u5b83\u5e76\u6ca1\u6709\u89c4\u5b9a\u5728\u8ba1\u7b97\u673a\u4e2d\u5982\u4f55\u5b58\u50a8\u8fd9\u4e9b\u5b57\u7b26\u7801\u70b9\u3002\u6211\u4eec\u4e0d\u7981\u4f1a\u95ee\uff1a\u5f53\u591a\u79cd\u957f\u5ea6\u7684 Unicode \u7801\u70b9\u540c\u65f6\u51fa\u73b0\u5728\u4e00\u4e2a\u6587\u672c\u4e2d\u65f6\uff0c\u7cfb\u7edf\u5982\u4f55\u89e3\u6790\u5b57\u7b26\uff1f\u4f8b\u5982\u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a 2 \u5b57\u8282\u7684\u7f16\u7801\uff0c\u7cfb\u7edf\u5982\u4f55\u786e\u8ba4\u5b83\u662f\u4e00\u4e2a 2 \u5b57\u8282\u7684\u5b57\u7b26\u8fd8\u662f\u4e24\u4e2a 1 \u5b57\u8282\u7684\u5b57\u7b26\uff1f

    \u5bf9\u4e8e\u4ee5\u4e0a\u95ee\u9898\uff0c\u4e00\u79cd\u76f4\u63a5\u7684\u89e3\u51b3\u65b9\u6848\u662f\u5c06\u6240\u6709\u5b57\u7b26\u5b58\u50a8\u4e3a\u7b49\u957f\u7684\u7f16\u7801\u3002\u5982\u56fe 3-7 \u6240\u793a\uff0c\u201cHello\u201d\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 1 \u5b57\u8282\uff0c\u201c\u7b97\u6cd5\u201d\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u9ad8\u4f4d\u586b 0 \u5c06\u201cHello \u7b97\u6cd5\u201d\u4e2d\u7684\u6240\u6709\u5b57\u7b26\u90fd\u7f16\u7801\u4e3a 2 \u5b57\u8282\u957f\u5ea6\u3002\u8fd9\u6837\u7cfb\u7edf\u5c31\u53ef\u4ee5\u6bcf\u9694 2 \u5b57\u8282\u89e3\u6790\u4e00\u4e2a\u5b57\u7b26\uff0c\u6062\u590d\u8fd9\u4e2a\u77ed\u8bed\u7684\u5185\u5bb9\u4e86\u3002

    \u56fe 3-7 \u00a0 Unicode \u7f16\u7801\u793a\u4f8b

    \u7136\u800c ASCII \u7801\u5df2\u7ecf\u5411\u6211\u4eec\u8bc1\u660e\uff0c\u7f16\u7801\u82f1\u6587\u53ea\u9700 1 \u5b57\u8282\u3002\u82e5\u91c7\u7528\u4e0a\u8ff0\u65b9\u6848\uff0c\u82f1\u6587\u6587\u672c\u5360\u7528\u7a7a\u95f4\u7684\u5927\u5c0f\u5c06\u4f1a\u662f ASCII \u7f16\u7801\u4e0b\u7684\u4e24\u500d\uff0c\u975e\u5e38\u6d6a\u8d39\u5185\u5b58\u7a7a\u95f4\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u9700\u8981\u4e00\u79cd\u66f4\u52a0\u9ad8\u6548\u7684 Unicode \u7f16\u7801\u65b9\u6cd5\u3002

    "},{"location":"chapter_data_structure/character_encoding/#344-utf-8","title":"3.4.4 \u00a0 UTF-8 \u7f16\u7801","text":"

    \u76ee\u524d\uff0cUTF-8 \u5df2\u6210\u4e3a\u56fd\u9645\u4e0a\u4f7f\u7528\u6700\u5e7f\u6cdb\u7684 Unicode \u7f16\u7801\u65b9\u6cd5\u3002\u5b83\u662f\u4e00\u79cd\u53ef\u53d8\u957f\u5ea6\u7684\u7f16\u7801\uff0c\u4f7f\u7528 1 \u5230 4 \u5b57\u8282\u6765\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u6839\u636e\u5b57\u7b26\u7684\u590d\u6742\u6027\u800c\u53d8\u3002ASCII \u5b57\u7b26\u53ea\u9700 1 \u5b57\u8282\uff0c\u62c9\u4e01\u5b57\u6bcd\u548c\u5e0c\u814a\u5b57\u6bcd\u9700\u8981 2 \u5b57\u8282\uff0c\u5e38\u7528\u7684\u4e2d\u6587\u5b57\u7b26\u9700\u8981 3 \u5b57\u8282\uff0c\u5176\u4ed6\u7684\u4e00\u4e9b\u751f\u50fb\u5b57\u7b26\u9700\u8981 4 \u5b57\u8282\u3002

    UTF-8 \u7684\u7f16\u7801\u89c4\u5219\u5e76\u4e0d\u590d\u6742\uff0c\u5206\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u60c5\u51b5\u3002

    • \u5bf9\u4e8e\u957f\u5ea6\u4e3a 1 \u5b57\u8282\u7684\u5b57\u7b26\uff0c\u5c06\u6700\u9ad8\u4f4d\u8bbe\u7f6e\u4e3a \\(0\\) \uff0c\u5176\u4f59 7 \u4f4d\u8bbe\u7f6e\u4e3a Unicode \u7801\u70b9\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cASCII \u5b57\u7b26\u5728 Unicode \u5b57\u7b26\u96c6\u4e2d\u5360\u636e\u4e86\u524d 128 \u4e2a\u7801\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cUTF-8 \u7f16\u7801\u53ef\u4ee5\u5411\u4e0b\u517c\u5bb9 ASCII \u7801\u3002\u8fd9\u610f\u5473\u7740\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 UTF-8 \u6765\u89e3\u6790\u5e74\u4ee3\u4e45\u8fdc\u7684 ASCII \u7801\u6587\u672c\u3002
    • \u5bf9\u4e8e\u957f\u5ea6\u4e3a \\(n\\) \u5b57\u8282\u7684\u5b57\u7b26\uff08\u5176\u4e2d \\(n > 1\\)\uff09\uff0c\u5c06\u9996\u4e2a\u5b57\u8282\u7684\u9ad8 \\(n\\) \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(1\\) \uff0c\u7b2c \\(n + 1\\) \u4f4d\u8bbe\u7f6e\u4e3a \\(0\\) \uff1b\u4ece\u7b2c\u4e8c\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5b57\u8282\u7684\u9ad8 2 \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(10\\) \uff1b\u5176\u4f59\u6240\u6709\u4f4d\u7528\u4e8e\u586b\u5145\u5b57\u7b26\u7684 Unicode \u7801\u70b9\u3002

    \u56fe 3-8 \u5c55\u793a\u4e86\u201cHello\u7b97\u6cd5\u201d\u5bf9\u5e94\u7684 UTF-8 \u7f16\u7801\u3002\u89c2\u5bdf\u53d1\u73b0\uff0c\u7531\u4e8e\u6700\u9ad8 \\(n\\) \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(1\\) \uff0c\u56e0\u6b64\u7cfb\u7edf\u53ef\u4ee5\u901a\u8fc7\u8bfb\u53d6\u6700\u9ad8\u4f4d \\(1\\) \u7684\u4e2a\u6570\u6765\u89e3\u6790\u51fa\u5b57\u7b26\u7684\u957f\u5ea6\u4e3a \\(n\\) \u3002

    \u4f46\u4e3a\u4ec0\u4e48\u8981\u5c06\u5176\u4f59\u6240\u6709\u5b57\u8282\u7684\u9ad8 2 \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(10\\) \u5462\uff1f\u5b9e\u9645\u4e0a\uff0c\u8fd9\u4e2a \\(10\\) \u80fd\u591f\u8d77\u5230\u6821\u9a8c\u7b26\u7684\u4f5c\u7528\u3002\u5047\u8bbe\u7cfb\u7edf\u4ece\u4e00\u4e2a\u9519\u8bef\u7684\u5b57\u8282\u5f00\u59cb\u89e3\u6790\u6587\u672c\uff0c\u5b57\u8282\u5934\u90e8\u7684 \\(10\\) \u80fd\u591f\u5e2e\u52a9\u7cfb\u7edf\u5feb\u901f\u5224\u65ad\u51fa\u5f02\u5e38\u3002

    \u4e4b\u6240\u4ee5\u5c06 \\(10\\) \u5f53\u4f5c\u6821\u9a8c\u7b26\uff0c\u662f\u56e0\u4e3a\u5728 UTF-8 \u7f16\u7801\u89c4\u5219\u4e0b\uff0c\u4e0d\u53ef\u80fd\u6709\u5b57\u7b26\u7684\u6700\u9ad8\u4e24\u4f4d\u662f \\(10\\) \u3002\u8fd9\u4e2a\u7ed3\u8bba\u53ef\u4ee5\u7528\u53cd\u8bc1\u6cd5\u6765\u8bc1\u660e\uff1a\u5047\u8bbe\u4e00\u4e2a\u5b57\u7b26\u7684\u6700\u9ad8\u4e24\u4f4d\u662f \\(10\\) \uff0c\u8bf4\u660e\u8be5\u5b57\u7b26\u7684\u957f\u5ea6\u4e3a \\(1\\) \uff0c\u5bf9\u5e94 ASCII \u7801\u3002\u800c ASCII \u7801\u7684\u6700\u9ad8\u4f4d\u5e94\u8be5\u662f \\(0\\) \uff0c\u4e0e\u5047\u8bbe\u77db\u76fe\u3002

    \u56fe 3-8 \u00a0 UTF-8 \u7f16\u7801\u793a\u4f8b

    \u9664\u4e86 UTF-8 \u4e4b\u5916\uff0c\u5e38\u89c1\u7684\u7f16\u7801\u65b9\u5f0f\u8fd8\u5305\u62ec\u4ee5\u4e0b\u4e24\u79cd\u3002

    • UTF-16 \u7f16\u7801\uff1a\u4f7f\u7528 2 \u6216 4 \u5b57\u8282\u6765\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\u3002\u6240\u6709\u7684 ASCII \u5b57\u7b26\u548c\u5e38\u7528\u7684\u975e\u82f1\u6587\u5b57\u7b26\uff0c\u90fd\u7528 2 \u5b57\u8282\u8868\u793a\uff1b\u5c11\u6570\u5b57\u7b26\u9700\u8981\u7528\u5230 4 \u5b57\u8282\u8868\u793a\u3002\u5bf9\u4e8e 2 \u5b57\u8282\u7684\u5b57\u7b26\uff0cUTF-16 \u7f16\u7801\u4e0e Unicode \u7801\u70b9\u76f8\u7b49\u3002
    • UTF-32 \u7f16\u7801\uff1a\u6bcf\u4e2a\u5b57\u7b26\u90fd\u4f7f\u7528 4 \u5b57\u8282\u3002\u8fd9\u610f\u5473\u7740 UTF-32 \u6bd4 UTF-8 \u548c UTF-16 \u66f4\u5360\u7528\u7a7a\u95f4\uff0c\u7279\u522b\u662f\u5bf9\u4e8e ASCII \u5b57\u7b26\u5360\u6bd4\u8f83\u9ad8\u7684\u6587\u672c\u3002

    \u4ece\u5b58\u50a8\u7a7a\u95f4\u5360\u7528\u7684\u89d2\u5ea6\u770b\uff0c\u4f7f\u7528 UTF-8 \u8868\u793a\u82f1\u6587\u5b57\u7b26\u975e\u5e38\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u4ec5\u9700 1 \u5b57\u8282\uff1b\u4f7f\u7528 UTF-16 \u7f16\u7801\u67d0\u4e9b\u975e\u82f1\u6587\u5b57\u7b26\uff08\u4f8b\u5982\u4e2d\u6587\uff09\u4f1a\u66f4\u52a0\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u4ec5\u9700 2 \u5b57\u8282\uff0c\u800c UTF-8 \u53ef\u80fd\u9700\u8981 3 \u5b57\u8282\u3002

    \u4ece\u517c\u5bb9\u6027\u7684\u89d2\u5ea6\u770b\uff0cUTF-8 \u7684\u901a\u7528\u6027\u6700\u4f73\uff0c\u8bb8\u591a\u5de5\u5177\u548c\u5e93\u4f18\u5148\u652f\u6301 UTF-8 \u3002

    "},{"location":"chapter_data_structure/character_encoding/#345","title":"3.4.5 \u00a0 \u7f16\u7a0b\u8bed\u8a00\u7684\u5b57\u7b26\u7f16\u7801","text":"

    \u5bf9\u4e8e\u4ee5\u5f80\u7684\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\uff0c\u7a0b\u5e8f\u8fd0\u884c\u4e2d\u7684\u5b57\u7b26\u4e32\u90fd\u91c7\u7528 UTF-16 \u6216 UTF-32 \u8fd9\u7c7b\u7b49\u957f\u7f16\u7801\u3002\u5728\u7b49\u957f\u7f16\u7801\u4e0b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5b57\u7b26\u4e32\u770b\u4f5c\u6570\u7ec4\u6765\u5904\u7406\uff0c\u8fd9\u79cd\u505a\u6cd5\u5177\u6709\u4ee5\u4e0b\u4f18\u70b9\u3002

    • \u968f\u673a\u8bbf\u95ee\uff1aUTF-16 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u3002UTF-8 \u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u8981\u60f3\u627e\u5230\u7b2c \\(i\\) \u4e2a\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u4ece\u5b57\u7b26\u4e32\u7684\u5f00\u59cb\u5904\u904d\u5386\u5230\u7b2c \\(i\\) \u4e2a\u5b57\u7b26\uff0c\u8fd9\u9700\u8981 \\(O(n)\\) \u7684\u65f6\u95f4\u3002
    • \u5b57\u7b26\u8ba1\u6570\uff1a\u4e0e\u968f\u673a\u8bbf\u95ee\u7c7b\u4f3c\uff0c\u8ba1\u7b97 UTF-16 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u4e5f\u662f \\(O(1)\\) \u7684\u64cd\u4f5c\u3002\u4f46\u662f\uff0c\u8ba1\u7b97 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u9700\u8981\u904d\u5386\u6574\u4e2a\u5b57\u7b26\u4e32\u3002
    • \u5b57\u7b26\u4e32\u64cd\u4f5c\uff1a\u5728 UTF-16 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u4e0a\uff0c\u5f88\u591a\u5b57\u7b26\u4e32\u64cd\u4f5c\uff08\u5982\u5206\u5272\u3001\u8fde\u63a5\u3001\u63d2\u5165\u3001\u5220\u9664\u7b49\uff09\u66f4\u5bb9\u6613\u8fdb\u884c\u3002\u5728 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u4e0a\uff0c\u8fdb\u884c\u8fd9\u4e9b\u64cd\u4f5c\u901a\u5e38\u9700\u8981\u989d\u5916\u7684\u8ba1\u7b97\uff0c\u4ee5\u786e\u4fdd\u4e0d\u4f1a\u4ea7\u751f\u65e0\u6548\u7684 UTF-8 \u7f16\u7801\u3002

    \u5b9e\u9645\u4e0a\uff0c\u7f16\u7a0b\u8bed\u8a00\u7684\u5b57\u7b26\u7f16\u7801\u65b9\u6848\u8bbe\u8ba1\u662f\u4e00\u4e2a\u5f88\u6709\u8da3\u7684\u8bdd\u9898\uff0c\u6d89\u53ca\u8bb8\u591a\u56e0\u7d20\u3002

    • Java \u7684 String \u7c7b\u578b\u4f7f\u7528 UTF-16 \u7f16\u7801\uff0c\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\u3002\u8fd9\u662f\u56e0\u4e3a Java \u8bed\u8a00\u8bbe\u8ba1\u4e4b\u521d\uff0c\u4eba\u4eec\u8ba4\u4e3a 16 \u4f4d\u8db3\u4ee5\u8868\u793a\u6240\u6709\u53ef\u80fd\u7684\u5b57\u7b26\u3002\u7136\u800c\uff0c\u8fd9\u662f\u4e00\u4e2a\u4e0d\u6b63\u786e\u7684\u5224\u65ad\u3002\u540e\u6765 Unicode \u89c4\u8303\u6269\u5c55\u5230\u4e86\u8d85\u8fc7 16 \u4f4d\uff0c\u6240\u4ee5 Java \u4e2d\u7684\u5b57\u7b26\u73b0\u5728\u53ef\u80fd\u7531\u4e00\u5bf9 16 \u4f4d\u7684\u503c\uff08\u79f0\u4e3a\u201c\u4ee3\u7406\u5bf9\u201d\uff09\u8868\u793a\u3002
    • JavaScript \u548c TypeScript \u7684\u5b57\u7b26\u4e32\u4f7f\u7528 UTF-16 \u7f16\u7801\u7684\u539f\u56e0\u4e0e Java \u7c7b\u4f3c\u3002\u5f53 1995 \u5e74 Netscape \u516c\u53f8\u9996\u6b21\u63a8\u51fa JavaScript \u8bed\u8a00\u65f6\uff0cUnicode \u8fd8\u5904\u4e8e\u53d1\u5c55\u65e9\u671f\uff0c\u90a3\u65f6\u5019\u4f7f\u7528 16 \u4f4d\u7684\u7f16\u7801\u5c31\u8db3\u4ee5\u8868\u793a\u6240\u6709\u7684 Unicode \u5b57\u7b26\u4e86\u3002
    • C# \u4f7f\u7528 UTF-16 \u7f16\u7801\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a .NET \u5e73\u53f0\u662f\u7531 Microsoft \u8bbe\u8ba1\u7684\uff0c\u800c Microsoft \u7684\u5f88\u591a\u6280\u672f\uff08\u5305\u62ec Windows \u64cd\u4f5c\u7cfb\u7edf\uff09\u90fd\u5e7f\u6cdb\u4f7f\u7528 UTF-16 \u7f16\u7801\u3002

    \u7531\u4e8e\u4ee5\u4e0a\u7f16\u7a0b\u8bed\u8a00\u5bf9\u5b57\u7b26\u6570\u91cf\u7684\u4f4e\u4f30\uff0c\u5b83\u4eec\u4e0d\u5f97\u4e0d\u91c7\u53d6\u201c\u4ee3\u7406\u5bf9\u201d\u7684\u65b9\u5f0f\u6765\u8868\u793a\u8d85\u8fc7 16 \u4f4d\u957f\u5ea6\u7684 Unicode \u5b57\u7b26\u3002\u8fd9\u662f\u4e00\u4e2a\u4e0d\u5f97\u5df2\u4e3a\u4e4b\u7684\u65e0\u5948\u4e4b\u4e3e\u3002\u4e00\u65b9\u9762\uff0c\u5305\u542b\u4ee3\u7406\u5bf9\u7684\u5b57\u7b26\u4e32\u4e2d\uff0c\u4e00\u4e2a\u5b57\u7b26\u53ef\u80fd\u5360\u7528 2 \u5b57\u8282\u6216 4 \u5b57\u8282\uff0c\u4ece\u800c\u4e27\u5931\u4e86\u7b49\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u5904\u7406\u4ee3\u7406\u5bf9\u9700\u8981\u989d\u5916\u589e\u52a0\u4ee3\u7801\uff0c\u8fd9\u63d0\u9ad8\u4e86\u7f16\u7a0b\u7684\u590d\u6742\u6027\u548c\u8c03\u8bd5\u96be\u5ea6\u3002

    \u51fa\u4e8e\u4ee5\u4e0a\u539f\u56e0\uff0c\u90e8\u5206\u7f16\u7a0b\u8bed\u8a00\u63d0\u51fa\u4e86\u4e00\u4e9b\u4e0d\u540c\u7684\u7f16\u7801\u65b9\u6848\u3002

    • Python \u4e2d\u7684 str \u4f7f\u7528 Unicode \u7f16\u7801\uff0c\u5e76\u91c7\u7528\u4e00\u79cd\u7075\u6d3b\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u5b58\u50a8\u7684\u5b57\u7b26\u957f\u5ea6\u53d6\u51b3\u4e8e\u5b57\u7b26\u4e32\u4e2d\u6700\u5927\u7684 Unicode \u7801\u70b9\u3002\u82e5\u5b57\u7b26\u4e32\u4e2d\u5168\u90e8\u662f ASCII \u5b57\u7b26\uff0c\u5219\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 1 \u5b57\u8282\uff1b\u5982\u679c\u6709\u5b57\u7b26\u8d85\u51fa\u4e86 ASCII \u8303\u56f4\uff0c\u4f46\u5168\u90e8\u5728\u57fa\u672c\u591a\u8bed\u8a00\u5e73\u9762\uff08BMP\uff09\u5185\uff0c\u5219\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\uff1b\u5982\u679c\u6709\u8d85\u51fa BMP \u7684\u5b57\u7b26\uff0c\u5219\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 4 \u5b57\u8282\u3002
    • Go \u8bed\u8a00\u7684 string \u7c7b\u578b\u5728\u5185\u90e8\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002Go \u8bed\u8a00\u8fd8\u63d0\u4f9b\u4e86 rune \u7c7b\u578b\uff0c\u5b83\u7528\u4e8e\u8868\u793a\u5355\u4e2a Unicode \u7801\u70b9\u3002
    • Rust \u8bed\u8a00\u7684 str \u548c String \u7c7b\u578b\u5728\u5185\u90e8\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002Rust \u4e5f\u63d0\u4f9b\u4e86 char \u7c7b\u578b\uff0c\u7528\u4e8e\u8868\u793a\u5355\u4e2a Unicode \u7801\u70b9\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4ee5\u4e0a\u8ba8\u8bba\u7684\u90fd\u662f\u5b57\u7b26\u4e32\u5728\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u5b58\u50a8\u65b9\u5f0f\uff0c\u8fd9\u548c\u5b57\u7b26\u4e32\u5982\u4f55\u5728\u6587\u4ef6\u4e2d\u5b58\u50a8\u6216\u5728\u7f51\u7edc\u4e2d\u4f20\u8f93\u662f\u4e0d\u540c\u7684\u95ee\u9898\u3002\u5728\u6587\u4ef6\u5b58\u50a8\u6216\u7f51\u7edc\u4f20\u8f93\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5c06\u5b57\u7b26\u4e32\u7f16\u7801\u4e3a UTF-8 \u683c\u5f0f\uff0c\u4ee5\u8fbe\u5230\u6700\u4f18\u7684\u517c\u5bb9\u6027\u548c\u7a7a\u95f4\u6548\u7387\u3002

    "},{"location":"chapter_data_structure/classification_of_data_structure/","title":"3.1 \u00a0 \u6570\u636e\u7ed3\u6784\u5206\u7c7b","text":"

    \u5e38\u89c1\u7684\u6570\u636e\u7ed3\u6784\u5305\u62ec\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\uff0c\u5b83\u4eec\u53ef\u4ee5\u4ece\u201c\u903b\u8f91\u7ed3\u6784\u201d\u548c\u201c\u7269\u7406\u7ed3\u6784\u201d\u4e24\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u5206\u7c7b\u3002

    "},{"location":"chapter_data_structure/classification_of_data_structure/#311","title":"3.1.1 \u00a0 \u903b\u8f91\u7ed3\u6784\uff1a\u7ebf\u6027\u4e0e\u975e\u7ebf\u6027","text":"

    \u903b\u8f91\u7ed3\u6784\u63ed\u793a\u4e86\u6570\u636e\u5143\u7d20\u4e4b\u95f4\u7684\u903b\u8f91\u5173\u7cfb\u3002\u5728\u6570\u7ec4\u548c\u94fe\u8868\u4e2d\uff0c\u6570\u636e\u6309\u7167\u4e00\u5b9a\u987a\u5e8f\u6392\u5217\uff0c\u4f53\u73b0\u4e86\u6570\u636e\u4e4b\u95f4\u7684\u7ebf\u6027\u5173\u7cfb\uff1b\u800c\u5728\u6811\u4e2d\uff0c\u6570\u636e\u4ece\u9876\u90e8\u5411\u4e0b\u6309\u5c42\u6b21\u6392\u5217\uff0c\u8868\u73b0\u51fa\u201c\u7956\u5148\u201d\u4e0e\u201c\u540e\u4ee3\u201d\u4e4b\u95f4\u7684\u6d3e\u751f\u5173\u7cfb\uff1b\u56fe\u5219\u7531\u8282\u70b9\u548c\u8fb9\u6784\u6210\uff0c\u53cd\u6620\u4e86\u590d\u6742\u7684\u7f51\u7edc\u5173\u7cfb\u3002

    \u5982\u56fe 3-1 \u6240\u793a\uff0c\u903b\u8f91\u7ed3\u6784\u53ef\u5206\u4e3a\u201c\u7ebf\u6027\u201d\u548c\u201c\u975e\u7ebf\u6027\u201d\u4e24\u5927\u7c7b\u3002\u7ebf\u6027\u7ed3\u6784\u6bd4\u8f83\u76f4\u89c2\uff0c\u6307\u6570\u636e\u5728\u903b\u8f91\u5173\u7cfb\u4e0a\u5448\u7ebf\u6027\u6392\u5217\uff1b\u975e\u7ebf\u6027\u7ed3\u6784\u5219\u76f8\u53cd\uff0c\u5448\u975e\u7ebf\u6027\u6392\u5217\u3002

    • \u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff1a\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\uff0c\u5143\u7d20\u4e4b\u95f4\u662f\u4e00\u5bf9\u4e00\u7684\u987a\u5e8f\u5173\u7cfb\u3002
    • \u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff1a\u6811\u3001\u5806\u3001\u56fe\u3001\u54c8\u5e0c\u8868\u3002

    \u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u8fdb\u4e00\u6b65\u5212\u5206\u4e3a\u6811\u5f62\u7ed3\u6784\u548c\u7f51\u72b6\u7ed3\u6784\u3002

    • \u6811\u5f62\u7ed3\u6784\uff1a\u6811\u3001\u5806\u3001\u54c8\u5e0c\u8868\uff0c\u5143\u7d20\u4e4b\u95f4\u662f\u4e00\u5bf9\u591a\u7684\u5173\u7cfb\u3002
    • \u7f51\u72b6\u7ed3\u6784\uff1a\u56fe\uff0c\u5143\u7d20\u4e4b\u95f4\u662f\u591a\u5bf9\u591a\u7684\u5173\u7cfb\u3002

    \u56fe 3-1 \u00a0 \u7ebf\u6027\u6570\u636e\u7ed3\u6784\u4e0e\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784

    "},{"location":"chapter_data_structure/classification_of_data_structure/#312","title":"3.1.2 \u00a0 \u7269\u7406\u7ed3\u6784\uff1a\u8fde\u7eed\u4e0e\u5206\u6563","text":"

    \u5f53\u7b97\u6cd5\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6b63\u5728\u5904\u7406\u7684\u6570\u636e\u4e3b\u8981\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\u3002\u56fe 3-2 \u5c55\u793a\u4e86\u4e00\u4e2a\u8ba1\u7b97\u673a\u5185\u5b58\u6761\uff0c\u5176\u4e2d\u6bcf\u4e2a\u9ed1\u8272\u65b9\u5757\u90fd\u5305\u542b\u4e00\u5757\u5185\u5b58\u7a7a\u95f4\u3002\u6211\u4eec\u53ef\u4ee5\u5c06\u5185\u5b58\u60f3\u8c61\u6210\u4e00\u4e2a\u5de8\u5927\u7684 Excel \u8868\u683c\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5355\u5143\u683c\u90fd\u53ef\u4ee5\u5b58\u50a8\u4e00\u5b9a\u5927\u5c0f\u7684\u6570\u636e\u3002

    \u7cfb\u7edf\u901a\u8fc7\u5185\u5b58\u5730\u5740\u6765\u8bbf\u95ee\u76ee\u6807\u4f4d\u7f6e\u7684\u6570\u636e\u3002\u5982\u56fe 3-2 \u6240\u793a\uff0c\u8ba1\u7b97\u673a\u6839\u636e\u7279\u5b9a\u89c4\u5219\u4e3a\u8868\u683c\u4e2d\u7684\u6bcf\u4e2a\u5355\u5143\u683c\u5206\u914d\u7f16\u53f7\uff0c\u786e\u4fdd\u6bcf\u4e2a\u5185\u5b58\u7a7a\u95f4\u90fd\u6709\u552f\u4e00\u7684\u5185\u5b58\u5730\u5740\u3002\u6709\u4e86\u8fd9\u4e9b\u5730\u5740\uff0c\u7a0b\u5e8f\u4fbf\u53ef\u4ee5\u8bbf\u95ee\u5185\u5b58\u4e2d\u7684\u6570\u636e\u3002

    \u56fe 3-2 \u00a0 \u5185\u5b58\u6761\u3001\u5185\u5b58\u7a7a\u95f4\u3001\u5185\u5b58\u5730\u5740

    Tip

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u5c06\u5185\u5b58\u6bd4\u4f5c Excel \u8868\u683c\u662f\u4e00\u4e2a\u7b80\u5316\u7684\u7c7b\u6bd4\uff0c\u5b9e\u9645\u5185\u5b58\u7684\u5de5\u4f5c\u673a\u5236\u6bd4\u8f83\u590d\u6742\uff0c\u6d89\u53ca\u5730\u5740\u7a7a\u95f4\u3001\u5185\u5b58\u7ba1\u7406\u3001\u7f13\u5b58\u673a\u5236\u3001\u865a\u62df\u5185\u5b58\u548c\u7269\u7406\u5185\u5b58\u7b49\u6982\u5ff5\u3002

    \u5185\u5b58\u662f\u6240\u6709\u7a0b\u5e8f\u7684\u5171\u4eab\u8d44\u6e90\uff0c\u5f53\u67d0\u5757\u5185\u5b58\u88ab\u67d0\u4e2a\u7a0b\u5e8f\u5360\u7528\u65f6\uff0c\u5219\u65e0\u6cd5\u88ab\u5176\u4ed6\u7a0b\u5e8f\u540c\u65f6\u4f7f\u7528\u4e86\u3002\u56e0\u6b64\u5728\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u8bbe\u8ba1\u4e2d\uff0c\u5185\u5b58\u8d44\u6e90\u662f\u4e00\u4e2a\u91cd\u8981\u7684\u8003\u8651\u56e0\u7d20\u3002\u6bd4\u5982\uff0c\u7b97\u6cd5\u6240\u5360\u7528\u7684\u5185\u5b58\u5cf0\u503c\u4e0d\u5e94\u8d85\u8fc7\u7cfb\u7edf\u5269\u4f59\u7a7a\u95f2\u5185\u5b58\uff1b\u5982\u679c\u7f3a\u5c11\u8fde\u7eed\u5927\u5757\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u90a3\u4e48\u6240\u9009\u7528\u7684\u6570\u636e\u7ed3\u6784\u5fc5\u987b\u80fd\u591f\u5b58\u50a8\u5728\u5206\u6563\u7684\u5185\u5b58\u7a7a\u95f4\u5185\u3002

    \u5982\u56fe 3-3 \u6240\u793a\uff0c\u7269\u7406\u7ed3\u6784\u53cd\u6620\u4e86\u6570\u636e\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u7684\u5b58\u50a8\u65b9\u5f0f\uff0c\u53ef\u5206\u4e3a\u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\uff08\u6570\u7ec4\uff09\u548c\u5206\u6563\u7a7a\u95f4\u5b58\u50a8\uff08\u94fe\u8868\uff09\u3002\u7269\u7406\u7ed3\u6784\u4ece\u5e95\u5c42\u51b3\u5b9a\u4e86\u6570\u636e\u7684\u8bbf\u95ee\u3001\u66f4\u65b0\u3001\u589e\u5220\u7b49\u64cd\u4f5c\u65b9\u6cd5\uff0c\u4e24\u79cd\u7269\u7406\u7ed3\u6784\u5728\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u65b9\u9762\u5448\u73b0\u51fa\u4e92\u8865\u7684\u7279\u70b9\u3002

    \u56fe 3-3 \u00a0 \u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\u4e0e\u5206\u6563\u7a7a\u95f4\u5b58\u50a8

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6240\u6709\u6570\u636e\u7ed3\u6784\u90fd\u662f\u57fa\u4e8e\u6570\u7ec4\u3001\u94fe\u8868\u6216\u4e8c\u8005\u7684\u7ec4\u5408\u5b9e\u73b0\u7684\u3002\u4f8b\u5982\uff0c\u6808\u548c\u961f\u5217\u65e2\u53ef\u4ee5\u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u94fe\u8868\u5b9e\u73b0\uff1b\u800c\u54c8\u5e0c\u8868\u7684\u5b9e\u73b0\u53ef\u80fd\u540c\u65f6\u5305\u542b\u6570\u7ec4\u548c\u94fe\u8868\u3002

    • \u57fa\u4e8e\u6570\u7ec4\u53ef\u5b9e\u73b0\uff1a\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\u3001\u77e9\u9635\u3001\u5f20\u91cf\uff08\u7ef4\u5ea6 \\(\\geq 3\\) \u7684\u6570\u7ec4\uff09\u7b49\u3002
    • \u57fa\u4e8e\u94fe\u8868\u53ef\u5b9e\u73b0\uff1a\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\u7b49\u3002

    \u94fe\u8868\u5728\u521d\u59cb\u5316\u540e\uff0c\u4ecd\u53ef\u4ee5\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u5bf9\u5176\u957f\u5ea6\u8fdb\u884c\u8c03\u6574\uff0c\u56e0\u6b64\u4e5f\u79f0\u201c\u52a8\u6001\u6570\u636e\u7ed3\u6784\u201d\u3002\u6570\u7ec4\u5728\u521d\u59cb\u5316\u540e\u957f\u5ea6\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u4e5f\u79f0\u201c\u9759\u6001\u6570\u636e\u7ed3\u6784\u201d\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6570\u7ec4\u53ef\u901a\u8fc7\u91cd\u65b0\u5206\u914d\u5185\u5b58\u5b9e\u73b0\u957f\u5ea6\u53d8\u5316\uff0c\u4ece\u800c\u5177\u5907\u4e00\u5b9a\u7684\u201c\u52a8\u6001\u6027\u201d\u3002

    Tip

    \u5982\u679c\u4f60\u611f\u89c9\u7269\u7406\u7ed3\u6784\u7406\u89e3\u8d77\u6765\u6709\u56f0\u96be\uff0c\u5efa\u8bae\u5148\u9605\u8bfb\u4e0b\u4e00\u7ae0\uff0c\u7136\u540e\u518d\u56de\u987e\u672c\u8282\u5185\u5bb9\u3002

    "},{"location":"chapter_data_structure/number_encoding/","title":"3.3 \u00a0 \u6570\u5b57\u7f16\u7801 *","text":"

    Tip

    \u5728\u672c\u4e66\u4e2d\uff0c\u6807\u9898\u5e26\u6709 * \u7b26\u53f7\u7684\u662f\u9009\u8bfb\u7ae0\u8282\u3002\u5982\u679c\u4f60\u65f6\u95f4\u6709\u9650\u6216\u611f\u5230\u7406\u89e3\u56f0\u96be\uff0c\u53ef\u4ee5\u5148\u8df3\u8fc7\uff0c\u7b49\u5b66\u5b8c\u5fc5\u8bfb\u7ae0\u8282\u540e\u518d\u5355\u72ec\u653b\u514b\u3002

    "},{"location":"chapter_data_structure/number_encoding/#331","title":"3.3.1 \u00a0 \u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801","text":"

    \u5728\u4e0a\u4e00\u8282\u7684\u8868\u683c\u4e2d\u6211\u4eec\u53d1\u73b0\uff0c\u6240\u6709\u6574\u6570\u7c7b\u578b\u80fd\u591f\u8868\u793a\u7684\u8d1f\u6570\u90fd\u6bd4\u6b63\u6570\u591a\u4e00\u4e2a\uff0c\u4f8b\u5982 byte \u7684\u53d6\u503c\u8303\u56f4\u662f \\([-128, 127]\\) \u3002\u8fd9\u4e2a\u73b0\u8c61\u6bd4\u8f83\u53cd\u76f4\u89c9\uff0c\u5b83\u7684\u5185\u5728\u539f\u56e0\u6d89\u53ca\u539f\u7801\u3001\u53cd\u7801\u3001\u8865\u7801\u7684\u76f8\u5173\u77e5\u8bc6\u3002

    \u9996\u5148\u9700\u8981\u6307\u51fa\uff0c\u6570\u5b57\u662f\u4ee5\u201c\u8865\u7801\u201d\u7684\u5f62\u5f0f\u5b58\u50a8\u5728\u8ba1\u7b97\u673a\u4e2d\u7684\u3002\u5728\u5206\u6790\u8fd9\u6837\u505a\u7684\u539f\u56e0\u4e4b\u524d\uff0c\u9996\u5148\u7ed9\u51fa\u4e09\u8005\u7684\u5b9a\u4e49\u3002

    • \u539f\u7801\uff1a\u6211\u4eec\u5c06\u6570\u5b57\u7684\u4e8c\u8fdb\u5236\u8868\u793a\u7684\u6700\u9ad8\u4f4d\u89c6\u4e3a\u7b26\u53f7\u4f4d\uff0c\u5176\u4e2d \\(0\\) \u8868\u793a\u6b63\u6570\uff0c\\(1\\) \u8868\u793a\u8d1f\u6570\uff0c\u5176\u4f59\u4f4d\u8868\u793a\u6570\u5b57\u7684\u503c\u3002
    • \u53cd\u7801\uff1a\u6b63\u6570\u7684\u53cd\u7801\u4e0e\u5176\u539f\u7801\u76f8\u540c\uff0c\u8d1f\u6570\u7684\u53cd\u7801\u662f\u5bf9\u5176\u539f\u7801\u9664\u7b26\u53f7\u4f4d\u5916\u7684\u6240\u6709\u4f4d\u53d6\u53cd\u3002
    • \u8865\u7801\uff1a\u6b63\u6570\u7684\u8865\u7801\u4e0e\u5176\u539f\u7801\u76f8\u540c\uff0c\u8d1f\u6570\u7684\u8865\u7801\u662f\u5728\u5176\u53cd\u7801\u7684\u57fa\u7840\u4e0a\u52a0 \\(1\\) \u3002

    \u56fe 3-4 \u5c55\u793a\u4e86\u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801\u4e4b\u95f4\u7684\u8f6c\u6362\u65b9\u6cd5\u3002

    \u56fe 3-4 \u00a0 \u539f\u7801\u3001\u53cd\u7801\u4e0e\u8865\u7801\u4e4b\u95f4\u7684\u76f8\u4e92\u8f6c\u6362

    \u539f\u7801\uff08sign-magnitude\uff09\u867d\u7136\u6700\u76f4\u89c2\uff0c\u4f46\u5b58\u5728\u4e00\u4e9b\u5c40\u9650\u6027\u3002\u4e00\u65b9\u9762\uff0c\u8d1f\u6570\u7684\u539f\u7801\u4e0d\u80fd\u76f4\u63a5\u7528\u4e8e\u8fd0\u7b97\u3002\u4f8b\u5982\u5728\u539f\u7801\u4e0b\u8ba1\u7b97 \\(1 + (-2)\\) \uff0c\u5f97\u5230\u7684\u7ed3\u679c\u662f \\(-3\\) \uff0c\u8fd9\u663e\u7136\u662f\u4e0d\u5bf9\u7684\u3002

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 + 1000 \\; 0010 \\newline & = 1000 \\; 0011 \\newline & \\rightarrow -3 \\end{aligned} \\]

    \u4e3a\u4e86\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u8ba1\u7b97\u673a\u5f15\u5165\u4e86\u53cd\u7801\uff081's complement\uff09\u3002\u5982\u679c\u6211\u4eec\u5148\u5c06\u539f\u7801\u8f6c\u6362\u4e3a\u53cd\u7801\uff0c\u5e76\u5728\u53cd\u7801\u4e0b\u8ba1\u7b97 \\(1 + (-2)\\) \uff0c\u6700\u540e\u5c06\u7ed3\u679c\u4ece\u53cd\u7801\u8f6c\u6362\u56de\u539f\u7801\uff0c\u5219\u53ef\u5f97\u5230\u6b63\u786e\u7ed3\u679c \\(-1\\) \u3002

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 \\; \\text{(\u539f\u7801)} + 1000 \\; 0010 \\; \\text{(\u539f\u7801)} \\newline & = 0000 \\; 0001 \\; \\text{(\u53cd\u7801)} + 1111 \\; 1101 \\; \\text{(\u53cd\u7801)} \\newline & = 1111 \\; 1110 \\; \\text{(\u53cd\u7801)} \\newline & = 1000 \\; 0001 \\; \\text{(\u539f\u7801)} \\newline & \\rightarrow -1 \\end{aligned} \\]

    \u53e6\u4e00\u65b9\u9762\uff0c\u6570\u5b57\u96f6\u7684\u539f\u7801\u6709 \\(+0\\) \u548c \\(-0\\) \u4e24\u79cd\u8868\u793a\u65b9\u5f0f\u3002\u8fd9\u610f\u5473\u7740\u6570\u5b57\u96f6\u5bf9\u5e94\u4e24\u4e2a\u4e0d\u540c\u7684\u4e8c\u8fdb\u5236\u7f16\u7801\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5e26\u6765\u6b67\u4e49\u3002\u6bd4\u5982\u5728\u6761\u4ef6\u5224\u65ad\u4e2d\uff0c\u5982\u679c\u6ca1\u6709\u533a\u5206\u6b63\u96f6\u548c\u8d1f\u96f6\uff0c\u5219\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5224\u65ad\u7ed3\u679c\u51fa\u9519\u3002\u800c\u5982\u679c\u6211\u4eec\u60f3\u5904\u7406\u6b63\u96f6\u548c\u8d1f\u96f6\u6b67\u4e49\uff0c\u5219\u9700\u8981\u5f15\u5165\u989d\u5916\u7684\u5224\u65ad\u64cd\u4f5c\uff0c\u8fd9\u53ef\u80fd\u4f1a\u964d\u4f4e\u8ba1\u7b97\u673a\u7684\u8fd0\u7b97\u6548\u7387\u3002

    \\[ \\begin{aligned} +0 & \\rightarrow 0000 \\; 0000 \\newline -0 & \\rightarrow 1000 \\; 0000 \\end{aligned} \\]

    \u4e0e\u539f\u7801\u4e00\u6837\uff0c\u53cd\u7801\u4e5f\u5b58\u5728\u6b63\u8d1f\u96f6\u6b67\u4e49\u95ee\u9898\uff0c\u56e0\u6b64\u8ba1\u7b97\u673a\u8fdb\u4e00\u6b65\u5f15\u5165\u4e86\u8865\u7801\uff082's complement\uff09\u3002\u6211\u4eec\u5148\u6765\u89c2\u5bdf\u4e00\u4e0b\u8d1f\u96f6\u7684\u539f\u7801\u3001\u53cd\u7801\u3001\u8865\u7801\u7684\u8f6c\u6362\u8fc7\u7a0b\uff1a

    \\[ \\begin{aligned} -0 \\rightarrow \\; & 1000 \\; 0000 \\; \\text{(\u539f\u7801)} \\newline = \\; & 1111 \\; 1111 \\; \\text{(\u53cd\u7801)} \\newline = 1 \\; & 0000 \\; 0000 \\; \\text{(\u8865\u7801)} \\newline \\end{aligned} \\]

    \u5728\u8d1f\u96f6\u7684\u53cd\u7801\u57fa\u7840\u4e0a\u52a0 \\(1\\) \u4f1a\u4ea7\u751f\u8fdb\u4f4d\uff0c\u4f46 byte \u7c7b\u578b\u7684\u957f\u5ea6\u53ea\u6709 8 \u4f4d\uff0c\u56e0\u6b64\u6ea2\u51fa\u5230\u7b2c 9 \u4f4d\u7684 \\(1\\) \u4f1a\u88ab\u820d\u5f03\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8d1f\u96f6\u7684\u8865\u7801\u4e3a \\(0000 \\; 0000\\) \uff0c\u4e0e\u6b63\u96f6\u7684\u8865\u7801\u76f8\u540c\u3002\u8fd9\u610f\u5473\u7740\u5728\u8865\u7801\u8868\u793a\u4e2d\u53ea\u5b58\u5728\u4e00\u4e2a\u96f6\uff0c\u6b63\u8d1f\u96f6\u6b67\u4e49\u4ece\u800c\u5f97\u5230\u89e3\u51b3\u3002

    \u8fd8\u5269\u6700\u540e\u4e00\u4e2a\u7591\u60d1\uff1abyte \u7c7b\u578b\u7684\u53d6\u503c\u8303\u56f4\u662f \\([-128, 127]\\) \uff0c\u591a\u51fa\u6765\u7684\u4e00\u4e2a\u8d1f\u6570 \\(-128\\) \u662f\u5982\u4f55\u5f97\u5230\u7684\u5462\uff1f\u6211\u4eec\u6ce8\u610f\u5230\uff0c\u533a\u95f4 \\([-127, +127]\\) \u5185\u7684\u6240\u6709\u6574\u6570\u90fd\u6709\u5bf9\u5e94\u7684\u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801\uff0c\u5e76\u4e14\u539f\u7801\u548c\u8865\u7801\u4e4b\u95f4\u53ef\u4ee5\u4e92\u76f8\u8f6c\u6362\u3002

    \u7136\u800c\uff0c\u8865\u7801 \\(1000 \\; 0000\\) \u662f\u4e00\u4e2a\u4f8b\u5916\uff0c\u5b83\u5e76\u6ca1\u6709\u5bf9\u5e94\u7684\u539f\u7801\u3002\u6839\u636e\u8f6c\u6362\u65b9\u6cd5\uff0c\u6211\u4eec\u5f97\u5230\u8be5\u8865\u7801\u7684\u539f\u7801\u4e3a \\(0000 \\; 0000\\) \u3002\u8fd9\u663e\u7136\u662f\u77db\u76fe\u7684\uff0c\u56e0\u4e3a\u8be5\u539f\u7801\u8868\u793a\u6570\u5b57 \\(0\\) \uff0c\u5b83\u7684\u8865\u7801\u5e94\u8be5\u662f\u81ea\u8eab\u3002\u8ba1\u7b97\u673a\u89c4\u5b9a\u8fd9\u4e2a\u7279\u6b8a\u7684\u8865\u7801 \\(1000 \\; 0000\\) \u4ee3\u8868 \\(-128\\) \u3002\u5b9e\u9645\u4e0a\uff0c\\((-1) + (-127)\\) \u5728\u8865\u7801\u4e0b\u7684\u8ba1\u7b97\u7ed3\u679c\u5c31\u662f \\(-128\\) \u3002

    \\[ \\begin{aligned} & (-127) + (-1) \\newline & \\rightarrow 1111 \\; 1111 \\; \\text{(\u539f\u7801)} + 1000 \\; 0001 \\; \\text{(\u539f\u7801)} \\newline & = 1000 \\; 0000 \\; \\text{(\u53cd\u7801)} + 1111 \\; 1110 \\; \\text{(\u53cd\u7801)} \\newline & = 1000 \\; 0001 \\; \\text{(\u8865\u7801)} + 1111 \\; 1111 \\; \\text{(\u8865\u7801)} \\newline & = 1000 \\; 0000 \\; \\text{(\u8865\u7801)} \\newline & \\rightarrow -128 \\end{aligned} \\]

    \u4f60\u53ef\u80fd\u5df2\u7ecf\u53d1\u73b0\u4e86\uff0c\u4e0a\u8ff0\u6240\u6709\u8ba1\u7b97\u90fd\u662f\u52a0\u6cd5\u8fd0\u7b97\u3002\u8fd9\u6697\u793a\u7740\u4e00\u4e2a\u91cd\u8981\u4e8b\u5b9e\uff1a\u8ba1\u7b97\u673a\u5185\u90e8\u7684\u786c\u4ef6\u7535\u8def\u4e3b\u8981\u662f\u57fa\u4e8e\u52a0\u6cd5\u8fd0\u7b97\u8bbe\u8ba1\u7684\u3002\u8fd9\u662f\u56e0\u4e3a\u52a0\u6cd5\u8fd0\u7b97\u76f8\u5bf9\u4e8e\u5176\u4ed6\u8fd0\u7b97\uff08\u6bd4\u5982\u4e58\u6cd5\u3001\u9664\u6cd5\u548c\u51cf\u6cd5\uff09\u6765\u8bf4\uff0c\u786c\u4ef6\u5b9e\u73b0\u8d77\u6765\u66f4\u7b80\u5355\uff0c\u66f4\u5bb9\u6613\u8fdb\u884c\u5e76\u884c\u5316\u5904\u7406\uff0c\u8fd0\u7b97\u901f\u5ea6\u66f4\u5feb\u3002

    \u8bf7\u6ce8\u610f\uff0c\u8fd9\u5e76\u4e0d\u610f\u5473\u7740\u8ba1\u7b97\u673a\u53ea\u80fd\u505a\u52a0\u6cd5\u3002\u901a\u8fc7\u5c06\u52a0\u6cd5\u4e0e\u4e00\u4e9b\u57fa\u672c\u903b\u8f91\u8fd0\u7b97\u7ed3\u5408\uff0c\u8ba1\u7b97\u673a\u80fd\u591f\u5b9e\u73b0\u5404\u79cd\u5176\u4ed6\u7684\u6570\u5b66\u8fd0\u7b97\u3002\u4f8b\u5982\uff0c\u8ba1\u7b97\u51cf\u6cd5 \\(a - b\\) \u53ef\u4ee5\u8f6c\u6362\u4e3a\u8ba1\u7b97\u52a0\u6cd5 \\(a + (-b)\\) \uff1b\u8ba1\u7b97\u4e58\u6cd5\u548c\u9664\u6cd5\u53ef\u4ee5\u8f6c\u6362\u4e3a\u8ba1\u7b97\u591a\u6b21\u52a0\u6cd5\u6216\u51cf\u6cd5\u3002

    \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u603b\u7ed3\u51fa\u8ba1\u7b97\u673a\u4f7f\u7528\u8865\u7801\u7684\u539f\u56e0\uff1a\u57fa\u4e8e\u8865\u7801\u8868\u793a\uff0c\u8ba1\u7b97\u673a\u53ef\u4ee5\u7528\u540c\u6837\u7684\u7535\u8def\u548c\u64cd\u4f5c\u6765\u5904\u7406\u6b63\u6570\u548c\u8d1f\u6570\u7684\u52a0\u6cd5\uff0c\u4e0d\u9700\u8981\u8bbe\u8ba1\u7279\u6b8a\u7684\u786c\u4ef6\u7535\u8def\u6765\u5904\u7406\u51cf\u6cd5\uff0c\u5e76\u4e14\u65e0\u987b\u7279\u522b\u5904\u7406\u6b63\u8d1f\u96f6\u7684\u6b67\u4e49\u95ee\u9898\u3002\u8fd9\u5927\u5927\u7b80\u5316\u4e86\u786c\u4ef6\u8bbe\u8ba1\uff0c\u63d0\u9ad8\u4e86\u8fd0\u7b97\u6548\u7387\u3002

    \u8865\u7801\u7684\u8bbe\u8ba1\u975e\u5e38\u7cbe\u5999\uff0c\u56e0\u7bc7\u5e45\u5173\u7cfb\u6211\u4eec\u5c31\u5148\u4ecb\u7ecd\u5230\u8fd9\u91cc\uff0c\u5efa\u8bae\u6709\u5174\u8da3\u7684\u8bfb\u8005\u8fdb\u4e00\u6b65\u6df1\u5165\u4e86\u89e3\u3002

    "},{"location":"chapter_data_structure/number_encoding/#332","title":"3.3.2 \u00a0 \u6d6e\u70b9\u6570\u7f16\u7801","text":"

    \u7ec6\u5fc3\u7684\u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0\uff1aint \u548c float \u957f\u5ea6\u76f8\u540c\uff0c\u90fd\u662f 4 \u5b57\u8282 \uff0c\u4f46\u4e3a\u4ec0\u4e48 float \u7684\u53d6\u503c\u8303\u56f4\u8fdc\u5927\u4e8e int \uff1f\u8fd9\u975e\u5e38\u53cd\u76f4\u89c9\uff0c\u56e0\u4e3a\u6309\u7406\u8bf4 float \u9700\u8981\u8868\u793a\u5c0f\u6570\uff0c\u53d6\u503c\u8303\u56f4\u5e94\u8be5\u53d8\u5c0f\u624d\u5bf9\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8fd9\u662f\u56e0\u4e3a\u6d6e\u70b9\u6570 float \u91c7\u7528\u4e86\u4e0d\u540c\u7684\u8868\u793a\u65b9\u5f0f\u3002\u8bb0\u4e00\u4e2a 32 \u6bd4\u7279\u957f\u5ea6\u7684\u4e8c\u8fdb\u5236\u6570\u4e3a\uff1a

    \\[ b_{31} b_{30} b_{29} \\ldots b_2 b_1 b_0 \\]

    \u6839\u636e IEEE 754 \u6807\u51c6\uff0c32-bit \u957f\u5ea6\u7684 float \u7531\u4ee5\u4e0b\u4e09\u4e2a\u90e8\u5206\u6784\u6210\u3002

    • \u7b26\u53f7\u4f4d \\(\\mathrm{S}\\) \uff1a\u5360 1 \u4f4d \uff0c\u5bf9\u5e94 \\(b_{31}\\) \u3002
    • \u6307\u6570\u4f4d \\(\\mathrm{E}\\) \uff1a\u5360 8 \u4f4d \uff0c\u5bf9\u5e94 \\(b_{30} b_{29} \\ldots b_{23}\\) \u3002
    • \u5206\u6570\u4f4d \\(\\mathrm{N}\\) \uff1a\u5360 23 \u4f4d \uff0c\u5bf9\u5e94 \\(b_{22} b_{21} \\ldots b_0\\) \u3002

    \u4e8c\u8fdb\u5236\u6570 float \u5bf9\u5e94\u503c\u7684\u8ba1\u7b97\u65b9\u6cd5\u4e3a\uff1a

    \\[ \\text {val} = (-1)^{b_{31}} \\times 2^{\\left(b_{30} b_{29} \\ldots b_{23}\\right)_2-127} \\times\\left(1 . b_{22} b_{21} \\ldots b_0\\right)_2 \\]

    \u8f6c\u5316\u5230\u5341\u8fdb\u5236\u4e0b\u7684\u8ba1\u7b97\u516c\u5f0f\u4e3a\uff1a

    \\[ \\text {val}=(-1)^{\\mathrm{S}} \\times 2^{\\mathrm{E} -127} \\times (1 + \\mathrm{N}) \\]

    \u5176\u4e2d\u5404\u9879\u7684\u53d6\u503c\u8303\u56f4\u4e3a\uff1a

    \\[ \\begin{aligned} \\mathrm{S} \\in & \\{ 0, 1\\}, \\quad \\mathrm{E} \\in \\{ 1, 2, \\dots, 254 \\} \\newline (1 + \\mathrm{N}) = & (1 + \\sum_{i=1}^{23} b_{23-i} 2^{-i}) \\subset [1, 2 - 2^{-23}] \\end{aligned} \\]

    \u56fe 3-5 \u00a0 IEEE 754 \u6807\u51c6\u4e0b\u7684 float \u7684\u8ba1\u7b97\u793a\u4f8b

    \u89c2\u5bdf\u56fe 3-5 \uff0c\u7ed9\u5b9a\u4e00\u4e2a\u793a\u4f8b\u6570\u636e \\(\\mathrm{S} = 0\\) \uff0c \\(\\mathrm{E} = 124\\) \uff0c\\(\\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\\) \uff0c\u5219\u6709\uff1a

    \\[ \\text { val } = (-1)^0 \\times 2^{124 - 127} \\times (1 + 0.375) = 0.171875 \\]

    \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u56de\u7b54\u6700\u521d\u7684\u95ee\u9898\uff1afloat \u7684\u8868\u793a\u65b9\u5f0f\u5305\u542b\u6307\u6570\u4f4d\uff0c\u5bfc\u81f4\u5176\u53d6\u503c\u8303\u56f4\u8fdc\u5927\u4e8e int \u3002\u6839\u636e\u4ee5\u4e0a\u8ba1\u7b97\uff0cfloat \u53ef\u8868\u793a\u7684\u6700\u5927\u6b63\u6570\u4e3a \\(2^{254 - 127} \\times (2 - 2^{-23}) \\approx 3.4 \\times 10^{38}\\) \uff0c\u5207\u6362\u7b26\u53f7\u4f4d\u4fbf\u53ef\u5f97\u5230\u6700\u5c0f\u8d1f\u6570\u3002

    \u5c3d\u7ba1\u6d6e\u70b9\u6570 float \u6269\u5c55\u4e86\u53d6\u503c\u8303\u56f4\uff0c\u4f46\u5176\u526f\u4f5c\u7528\u662f\u727a\u7272\u4e86\u7cbe\u5ea6\u3002\u6574\u6570\u7c7b\u578b int \u5c06\u5168\u90e8 32 \u6bd4\u7279\u7528\u4e8e\u8868\u793a\u6570\u5b57\uff0c\u6570\u5b57\u662f\u5747\u5300\u5206\u5e03\u7684\uff1b\u800c\u7531\u4e8e\u6307\u6570\u4f4d\u7684\u5b58\u5728\uff0c\u6d6e\u70b9\u6570 float \u7684\u6570\u503c\u8d8a\u5927\uff0c\u76f8\u90bb\u4e24\u4e2a\u6570\u5b57\u4e4b\u95f4\u7684\u5dee\u503c\u5c31\u4f1a\u8d8b\u5411\u8d8a\u5927\u3002

    \u5982\u8868 3-2 \u6240\u793a\uff0c\u6307\u6570\u4f4d \\(\\mathrm{E} = 0\\) \u548c \\(\\mathrm{E} = 255\\) \u5177\u6709\u7279\u6b8a\u542b\u4e49\uff0c\u7528\u4e8e\u8868\u793a\u96f6\u3001\u65e0\u7a77\u5927\u3001\\(\\mathrm{NaN}\\) \u7b49\u3002

    \u8868 3-2 \u00a0 \u6307\u6570\u4f4d\u542b\u4e49

    \u6307\u6570\u4f4d E \u5206\u6570\u4f4d \\(\\mathrm{N} = 0\\) \u5206\u6570\u4f4d \\(\\mathrm{N} \\ne 0\\) \u8ba1\u7b97\u516c\u5f0f \\(0\\) \\(\\pm 0\\) \u6b21\u6b63\u89c4\u6570 \\((-1)^{\\mathrm{S}} \\times 2^{-126} \\times (0.\\mathrm{N})\\) \\(1, 2, \\dots, 254\\) \u6b63\u89c4\u6570 \u6b63\u89c4\u6570 \\((-1)^{\\mathrm{S}} \\times 2^{(\\mathrm{E} -127)} \\times (1.\\mathrm{N})\\) \\(255\\) \\(\\pm \\infty\\) \\(\\mathrm{NaN}\\)

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6b21\u6b63\u89c4\u6570\u663e\u8457\u63d0\u5347\u4e86\u6d6e\u70b9\u6570\u7684\u7cbe\u5ea6\u3002\u6700\u5c0f\u6b63\u6b63\u89c4\u6570\u4e3a \\(2^{-126}\\) \uff0c\u6700\u5c0f\u6b63\u6b21\u6b63\u89c4\u6570\u4e3a \\(2^{-126} \\times 2^{-23}\\) \u3002

    \u53cc\u7cbe\u5ea6 double \u4e5f\u91c7\u7528\u7c7b\u4f3c\u4e8e float \u7684\u8868\u793a\u65b9\u6cd5\uff0c\u5728\u6b64\u4e0d\u505a\u8d58\u8ff0\u3002

    "},{"location":"chapter_data_structure/summary/","title":"3.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_data_structure/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u4ece\u903b\u8f91\u7ed3\u6784\u548c\u7269\u7406\u7ed3\u6784\u4e24\u4e2a\u89d2\u5ea6\u8fdb\u884c\u5206\u7c7b\u3002\u903b\u8f91\u7ed3\u6784\u63cf\u8ff0\u4e86\u6570\u636e\u5143\u7d20\u4e4b\u95f4\u7684\u903b\u8f91\u5173\u7cfb\uff0c\u800c\u7269\u7406\u7ed3\u6784\u63cf\u8ff0\u4e86\u6570\u636e\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u7684\u5b58\u50a8\u65b9\u5f0f\u3002
    • \u5e38\u89c1\u7684\u903b\u8f91\u7ed3\u6784\u5305\u62ec\u7ebf\u6027\u3001\u6811\u72b6\u548c\u7f51\u72b6\u7b49\u3002\u901a\u5e38\u6211\u4eec\u6839\u636e\u903b\u8f91\u7ed3\u6784\u5c06\u6570\u636e\u7ed3\u6784\u5206\u4e3a\u7ebf\u6027\uff08\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\uff09\u548c\u975e\u7ebf\u6027\uff08\u6811\u3001\u56fe\u3001\u5806\uff09\u4e24\u79cd\u3002\u54c8\u5e0c\u8868\u7684\u5b9e\u73b0\u53ef\u80fd\u540c\u65f6\u5305\u542b\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u548c\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002
    • \u5f53\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6570\u636e\u88ab\u5b58\u50a8\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u3002\u6bcf\u4e2a\u5185\u5b58\u7a7a\u95f4\u90fd\u62e5\u6709\u5bf9\u5e94\u7684\u5185\u5b58\u5730\u5740\uff0c\u7a0b\u5e8f\u901a\u8fc7\u8fd9\u4e9b\u5185\u5b58\u5730\u5740\u8bbf\u95ee\u6570\u636e\u3002
    • \u7269\u7406\u7ed3\u6784\u4e3b\u8981\u5206\u4e3a\u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\uff08\u6570\u7ec4\uff09\u548c\u5206\u6563\u7a7a\u95f4\u5b58\u50a8\uff08\u94fe\u8868\uff09\u3002\u6240\u6709\u6570\u636e\u7ed3\u6784\u90fd\u662f\u7531\u6570\u7ec4\u3001\u94fe\u8868\u6216\u4e24\u8005\u7684\u7ec4\u5408\u5b9e\u73b0\u7684\u3002
    • \u8ba1\u7b97\u673a\u4e2d\u7684\u57fa\u672c\u6570\u636e\u7c7b\u578b\u5305\u62ec\u6574\u6570 byte\u3001short\u3001int\u3001long \uff0c\u6d6e\u70b9\u6570 float\u3001double \uff0c\u5b57\u7b26 char \u548c\u5e03\u5c14 bool \u3002\u5b83\u4eec\u7684\u53d6\u503c\u8303\u56f4\u53d6\u51b3\u4e8e\u5360\u7528\u7a7a\u95f4\u5927\u5c0f\u548c\u8868\u793a\u65b9\u5f0f\u3002
    • \u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801\u662f\u5728\u8ba1\u7b97\u673a\u4e2d\u7f16\u7801\u6570\u5b57\u7684\u4e09\u79cd\u65b9\u6cd5\uff0c\u5b83\u4eec\u4e4b\u95f4\u53ef\u4ee5\u76f8\u4e92\u8f6c\u6362\u3002\u6574\u6570\u7684\u539f\u7801\u7684\u6700\u9ad8\u4f4d\u662f\u7b26\u53f7\u4f4d\uff0c\u5176\u4f59\u4f4d\u662f\u6570\u5b57\u7684\u503c\u3002
    • \u6574\u6570\u5728\u8ba1\u7b97\u673a\u4e2d\u662f\u4ee5\u8865\u7801\u7684\u5f62\u5f0f\u5b58\u50a8\u7684\u3002\u5728\u8865\u7801\u8868\u793a\u4e0b\uff0c\u8ba1\u7b97\u673a\u53ef\u4ee5\u5bf9\u6b63\u6570\u548c\u8d1f\u6570\u7684\u52a0\u6cd5\u4e00\u89c6\u540c\u4ec1\uff0c\u4e0d\u9700\u8981\u4e3a\u51cf\u6cd5\u64cd\u4f5c\u5355\u72ec\u8bbe\u8ba1\u7279\u6b8a\u7684\u786c\u4ef6\u7535\u8def\uff0c\u5e76\u4e14\u4e0d\u5b58\u5728\u6b63\u8d1f\u96f6\u6b67\u4e49\u7684\u95ee\u9898\u3002
    • \u6d6e\u70b9\u6570\u7684\u7f16\u7801\u7531 1 \u4f4d\u7b26\u53f7\u4f4d\u30018 \u4f4d\u6307\u6570\u4f4d\u548c 23 \u4f4d\u5206\u6570\u4f4d\u6784\u6210\u3002\u7531\u4e8e\u5b58\u5728\u6307\u6570\u4f4d\uff0c\u56e0\u6b64\u6d6e\u70b9\u6570\u7684\u53d6\u503c\u8303\u56f4\u8fdc\u5927\u4e8e\u6574\u6570\uff0c\u4ee3\u4ef7\u662f\u727a\u7272\u4e86\u7cbe\u5ea6\u3002
    • ASCII \u7801\u662f\u6700\u65e9\u51fa\u73b0\u7684\u82f1\u6587\u5b57\u7b26\u96c6\uff0c\u957f\u5ea6\u4e3a 1 \u5b57\u8282\uff0c\u5171\u6536\u5f55 127 \u4e2a\u5b57\u7b26\u3002GBK \u5b57\u7b26\u96c6\u662f\u5e38\u7528\u7684\u4e2d\u6587\u5b57\u7b26\u96c6\uff0c\u5171\u6536\u5f55\u4e24\u4e07\u591a\u4e2a\u6c49\u5b57\u3002Unicode \u81f4\u529b\u4e8e\u63d0\u4f9b\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\u96c6\u6807\u51c6\uff0c\u6536\u5f55\u4e16\u754c\u4e0a\u5404\u79cd\u8bed\u8a00\u7684\u5b57\u7b26\uff0c\u4ece\u800c\u89e3\u51b3\u7531\u4e8e\u5b57\u7b26\u7f16\u7801\u65b9\u6cd5\u4e0d\u4e00\u81f4\u800c\u5bfc\u81f4\u7684\u4e71\u7801\u95ee\u9898\u3002
    • UTF-8 \u662f\u6700\u53d7\u6b22\u8fce\u7684 Unicode \u7f16\u7801\u65b9\u6cd5\uff0c\u901a\u7528\u6027\u975e\u5e38\u597d\u3002\u5b83\u662f\u4e00\u79cd\u53d8\u957f\u7684\u7f16\u7801\u65b9\u6cd5\uff0c\u5177\u6709\u5f88\u597d\u7684\u6269\u5c55\u6027\uff0c\u6709\u6548\u63d0\u5347\u4e86\u5b58\u50a8\u7a7a\u95f4\u7684\u4f7f\u7528\u6548\u7387\u3002UTF-16 \u548c UTF-32 \u662f\u7b49\u957f\u7684\u7f16\u7801\u65b9\u6cd5\u3002\u5728\u7f16\u7801\u4e2d\u6587\u65f6\uff0cUTF-16 \u5360\u7528\u7684\u7a7a\u95f4\u6bd4 UTF-8 \u66f4\u5c0f\u3002Java \u548c C# \u7b49\u7f16\u7a0b\u8bed\u8a00\u9ed8\u8ba4\u4f7f\u7528 UTF-16 \u7f16\u7801\u3002
    "},{"location":"chapter_data_structure/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u4e3a\u4ec0\u4e48\u54c8\u5e0c\u8868\u540c\u65f6\u5305\u542b\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u548c\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff1f

    \u54c8\u5e0c\u8868\u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u800c\u4e3a\u4e86\u89e3\u51b3\u54c8\u5e0c\u51b2\u7a81\uff0c\u6211\u4eec\u53ef\u80fd\u4f1a\u4f7f\u7528\u201c\u94fe\u5f0f\u5730\u5740\u201d\uff08\u540e\u7eed\u201c\u54c8\u5e0c\u51b2\u7a81\u201d\u7ae0\u8282\u4f1a\u8bb2\uff09\uff1a\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u6876\u6307\u5411\u4e00\u4e2a\u94fe\u8868\uff0c\u5f53\u94fe\u8868\u957f\u5ea6\u8d85\u8fc7\u4e00\u5b9a\u9608\u503c\u65f6\uff0c\u53c8\u53ef\u80fd\u88ab\u8f6c\u5316\u4e3a\u6811\uff08\u901a\u5e38\u4e3a\u7ea2\u9ed1\u6811\uff09\u3002

    \u4ece\u5b58\u50a8\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u54c8\u5e0c\u8868\u7684\u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e00\u4e2a\u6876\u69fd\u4f4d\u53ef\u80fd\u5305\u542b\u4e00\u4e2a\u503c\uff0c\u4e5f\u53ef\u80fd\u5305\u542b\u4e00\u4e2a\u94fe\u8868\u6216\u4e00\u68f5\u6811\u3002\u56e0\u6b64\uff0c\u54c8\u5e0c\u8868\u53ef\u80fd\u540c\u65f6\u5305\u542b\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff08\u6570\u7ec4\u3001\u94fe\u8868\uff09\u548c\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff08\u6811\uff09\u3002

    Q\uff1achar \u7c7b\u578b\u7684\u957f\u5ea6\u662f 1 \u5b57\u8282\u5417\uff1f

    char \u7c7b\u578b\u7684\u957f\u5ea6\u7531\u7f16\u7a0b\u8bed\u8a00\u91c7\u7528\u7684\u7f16\u7801\u65b9\u6cd5\u51b3\u5b9a\u3002\u4f8b\u5982\uff0cJava\u3001JavaScript\u3001TypeScript\u3001C# \u90fd\u91c7\u7528 UTF-16 \u7f16\u7801\uff08\u4fdd\u5b58 Unicode \u7801\u70b9\uff09\uff0c\u56e0\u6b64 char \u7c7b\u578b\u7684\u957f\u5ea6\u4e3a 2 \u5b57\u8282\u3002

    Q\uff1a\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u4e5f\u79f0\u201c\u9759\u6001\u6570\u636e\u7ed3\u6784\u201d \u662f\u5426\u6709\u6b67\u4e49\uff1f\u6808\u4e5f\u53ef\u4ee5\u8fdb\u884c\u51fa\u6808\u548c\u5165\u6808\u7b49\u64cd\u4f5c\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u90fd\u662f\u201c\u52a8\u6001\u201d\u7684\u3002

    \u6808\u786e\u5b9e\u53ef\u4ee5\u5b9e\u73b0\u52a8\u6001\u7684\u6570\u636e\u64cd\u4f5c\uff0c\u4f46\u6570\u636e\u7ed3\u6784\u4ecd\u7136\u662f\u201c\u9759\u6001\u201d\uff08\u957f\u5ea6\u4e0d\u53ef\u53d8\uff09\u7684\u3002\u5c3d\u7ba1\u57fa\u4e8e\u6570\u7ec4\u7684\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u52a8\u6001\u5730\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u7684\u5bb9\u91cf\u662f\u56fa\u5b9a\u7684\u3002\u5982\u679c\u6570\u636e\u91cf\u8d85\u51fa\u4e86\u9884\u5206\u914d\u7684\u5927\u5c0f\uff0c\u5c31\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u66f4\u5927\u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u65e7\u6570\u7ec4\u7684\u5185\u5bb9\u590d\u5236\u5230\u65b0\u6570\u7ec4\u4e2d\u3002

    Q\uff1a\u5728\u6784\u5efa\u6808\uff08\u961f\u5217\uff09\u7684\u65f6\u5019\uff0c\u672a\u6307\u5b9a\u5b83\u7684\u5927\u5c0f\uff0c\u4e3a\u4ec0\u4e48\u5b83\u4eec\u662f\u201c\u9759\u6001\u6570\u636e\u7ed3\u6784\u201d\u5462\uff1f

    \u5728\u9ad8\u7ea7\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u6211\u4eec\u65e0\u987b\u4eba\u5de5\u6307\u5b9a\u6808\uff08\u961f\u5217\uff09\u7684\u521d\u59cb\u5bb9\u91cf\uff0c\u8fd9\u4e2a\u5de5\u4f5c\u7531\u7c7b\u5185\u90e8\u81ea\u52a8\u5b8c\u6210\u3002\u4f8b\u5982\uff0cJava \u7684 ArrayList \u7684\u521d\u59cb\u5bb9\u91cf\u901a\u5e38\u4e3a 10\u3002\u53e6\u5916\uff0c\u6269\u5bb9\u64cd\u4f5c\u4e5f\u662f\u81ea\u52a8\u5b9e\u73b0\u7684\u3002\u8be6\u89c1\u540e\u7eed\u7684\u201c\u5217\u8868\u201d\u7ae0\u8282\u3002

    Q\uff1a\u539f\u7801\u8f6c\u8865\u7801\u7684\u65b9\u6cd5\u662f\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\uff0c\u90a3\u4e48\u8865\u7801\u8f6c\u539f\u7801\u5e94\u8be5\u662f\u9006\u8fd0\u7b97\u201c\u5148\u51cf 1 \u540e\u53d6\u53cd\u201d\uff0c\u800c\u8865\u7801\u8f6c\u539f\u7801\u4e5f\u4e00\u6837\u53ef\u4ee5\u901a\u8fc7\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5f97\u5230\uff0c\u8fd9\u662f\u4e3a\u4ec0\u4e48\u5462\uff1f

    A\uff1a\u8fd9\u662f\u56e0\u4e3a\u539f\u7801\u548c\u8865\u7801\u7684\u76f8\u4e92\u8f6c\u6362\u5b9e\u9645\u4e0a\u662f\u8ba1\u7b97\u201c\u8865\u6570\u201d\u7684\u8fc7\u7a0b\u3002\u6211\u4eec\u5148\u7ed9\u51fa\u8865\u6570\u7684\u5b9a\u4e49\uff1a\u5047\u8bbe \\(a + b = c\\) \uff0c\u90a3\u4e48\u6211\u4eec\u79f0 \\(a\\) \u662f \\(b\\) \u5230 \\(c\\) \u7684\u8865\u6570\uff0c\u53cd\u4e4b\u4e5f\u79f0 \\(b\\) \u662f \\(a\\) \u5230 \\(c\\) \u7684\u8865\u6570\u3002

    \u7ed9\u5b9a\u4e00\u4e2a \\(n = 4\\) \u4f4d\u957f\u5ea6\u7684\u4e8c\u8fdb\u5236\u6570 \\(0010\\) \uff0c\u5982\u679c\u5c06\u8fd9\u4e2a\u6570\u5b57\u770b\u4f5c\u539f\u7801\uff08\u4e0d\u8003\u8651\u7b26\u53f7\u4f4d\uff09\uff0c\u90a3\u4e48\u5b83\u7684\u8865\u7801\u9700\u901a\u8fc7\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5f97\u5230\uff1a

    \\[ 0010 \\rightarrow 1101 \\rightarrow 1110 \\]

    \u6211\u4eec\u4f1a\u53d1\u73b0\uff0c\u539f\u7801\u548c\u8865\u7801\u7684\u548c\u662f \\(0010 + 1110 = 10000\\) \uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8865\u7801 \\(1110\\) \u662f\u539f\u7801 \\(0010\\) \u5230 \\(10000\\) \u7684\u201c\u8865\u6570\u201d\u3002\u8fd9\u610f\u5473\u7740\u4e0a\u8ff0\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5b9e\u9645\u4e0a\u662f\u8ba1\u7b97\u5230 \\(10000\\) \u7684\u8865\u6570\u7684\u8fc7\u7a0b\u3002

    \u90a3\u4e48\uff0c\u8865\u7801 \\(1110\\) \u5230 \\(10000\\) \u7684\u201c\u8865\u6570\u201d\u662f\u591a\u5c11\u5462\uff1f\u6211\u4eec\u4f9d\u7136\u53ef\u4ee5\u7528\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5f97\u5230\u5b83\uff1a

    \\[ 1110 \\rightarrow 0001 \\rightarrow 0010 \\]

    \u6362\u53e5\u8bdd\u8bf4\uff0c\u539f\u7801\u548c\u8865\u7801\u4e92\u4e3a\u5bf9\u65b9\u5230 \\(10000\\) \u7684\u201c\u8865\u6570\u201d\uff0c\u56e0\u6b64\u201c\u539f\u7801\u8f6c\u8865\u7801\u201d\u548c\u201c\u8865\u7801\u8f6c\u539f\u7801\u201d\u53ef\u4ee5\u7528\u76f8\u540c\u7684\u64cd\u4f5c\uff08\u5148\u53d6\u53cd\u540e\u52a0 1 \uff09\u5b9e\u73b0\u3002

    \u5f53\u7136\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u7528\u9006\u8fd0\u7b97\u6765\u6c42\u8865\u7801 \\(1110\\) \u7684\u539f\u7801\uff0c\u5373\u201c\u5148\u51cf 1 \u540e\u53d6\u53cd\u201d\uff1a

    \\[ 1110 \\rightarrow 1101 \\rightarrow 0010 \\]

    \u603b\u7ed3\u6765\u770b\uff0c\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u548c\u201c\u5148\u51cf 1 \u540e\u53d6\u53cd\u201d\u8fd9\u4e24\u79cd\u8fd0\u7b97\u90fd\u662f\u5728\u8ba1\u7b97\u5230 \\(10000\\) \u7684\u8865\u6570\uff0c\u5b83\u4eec\u662f\u7b49\u4ef7\u7684\u3002

    \u672c\u8d28\u4e0a\u770b\uff0c\u201c\u53d6\u53cd\u201d\u64cd\u4f5c\u5b9e\u9645\u4e0a\u662f\u6c42\u5230 \\(1111\\) \u7684\u8865\u6570\uff08\u56e0\u4e3a\u6052\u6709 \u539f\u7801 + \u53cd\u7801 = 1111\uff09\uff1b\u800c\u5728\u53cd\u7801\u57fa\u7840\u4e0a\u518d\u52a0 1 \u5f97\u5230\u7684\u8865\u7801\uff0c\u5c31\u662f\u5230 \\(10000\\) \u7684\u8865\u6570\u3002

    \u4e0a\u8ff0 \\(n = 4\\) \u4e3a\u4f8b\uff0c\u5176\u53ef\u63a8\u5e7f\u81f3\u4efb\u610f\u4f4d\u6570\u7684\u4e8c\u8fdb\u5236\u6570\u3002

    "},{"location":"chapter_divide_and_conquer/","title":"\u7b2c 12 \u7ae0 \u00a0 \u5206\u6cbb","text":"

    Abstract

    \u96be\u9898\u88ab\u9010\u5c42\u62c6\u89e3\uff0c\u6bcf\u4e00\u6b21\u7684\u62c6\u89e3\u90fd\u4f7f\u5b83\u53d8\u5f97\u66f4\u4e3a\u7b80\u5355\u3002

    \u5206\u800c\u6cbb\u4e4b\u63ed\u793a\u4e86\u4e00\u4e2a\u91cd\u8981\u7684\u4e8b\u5b9e\uff1a\u4ece\u7b80\u5355\u505a\u8d77\uff0c\u4e00\u5207\u90fd\u4e0d\u518d\u590d\u6742\u3002

    "},{"location":"chapter_divide_and_conquer/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 12.1 \u00a0 \u5206\u6cbb\u7b97\u6cd5
    • 12.2 \u00a0 \u5206\u6cbb\u641c\u7d22\u7b56\u7565
    • 12.3 \u00a0 \u6784\u5efa\u6811\u95ee\u9898
    • 12.4 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898
    • 12.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_divide_and_conquer/binary_search_recur/","title":"12.2 \u00a0 \u5206\u6cbb\u641c\u7d22\u7b56\u7565","text":"

    \u6211\u4eec\u5df2\u7ecf\u5b66\u8fc7\uff0c\u641c\u7d22\u7b97\u6cd5\u5206\u4e3a\u4e24\u5927\u7c7b\u3002

    • \u66b4\u529b\u641c\u7d22\uff1a\u5b83\u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u5b9e\u73b0\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002
    • \u81ea\u9002\u5e94\u641c\u7d22\uff1a\u5b83\u5229\u7528\u7279\u6709\u7684\u6570\u636e\u7ec4\u7ec7\u5f62\u5f0f\u6216\u5148\u9a8c\u4fe1\u606f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe\u5230 \\(O(\\log n)\\) \u751a\u81f3 \\(O(1)\\) \u3002

    \u5b9e\u9645\u4e0a\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u7684\u641c\u7d22\u7b97\u6cd5\u901a\u5e38\u662f\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u5b9e\u73b0\u7684\uff0c\u4f8b\u5982\u4e8c\u5206\u67e5\u627e\u548c\u6811\u3002

    • \u4e8c\u5206\u67e5\u627e\u7684\u6bcf\u4e00\u6b65\u90fd\u5c06\u95ee\u9898\uff08\u5728\u6570\u7ec4\u4e2d\u641c\u7d22\u76ee\u6807\u5143\u7d20\uff09\u5206\u89e3\u4e3a\u4e00\u4e2a\u5c0f\u95ee\u9898\uff08\u5728\u6570\u7ec4\u7684\u4e00\u534a\u4e2d\u641c\u7d22\u76ee\u6807\u5143\u7d20\uff09\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u4e00\u76f4\u6301\u7eed\u5230\u6570\u7ec4\u4e3a\u7a7a\u6216\u627e\u5230\u76ee\u6807\u5143\u7d20\u4e3a\u6b62\u3002
    • \u6811\u662f\u5206\u6cbb\u601d\u60f3\u7684\u4ee3\u8868\uff0c\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u3001AVL \u6811\u3001\u5806\u7b49\u6570\u636e\u7ed3\u6784\u4e2d\uff0c\u5404\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7686\u4e3a \\(O(\\log n)\\) \u3002

    \u4e8c\u5206\u67e5\u627e\u7684\u5206\u6cbb\u7b56\u7565\u5982\u4e0b\u6240\u793a\u3002

    • \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u4e8c\u5206\u67e5\u627e\u9012\u5f52\u5730\u5c06\u539f\u95ee\u9898\uff08\u5728\u6570\u7ec4\u4e2d\u8fdb\u884c\u67e5\u627e\uff09\u5206\u89e3\u4e3a\u5b50\u95ee\u9898\uff08\u5728\u6570\u7ec4\u7684\u4e00\u534a\u4e2d\u8fdb\u884c\u67e5\u627e\uff09\uff0c\u8fd9\u662f\u901a\u8fc7\u6bd4\u8f83\u4e2d\u95f4\u5143\u7d20\u548c\u76ee\u6807\u5143\u7d20\u6765\u5b9e\u73b0\u7684\u3002
    • \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u5728\u4e8c\u5206\u67e5\u627e\u4e2d\uff0c\u6bcf\u8f6e\u53ea\u5904\u7406\u4e00\u4e2a\u5b50\u95ee\u9898\uff0c\u5b83\u4e0d\u53d7\u5176\u4ed6\u5b50\u95ee\u9898\u7684\u5f71\u54cd\u3002
    • \u5b50\u95ee\u9898\u7684\u89e3\u65e0\u987b\u5408\u5e76\uff1a\u4e8c\u5206\u67e5\u627e\u65e8\u5728\u67e5\u627e\u4e00\u4e2a\u7279\u5b9a\u5143\u7d20\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u8fdb\u884c\u5408\u5e76\u3002\u5f53\u5b50\u95ee\u9898\u5f97\u5230\u89e3\u51b3\u65f6\uff0c\u539f\u95ee\u9898\u4e5f\u4f1a\u540c\u65f6\u5f97\u5230\u89e3\u51b3\u3002

    \u5206\u6cbb\u80fd\u591f\u63d0\u5347\u641c\u7d22\u6548\u7387\uff0c\u672c\u8d28\u4e0a\u662f\u56e0\u4e3a\u66b4\u529b\u641c\u7d22\u6bcf\u8f6e\u53ea\u80fd\u6392\u9664\u4e00\u4e2a\u9009\u9879\uff0c\u800c\u5206\u6cbb\u641c\u7d22\u6bcf\u8f6e\u53ef\u4ee5\u6392\u9664\u4e00\u534a\u9009\u9879\u3002

    "},{"location":"chapter_divide_and_conquer/binary_search_recur/#1","title":"1. \u00a0 \u57fa\u4e8e\u5206\u6cbb\u5b9e\u73b0\u4e8c\u5206\u67e5\u627e","text":"

    \u5728\u4e4b\u524d\u7684\u7ae0\u8282\u4e2d\uff0c\u4e8c\u5206\u67e5\u627e\u662f\u57fa\u4e8e\u9012\u63a8\uff08\u8fed\u4ee3\uff09\u5b9e\u73b0\u7684\u3002\u73b0\u5728\u6211\u4eec\u57fa\u4e8e\u5206\u6cbb\uff08\u9012\u5f52\uff09\u6765\u5b9e\u73b0\u5b83\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6709\u5e8f\u6570\u7ec4 nums \uff0c\u5176\u4e2d\u6240\u6709\u5143\u7d20\u90fd\u662f\u552f\u4e00\u7684\uff0c\u8bf7\u67e5\u627e\u5143\u7d20 target \u3002

    \u4ece\u5206\u6cbb\u89d2\u5ea6\uff0c\u6211\u4eec\u5c06\u641c\u7d22\u533a\u95f4 \\([i, j]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u8bb0\u4e3a \\(f(i, j)\\) \u3002

    \u4ee5\u539f\u95ee\u9898 \\(f(0, n-1)\\) \u4e3a\u8d77\u59cb\u70b9\uff0c\u901a\u8fc7\u4ee5\u4e0b\u6b65\u9aa4\u8fdb\u884c\u4e8c\u5206\u67e5\u627e\u3002

    1. \u8ba1\u7b97\u641c\u7d22\u533a\u95f4 \\([i, j]\\) \u7684\u4e2d\u70b9 \\(m\\) \uff0c\u6839\u636e\u5b83\u6392\u9664\u4e00\u534a\u641c\u7d22\u533a\u95f4\u3002
    2. \u9012\u5f52\u6c42\u89e3\u89c4\u6a21\u51cf\u5c0f\u4e00\u534a\u7684\u5b50\u95ee\u9898\uff0c\u53ef\u80fd\u4e3a \\(f(i, m-1)\\) \u6216 \\(f(m+1, j)\\) \u3002
    3. \u5faa\u73af\u7b2c 1. \u6b65\u548c\u7b2c 2. \u6b65\uff0c\u76f4\u81f3\u627e\u5230 target \u6216\u533a\u95f4\u4e3a\u7a7a\u65f6\u8fd4\u56de\u3002

    \u56fe 12-4 \u5c55\u793a\u4e86\u5728\u6570\u7ec4\u4e2d\u4e8c\u5206\u67e5\u627e\u5143\u7d20 \\(6\\) \u7684\u5206\u6cbb\u8fc7\u7a0b\u3002

    \u56fe 12-4 \u00a0 \u4e8c\u5206\u67e5\u627e\u7684\u5206\u6cbb\u8fc7\u7a0b

    \u5728\u5b9e\u73b0\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u9012\u5f52\u51fd\u6570 dfs() \u6765\u6c42\u89e3\u95ee\u9898 \\(f(i, j)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_recur.py
    def dfs(nums: list[int], target: int, i: int, j: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j)\"\"\"\n    # \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j:\n        return -1\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) // 2\n    if nums[m] < target:\n        # \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j)\n    elif nums[m] > target:\n        # \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1)\n    else:\n        # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n\ndef binary_search(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\"\"\"\n    n = len(nums)\n    # \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1)\n
    binary_search_recur.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(vector<int> &nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(vector<int> &nums, int target) {\n    int n = nums.size();\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.java
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(int[] nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(int[] nums, int target) {\n    int n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.cs
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint DFS(int[] nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return DFS(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return DFS(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint BinarySearch(int[] nums, int target) {\n    int n = nums.Length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return DFS(nums, target, 0, n - 1);\n}\n
    binary_search_recur.go
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunc dfs(nums []int, target, i, j int) int {\n    // \u5982\u679c\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u6ca1\u6709\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1\n    }\n    //    \u8ba1\u7b97\u7d22\u5f15\u4e2d\u70b9\n    m := i + ((j - i) >> 1)\n    //\u5224\u65ad\u4e2d\u70b9\u4e0e\u76ee\u6807\u5143\u7d20\u5927\u5c0f\n    if nums[m] < target {\n        // \u5c0f\u4e8e\u5219\u9012\u5f52\u53f3\u534a\u6570\u7ec4\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m+1, j)\n    } else if nums[m] > target {\n        // \u5c0f\u4e8e\u5219\u9012\u5f52\u5de6\u534a\u6570\u7ec4\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m-1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunc binarySearch(nums []int, target int) int {\n    n := len(nums)\n    return dfs(nums, target, 0, n-1)\n}\n
    binary_search_recur.swift
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunc dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    let m = (i + j) / 2\n    if nums[m] < target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums: nums, target: target, i: m + 1, j: j)\n    } else if nums[m] > target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums: nums, target: target, i: i, j: m - 1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunc binarySearch(nums: [Int], target: Int) -> Int {\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    dfs(nums: nums, target: target, i: nums.startIndex, j: nums.endIndex - 1)\n}\n
    binary_search_recur.js
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunction dfs(nums, target, i, j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    const m = i + ((j - i) >> 1);\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunction binarySearch(nums, target) {\n    const n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.ts
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunction dfs(nums: number[], target: number, i: number, j: number): number {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    const m = i + ((j - i) >> 1);\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunction binarySearch(nums: number[], target: number): number {\n    const n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.dart
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(List<int> nums, int target, int i, int j) {\n  // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n  if (i > j) {\n    return -1;\n  }\n  // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n  int m = (i + j) ~/ 2;\n  if (nums[m] < target) {\n    // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n    return dfs(nums, target, m + 1, j);\n  } else if (nums[m] > target) {\n    // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n    return dfs(nums, target, i, m - 1);\n  } else {\n    // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return m;\n  }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(List<int> nums, int target) {\n  int n = nums.length;\n  // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n  return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.rs
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfn dfs(nums: &[i32], target: i32, i: i32, j: i32) -> i32 {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1;\n    }\n    let m: i32 = (i + j) / 2;\n    if nums[m as usize] < target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if nums[m as usize] > target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfn binary_search(nums: &[i32], target: i32) -> i32 {\n    let n = nums.len() as i32;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    dfs(nums, target, 0, n - 1)\n}\n
    binary_search_recur.c
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(int nums[], int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(int nums[], int target, int numsSize) {\n    int n = numsSize;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.kt
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfun dfs(\n    nums: IntArray,\n    target: Int,\n    i: Int,\n    j: Int\n): Int {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    val m = (i + j) / 2\n    return if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        dfs(nums, target, m + 1, j)\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        dfs(nums, target, i, m - 1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfun binarySearch(nums: IntArray, target: Int): Int {\n    val n = nums.size\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1)\n}\n
    binary_search_recur.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{binary_search}\n
    binary_search_recur.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{binarySearch}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/","title":"12.3 \u00a0 \u6784\u5efa\u4e8c\u53c9\u6811\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a\u4e00\u68f5\u4e8c\u53c9\u6811\u7684\u524d\u5e8f\u904d\u5386 preorder \u548c\u4e2d\u5e8f\u904d\u5386 inorder \uff0c\u8bf7\u4ece\u4e2d\u6784\u5efa\u4e8c\u53c9\u6811\uff0c\u8fd4\u56de\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\u3002\u5047\u8bbe\u4e8c\u53c9\u6811\u4e2d\u6ca1\u6709\u503c\u91cd\u590d\u7684\u8282\u70b9\uff08\u5982\u56fe 12-5 \u6240\u793a\uff09\u3002

    \u56fe 12-5 \u00a0 \u6784\u5efa\u4e8c\u53c9\u6811\u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#1","title":"1. \u00a0 \u5224\u65ad\u662f\u5426\u4e3a\u5206\u6cbb\u95ee\u9898","text":"

    \u539f\u95ee\u9898\u5b9a\u4e49\u4e3a\u4ece preorder \u548c inorder \u6784\u5efa\u4e8c\u53c9\u6811\uff0c\u662f\u4e00\u4e2a\u5178\u578b\u7684\u5206\u6cbb\u95ee\u9898\u3002

    • \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u4ece\u5206\u6cbb\u7684\u89d2\u5ea6\u5207\u5165\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u539f\u95ee\u9898\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\u3001\u6784\u5efa\u53f3\u5b50\u6811\uff0c\u52a0\u4e0a\u4e00\u6b65\u64cd\u4f5c\uff1a\u521d\u59cb\u5316\u6839\u8282\u70b9\u3002\u800c\u5bf9\u4e8e\u6bcf\u68f5\u5b50\u6811\uff08\u5b50\u95ee\u9898\uff09\uff0c\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u590d\u7528\u4ee5\u4e0a\u5212\u5206\u65b9\u6cd5\uff0c\u5c06\u5176\u5212\u5206\u4e3a\u66f4\u5c0f\u7684\u5b50\u6811\uff08\u5b50\u95ee\u9898\uff09\uff0c\u76f4\u81f3\u8fbe\u5230\u6700\u5c0f\u5b50\u95ee\u9898\uff08\u7a7a\u5b50\u6811\uff09\u65f6\u7ec8\u6b62\u3002
    • \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u662f\u76f8\u4e92\u72ec\u7acb\u7684\uff0c\u5b83\u4eec\u4e4b\u95f4\u6ca1\u6709\u4ea4\u96c6\u3002\u5728\u6784\u5efa\u5de6\u5b50\u6811\u65f6\uff0c\u6211\u4eec\u53ea\u9700\u5173\u6ce8\u4e2d\u5e8f\u904d\u5386\u548c\u524d\u5e8f\u904d\u5386\u4e2d\u4e0e\u5de6\u5b50\u6811\u5bf9\u5e94\u7684\u90e8\u5206\u3002\u53f3\u5b50\u6811\u540c\u7406\u3002
    • \u5b50\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u5408\u5e76\uff1a\u4e00\u65e6\u5f97\u5230\u4e86\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\uff08\u5b50\u95ee\u9898\u7684\u89e3\uff09\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5c06\u5b83\u4eec\u94fe\u63a5\u5230\u6839\u8282\u70b9\u4e0a\uff0c\u5f97\u5230\u539f\u95ee\u9898\u7684\u89e3\u3002
    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#2","title":"2. \u00a0 \u5982\u4f55\u5212\u5206\u5b50\u6811","text":"

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u8fd9\u9053\u9898\u53ef\u4ee5\u4f7f\u7528\u5206\u6cbb\u6765\u6c42\u89e3\uff0c\u4f46\u5982\u4f55\u901a\u8fc7\u524d\u5e8f\u904d\u5386 preorder \u548c\u4e2d\u5e8f\u904d\u5386 inorder \u6765\u5212\u5206\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u5462\uff1f

    \u6839\u636e\u5b9a\u4e49\uff0cpreorder \u548c inorder \u90fd\u53ef\u4ee5\u5212\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\u3002

    • \u524d\u5e8f\u904d\u5386\uff1a[ \u6839\u8282\u70b9 | \u5de6\u5b50\u6811 | \u53f3\u5b50\u6811 ] \uff0c\u4f8b\u5982\u56fe 12-5 \u7684\u6811\u5bf9\u5e94 [ 3 | 9 | 2 1 7 ] \u3002
    • \u4e2d\u5e8f\u904d\u5386\uff1a[ \u5de6\u5b50\u6811 | \u6839\u8282\u70b9 \uff5c \u53f3\u5b50\u6811 ] \uff0c\u4f8b\u5982\u56fe 12-5 \u7684\u6811\u5bf9\u5e94 [ 9 | 3 | 1 2 7 ] \u3002

    \u4ee5\u4e0a\u56fe\u6570\u636e\u4e3a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u56fe 12-6 \u6240\u793a\u7684\u6b65\u9aa4\u5f97\u5230\u5212\u5206\u7ed3\u679c\u3002

    1. \u524d\u5e8f\u904d\u5386\u7684\u9996\u5143\u7d20 3 \u662f\u6839\u8282\u70b9\u7684\u503c\u3002
    2. \u67e5\u627e\u6839\u8282\u70b9 3 \u5728 inorder \u4e2d\u7684\u7d22\u5f15\uff0c\u5229\u7528\u8be5\u7d22\u5f15\u53ef\u5c06 inorder \u5212\u5206\u4e3a [ 9 | 3 \uff5c 1 2 7 ] \u3002
    3. \u6839\u636e inorder \u7684\u5212\u5206\u7ed3\u679c\uff0c\u6613\u5f97\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u7684\u8282\u70b9\u6570\u91cf\u5206\u522b\u4e3a 1 \u548c 3 \uff0c\u4ece\u800c\u53ef\u5c06 preorder \u5212\u5206\u4e3a [ 3 | 9 | 2 1 7 ] \u3002

    \u56fe 12-6 \u00a0 \u5728\u524d\u5e8f\u904d\u5386\u548c\u4e2d\u5e8f\u904d\u5386\u4e2d\u5212\u5206\u5b50\u6811

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#3","title":"3. \u00a0 \u57fa\u4e8e\u53d8\u91cf\u63cf\u8ff0\u5b50\u6811\u533a\u95f4","text":"

    \u6839\u636e\u4ee5\u4e0a\u5212\u5206\u65b9\u6cd5\uff0c\u6211\u4eec\u5df2\u7ecf\u5f97\u5230\u6839\u8282\u70b9\u3001\u5de6\u5b50\u6811\u3001\u53f3\u5b50\u6811\u5728 preorder \u548c inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4\u3002\u800c\u4e3a\u4e86\u63cf\u8ff0\u8fd9\u4e9b\u7d22\u5f15\u533a\u95f4\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u51e0\u4e2a\u6307\u9488\u53d8\u91cf\u3002

    • \u5c06\u5f53\u524d\u6811\u7684\u6839\u8282\u70b9\u5728 preorder \u4e2d\u7684\u7d22\u5f15\u8bb0\u4e3a \\(i\\) \u3002
    • \u5c06\u5f53\u524d\u6811\u7684\u6839\u8282\u70b9\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u8bb0\u4e3a \\(m\\) \u3002
    • \u5c06\u5f53\u524d\u6811\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4\u8bb0\u4e3a \\([l, r]\\) \u3002

    \u5982\u8868 12-1 \u6240\u793a\uff0c\u901a\u8fc7\u4ee5\u4e0a\u53d8\u91cf\u5373\u53ef\u8868\u793a\u6839\u8282\u70b9\u5728 preorder \u4e2d\u7684\u7d22\u5f15\uff0c\u4ee5\u53ca\u5b50\u6811\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4\u3002

    \u8868 12-1 \u00a0 \u6839\u8282\u70b9\u548c\u5b50\u6811\u5728\u524d\u5e8f\u904d\u5386\u548c\u4e2d\u5e8f\u904d\u5386\u4e2d\u7684\u7d22\u5f15

    \u6839\u8282\u70b9\u5728 preorder \u4e2d\u7684\u7d22\u5f15 \u5b50\u6811\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4 \u5f53\u524d\u6811 \\(i\\) \\([l, r]\\) \u5de6\u5b50\u6811 \\(i + 1\\) \\([l, m-1]\\) \u53f3\u5b50\u6811 \\(i + 1 + (m - l)\\) \\([m+1, r]\\)

    \u8bf7\u6ce8\u610f\uff0c\u53f3\u5b50\u6811\u6839\u8282\u70b9\u7d22\u5f15\u4e2d\u7684 \\((m-l)\\) \u7684\u542b\u4e49\u662f\u201c\u5de6\u5b50\u6811\u7684\u8282\u70b9\u6570\u91cf\u201d\uff0c\u5efa\u8bae\u7ed3\u5408\u56fe 12-7 \u7406\u89e3\u3002

    \u56fe 12-7 \u00a0 \u6839\u8282\u70b9\u548c\u5de6\u53f3\u5b50\u6811\u7684\u7d22\u5f15\u533a\u95f4\u8868\u793a

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#4","title":"4. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u4e3a\u4e86\u63d0\u5347\u67e5\u8be2 \\(m\\) \u7684\u6548\u7387\uff0c\u6211\u4eec\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u8868 hmap \u6765\u5b58\u50a8\u6570\u7ec4 inorder \u4e2d\u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig build_tree.py
    def dfs(\n    preorder: list[int],\n    inorder_map: dict[int, int],\n    i: int,\n    l: int,\n    r: int,\n) -> TreeNode | None:\n    \"\"\"\u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb\"\"\"\n    # \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0:\n        return None\n    # \u521d\u59cb\u5316\u6839\u8282\u70b9\n    root = TreeNode(preorder[i])\n    # \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    m = inorder_map[preorder[i]]\n    # \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorder_map, i + 1, l, m - 1)\n    # \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r)\n    # \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n\ndef build_tree(preorder: list[int], inorder: list[int]) -> TreeNode | None:\n    \"\"\"\u6784\u5efa\u4e8c\u53c9\u6811\"\"\"\n    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    inorder_map = {val: i for i, val in enumerate(inorder)}\n    root = dfs(preorder, inorder_map, 0, 0, len(inorder) - 1)\n    return root\n
    build_tree.cpp
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode *dfs(vector<int> &preorder, unordered_map<int, int> &inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return NULL;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode *root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    unordered_map<int, int> inorderMap;\n    for (int i = 0; i < inorder.size(); i++) {\n        inorderMap[inorder[i]] = i;\n    }\n    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorder.size() - 1);\n    return root;\n}\n
    build_tree.java
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode dfs(int[] preorder, Map<Integer, Integer> inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode buildTree(int[] preorder, int[] inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    Map<Integer, Integer> inorderMap = new HashMap<>();\n    for (int i = 0; i < inorder.length; i++) {\n        inorderMap.put(inorder[i], i);\n    }\n    TreeNode root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.cs
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode? DFS(int[] preorder, Dictionary<int, int> inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode root = new(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = DFS(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = DFS(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode? BuildTree(int[] preorder, int[] inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    Dictionary<int, int> inorderMap = [];\n    for (int i = 0; i < inorder.Length; i++) {\n        inorderMap.TryAdd(inorder[i], i);\n    }\n    TreeNode? root = DFS(preorder, inorderMap, 0, 0, inorder.Length - 1);\n    return root;\n}\n
    build_tree.go
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunc dfsBuildTree(preorder []int, inorderMap map[int]int, i, l, r int) *TreeNode {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r-l < 0 {\n        return nil\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    root := NewTreeNode(preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    m := inorderMap[preorder[i]]\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.Left = dfsBuildTree(preorder, inorderMap, i+1, l, m-1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.Right = dfsBuildTree(preorder, inorderMap, i+1+m-l, m+1, r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunc buildTree(preorder, inorder []int) *TreeNode {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    inorderMap := make(map[int]int, len(inorder))\n    for i := 0; i < len(inorder); i++ {\n        inorderMap[inorder[i]] = i\n    }\n\n    root := dfsBuildTree(preorder, inorderMap, 0, 0, len(inorder)-1)\n    return root\n}\n
    build_tree.swift
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunc dfs(preorder: [Int], inorderMap: [Int: Int], i: Int, l: Int, r: Int) -> TreeNode? {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0 {\n        return nil\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    let root = TreeNode(x: preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    let m = inorderMap[preorder[i]]!\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1, l: l, r: m - 1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1 + m - l, l: m + 1, r: r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunc buildTree(preorder: [Int], inorder: [Int]) -> TreeNode? {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = inorder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }\n    return dfs(preorder: preorder, inorderMap: inorderMap, i: inorder.startIndex, l: inorder.startIndex, r: inorder.endIndex - 1)\n}\n
    build_tree.js
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunction dfs(preorder, inorderMap, i, l, r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    const root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    const m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunction buildTree(preorder, inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = new Map();\n    for (let i = 0; i < inorder.length; i++) {\n        inorderMap.set(inorder[i], i);\n    }\n    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.ts
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunction dfs(\n    preorder: number[],\n    inorderMap: Map<number, number>,\n    i: number,\n    l: number,\n    r: number\n): TreeNode | null {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    const root: TreeNode = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    const m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunction buildTree(preorder: number[], inorder: number[]): TreeNode | null {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = new Map<number, number>();\n    for (let i = 0; i < inorder.length; i++) {\n        inorderMap.set(inorder[i], i);\n    }\n    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.dart
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode? dfs(\n  List<int> preorder,\n  Map<int, int> inorderMap,\n  int i,\n  int l,\n  int r,\n) {\n  // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n  if (r - l < 0) {\n    return null;\n  }\n  // \u521d\u59cb\u5316\u6839\u8282\u70b9\n  TreeNode? root = TreeNode(preorder[i]);\n  // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n  int m = inorderMap[preorder[i]]!;\n  // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n  root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n  // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n  root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n  // \u8fd4\u56de\u6839\u8282\u70b9\n  return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode? buildTree(List<int> preorder, List<int> inorder) {\n  // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n  Map<int, int> inorderMap = {};\n  for (int i = 0; i < inorder.length; i++) {\n    inorderMap[inorder[i]] = i;\n  }\n  TreeNode? root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n  return root;\n}\n
    build_tree.rs
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfn dfs(\n    preorder: &[i32],\n    inorder_map: &HashMap<i32, i32>,\n    i: i32,\n    l: i32,\n    r: i32,\n) -> Option<Rc<RefCell<TreeNode>>> {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0 {\n        return None;\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    let root = TreeNode::new(preorder[i as usize]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    let m = inorder_map.get(&preorder[i as usize]).unwrap();\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.borrow_mut().left = dfs(preorder, inorder_map, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.borrow_mut().right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    Some(root)\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfn build_tree(preorder: &[i32], inorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let mut inorder_map: HashMap<i32, i32> = HashMap::new();\n    for i in 0..inorder.len() {\n        inorder_map.insert(inorder[i], i as i32);\n    }\n    let root = dfs(preorder, &inorder_map, 0, 0, inorder.len() as i32 - 1);\n    root\n}\n
    build_tree.c
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode *dfs(int *preorder, int *inorderMap, int i, int l, int r, int size) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return NULL;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));\n    root->val = preorder[i];\n    root->left = NULL;\n    root->right = NULL;\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1, size);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r, size);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    int *inorderMap = (int *)malloc(sizeof(int) * MAX_SIZE);\n    for (int i = 0; i < inorderSize; i++) {\n        inorderMap[inorder[i]] = i;\n    }\n    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorderSize - 1, inorderSize);\n    free(inorderMap);\n    return root;\n}\n
    build_tree.kt
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfun dfs(\n    preorder: IntArray,\n    inorderMap: Map<Int?, Int?>,\n    i: Int,\n    l: Int,\n    r: Int\n): TreeNode? {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    val root = TreeNode(preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    val m = inorderMap[preorder[i]]!!\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    val inorderMap = HashMap<Int?, Int?>()\n    for (i in inorder.indices) {\n        inorderMap[inorder[i]] = i\n    }\n    val root = dfs(preorder, inorderMap, 0, 0, inorder.size - 1)\n    return root\n}\n
    build_tree.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{build_tree}\n
    build_tree.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{buildTree}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 12-8 \u5c55\u793a\u4e86\u6784\u5efa\u4e8c\u53c9\u6811\u7684\u9012\u5f52\u8fc7\u7a0b\uff0c\u5404\u4e2a\u8282\u70b9\u662f\u5728\u5411\u4e0b\u201c\u9012\u201d\u7684\u8fc7\u7a0b\u4e2d\u5efa\u7acb\u7684\uff0c\u800c\u5404\u6761\u8fb9\uff08\u5f15\u7528\uff09\u662f\u5728\u5411\u4e0a\u201c\u5f52\u201d\u7684\u8fc7\u7a0b\u4e2d\u5efa\u7acb\u7684\u3002

    <1><2><3><4><5><6><7><8><9>

    \u56fe 12-8 \u00a0 \u6784\u5efa\u4e8c\u53c9\u6811\u7684\u9012\u5f52\u8fc7\u7a0b

    \u6bcf\u4e2a\u9012\u5f52\u51fd\u6570\u5185\u7684\u524d\u5e8f\u904d\u5386 preorder \u548c\u4e2d\u5e8f\u904d\u5386 inorder \u7684\u5212\u5206\u7ed3\u679c\u5982\u56fe 12-9 \u6240\u793a\u3002

    \u56fe 12-9 \u00a0 \u6bcf\u4e2a\u9012\u5f52\u51fd\u6570\u4e2d\u7684\u5212\u5206\u7ed3\u679c

    \u8bbe\u6811\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(n\\) \uff0c\u521d\u59cb\u5316\u6bcf\u4e00\u4e2a\u8282\u70b9\uff08\u6267\u884c\u4e00\u4e2a\u9012\u5f52\u51fd\u6570 dfs() \uff09\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002\u56e0\u6b64\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    \u54c8\u5e0c\u8868\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u5373\u4e8c\u53c9\u6811\u9000\u5316\u4e3a\u94fe\u8868\u65f6\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230 \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u7684\u6808\u5e27\u7a7a\u95f4\u3002\u56e0\u6b64\u603b\u4f53\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/","title":"12.1 \u00a0 \u5206\u6cbb\u7b97\u6cd5","text":"

    \u5206\u6cbb\uff08divide and conquer\uff09\uff0c\u5168\u79f0\u5206\u800c\u6cbb\u4e4b\uff0c\u662f\u4e00\u79cd\u975e\u5e38\u91cd\u8981\u4e14\u5e38\u89c1\u7684\u7b97\u6cd5\u7b56\u7565\u3002\u5206\u6cbb\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\uff0c\u5305\u62ec\u201c\u5206\u201d\u548c\u201c\u6cbb\u201d\u4e24\u4e2a\u6b65\u9aa4\u3002

    1. \u5206\uff08\u5212\u5206\u9636\u6bb5\uff09\uff1a\u9012\u5f52\u5730\u5c06\u539f\u95ee\u9898\u5206\u89e3\u4e3a\u4e24\u4e2a\u6216\u591a\u4e2a\u5b50\u95ee\u9898\uff0c\u76f4\u81f3\u5230\u8fbe\u6700\u5c0f\u5b50\u95ee\u9898\u65f6\u7ec8\u6b62\u3002
    2. \u6cbb\uff08\u5408\u5e76\u9636\u6bb5\uff09\uff1a\u4ece\u5df2\u77e5\u89e3\u7684\u6700\u5c0f\u5b50\u95ee\u9898\u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5730\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u8fdb\u884c\u5408\u5e76\uff0c\u4ece\u800c\u6784\u5efa\u51fa\u539f\u95ee\u9898\u7684\u89e3\u3002

    \u5982\u56fe 12-1 \u6240\u793a\uff0c\u201c\u5f52\u5e76\u6392\u5e8f\u201d\u662f\u5206\u6cbb\u7b56\u7565\u7684\u5178\u578b\u5e94\u7528\u4e4b\u4e00\u3002

    1. \u5206\uff1a\u9012\u5f52\u5730\u5c06\u539f\u6570\u7ec4\uff08\u539f\u95ee\u9898\uff09\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\uff09\uff0c\u76f4\u5230\u5b50\u6570\u7ec4\u53ea\u5269\u4e00\u4e2a\u5143\u7d20\uff08\u6700\u5c0f\u5b50\u95ee\u9898\uff09\u3002
    2. \u6cbb\uff1a\u4ece\u5e95\u81f3\u9876\u5730\u5c06\u6709\u5e8f\u7684\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\u7684\u89e3\uff09\u8fdb\u884c\u5408\u5e76\uff0c\u4ece\u800c\u5f97\u5230\u6709\u5e8f\u7684\u539f\u6570\u7ec4\uff08\u539f\u95ee\u9898\u7684\u89e3\uff09\u3002

    \u56fe 12-1 \u00a0 \u5f52\u5e76\u6392\u5e8f\u7684\u5206\u6cbb\u7b56\u7565

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1211","title":"12.1.1 \u00a0 \u5982\u4f55\u5224\u65ad\u5206\u6cbb\u95ee\u9898","text":"

    \u4e00\u4e2a\u95ee\u9898\u662f\u5426\u9002\u5408\u4f7f\u7528\u5206\u6cbb\u89e3\u51b3\uff0c\u901a\u5e38\u53ef\u4ee5\u53c2\u8003\u4ee5\u4e0b\u51e0\u4e2a\u5224\u65ad\u4f9d\u636e\u3002

    1. \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u539f\u95ee\u9898\u53ef\u4ee5\u5206\u89e3\u6210\u89c4\u6a21\u66f4\u5c0f\u3001\u7c7b\u4f3c\u7684\u5b50\u95ee\u9898\uff0c\u4ee5\u53ca\u80fd\u591f\u4ee5\u76f8\u540c\u65b9\u5f0f\u9012\u5f52\u5730\u8fdb\u884c\u5212\u5206\u3002
    2. \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u5b50\u95ee\u9898\u4e4b\u95f4\u6ca1\u6709\u91cd\u53e0\uff0c\u4e92\u4e0d\u4f9d\u8d56\uff0c\u53ef\u4ee5\u72ec\u7acb\u89e3\u51b3\u3002
    3. \u5b50\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u5408\u5e76\uff1a\u539f\u95ee\u9898\u7684\u89e3\u901a\u8fc7\u5408\u5e76\u5b50\u95ee\u9898\u7684\u89e3\u5f97\u6765\u3002

    \u663e\u7136\uff0c\u5f52\u5e76\u6392\u5e8f\u6ee1\u8db3\u4ee5\u4e0a\u4e09\u4e2a\u5224\u65ad\u4f9d\u636e\u3002

    1. \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u9012\u5f52\u5730\u5c06\u6570\u7ec4\uff08\u539f\u95ee\u9898\uff09\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\uff09\u3002
    2. \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u6bcf\u4e2a\u5b50\u6570\u7ec4\u90fd\u53ef\u4ee5\u72ec\u7acb\u5730\u8fdb\u884c\u6392\u5e8f\uff08\u5b50\u95ee\u9898\u53ef\u4ee5\u72ec\u7acb\u8fdb\u884c\u6c42\u89e3\uff09\u3002
    3. \u5b50\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u5408\u5e76\uff1a\u4e24\u4e2a\u6709\u5e8f\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\u7684\u89e3\uff09\u53ef\u4ee5\u5408\u5e76\u4e3a\u4e00\u4e2a\u6709\u5e8f\u6570\u7ec4\uff08\u539f\u95ee\u9898\u7684\u89e3\uff09\u3002
    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1212","title":"12.1.2 \u00a0 \u901a\u8fc7\u5206\u6cbb\u63d0\u5347\u6548\u7387","text":"

    \u5206\u6cbb\u4e0d\u4ec5\u53ef\u4ee5\u6709\u6548\u5730\u89e3\u51b3\u7b97\u6cd5\u95ee\u9898\uff0c\u5f80\u5f80\u8fd8\u53ef\u4ee5\u63d0\u5347\u7b97\u6cd5\u6548\u7387\u3002\u5728\u6392\u5e8f\u7b97\u6cd5\u4e2d\uff0c\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u3001\u5806\u6392\u5e8f\u76f8\u8f83\u4e8e\u9009\u62e9\u3001\u5192\u6ce1\u3001\u63d2\u5165\u6392\u5e8f\u66f4\u5feb\uff0c\u5c31\u662f\u56e0\u4e3a\u5b83\u4eec\u5e94\u7528\u4e86\u5206\u6cbb\u7b56\u7565\u3002

    \u90a3\u4e48\uff0c\u6211\u4eec\u4e0d\u7981\u53d1\u95ee\uff1a\u4e3a\u4ec0\u4e48\u5206\u6cbb\u53ef\u4ee5\u63d0\u5347\u7b97\u6cd5\u6548\u7387\uff0c\u5176\u5e95\u5c42\u903b\u8f91\u662f\u4ec0\u4e48\uff1f\u6362\u53e5\u8bdd\u8bf4\uff0c\u5c06\u5927\u95ee\u9898\u5206\u89e3\u4e3a\u591a\u4e2a\u5b50\u95ee\u9898\u3001\u89e3\u51b3\u5b50\u95ee\u9898\u3001\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u5408\u5e76\u4e3a\u539f\u95ee\u9898\u7684\u89e3\uff0c\u8fd9\u51e0\u6b65\u7684\u6548\u7387\u4e3a\u4ec0\u4e48\u6bd4\u76f4\u63a5\u89e3\u51b3\u539f\u95ee\u9898\u7684\u6548\u7387\u66f4\u9ad8\uff1f\u8fd9\u4e2a\u95ee\u9898\u53ef\u4ee5\u4ece\u64cd\u4f5c\u6570\u91cf\u548c\u5e76\u884c\u8ba1\u7b97\u4e24\u65b9\u9762\u6765\u8ba8\u8bba\u3002

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1","title":"1. \u00a0 \u64cd\u4f5c\u6570\u91cf\u4f18\u5316","text":"

    \u4ee5\u201c\u5192\u6ce1\u6392\u5e8f\u201d\u4e3a\u4f8b\uff0c\u5176\u5904\u7406\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\u9700\u8981 \\(O(n^2)\\) \u65f6\u95f4\u3002\u5047\u8bbe\u6211\u4eec\u6309\u7167\u56fe 12-2 \u6240\u793a\u7684\u65b9\u5f0f\uff0c\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5904\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u5219\u5212\u5206\u9700\u8981 \\(O(n)\\) \u65f6\u95f4\uff0c\u6392\u5e8f\u6bcf\u4e2a\u5b50\u6570\u7ec4\u9700\u8981 \\(O((n / 2)^2)\\) \u65f6\u95f4\uff0c\u5408\u5e76\u4e24\u4e2a\u5b50\u6570\u7ec4\u9700\u8981 \\(O(n)\\) \u65f6\u95f4\uff0c\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\uff1a

    \\[ O(n + (\\frac{n}{2})^2 \\times 2 + n) = O(\\frac{n^2}{2} + 2n) \\]

    \u56fe 12-2 \u00a0 \u5212\u5206\u6570\u7ec4\u524d\u540e\u7684\u5192\u6ce1\u6392\u5e8f

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8ba1\u7b97\u4ee5\u4e0b\u4e0d\u7b49\u5f0f\uff0c\u5176\u5de6\u8fb9\u548c\u53f3\u8fb9\u5206\u522b\u4e3a\u5212\u5206\u524d\u548c\u5212\u5206\u540e\u7684\u64cd\u4f5c\u603b\u6570\uff1a

    \\[ \\begin{aligned} n^2 & > \\frac{n^2}{2} + 2n \\newline n^2 - \\frac{n^2}{2} - 2n & > 0 \\newline n(n - 4) & > 0 \\end{aligned} \\]

    \u8fd9\u610f\u5473\u7740\u5f53 \\(n > 4\\) \u65f6\uff0c\u5212\u5206\u540e\u7684\u64cd\u4f5c\u6570\u91cf\u66f4\u5c11\uff0c\u6392\u5e8f\u6548\u7387\u5e94\u8be5\u66f4\u9ad8\u3002\u8bf7\u6ce8\u610f\uff0c\u5212\u5206\u540e\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e73\u65b9\u9636 \\(O(n^2)\\) \uff0c\u53ea\u662f\u590d\u6742\u5ea6\u4e2d\u7684\u5e38\u6570\u9879\u53d8\u5c0f\u4e86\u3002

    \u8fdb\u4e00\u6b65\u60f3\uff0c\u5982\u679c\u6211\u4eec\u628a\u5b50\u6570\u7ec4\u4e0d\u65ad\u5730\u518d\u4ece\u4e2d\u70b9\u5904\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u53ea\u5269\u4e00\u4e2a\u5143\u7d20\u65f6\u505c\u6b62\u5212\u5206\u5462\uff1f\u8fd9\u79cd\u601d\u8def\u5b9e\u9645\u4e0a\u5c31\u662f\u201c\u5f52\u5e76\u6392\u5e8f\u201d\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    \u518d\u601d\u8003\uff0c\u5982\u679c\u6211\u4eec\u591a\u8bbe\u7f6e\u51e0\u4e2a\u5212\u5206\u70b9\uff0c\u5c06\u539f\u6570\u7ec4\u5e73\u5747\u5212\u5206\u4e3a \\(k\\) \u4e2a\u5b50\u6570\u7ec4\u5462\uff1f\u8fd9\u79cd\u60c5\u51b5\u4e0e\u201c\u6876\u6392\u5e8f\u201d\u975e\u5e38\u7c7b\u4f3c\uff0c\u5b83\u975e\u5e38\u9002\u5408\u6392\u5e8f\u6d77\u91cf\u6570\u636e\uff0c\u7406\u8bba\u4e0a\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230 \\(O(n + k)\\) \u3002

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#2","title":"2. \u00a0 \u5e76\u884c\u8ba1\u7b97\u4f18\u5316","text":"

    \u6211\u4eec\u77e5\u9053\uff0c\u5206\u6cbb\u751f\u6210\u7684\u5b50\u95ee\u9898\u662f\u76f8\u4e92\u72ec\u7acb\u7684\uff0c\u56e0\u6b64\u901a\u5e38\u53ef\u4ee5\u5e76\u884c\u89e3\u51b3\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5206\u6cbb\u4e0d\u4ec5\u53ef\u4ee5\u964d\u4f4e\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8fd8\u6709\u5229\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u7684\u5e76\u884c\u4f18\u5316\u3002

    \u5e76\u884c\u4f18\u5316\u5728\u591a\u6838\u6216\u591a\u5904\u7406\u5668\u7684\u73af\u5883\u4e2d\u5c24\u5176\u6709\u6548\uff0c\u56e0\u4e3a\u7cfb\u7edf\u53ef\u4ee5\u540c\u65f6\u5904\u7406\u591a\u4e2a\u5b50\u95ee\u9898\uff0c\u66f4\u52a0\u5145\u5206\u5730\u5229\u7528\u8ba1\u7b97\u8d44\u6e90\uff0c\u4ece\u800c\u663e\u8457\u51cf\u5c11\u603b\u4f53\u7684\u8fd0\u884c\u65f6\u95f4\u3002

    \u6bd4\u5982\u5728\u56fe 12-3 \u6240\u793a\u7684\u201c\u6876\u6392\u5e8f\u201d\u4e2d\uff0c\u6211\u4eec\u5c06\u6d77\u91cf\u7684\u6570\u636e\u5e73\u5747\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\uff0c\u5219\u53ef\u5c06\u6240\u6709\u6876\u7684\u6392\u5e8f\u4efb\u52a1\u5206\u6563\u5230\u5404\u4e2a\u8ba1\u7b97\u5355\u5143\uff0c\u5b8c\u6210\u540e\u518d\u5408\u5e76\u7ed3\u679c\u3002

    \u56fe 12-3 \u00a0 \u6876\u6392\u5e8f\u7684\u5e76\u884c\u8ba1\u7b97

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1213","title":"12.1.3 \u00a0 \u5206\u6cbb\u5e38\u89c1\u5e94\u7528","text":"

    \u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u53ef\u4ee5\u7528\u6765\u89e3\u51b3\u8bb8\u591a\u7ecf\u5178\u7b97\u6cd5\u95ee\u9898\u3002

    • \u5bfb\u627e\u6700\u8fd1\u70b9\u5bf9\uff1a\u8be5\u7b97\u6cd5\u9996\u5148\u5c06\u70b9\u96c6\u5206\u6210\u4e24\u90e8\u5206\uff0c\u7136\u540e\u5206\u522b\u627e\u51fa\u4e24\u90e8\u5206\u4e2d\u7684\u6700\u8fd1\u70b9\u5bf9\uff0c\u6700\u540e\u627e\u51fa\u8de8\u8d8a\u4e24\u90e8\u5206\u7684\u6700\u8fd1\u70b9\u5bf9\u3002
    • \u5927\u6574\u6570\u4e58\u6cd5\uff1a\u4f8b\u5982 Karatsuba \u7b97\u6cd5\uff0c\u5b83\u5c06\u5927\u6574\u6570\u4e58\u6cd5\u5206\u89e3\u4e3a\u51e0\u4e2a\u8f83\u5c0f\u7684\u6574\u6570\u7684\u4e58\u6cd5\u548c\u52a0\u6cd5\u3002
    • \u77e9\u9635\u4e58\u6cd5\uff1a\u4f8b\u5982 Strassen \u7b97\u6cd5\uff0c\u5b83\u5c06\u5927\u77e9\u9635\u4e58\u6cd5\u5206\u89e3\u4e3a\u591a\u4e2a\u5c0f\u77e9\u9635\u7684\u4e58\u6cd5\u548c\u52a0\u6cd5\u3002
    • \u6c49\u8bfa\u5854\u95ee\u9898\uff1a\u6c49\u8bfa\u5854\u95ee\u9898\u53ef\u4ee5\u901a\u8fc7\u9012\u5f52\u89e3\u51b3\uff0c\u8fd9\u662f\u5178\u578b\u7684\u5206\u6cbb\u7b56\u7565\u5e94\u7528\u3002
    • \u6c42\u89e3\u9006\u5e8f\u5bf9\uff1a\u5728\u4e00\u4e2a\u5e8f\u5217\u4e2d\uff0c\u5982\u679c\u524d\u9762\u7684\u6570\u5b57\u5927\u4e8e\u540e\u9762\u7684\u6570\u5b57\uff0c\u90a3\u4e48\u8fd9\u4e24\u4e2a\u6570\u5b57\u6784\u6210\u4e00\u4e2a\u9006\u5e8f\u5bf9\u3002\u6c42\u89e3\u9006\u5e8f\u5bf9\u95ee\u9898\u53ef\u4ee5\u5229\u7528\u5206\u6cbb\u7684\u601d\u60f3\uff0c\u501f\u52a9\u5f52\u5e76\u6392\u5e8f\u8fdb\u884c\u6c42\u89e3\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u5728\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u4e2d\u5e94\u7528\u5f97\u975e\u5e38\u5e7f\u6cdb\u3002

    • \u4e8c\u5206\u67e5\u627e\uff1a\u4e8c\u5206\u67e5\u627e\u662f\u5c06\u6709\u5e8f\u6570\u7ec4\u4ece\u4e2d\u70b9\u7d22\u5f15\u5904\u5206\u4e3a\u4e24\u90e8\u5206\uff0c\u7136\u540e\u6839\u636e\u76ee\u6807\u503c\u4e0e\u4e2d\u95f4\u5143\u7d20\u503c\u6bd4\u8f83\u7ed3\u679c\uff0c\u51b3\u5b9a\u6392\u9664\u54ea\u4e00\u534a\u533a\u95f4\uff0c\u5e76\u5728\u5269\u4f59\u533a\u95f4\u6267\u884c\u76f8\u540c\u7684\u4e8c\u5206\u64cd\u4f5c\u3002
    • \u5f52\u5e76\u6392\u5e8f\uff1a\u672c\u8282\u5f00\u5934\u5df2\u4ecb\u7ecd\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002
    • \u5feb\u901f\u6392\u5e8f\uff1a\u5feb\u901f\u6392\u5e8f\u662f\u9009\u53d6\u4e00\u4e2a\u57fa\u51c6\u503c\uff0c\u7136\u540e\u628a\u6570\u7ec4\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5143\u7d20\u6bd4\u57fa\u51c6\u503c\u5c0f\uff0c\u53e6\u4e00\u5b50\u6570\u7ec4\u7684\u5143\u7d20\u6bd4\u57fa\u51c6\u503c\u5927\uff0c\u518d\u5bf9\u8fd9\u4e24\u90e8\u5206\u8fdb\u884c\u76f8\u540c\u7684\u5212\u5206\u64cd\u4f5c\uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u53ea\u5269\u4e0b\u4e00\u4e2a\u5143\u7d20\u3002
    • \u6876\u6392\u5e8f\uff1a\u6876\u6392\u5e8f\u7684\u57fa\u672c\u601d\u60f3\u662f\u5c06\u6570\u636e\u5206\u6563\u5230\u591a\u4e2a\u6876\uff0c\u7136\u540e\u5bf9\u6bcf\u4e2a\u6876\u5185\u7684\u5143\u7d20\u8fdb\u884c\u6392\u5e8f\uff0c\u6700\u540e\u5c06\u5404\u4e2a\u6876\u7684\u5143\u7d20\u4f9d\u6b21\u53d6\u51fa\uff0c\u4ece\u800c\u5f97\u5230\u4e00\u4e2a\u6709\u5e8f\u6570\u7ec4\u3002
    • \u6811\uff1a\u4f8b\u5982\u4e8c\u53c9\u641c\u7d22\u6811\u3001AVL \u6811\u3001\u7ea2\u9ed1\u6811\u3001B \u6811\u3001B+ \u6811\u7b49\uff0c\u5b83\u4eec\u7684\u67e5\u627e\u3001\u63d2\u5165\u548c\u5220\u9664\u7b49\u64cd\u4f5c\u90fd\u53ef\u4ee5\u89c6\u4e3a\u5206\u6cbb\u7b56\u7565\u7684\u5e94\u7528\u3002
    • \u5806\uff1a\u5806\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u5176\u5404\u79cd\u64cd\u4f5c\uff0c\u5982\u63d2\u5165\u3001\u5220\u9664\u548c\u5806\u5316\uff0c\u5b9e\u9645\u4e0a\u90fd\u9690\u542b\u4e86\u5206\u6cbb\u7684\u601d\u60f3\u3002
    • \u54c8\u5e0c\u8868\uff1a\u867d\u7136\u54c8\u5e0c\u8868\u5e76\u4e0d\u76f4\u63a5\u5e94\u7528\u5206\u6cbb\uff0c\u4f46\u67d0\u4e9b\u54c8\u5e0c\u51b2\u7a81\u89e3\u51b3\u65b9\u6848\u95f4\u63a5\u5e94\u7528\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u4f8b\u5982\uff0c\u94fe\u5f0f\u5730\u5740\u4e2d\u7684\u957f\u94fe\u8868\u4f1a\u88ab\u8f6c\u5316\u4e3a\u7ea2\u9ed1\u6811\uff0c\u4ee5\u63d0\u5347\u67e5\u8be2\u6548\u7387\u3002

    \u53ef\u4ee5\u770b\u51fa\uff0c\u5206\u6cbb\u662f\u4e00\u79cd\u201c\u6da6\u7269\u7ec6\u65e0\u58f0\u201d\u7684\u7b97\u6cd5\u601d\u60f3\uff0c\u9690\u542b\u5728\u5404\u79cd\u7b97\u6cd5\u4e0e\u6570\u636e\u7ed3\u6784\u4e4b\u4e2d\u3002

    "},{"location":"chapter_divide_and_conquer/hanota_problem/","title":"12.4 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898","text":"

    \u5728\u5f52\u5e76\u6392\u5e8f\u548c\u6784\u5efa\u4e8c\u53c9\u6811\u4e2d\uff0c\u6211\u4eec\u90fd\u662f\u5c06\u539f\u95ee\u9898\u5206\u89e3\u4e3a\u4e24\u4e2a\u89c4\u6a21\u4e3a\u539f\u95ee\u9898\u4e00\u534a\u7684\u5b50\u95ee\u9898\u3002\u7136\u800c\u5bf9\u4e8e\u6c49\u8bfa\u5854\u95ee\u9898\uff0c\u6211\u4eec\u91c7\u7528\u4e0d\u540c\u7684\u5206\u89e3\u7b56\u7565\u3002

    Question

    \u7ed9\u5b9a\u4e09\u6839\u67f1\u5b50\uff0c\u8bb0\u4e3a A\u3001B \u548c C \u3002\u8d77\u59cb\u72b6\u6001\u4e0b\uff0c\u67f1\u5b50 A \u4e0a\u5957\u7740 \\(n\\) \u4e2a\u5706\u76d8\uff0c\u5b83\u4eec\u4ece\u4e0a\u5230\u4e0b\u6309\u7167\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u3002\u6211\u4eec\u7684\u4efb\u52a1\u662f\u8981\u628a\u8fd9 \\(n\\) \u4e2a\u5706\u76d8\u79fb\u5230\u67f1\u5b50 C \u4e0a\uff0c\u5e76\u4fdd\u6301\u5b83\u4eec\u7684\u539f\u6709\u987a\u5e8f\u4e0d\u53d8\uff08\u5982\u56fe 12-10 \u6240\u793a\uff09\u3002\u5728\u79fb\u52a8\u5706\u76d8\u7684\u8fc7\u7a0b\u4e2d\uff0c\u9700\u8981\u9075\u5b88\u4ee5\u4e0b\u89c4\u5219\u3002

    1. \u5706\u76d8\u53ea\u80fd\u4ece\u4e00\u6839\u67f1\u5b50\u9876\u90e8\u62ff\u51fa\uff0c\u4ece\u53e6\u4e00\u6839\u67f1\u5b50\u9876\u90e8\u653e\u5165\u3002
    2. \u6bcf\u6b21\u53ea\u80fd\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\u3002
    3. \u5c0f\u5706\u76d8\u5fc5\u987b\u65f6\u523b\u4f4d\u4e8e\u5927\u5706\u76d8\u4e4b\u4e0a\u3002

    \u56fe 12-10 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898\u793a\u4f8b

    \u6211\u4eec\u5c06\u89c4\u6a21\u4e3a \\(i\\) \u7684\u6c49\u8bfa\u5854\u95ee\u9898\u8bb0\u4f5c \\(f(i)\\) \u3002\u4f8b\u5982 \\(f(3)\\) \u4ee3\u8868\u5c06 \\(3\\) \u4e2a\u5706\u76d8\u4ece A \u79fb\u52a8\u81f3 C \u7684\u6c49\u8bfa\u5854\u95ee\u9898\u3002

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#1","title":"1. \u00a0 \u8003\u8651\u57fa\u672c\u60c5\u51b5","text":"

    \u5982\u56fe 12-11 \u6240\u793a\uff0c\u5bf9\u4e8e\u95ee\u9898 \\(f(1)\\) \uff0c\u5373\u5f53\u53ea\u6709\u4e00\u4e2a\u5706\u76d8\u65f6\uff0c\u6211\u4eec\u5c06\u5b83\u76f4\u63a5\u4ece A \u79fb\u52a8\u81f3 C \u5373\u53ef\u3002

    <1><2>

    \u56fe 12-11 \u00a0 \u89c4\u6a21\u4e3a 1 \u7684\u95ee\u9898\u7684\u89e3

    \u5982\u56fe 12-12 \u6240\u793a\uff0c\u5bf9\u4e8e\u95ee\u9898 \\(f(2)\\) \uff0c\u5373\u5f53\u6709\u4e24\u4e2a\u5706\u76d8\u65f6\uff0c\u7531\u4e8e\u8981\u65f6\u523b\u6ee1\u8db3\u5c0f\u5706\u76d8\u5728\u5927\u5706\u76d8\u4e4b\u4e0a\uff0c\u56e0\u6b64\u9700\u8981\u501f\u52a9 B \u6765\u5b8c\u6210\u79fb\u52a8\u3002

    1. \u5148\u5c06\u4e0a\u9762\u7684\u5c0f\u5706\u76d8\u4ece A \u79fb\u81f3 B \u3002
    2. \u518d\u5c06\u5927\u5706\u76d8\u4ece A \u79fb\u81f3 C \u3002
    3. \u6700\u540e\u5c06\u5c0f\u5706\u76d8\u4ece B \u79fb\u81f3 C \u3002
    <1><2><3><4>

    \u56fe 12-12 \u00a0 \u89c4\u6a21\u4e3a 2 \u7684\u95ee\u9898\u7684\u89e3

    \u89e3\u51b3\u95ee\u9898 \\(f(2)\\) \u7684\u8fc7\u7a0b\u53ef\u603b\u7ed3\u4e3a\uff1a\u5c06\u4e24\u4e2a\u5706\u76d8\u501f\u52a9 B \u4ece A \u79fb\u81f3 C \u3002\u5176\u4e2d\uff0cC \u79f0\u4e3a\u76ee\u6807\u67f1\u3001B \u79f0\u4e3a\u7f13\u51b2\u67f1\u3002

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#2","title":"2. \u00a0 \u5b50\u95ee\u9898\u5206\u89e3","text":"

    \u5bf9\u4e8e\u95ee\u9898 \\(f(3)\\) \uff0c\u5373\u5f53\u6709\u4e09\u4e2a\u5706\u76d8\u65f6\uff0c\u60c5\u51b5\u53d8\u5f97\u7a0d\u5fae\u590d\u6742\u4e86\u4e00\u4e9b\u3002

    \u56e0\u4e3a\u5df2\u77e5 \\(f(1)\\) \u548c \\(f(2)\\) \u7684\u89e3\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ece\u5206\u6cbb\u89d2\u5ea6\u601d\u8003\uff0c\u5c06 A \u9876\u90e8\u7684\u4e24\u4e2a\u5706\u76d8\u770b\u4f5c\u4e00\u4e2a\u6574\u4f53\uff0c\u6267\u884c\u56fe 12-13 \u6240\u793a\u7684\u6b65\u9aa4\u3002\u8fd9\u6837\u4e09\u4e2a\u5706\u76d8\u5c31\u88ab\u987a\u5229\u5730\u4ece A \u79fb\u81f3 C \u4e86\u3002

    1. \u4ee4 B \u4e3a\u76ee\u6807\u67f1\u3001C \u4e3a\u7f13\u51b2\u67f1\uff0c\u5c06\u4e24\u4e2a\u5706\u76d8\u4ece A \u79fb\u81f3 B \u3002
    2. \u5c06 A \u4e2d\u5269\u4f59\u7684\u4e00\u4e2a\u5706\u76d8\u4ece A \u76f4\u63a5\u79fb\u52a8\u81f3 C \u3002
    3. \u4ee4 C \u4e3a\u76ee\u6807\u67f1\u3001A \u4e3a\u7f13\u51b2\u67f1\uff0c\u5c06\u4e24\u4e2a\u5706\u76d8\u4ece B \u79fb\u81f3 C \u3002
    <1><2><3><4>

    \u56fe 12-13 \u00a0 \u89c4\u6a21\u4e3a 3 \u7684\u95ee\u9898\u7684\u89e3

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u6211\u4eec\u5c06\u95ee\u9898 \\(f(3)\\) \u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u95ee\u9898 \\(f(2)\\) \u548c\u4e00\u4e2a\u5b50\u95ee\u9898 \\(f(1)\\) \u3002\u6309\u987a\u5e8f\u89e3\u51b3\u8fd9\u4e09\u4e2a\u5b50\u95ee\u9898\u4e4b\u540e\uff0c\u539f\u95ee\u9898\u968f\u4e4b\u5f97\u5230\u89e3\u51b3\u3002\u8fd9\u8bf4\u660e\u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff0c\u800c\u4e14\u89e3\u53ef\u4ee5\u5408\u5e76\u3002

    \u81f3\u6b64\uff0c\u6211\u4eec\u53ef\u603b\u7ed3\u51fa\u56fe 12-14 \u6240\u793a\u7684\u89e3\u51b3\u6c49\u8bfa\u5854\u95ee\u9898\u7684\u5206\u6cbb\u7b56\u7565\uff1a\u5c06\u539f\u95ee\u9898 \\(f(n)\\) \u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u95ee\u9898 \\(f(n-1)\\) \u548c\u4e00\u4e2a\u5b50\u95ee\u9898 \\(f(1)\\) \uff0c\u5e76\u6309\u7167\u4ee5\u4e0b\u987a\u5e8f\u89e3\u51b3\u8fd9\u4e09\u4e2a\u5b50\u95ee\u9898\u3002

    1. \u5c06 \\(n-1\\) \u4e2a\u5706\u76d8\u501f\u52a9 C \u4ece A \u79fb\u81f3 B \u3002
    2. \u5c06\u5269\u4f59 \\(1\\) \u4e2a\u5706\u76d8\u4ece A \u76f4\u63a5\u79fb\u81f3 C \u3002
    3. \u5c06 \\(n-1\\) \u4e2a\u5706\u76d8\u501f\u52a9 A \u4ece B \u79fb\u81f3 C \u3002

    \u5bf9\u4e8e\u8fd9\u4e24\u4e2a\u5b50\u95ee\u9898 \\(f(n-1)\\) \uff0c\u53ef\u4ee5\u901a\u8fc7\u76f8\u540c\u7684\u65b9\u5f0f\u8fdb\u884c\u9012\u5f52\u5212\u5206\uff0c\u76f4\u81f3\u8fbe\u5230\u6700\u5c0f\u5b50\u95ee\u9898 \\(f(1)\\) \u3002\u800c \\(f(1)\\) \u7684\u89e3\u662f\u5df2\u77e5\u7684\uff0c\u53ea\u9700\u4e00\u6b21\u79fb\u52a8\u64cd\u4f5c\u5373\u53ef\u3002

    \u56fe 12-14 \u00a0 \u89e3\u51b3\u6c49\u8bfa\u5854\u95ee\u9898\u7684\u5206\u6cbb\u7b56\u7565

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#3","title":"3. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5728\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u9012\u5f52\u51fd\u6570 dfs(i, src, buf, tar) \uff0c\u5b83\u7684\u4f5c\u7528\u662f\u5c06\u67f1 src \u9876\u90e8\u7684 \\(i\\) \u4e2a\u5706\u76d8\u501f\u52a9\u7f13\u51b2\u67f1 buf \u79fb\u52a8\u81f3\u76ee\u6807\u67f1 tar \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hanota.py
    def move(src: list[int], tar: list[int]):\n    \"\"\"\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\"\"\"\n    # \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    pan = src.pop()\n    # \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.append(pan)\n\ndef dfs(i: int, src: list[int], buf: list[int], tar: list[int]):\n    \"\"\"\u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i)\"\"\"\n    # \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1:\n        move(src, tar)\n        return\n    # \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf)\n    # \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    # \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar)\n\ndef solve_hanota(A: list[int], B: list[int], C: list[int]):\n    \"\"\"\u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898\"\"\"\n    n = len(A)\n    # \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C)\n
    hanota.cpp
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(vector<int> &src, vector<int> &tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src.back();\n    src.pop_back();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push_back(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, vector<int> &src, vector<int> &buf, vector<int> &tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(vector<int> &A, vector<int> &B, vector<int> &C) {\n    int n = A.size();\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.java
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(List<Integer> src, List<Integer> tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    Integer pan = src.remove(src.size() - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, List<Integer> src, List<Integer> buf, List<Integer> tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(List<Integer> A, List<Integer> B, List<Integer> C) {\n    int n = A.size();\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.cs
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid Move(List<int> src, List<int> tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src[^1];\n    src.RemoveAt(src.Count - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.Add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid DFS(int i, List<int> src, List<int> buf, List<int> tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        Move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    DFS(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    Move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    DFS(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid SolveHanota(List<int> A, List<int> B, List<int> C) {\n    int n = A.Count;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    DFS(n, A, B, C);\n}\n
    hanota.go
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunc move(src, tar *list.List) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    pan := src.Back()\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.PushBack(pan.Value)\n    // \u79fb\u9664 src \u9876\u90e8\u5706\u76d8\n    src.Remove(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunc dfsHanota(i int, src, buf, tar *list.List) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move(src, tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfsHanota(i-1, src, tar, buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfsHanota(i-1, buf, src, tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunc solveHanota(A, B, C *list.List) {\n    n := A.Len()\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfsHanota(n, A, B, C)\n}\n
    hanota.swift
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunc move(src: inout [Int], tar: inout [Int]) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    let pan = src.popLast()!\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.append(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunc dfs(i: Int, src: inout [Int], buf: inout [Int], tar: inout [Int]) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move(src: &src, tar: &tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i: i - 1, src: &src, buf: &tar, tar: &buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src: &src, tar: &tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i: i - 1, src: &buf, buf: &src, tar: &tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunc solveHanota(A: inout [Int], B: inout [Int], C: inout [Int]) {\n    let n = A.count\n    // \u5217\u8868\u5c3e\u90e8\u662f\u67f1\u5b50\u9876\u90e8\n    // \u5c06 src \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(i: n, src: &A, buf: &B, tar: &C)\n}\n
    hanota.js
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunction move(src, tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    const pan = src.pop();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunction dfs(i, src, buf, tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i === 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunction solveHanota(A, B, C) {\n    const n = A.length;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.ts
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunction move(src: number[], tar: number[]): void {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    const pan = src.pop();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunction dfs(i: number, src: number[], buf: number[], tar: number[]): void {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i === 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunction solveHanota(A: number[], B: number[], C: number[]): void {\n    const n = A.length;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.dart
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(List<int> src, List<int> tar) {\n  // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n  int pan = src.removeLast();\n  // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n  tar.add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, List<int> src, List<int> buf, List<int> tar) {\n  // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n  if (i == 1) {\n    move(src, tar);\n    return;\n  }\n  // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n  dfs(i - 1, src, tar, buf);\n  // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n  move(src, tar);\n  // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n  dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(List<int> A, List<int> B, List<int> C) {\n  int n = A.length;\n  // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n  dfs(n, A, B, C);\n}\n
    hanota.rs
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfn move_pan(src: &mut Vec<i32>, tar: &mut Vec<i32>) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    let pan = src.remove(src.len() - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfn dfs(i: i32, src: &mut Vec<i32>, buf: &mut Vec<i32>, tar: &mut Vec<i32>) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move_pan(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move_pan(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfn solve_hanota(A: &mut Vec<i32>, B: &mut Vec<i32>, C: &mut Vec<i32>) {\n    let n = A.len() as i32;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.c
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(int *src, int *srcSize, int *tar, int *tarSize) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src[*srcSize - 1];\n    src[*srcSize - 1] = 0;\n    (*srcSize)--;\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar[*tarSize] = pan;\n    (*tarSize)++;\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, int *src, int *srcSize, int *buf, int *bufSize, int *tar, int *tarSize) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, srcSize, tar, tarSize);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, srcSize, tar, tarSize, buf, bufSize);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, srcSize, tar, tarSize);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, bufSize, src, srcSize, tar, tarSize);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(int *A, int *ASize, int *B, int *BSize, int *C, int *CSize) {\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(*ASize, A, ASize, B, BSize, C, CSize);\n}\n
    hanota.kt
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfun move(src: MutableList<Int>, tar: MutableList<Int>) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    val pan = src.removeAt(src.size - 1)\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.add(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfun dfs(i: Int, src: MutableList<Int>, buf: MutableList<Int>, tar: MutableList<Int>) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfun solveHanota(A: MutableList<Int>, B: MutableList<Int>, C: MutableList<Int>) {\n    val n = A.size\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C)\n}\n
    hanota.rb
    [class]{}-[func]{move}\n\n[class]{}-[func]{dfs}\n\n[class]{}-[func]{solve_hanota}\n
    hanota.zig
    [class]{}-[func]{move}\n\n[class]{}-[func]{dfs}\n\n[class]{}-[func]{solveHanota}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 12-15 \u6240\u793a\uff0c\u6c49\u8bfa\u5854\u95ee\u9898\u5f62\u6210\u4e00\u68f5\u9ad8\u5ea6\u4e3a \\(n\\) \u7684\u9012\u5f52\u6811\uff0c\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u4e00\u4e2a\u5b50\u95ee\u9898\uff0c\u5bf9\u5e94\u4e00\u4e2a\u5f00\u542f\u7684 dfs() \u51fd\u6570\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    \u56fe 12-15 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898\u7684\u9012\u5f52\u6811

    Quote

    \u6c49\u8bfa\u5854\u95ee\u9898\u6e90\u81ea\u4e00\u4e2a\u53e4\u8001\u7684\u4f20\u8bf4\u3002\u5728\u53e4\u5370\u5ea6\u7684\u4e00\u4e2a\u5bfa\u5e99\u91cc\uff0c\u50e7\u4fa3\u4eec\u6709\u4e09\u6839\u9ad8\u5927\u7684\u94bb\u77f3\u67f1\u5b50\uff0c\u4ee5\u53ca \\(64\\) \u4e2a\u5927\u5c0f\u4e0d\u4e00\u7684\u91d1\u5706\u76d8\u3002\u50e7\u4fa3\u4eec\u4e0d\u65ad\u5730\u79fb\u52a8\u5706\u76d8\uff0c\u4ed6\u4eec\u76f8\u4fe1\u5728\u6700\u540e\u4e00\u4e2a\u5706\u76d8\u88ab\u6b63\u786e\u653e\u7f6e\u7684\u90a3\u4e00\u523b\uff0c\u8fd9\u4e2a\u4e16\u754c\u5c31\u4f1a\u7ed3\u675f\u3002

    \u7136\u800c\uff0c\u5373\u4f7f\u50e7\u4fa3\u4eec\u6bcf\u79d2\u949f\u79fb\u52a8\u4e00\u6b21\uff0c\u603b\u5171\u9700\u8981\u5927\u7ea6 \\(2^{64} \\approx 1.84\u00d710^{19}\\) \u79d2\uff0c\u5408\u7ea6 \\(5850\\) \u4ebf\u5e74\uff0c\u8fdc\u8fdc\u8d85\u8fc7\u4e86\u73b0\u5728\u5bf9\u5b87\u5b99\u5e74\u9f84\u7684\u4f30\u8ba1\u3002\u6240\u4ee5\uff0c\u5018\u82e5\u8fd9\u4e2a\u4f20\u8bf4\u662f\u771f\u7684\uff0c\u6211\u4eec\u5e94\u8be5\u4e0d\u9700\u8981\u62c5\u5fc3\u4e16\u754c\u672b\u65e5\u7684\u5230\u6765\u3002

    "},{"location":"chapter_divide_and_conquer/summary/","title":"12.5 \u00a0 \u5c0f\u7ed3","text":"
    • \u5206\u6cbb\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u7b97\u6cd5\u8bbe\u8ba1\u7b56\u7565\uff0c\u5305\u62ec\u5206\uff08\u5212\u5206\uff09\u548c\u6cbb\uff08\u5408\u5e76\uff09\u4e24\u4e2a\u9636\u6bb5\uff0c\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\u3002
    • \u5224\u65ad\u662f\u5426\u662f\u5206\u6cbb\u7b97\u6cd5\u95ee\u9898\u7684\u4f9d\u636e\u5305\u62ec\uff1a\u95ee\u9898\u80fd\u5426\u5206\u89e3\u3001\u5b50\u95ee\u9898\u662f\u5426\u72ec\u7acb\u3001\u5b50\u95ee\u9898\u80fd\u5426\u5408\u5e76\u3002
    • \u5f52\u5e76\u6392\u5e8f\u662f\u5206\u6cbb\u7b56\u7565\u7684\u5178\u578b\u5e94\u7528\uff0c\u5176\u9012\u5f52\u5730\u5c06\u6570\u7ec4\u5212\u5206\u4e3a\u7b49\u957f\u7684\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u76f4\u5230\u53ea\u5269\u4e00\u4e2a\u5143\u7d20\u65f6\u5f00\u59cb\u9010\u5c42\u5408\u5e76\uff0c\u4ece\u800c\u5b8c\u6210\u6392\u5e8f\u3002
    • \u5f15\u5165\u5206\u6cbb\u7b56\u7565\u5f80\u5f80\u53ef\u4ee5\u63d0\u5347\u7b97\u6cd5\u6548\u7387\u3002\u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u7b56\u7565\u51cf\u5c11\u4e86\u64cd\u4f5c\u6570\u91cf\uff1b\u53e6\u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u540e\u6709\u5229\u4e8e\u7cfb\u7edf\u7684\u5e76\u884c\u4f18\u5316\u3002
    • \u5206\u6cbb\u65e2\u53ef\u4ee5\u89e3\u51b3\u8bb8\u591a\u7b97\u6cd5\u95ee\u9898\uff0c\u4e5f\u5e7f\u6cdb\u5e94\u7528\u4e8e\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u8bbe\u8ba1\u4e2d\uff0c\u5904\u5904\u53ef\u89c1\u5176\u8eab\u5f71\u3002
    • \u76f8\u8f83\u4e8e\u66b4\u529b\u641c\u7d22\uff0c\u81ea\u9002\u5e94\u641c\u7d22\u6548\u7387\u66f4\u9ad8\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u7684\u641c\u7d22\u7b97\u6cd5\u901a\u5e38\u662f\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u5b9e\u73b0\u7684\u3002
    • \u4e8c\u5206\u67e5\u627e\u662f\u5206\u6cbb\u7b56\u7565\u7684\u53e6\u4e00\u4e2a\u5178\u578b\u5e94\u7528\uff0c\u5b83\u4e0d\u5305\u542b\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u8fdb\u884c\u5408\u5e76\u7684\u6b65\u9aa4\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u9012\u5f52\u5206\u6cbb\u5b9e\u73b0\u4e8c\u5206\u67e5\u627e\u3002
    • \u5728\u6784\u5efa\u4e8c\u53c9\u6811\u7684\u95ee\u9898\u4e2d\uff0c\u6784\u5efa\u6811\uff08\u539f\u95ee\u9898\uff09\u53ef\u4ee5\u5212\u5206\u4e3a\u6784\u5efa\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\uff08\u5b50\u95ee\u9898\uff09\uff0c\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5212\u5206\u524d\u5e8f\u904d\u5386\u548c\u4e2d\u5e8f\u904d\u5386\u7684\u7d22\u5f15\u533a\u95f4\u6765\u5b9e\u73b0\u3002
    • \u5728\u6c49\u8bfa\u5854\u95ee\u9898\u4e2d\uff0c\u4e00\u4e2a\u89c4\u6a21\u4e3a \\(n\\) \u7684\u95ee\u9898\u53ef\u4ee5\u5212\u5206\u4e3a\u4e24\u4e2a\u89c4\u6a21\u4e3a \\(n-1\\) \u7684\u5b50\u95ee\u9898\u548c\u4e00\u4e2a\u89c4\u6a21\u4e3a \\(1\\) \u7684\u5b50\u95ee\u9898\u3002\u6309\u987a\u5e8f\u89e3\u51b3\u8fd9\u4e09\u4e2a\u5b50\u95ee\u9898\u540e\uff0c\u539f\u95ee\u9898\u968f\u4e4b\u5f97\u5230\u89e3\u51b3\u3002
    "},{"location":"chapter_dynamic_programming/","title":"\u7b2c 14 \u7ae0 \u00a0 \u52a8\u6001\u89c4\u5212","text":"

    Abstract

    \u5c0f\u6eaa\u6c47\u5165\u6cb3\u6d41\uff0c\u6c5f\u6cb3\u6c47\u5165\u5927\u6d77\u3002

    \u52a8\u6001\u89c4\u5212\u5c06\u5c0f\u95ee\u9898\u7684\u89e3\u6c47\u96c6\u6210\u5927\u95ee\u9898\u7684\u7b54\u6848\uff0c\u4e00\u6b65\u6b65\u5f15\u9886\u6211\u4eec\u8d70\u5411\u89e3\u51b3\u95ee\u9898\u7684\u5f7c\u5cb8\u3002

    "},{"location":"chapter_dynamic_programming/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 14.1 \u00a0 \u521d\u63a2\u52a8\u6001\u89c4\u5212
    • 14.2 \u00a0 DP \u95ee\u9898\u7279\u6027
    • 14.3 \u00a0 DP \u89e3\u9898\u601d\u8def
    • 14.4 \u00a0 0-1 \u80cc\u5305\u95ee\u9898
    • 14.5 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898
    • 14.6 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898
    • 14.7 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_dynamic_programming/dp_problem_features/","title":"14.2 \u00a0 \u52a8\u6001\u89c4\u5212\u95ee\u9898\u7279\u6027","text":"

    \u5728\u4e0a\u4e00\u8282\u4e2d\uff0c\u6211\u4eec\u5b66\u4e60\u4e86\u52a8\u6001\u89c4\u5212\u662f\u5982\u4f55\u901a\u8fc7\u5b50\u95ee\u9898\u5206\u89e3\u6765\u6c42\u89e3\u539f\u95ee\u9898\u7684\u3002\u5b9e\u9645\u4e0a\uff0c\u5b50\u95ee\u9898\u5206\u89e3\u662f\u4e00\u79cd\u901a\u7528\u7684\u7b97\u6cd5\u601d\u8def\uff0c\u5728\u5206\u6cbb\u3001\u52a8\u6001\u89c4\u5212\u3001\u56de\u6eaf\u4e2d\u7684\u4fa7\u91cd\u70b9\u4e0d\u540c\u3002

    • \u5206\u6cbb\u7b97\u6cd5\u9012\u5f52\u5730\u5c06\u539f\u95ee\u9898\u5212\u5206\u4e3a\u591a\u4e2a\u76f8\u4e92\u72ec\u7acb\u7684\u5b50\u95ee\u9898\uff0c\u76f4\u81f3\u6700\u5c0f\u5b50\u95ee\u9898\uff0c\u5e76\u5728\u56de\u6eaf\u4e2d\u5408\u5e76\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u6700\u7ec8\u5f97\u5230\u539f\u95ee\u9898\u7684\u89e3\u3002
    • \u52a8\u6001\u89c4\u5212\u4e5f\u5bf9\u95ee\u9898\u8fdb\u884c\u9012\u5f52\u5206\u89e3\uff0c\u4f46\u4e0e\u5206\u6cbb\u7b97\u6cd5\u7684\u4e3b\u8981\u533a\u522b\u662f\uff0c\u52a8\u6001\u89c4\u5212\u4e2d\u7684\u5b50\u95ee\u9898\u662f\u76f8\u4e92\u4f9d\u8d56\u7684\uff0c\u5728\u5206\u89e3\u8fc7\u7a0b\u4e2d\u4f1a\u51fa\u73b0\u8bb8\u591a\u91cd\u53e0\u5b50\u95ee\u9898\u3002
    • \u56de\u6eaf\u7b97\u6cd5\u5728\u5c1d\u8bd5\u548c\u56de\u9000\u4e2d\u7a77\u4e3e\u6240\u6709\u53ef\u80fd\u7684\u89e3\uff0c\u5e76\u901a\u8fc7\u526a\u679d\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u641c\u7d22\u5206\u652f\u3002\u539f\u95ee\u9898\u7684\u89e3\u7531\u4e00\u7cfb\u5217\u51b3\u7b56\u6b65\u9aa4\u6784\u6210\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6bcf\u4e2a\u51b3\u7b56\u6b65\u9aa4\u4e4b\u524d\u7684\u5b50\u5e8f\u5217\u770b\u4f5c\u4e00\u4e2a\u5b50\u95ee\u9898\u3002

    \u5b9e\u9645\u4e0a\uff0c\u52a8\u6001\u89c4\u5212\u5e38\u7528\u6765\u6c42\u89e3\u6700\u4f18\u5316\u95ee\u9898\uff0c\u5b83\u4eec\u4e0d\u4ec5\u5305\u542b\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u8fd8\u5177\u6709\u53e6\u5916\u4e24\u5927\u7279\u6027\uff1a\u6700\u4f18\u5b50\u7ed3\u6784\u3001\u65e0\u540e\u6548\u6027\u3002

    "},{"location":"chapter_dynamic_programming/dp_problem_features/#1421","title":"14.2.1 \u00a0 \u6700\u4f18\u5b50\u7ed3\u6784","text":"

    \u6211\u4eec\u5bf9\u722c\u697c\u68af\u95ee\u9898\u7a0d\u4f5c\u6539\u52a8\uff0c\u4f7f\u4e4b\u66f4\u52a0\u9002\u5408\u5c55\u793a\u6700\u4f18\u5b50\u7ed3\u6784\u6982\u5ff5\u3002

    \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7

    \u7ed9\u5b9a\u4e00\u4e2a\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\uff0c\u6bcf\u4e00\u9636\u697c\u68af\u4e0a\u90fd\u8d34\u6709\u4e00\u4e2a\u975e\u8d1f\u6574\u6570\uff0c\u8868\u793a\u4f60\u5728\u8be5\u53f0\u9636\u6240\u9700\u8981\u4ed8\u51fa\u7684\u4ee3\u4ef7\u3002\u7ed9\u5b9a\u4e00\u4e2a\u975e\u8d1f\u6574\u6570\u6570\u7ec4 \\(cost\\) \uff0c\u5176\u4e2d \\(cost[i]\\) \u8868\u793a\u5728\u7b2c \\(i\\) \u4e2a\u53f0\u9636\u9700\u8981\u4ed8\u51fa\u7684\u4ee3\u4ef7\uff0c\\(cost[0]\\) \u4e3a\u5730\u9762\uff08\u8d77\u59cb\u70b9\uff09\u3002\u8bf7\u8ba1\u7b97\u6700\u5c11\u9700\u8981\u4ed8\u51fa\u591a\u5c11\u4ee3\u4ef7\u624d\u80fd\u5230\u8fbe\u9876\u90e8\uff1f

    \u5982\u56fe 14-6 \u6240\u793a\uff0c\u82e5\u7b2c \\(1\\)\u3001\\(2\\)\u3001\\(3\\) \u9636\u7684\u4ee3\u4ef7\u5206\u522b\u4e3a \\(1\\)\u3001\\(10\\)\u3001\\(1\\) \uff0c\u5219\u4ece\u5730\u9762\u722c\u5230\u7b2c \\(3\\) \u9636\u7684\u6700\u5c0f\u4ee3\u4ef7\u4e3a \\(2\\) \u3002

    \u56fe 14-6 \u00a0 \u722c\u5230\u7b2c 3 \u9636\u7684\u6700\u5c0f\u4ee3\u4ef7

    \u8bbe \\(dp[i]\\) \u4e3a\u722c\u5230\u7b2c \\(i\\) \u9636\u7d2f\u8ba1\u4ed8\u51fa\u7684\u4ee3\u4ef7\uff0c\u7531\u4e8e\u7b2c \\(i\\) \u9636\u53ea\u53ef\u80fd\u4ece \\(i - 1\\) \u9636\u6216 \\(i - 2\\) \u9636\u8d70\u6765\uff0c\u56e0\u6b64 \\(dp[i]\\) \u53ea\u53ef\u80fd\u7b49\u4e8e \\(dp[i - 1] + cost[i]\\) \u6216 \\(dp[i - 2] + cost[i]\\) \u3002\u4e3a\u4e86\u5c3d\u53ef\u80fd\u51cf\u5c11\u4ee3\u4ef7\uff0c\u6211\u4eec\u5e94\u8be5\u9009\u62e9\u4e24\u8005\u4e2d\u8f83\u5c0f\u7684\u90a3\u4e00\u4e2a\uff1a

    \\[ dp[i] = \\min(dp[i-1], dp[i-2]) + cost[i] \\]

    \u8fd9\u4fbf\u53ef\u4ee5\u5f15\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\u7684\u542b\u4e49\uff1a\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u662f\u4ece\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u6784\u5efa\u5f97\u6765\u7684\u3002

    \u672c\u9898\u663e\u7136\u5177\u6709\u6700\u4f18\u5b50\u7ed3\u6784\uff1a\u6211\u4eec\u4ece\u4e24\u4e2a\u5b50\u95ee\u9898\u6700\u4f18\u89e3 \\(dp[i-1]\\) \u548c \\(dp[i-2]\\) \u4e2d\u6311\u9009\u51fa\u8f83\u4f18\u7684\u90a3\u4e00\u4e2a\uff0c\u5e76\u7528\u5b83\u6784\u5efa\u51fa\u539f\u95ee\u9898 \\(dp[i]\\) \u7684\u6700\u4f18\u89e3\u3002

    \u90a3\u4e48\uff0c\u4e0a\u4e00\u8282\u7684\u722c\u697c\u68af\u9898\u76ee\u6709\u6ca1\u6709\u6700\u4f18\u5b50\u7ed3\u6784\u5462\uff1f\u5b83\u7684\u76ee\u6807\u662f\u6c42\u89e3\u65b9\u6848\u6570\u91cf\uff0c\u770b\u4f3c\u662f\u4e00\u4e2a\u8ba1\u6570\u95ee\u9898\uff0c\u4f46\u5982\u679c\u6362\u4e00\u79cd\u95ee\u6cd5\uff1a\u201c\u6c42\u89e3\u6700\u5927\u65b9\u6848\u6570\u91cf\u201d\u3002\u6211\u4eec\u610f\u5916\u5730\u53d1\u73b0\uff0c\u867d\u7136\u9898\u76ee\u4fee\u6539\u524d\u540e\u662f\u7b49\u4ef7\u7684\uff0c\u4f46\u6700\u4f18\u5b50\u7ed3\u6784\u6d6e\u73b0\u51fa\u6765\u4e86\uff1a\u7b2c \\(n\\) \u9636\u6700\u5927\u65b9\u6848\u6570\u91cf\u7b49\u4e8e\u7b2c \\(n-1\\) \u9636\u548c\u7b2c \\(n-2\\) \u9636\u6700\u5927\u65b9\u6848\u6570\u91cf\u4e4b\u548c\u3002\u6240\u4ee5\u8bf4\uff0c\u6700\u4f18\u5b50\u7ed3\u6784\u7684\u89e3\u91ca\u65b9\u5f0f\u6bd4\u8f83\u7075\u6d3b\uff0c\u5728\u4e0d\u540c\u95ee\u9898\u4e2d\u4f1a\u6709\u4e0d\u540c\u7684\u542b\u4e49\u3002

    \u6839\u636e\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff0c\u4ee5\u53ca\u521d\u59cb\u72b6\u6001 \\(dp[1] = cost[1]\\) \u548c \\(dp[2] = cost[2]\\) \uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5f97\u5230\u52a8\u6001\u89c4\u5212\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp(cost: list[int]) -> int:\n    \"\"\"\u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(cost) - 1\n    if n == 1 or n == 2:\n        return cost[n]\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [0] * (n + 1)\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1], dp[2] = cost[1], cost[2]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    return dp[n]\n
    min_cost_climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(vector<int> &cost) {\n    int n = cost.size() - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<int> dp(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.java
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(int[] cost) {\n    int n = cost.length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint MinCostClimbingStairsDP(int[] cost) {\n    int n = cost.Length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = Math.Min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.go
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDP(cost []int) int {\n    n := len(cost) - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    min := func(a, b int) int {\n        if a < b {\n            return a\n        }\n        return b\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i] = min(dp[i-1], dp[i-2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDP(cost: [Int]) -> Int {\n    let n = cost.count - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: 0, count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.js
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDP(cost) {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDP(cost: Array<number>): number {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(List<int> cost) {\n  int n = cost.length - 1;\n  if (n == 1 || n == 2) return cost[n];\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<int> dp = List.filled(n + 1, 0);\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1] = cost[1];\n  dp[2] = cost[2];\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];\n  }\n  return dp[n];\n}\n
    min_cost_climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfn min_cost_climbing_stairs_dp(cost: &[i32]) -> i32 {\n    let n = cost.len() - 1;\n    if n == 1 || n == 2 {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![-1; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i] = cmp::min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    dp[n]\n}\n
    min_cost_climbing_stairs_dp.c
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(int cost[], int costSize) {\n    int n = costSize - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int *dp = calloc(n + 1, sizeof(int));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = myMin(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    int res = dp[n];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    min_cost_climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfun minCostClimbingStairsDP(cost: IntArray): Int {\n    val n = cost.size - 1\n    if (n == 1 || n == 2) return cost[n]\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = IntArray(n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp}\n
    min_cost_climbing_stairs_dp.zig
    // \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212\nfn minCostClimbingStairsDP(comptime cost: []i32) i32 {\n    comptime var n = cost.len - 1;\n    if (n == 1 or n == 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_]i32{-1} ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i] = @min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-7 \u5c55\u793a\u4e86\u4ee5\u4e0a\u4ee3\u7801\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b\u3002

    \u56fe 14-7 \u00a0 \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u672c\u9898\u4e5f\u53ef\u4ee5\u8fdb\u884c\u7a7a\u95f4\u4f18\u5316\uff0c\u5c06\u4e00\u7ef4\u538b\u7f29\u81f3\u96f6\u7ef4\uff0c\u4f7f\u5f97\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n)\\) \u964d\u81f3 \\(O(1)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp_comp(cost: list[int]) -> int:\n    \"\"\"\u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(cost) - 1\n    if n == 1 or n == 2:\n        return cost[n]\n    a, b = cost[1], cost[2]\n    for i in range(3, n + 1):\n        a, b = b, min(a, b) + cost[i]\n    return b\n
    min_cost_climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(vector<int> &cost) {\n    int n = cost.size() - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.java
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(int[] cost) {\n    int n = cost.length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint MinCostClimbingStairsDPComp(int[] cost) {\n    int n = cost.Length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = Math.Min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.go
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDPComp(cost []int) int {\n    n := len(cost) - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    min := func(a, b int) int {\n        if a < b {\n            return a\n        }\n        return b\n    }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    a, b := cost[1], cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        tmp := b\n        b = min(a, tmp) + cost[i]\n        a = tmp\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDPComp(cost: [Int]) -> Int {\n    let n = cost.count - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    var (a, b) = (cost[1], cost[2])\n    for i in 3 ... n {\n        (a, b) = (b, min(a, b) + cost[i])\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.js
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDPComp(cost) {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    let a = cost[1],\n        b = cost[2];\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDPComp(cost: Array<number>): number {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    let a = cost[1],\n        b = cost[2];\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(List<int> cost) {\n  int n = cost.length - 1;\n  if (n == 1 || n == 2) return cost[n];\n  int a = cost[1], b = cost[2];\n  for (int i = 3; i <= n; i++) {\n    int tmp = b;\n    b = min(a, tmp) + cost[i];\n    a = tmp;\n  }\n  return b;\n}\n
    min_cost_climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn min_cost_climbing_stairs_dp_comp(cost: &[i32]) -> i32 {\n    let n = cost.len() - 1;\n    if n == 1 || n == 2 {\n        return cost[n];\n    };\n    let (mut a, mut b) = (cost[1], cost[2]);\n    for i in 3..=n {\n        let tmp = b;\n        b = cmp::min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    b\n}\n
    min_cost_climbing_stairs_dp.c
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(int cost[], int costSize) {\n    int n = costSize - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = myMin(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun minCostClimbingStairsDPComp(cost: IntArray): Int {\n    val n = cost.size - 1\n    if (n == 1 || n == 2) return cost[n]\n    var a = cost[1]\n    var b = cost[2]\n    for (i in 3..n) {\n        val tmp = b\n        b = min(a, tmp) + cost[i]\n        a = tmp\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp_comp}\n
    min_cost_climbing_stairs_dp.zig
    // \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn minCostClimbingStairsDPComp(cost: []i32) i32 {\n    var n = cost.len - 1;\n    if (n == 1 or n == 2) {\n        return cost[n];\n    }\n    var a = cost[1];\n    var b = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        var tmp = b;\n        b = @min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/dp_problem_features/#1422","title":"14.2.2 \u00a0 \u65e0\u540e\u6548\u6027","text":"

    \u65e0\u540e\u6548\u6027\u662f\u52a8\u6001\u89c4\u5212\u80fd\u591f\u6709\u6548\u89e3\u51b3\u95ee\u9898\u7684\u91cd\u8981\u7279\u6027\u4e4b\u4e00\uff0c\u5176\u5b9a\u4e49\u4e3a\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u786e\u5b9a\u7684\u72b6\u6001\uff0c\u5b83\u7684\u672a\u6765\u53d1\u5c55\u53ea\u4e0e\u5f53\u524d\u72b6\u6001\u6709\u5173\uff0c\u800c\u4e0e\u8fc7\u53bb\u7ecf\u5386\u7684\u6240\u6709\u72b6\u6001\u65e0\u5173\u3002

    \u4ee5\u722c\u697c\u68af\u95ee\u9898\u4e3a\u4f8b\uff0c\u7ed9\u5b9a\u72b6\u6001 \\(i\\) \uff0c\u5b83\u4f1a\u53d1\u5c55\u51fa\u72b6\u6001 \\(i+1\\) \u548c\u72b6\u6001 \\(i+2\\) \uff0c\u5206\u522b\u5bf9\u5e94\u8df3 \\(1\\) \u6b65\u548c\u8df3 \\(2\\) \u6b65\u3002\u5728\u505a\u51fa\u8fd9\u4e24\u79cd\u9009\u62e9\u65f6\uff0c\u6211\u4eec\u65e0\u987b\u8003\u8651\u72b6\u6001 \\(i\\) \u4e4b\u524d\u7684\u72b6\u6001\uff0c\u5b83\u4eec\u5bf9\u72b6\u6001 \\(i\\) \u7684\u672a\u6765\u6ca1\u6709\u5f71\u54cd\u3002

    \u7136\u800c\uff0c\u5982\u679c\u6211\u4eec\u7ed9\u722c\u697c\u68af\u95ee\u9898\u6dfb\u52a0\u4e00\u4e2a\u7ea6\u675f\uff0c\u60c5\u51b5\u5c31\u4e0d\u4e00\u6837\u4e86\u3002

    \u5e26\u7ea6\u675f\u722c\u697c\u68af

    \u7ed9\u5b9a\u4e00\u4e2a\u5171\u6709 \\(n\\) \u9636\u7684\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\uff0c\u4f46\u4e0d\u80fd\u8fde\u7eed\u4e24\u8f6e\u8df3 \\(1\\) \u9636\uff0c\u8bf7\u95ee\u6709\u591a\u5c11\u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\uff1f

    \u5982\u56fe 14-8 \u6240\u793a\uff0c\u722c\u4e0a\u7b2c \\(3\\) \u9636\u4ec5\u5269 \\(2\\) \u79cd\u53ef\u884c\u65b9\u6848\uff0c\u5176\u4e2d\u8fde\u7eed\u4e09\u6b21\u8df3 \\(1\\) \u9636\u7684\u65b9\u6848\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\uff0c\u56e0\u6b64\u88ab\u820d\u5f03\u3002

    \u56fe 14-8 \u00a0 \u5e26\u7ea6\u675f\u722c\u5230\u7b2c 3 \u9636\u7684\u65b9\u6848\u6570\u91cf

    \u5728\u8be5\u95ee\u9898\u4e2d\uff0c\u5982\u679c\u4e0a\u4e00\u8f6e\u662f\u8df3 \\(1\\) \u9636\u4e0a\u6765\u7684\uff0c\u90a3\u4e48\u4e0b\u4e00\u8f6e\u5c31\u5fc5\u987b\u8df3 \\(2\\) \u9636\u3002\u8fd9\u610f\u5473\u7740\uff0c\u4e0b\u4e00\u6b65\u9009\u62e9\u4e0d\u80fd\u7531\u5f53\u524d\u72b6\u6001\uff08\u5f53\u524d\u6240\u5728\u697c\u68af\u9636\u6570\uff09\u72ec\u7acb\u51b3\u5b9a\uff0c\u8fd8\u548c\u524d\u4e00\u4e2a\u72b6\u6001\uff08\u4e0a\u4e00\u8f6e\u6240\u5728\u697c\u68af\u9636\u6570\uff09\u6709\u5173\u3002

    \u4e0d\u96be\u53d1\u73b0\uff0c\u6b64\u95ee\u9898\u5df2\u4e0d\u6ee1\u8db3\u65e0\u540e\u6548\u6027\uff0c\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b \\(dp[i] = dp[i-1] + dp[i-2]\\) \u4e5f\u5931\u6548\u4e86\uff0c\u56e0\u4e3a \\(dp[i-1]\\) \u4ee3\u8868\u672c\u8f6e\u8df3 \\(1\\) \u9636\uff0c\u4f46\u5176\u4e2d\u5305\u542b\u4e86\u8bb8\u591a\u201c\u4e0a\u4e00\u8f6e\u662f\u8df3 \\(1\\) \u9636\u4e0a\u6765\u7684\u201d\u65b9\u6848\uff0c\u800c\u4e3a\u4e86\u6ee1\u8db3\u7ea6\u675f\uff0c\u6211\u4eec\u5c31\u4e0d\u80fd\u5c06 \\(dp[i-1]\\) \u76f4\u63a5\u8ba1\u5165 \\(dp[i]\\) \u4e2d\u3002

    \u4e3a\u6b64\uff0c\u6211\u4eec\u9700\u8981\u6269\u5c55\u72b6\u6001\u5b9a\u4e49\uff1a\u72b6\u6001 \\([i, j]\\) \u8868\u793a\u5904\u5728\u7b2c \\(i\\) \u9636\u5e76\u4e14\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(j\\) \u9636\uff0c\u5176\u4e2d \\(j \\in \\{1, 2\\}\\) \u3002\u6b64\u72b6\u6001\u5b9a\u4e49\u6709\u6548\u5730\u533a\u5206\u4e86\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(1\\) \u9636\u8fd8\u662f \\(2\\) \u9636\uff0c\u6211\u4eec\u53ef\u4ee5\u636e\u6b64\u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u4ece\u4f55\u800c\u6765\u7684\u3002

    • \u5f53\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(1\\) \u9636\u65f6\uff0c\u4e0a\u4e0a\u4e00\u8f6e\u53ea\u80fd\u9009\u62e9\u8df3 \\(2\\) \u9636\uff0c\u5373 \\(dp[i, 1]\\) \u53ea\u80fd\u4ece \\(dp[i-1, 2]\\) \u8f6c\u79fb\u8fc7\u6765\u3002
    • \u5f53\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(2\\) \u9636\u65f6\uff0c\u4e0a\u4e0a\u4e00\u8f6e\u53ef\u9009\u62e9\u8df3 \\(1\\) \u9636\u6216\u8df3 \\(2\\) \u9636\uff0c\u5373 \\(dp[i, 2]\\) \u53ef\u4ee5\u4ece \\(dp[i-2, 1]\\) \u6216 \\(dp[i-2, 2]\\) \u8f6c\u79fb\u8fc7\u6765\u3002

    \u5982\u56fe 14-9 \u6240\u793a\uff0c\u5728\u8be5\u5b9a\u4e49\u4e0b\uff0c\\(dp[i, j]\\) \u8868\u793a\u72b6\u6001 \\([i, j]\\) \u5bf9\u5e94\u7684\u65b9\u6848\u6570\u3002\u6b64\u65f6\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ \\begin{cases} dp[i, 1] = dp[i-1, 2] \\\\ dp[i, 2] = dp[i-2, 1] + dp[i-2, 2] \\end{cases} \\]

    \u56fe 14-9 \u00a0 \u8003\u8651\u7ea6\u675f\u4e0b\u7684\u9012\u63a8\u5173\u7cfb

    \u6700\u7ec8\uff0c\u8fd4\u56de \\(dp[n, 1] + dp[n, 2]\\) \u5373\u53ef\uff0c\u4e24\u8005\u4e4b\u548c\u4ee3\u8868\u722c\u5230\u7b2c \\(n\\) \u9636\u7684\u65b9\u6848\u603b\u6570\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_constraint_dp.py
    def climbing_stairs_constraint_dp(n: int) -> int:\n    \"\"\"\u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return 1\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [[0] * 3 for _ in range(n + 1)]\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1], dp[1][2] = 1, 0\n    dp[2][1], dp[2][2] = 0, 1\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    return dp[n][1] + dp[n][2]\n
    climbing_stairs_constraint_dp.cpp
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<vector<int>> dp(n + 1, vector<int>(3, 0));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.java
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[][] dp = new int[n + 1][3];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.cs
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[,] dp = new int[n + 1, 3];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1, 1] = 1;\n    dp[1, 2] = 0;\n    dp[2, 1] = 0;\n    dp[2, 2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i, 1] = dp[i - 1, 2];\n        dp[i, 2] = dp[i - 2, 1] + dp[i - 2, 2];\n    }\n    return dp[n, 1] + dp[n, 2];\n}\n
    climbing_stairs_constraint_dp.go
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsConstraintDP(n int) int {\n    if n == 1 || n == 2 {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([][3]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i][1] = dp[i-1][2]\n        dp[i][2] = dp[i-2][1] + dp[i-2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.swift
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsConstraintDP(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: Array(repeating: 0, count: 3), count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.js
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsConstraintDP(n) {\n    if (n === 1 || n === 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = Array.from(new Array(n + 1), () => new Array(3));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.ts
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsConstraintDP(n: number): number {\n    if (n === 1 || n === 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = Array.from({ length: n + 1 }, () => new Array(3));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.dart
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n  if (n == 1 || n == 2) {\n    return 1;\n  }\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(3, 0));\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1][1] = 1;\n  dp[1][2] = 0;\n  dp[2][1] = 0;\n  dp[2][2] = 1;\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i][1] = dp[i - 1][2];\n    dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n  }\n  return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.rs
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_constraint_dp(n: usize) -> i32 {\n    if n == 1 || n == 2 {\n        return 1;\n    };\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![vec![-1; 3]; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.c
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(3, sizeof(int));\n    }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    int res = dp[n][1] + dp[n][2];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    climbing_stairs_constraint_dp.kt
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsConstraintDP(n: Int): Int {\n    if (n == 1 || n == 2) {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = Array(n + 1) { IntArray(3) }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.rb
    [class]{}-[func]{climbing_stairs_constraint_dp}\n
    climbing_stairs_constraint_dp.zig
    // \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\nfn climbingStairsConstraintDP(comptime n: usize) i32 {\n    if (n == 1 or n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_][3]i32{ [_]i32{ -1, -1, -1 } } ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5728\u4e0a\u9762\u7684\u6848\u4f8b\u4e2d\uff0c\u7531\u4e8e\u4ec5\u9700\u591a\u8003\u8651\u524d\u9762\u4e00\u4e2a\u72b6\u6001\uff0c\u56e0\u6b64\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u901a\u8fc7\u6269\u5c55\u72b6\u6001\u5b9a\u4e49\uff0c\u4f7f\u5f97\u95ee\u9898\u91cd\u65b0\u6ee1\u8db3\u65e0\u540e\u6548\u6027\u3002\u7136\u800c\uff0c\u67d0\u4e9b\u95ee\u9898\u5177\u6709\u975e\u5e38\u4e25\u91cd\u7684\u201c\u6709\u540e\u6548\u6027\u201d\u3002

    \u722c\u697c\u68af\u4e0e\u969c\u788d\u751f\u6210

    \u7ed9\u5b9a\u4e00\u4e2a\u5171\u6709 \\(n\\) \u9636\u7684\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\u3002\u89c4\u5b9a\u5f53\u722c\u5230\u7b2c \\(i\\) \u9636\u65f6\uff0c\u7cfb\u7edf\u81ea\u52a8\u4f1a\u5728\u7b2c \\(2i\\) \u9636\u4e0a\u653e\u4e0a\u969c\u788d\u7269\uff0c\u4e4b\u540e\u6240\u6709\u8f6e\u90fd\u4e0d\u5141\u8bb8\u8df3\u5230\u7b2c \\(2i\\) \u9636\u4e0a\u3002\u4f8b\u5982\uff0c\u524d\u4e24\u8f6e\u5206\u522b\u8df3\u5230\u4e86\u7b2c \\(2\\)\u3001\\(3\\) \u9636\u4e0a\uff0c\u5219\u4e4b\u540e\u5c31\u4e0d\u80fd\u8df3\u5230\u7b2c \\(4\\)\u3001\\(6\\) \u9636\u4e0a\u3002\u8bf7\u95ee\u6709\u591a\u5c11\u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\uff1f

    \u5728\u8fd9\u4e2a\u95ee\u9898\u4e2d\uff0c\u4e0b\u6b21\u8df3\u8dc3\u4f9d\u8d56\u8fc7\u53bb\u6240\u6709\u7684\u72b6\u6001\uff0c\u56e0\u4e3a\u6bcf\u4e00\u6b21\u8df3\u8dc3\u90fd\u4f1a\u5728\u66f4\u9ad8\u7684\u9636\u68af\u4e0a\u8bbe\u7f6e\u969c\u788d\uff0c\u5e76\u5f71\u54cd\u672a\u6765\u7684\u8df3\u8dc3\u3002\u5bf9\u4e8e\u8fd9\u7c7b\u95ee\u9898\uff0c\u52a8\u6001\u89c4\u5212\u5f80\u5f80\u96be\u4ee5\u89e3\u51b3\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u590d\u6742\u7684\u7ec4\u5408\u4f18\u5316\u95ee\u9898\uff08\u4f8b\u5982\u65c5\u884c\u5546\u95ee\u9898\uff09\u4e0d\u6ee1\u8db3\u65e0\u540e\u6548\u6027\u3002\u5bf9\u4e8e\u8fd9\u7c7b\u95ee\u9898\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u9009\u62e9\u4f7f\u7528\u5176\u4ed6\u65b9\u6cd5\uff0c\u4f8b\u5982\u542f\u53d1\u5f0f\u641c\u7d22\u3001\u9057\u4f20\u7b97\u6cd5\u3001\u5f3a\u5316\u5b66\u4e60\u7b49\uff0c\u4ece\u800c\u5728\u6709\u9650\u65f6\u95f4\u5185\u5f97\u5230\u53ef\u7528\u7684\u5c40\u90e8\u6700\u4f18\u89e3\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/","title":"14.3 \u00a0 \u52a8\u6001\u89c4\u5212\u89e3\u9898\u601d\u8def","text":"

    \u4e0a\u4e24\u8282\u4ecb\u7ecd\u4e86\u52a8\u6001\u89c4\u5212\u95ee\u9898\u7684\u4e3b\u8981\u7279\u5f81\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u4e00\u8d77\u63a2\u7a76\u4e24\u4e2a\u66f4\u52a0\u5b9e\u7528\u7684\u95ee\u9898\u3002

    1. \u5982\u4f55\u5224\u65ad\u4e00\u4e2a\u95ee\u9898\u662f\u4e0d\u662f\u52a8\u6001\u89c4\u5212\u95ee\u9898\uff1f
    2. \u6c42\u89e3\u52a8\u6001\u89c4\u5212\u95ee\u9898\u8be5\u4ece\u4f55\u5904\u5165\u624b\uff0c\u5b8c\u6574\u6b65\u9aa4\u662f\u4ec0\u4e48\uff1f
    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1431","title":"14.3.1 \u00a0 \u95ee\u9898\u5224\u65ad","text":"

    \u603b\u7684\u6765\u8bf4\uff0c\u5982\u679c\u4e00\u4e2a\u95ee\u9898\u5305\u542b\u91cd\u53e0\u5b50\u95ee\u9898\u3001\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u5e76\u6ee1\u8db3\u65e0\u540e\u6548\u6027\uff0c\u90a3\u4e48\u5b83\u901a\u5e38\u9002\u5408\u7528\u52a8\u6001\u89c4\u5212\u6c42\u89e3\u3002\u7136\u800c\uff0c\u6211\u4eec\u5f88\u96be\u4ece\u95ee\u9898\u63cf\u8ff0\u4e2d\u76f4\u63a5\u63d0\u53d6\u51fa\u8fd9\u4e9b\u7279\u6027\u3002\u56e0\u6b64\u6211\u4eec\u901a\u5e38\u4f1a\u653e\u5bbd\u6761\u4ef6\uff0c\u5148\u89c2\u5bdf\u95ee\u9898\u662f\u5426\u9002\u5408\u4f7f\u7528\u56de\u6eaf\uff08\u7a77\u4e3e\uff09\u89e3\u51b3\u3002

    \u9002\u5408\u7528\u56de\u6eaf\u89e3\u51b3\u7684\u95ee\u9898\u901a\u5e38\u6ee1\u8db3\u201c\u51b3\u7b56\u6811\u6a21\u578b\u201d\uff0c\u8fd9\u79cd\u95ee\u9898\u53ef\u4ee5\u4f7f\u7528\u6811\u5f62\u7ed3\u6784\u6765\u63cf\u8ff0\uff0c\u5176\u4e2d\u6bcf\u4e00\u4e2a\u8282\u70b9\u4ee3\u8868\u4e00\u4e2a\u51b3\u7b56\uff0c\u6bcf\u4e00\u6761\u8def\u5f84\u4ee3\u8868\u4e00\u4e2a\u51b3\u7b56\u5e8f\u5217\u3002

    \u6362\u53e5\u8bdd\u8bf4\uff0c\u5982\u679c\u95ee\u9898\u5305\u542b\u660e\u786e\u7684\u51b3\u7b56\u6982\u5ff5\uff0c\u5e76\u4e14\u89e3\u662f\u901a\u8fc7\u4e00\u7cfb\u5217\u51b3\u7b56\u4ea7\u751f\u7684\uff0c\u90a3\u4e48\u5b83\u5c31\u6ee1\u8db3\u51b3\u7b56\u6811\u6a21\u578b\uff0c\u901a\u5e38\u53ef\u4ee5\u4f7f\u7528\u56de\u6eaf\u6765\u89e3\u51b3\u3002

    \u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u52a8\u6001\u89c4\u5212\u95ee\u9898\u8fd8\u6709\u4e00\u4e9b\u5224\u65ad\u7684\u201c\u52a0\u5206\u9879\u201d\u3002

    • \u95ee\u9898\u5305\u542b\u6700\u5927\uff08\u5c0f\uff09\u6216\u6700\u591a\uff08\u5c11\uff09\u7b49\u6700\u4f18\u5316\u63cf\u8ff0\u3002
    • \u95ee\u9898\u7684\u72b6\u6001\u80fd\u591f\u4f7f\u7528\u4e00\u4e2a\u5217\u8868\u3001\u591a\u7ef4\u77e9\u9635\u6216\u6811\u6765\u8868\u793a\uff0c\u5e76\u4e14\u4e00\u4e2a\u72b6\u6001\u4e0e\u5176\u5468\u56f4\u7684\u72b6\u6001\u5b58\u5728\u9012\u63a8\u5173\u7cfb\u3002

    \u76f8\u5e94\u5730\uff0c\u4e5f\u5b58\u5728\u4e00\u4e9b\u201c\u51cf\u5206\u9879\u201d\u3002

    • \u95ee\u9898\u7684\u76ee\u6807\u662f\u627e\u51fa\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u800c\u4e0d\u662f\u627e\u51fa\u6700\u4f18\u89e3\u3002
    • \u95ee\u9898\u63cf\u8ff0\u4e2d\u6709\u660e\u663e\u7684\u6392\u5217\u7ec4\u5408\u7684\u7279\u5f81\uff0c\u9700\u8981\u8fd4\u56de\u5177\u4f53\u7684\u591a\u4e2a\u65b9\u6848\u3002

    \u5982\u679c\u4e00\u4e2a\u95ee\u9898\u6ee1\u8db3\u51b3\u7b56\u6811\u6a21\u578b\uff0c\u5e76\u5177\u6709\u8f83\u4e3a\u660e\u663e\u7684\u201c\u52a0\u5206\u9879\u201d\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5047\u8bbe\u5b83\u662f\u4e00\u4e2a\u52a8\u6001\u89c4\u5212\u95ee\u9898\uff0c\u5e76\u5728\u6c42\u89e3\u8fc7\u7a0b\u4e2d\u9a8c\u8bc1\u5b83\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1432","title":"14.3.2 \u00a0 \u95ee\u9898\u6c42\u89e3\u6b65\u9aa4","text":"

    \u52a8\u6001\u89c4\u5212\u7684\u89e3\u9898\u6d41\u7a0b\u4f1a\u56e0\u95ee\u9898\u7684\u6027\u8d28\u548c\u96be\u5ea6\u800c\u6709\u6240\u4e0d\u540c\uff0c\u4f46\u901a\u5e38\u9075\u5faa\u4ee5\u4e0b\u6b65\u9aa4\uff1a\u63cf\u8ff0\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u5efa\u7acb \\(dp\\) \u8868\uff0c\u63a8\u5bfc\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff0c\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u7b49\u3002

    \u4e3a\u4e86\u66f4\u5f62\u8c61\u5730\u5c55\u793a\u89e3\u9898\u6b65\u9aa4\uff0c\u6211\u4eec\u4f7f\u7528\u4e00\u4e2a\u7ecf\u5178\u95ee\u9898\u201c\u6700\u5c0f\u8def\u5f84\u548c\u201d\u6765\u4e3e\u4f8b\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a \\(n \\times m\\) \u7684\u4e8c\u7ef4\u7f51\u683c grid \uff0c\u7f51\u683c\u4e2d\u7684\u6bcf\u4e2a\u5355\u5143\u683c\u5305\u542b\u4e00\u4e2a\u975e\u8d1f\u6574\u6570\uff0c\u8868\u793a\u8be5\u5355\u5143\u683c\u7684\u4ee3\u4ef7\u3002\u673a\u5668\u4eba\u4ee5\u5de6\u4e0a\u89d2\u5355\u5143\u683c\u4e3a\u8d77\u59cb\u70b9\uff0c\u6bcf\u6b21\u53ea\u80fd\u5411\u4e0b\u6216\u8005\u5411\u53f3\u79fb\u52a8\u4e00\u6b65\uff0c\u76f4\u81f3\u5230\u8fbe\u53f3\u4e0b\u89d2\u5355\u5143\u683c\u3002\u8bf7\u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230\u53f3\u4e0b\u89d2\u7684\u6700\u5c0f\u8def\u5f84\u548c\u3002

    \u56fe 14-10 \u5c55\u793a\u4e86\u4e00\u4e2a\u4f8b\u5b50\uff0c\u7ed9\u5b9a\u7f51\u683c\u7684\u6700\u5c0f\u8def\u5f84\u548c\u4e3a \\(13\\) \u3002

    \u56fe 14-10 \u00a0 \u6700\u5c0f\u8def\u5f84\u548c\u793a\u4f8b\u6570\u636e

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u672c\u9898\u7684\u6bcf\u4e00\u8f6e\u7684\u51b3\u7b56\u5c31\u662f\u4ece\u5f53\u524d\u683c\u5b50\u5411\u4e0b\u6216\u5411\u53f3\u8d70\u4e00\u6b65\u3002\u8bbe\u5f53\u524d\u683c\u5b50\u7684\u884c\u5217\u7d22\u5f15\u4e3a \\([i, j]\\) \uff0c\u5219\u5411\u4e0b\u6216\u5411\u53f3\u8d70\u4e00\u6b65\u540e\uff0c\u7d22\u5f15\u53d8\u4e3a \\([i+1, j]\\) \u6216 \\([i, j+1]\\) \u3002\u56e0\u6b64\uff0c\u72b6\u6001\u5e94\u5305\u542b\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u4e24\u4e2a\u53d8\u91cf\uff0c\u8bb0\u4e3a \\([i, j]\\) \u3002

    \u72b6\u6001 \\([i, j]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u4e3a\uff1a\u4ece\u8d77\u59cb\u70b9 \\([0, 0]\\) \u8d70\u5230 \\([i, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\uff0c\u89e3\u8bb0\u4e3a \\(dp[i, j]\\) \u3002

    \u81f3\u6b64\uff0c\u6211\u4eec\u5c31\u5f97\u5230\u4e86\u56fe 14-11 \u6240\u793a\u7684\u4e8c\u7ef4 \\(dp\\) \u77e9\u9635\uff0c\u5176\u5c3a\u5bf8\u4e0e\u8f93\u5165\u7f51\u683c \\(grid\\) \u76f8\u540c\u3002

    \u56fe 14-11 \u00a0 \u72b6\u6001\u5b9a\u4e49\u4e0e dp \u8868

    Note

    \u52a8\u6001\u89c4\u5212\u548c\u56de\u6eaf\u8fc7\u7a0b\u53ef\u4ee5\u63cf\u8ff0\u4e3a\u4e00\u4e2a\u51b3\u7b56\u5e8f\u5217\uff0c\u800c\u72b6\u6001\u7531\u6240\u6709\u51b3\u7b56\u53d8\u91cf\u6784\u6210\u3002\u5b83\u5e94\u5f53\u5305\u542b\u63cf\u8ff0\u89e3\u9898\u8fdb\u5ea6\u7684\u6240\u6709\u53d8\u91cf\uff0c\u5176\u5305\u542b\u4e86\u8db3\u591f\u7684\u4fe1\u606f\uff0c\u80fd\u591f\u7528\u6765\u63a8\u5bfc\u51fa\u4e0b\u4e00\u4e2a\u72b6\u6001\u3002

    \u6bcf\u4e2a\u72b6\u6001\u90fd\u5bf9\u5e94\u4e00\u4e2a\u5b50\u95ee\u9898\uff0c\u6211\u4eec\u4f1a\u5b9a\u4e49\u4e00\u4e2a \\(dp\\) \u8868\u6765\u5b58\u50a8\u6240\u6709\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u72b6\u6001\u7684\u6bcf\u4e2a\u72ec\u7acb\u53d8\u91cf\u90fd\u662f \\(dp\\) \u8868\u7684\u4e00\u4e2a\u7ef4\u5ea6\u3002\u4ece\u672c\u8d28\u4e0a\u770b\uff0c\\(dp\\) \u8868\u662f\u72b6\u6001\u548c\u5b50\u95ee\u9898\u7684\u89e3\u4e4b\u95f4\u7684\u6620\u5c04\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u5bf9\u4e8e\u72b6\u6001 \\([i, j]\\) \uff0c\u5b83\u53ea\u80fd\u4ece\u4e0a\u8fb9\u683c\u5b50 \\([i-1, j]\\) \u548c\u5de6\u8fb9\u683c\u5b50 \\([i, j-1]\\) \u8f6c\u79fb\u800c\u6765\u3002\u56e0\u6b64\u6700\u4f18\u5b50\u7ed3\u6784\u4e3a\uff1a\u5230\u8fbe \\([i, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\u7531 \\([i, j-1]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\u4e0e \\([i-1, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\u4e2d\u8f83\u5c0f\u7684\u90a3\u4e00\u4e2a\u51b3\u5b9a\u3002

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u53ef\u63a8\u51fa\u56fe 14-12 \u6240\u793a\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff1a

    \\[ dp[i, j] = \\min(dp[i-1, j], dp[i, j-1]) + grid[i, j] \\]

    \u56fe 14-12 \u00a0 \u6700\u4f18\u5b50\u7ed3\u6784\u4e0e\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    Note

    \u6839\u636e\u5b9a\u4e49\u597d\u7684 \\(dp\\) \u8868\uff0c\u601d\u8003\u539f\u95ee\u9898\u548c\u5b50\u95ee\u9898\u7684\u5173\u7cfb\uff0c\u627e\u51fa\u901a\u8fc7\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u6765\u6784\u9020\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u7684\u65b9\u6cd5\uff0c\u5373\u6700\u4f18\u5b50\u7ed3\u6784\u3002

    \u4e00\u65e6\u6211\u4eec\u627e\u5230\u4e86\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528\u5b83\u6765\u6784\u5efa\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5728\u672c\u9898\u4e2d\uff0c\u5904\u5728\u9996\u884c\u7684\u72b6\u6001\u53ea\u80fd\u4ece\u5176\u5de6\u8fb9\u7684\u72b6\u6001\u5f97\u6765\uff0c\u5904\u5728\u9996\u5217\u7684\u72b6\u6001\u53ea\u80fd\u4ece\u5176\u4e0a\u8fb9\u7684\u72b6\u6001\u5f97\u6765\uff0c\u56e0\u6b64\u9996\u884c \\(i = 0\\) \u548c\u9996\u5217 \\(j = 0\\) \u662f\u8fb9\u754c\u6761\u4ef6\u3002

    \u5982\u56fe 14-13 \u6240\u793a\uff0c\u7531\u4e8e\u6bcf\u4e2a\u683c\u5b50\u662f\u7531\u5176\u5de6\u65b9\u683c\u5b50\u548c\u4e0a\u65b9\u683c\u5b50\u8f6c\u79fb\u800c\u6765\uff0c\u56e0\u6b64\u6211\u4eec\u4f7f\u7528\u5faa\u73af\u6765\u904d\u5386\u77e9\u9635\uff0c\u5916\u5faa\u73af\u904d\u5386\u5404\u884c\uff0c\u5185\u5faa\u73af\u904d\u5386\u5404\u5217\u3002

    \u56fe 14-13 \u00a0 \u8fb9\u754c\u6761\u4ef6\u4e0e\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    Note

    \u8fb9\u754c\u6761\u4ef6\u5728\u52a8\u6001\u89c4\u5212\u4e2d\u7528\u4e8e\u521d\u59cb\u5316 \\(dp\\) \u8868\uff0c\u5728\u641c\u7d22\u4e2d\u7528\u4e8e\u526a\u679d\u3002

    \u72b6\u6001\u8f6c\u79fb\u987a\u5e8f\u7684\u6838\u5fc3\u662f\u8981\u4fdd\u8bc1\u5728\u8ba1\u7b97\u5f53\u524d\u95ee\u9898\u7684\u89e3\u65f6\uff0c\u6240\u6709\u5b83\u4f9d\u8d56\u7684\u66f4\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\u90fd\u5df2\u7ecf\u88ab\u6b63\u786e\u5730\u8ba1\u7b97\u51fa\u6765\u3002

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u6211\u4eec\u5df2\u7ecf\u53ef\u4ee5\u76f4\u63a5\u5199\u51fa\u52a8\u6001\u89c4\u5212\u4ee3\u7801\u3002\u7136\u800c\u5b50\u95ee\u9898\u5206\u89e3\u662f\u4e00\u79cd\u4ece\u9876\u81f3\u5e95\u7684\u601d\u60f3\uff0c\u56e0\u6b64\u6309\u7167\u201c\u66b4\u529b\u641c\u7d22 \\(\\rightarrow\\) \u8bb0\u5fc6\u5316\u641c\u7d22 \\(\\rightarrow\\) \u52a8\u6001\u89c4\u5212\u201d\u7684\u987a\u5e8f\u5b9e\u73b0\u66f4\u52a0\u7b26\u5408\u601d\u7ef4\u4e60\u60ef\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1","title":"1. \u00a0 \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u641c\u7d22","text":"

    \u4ece\u72b6\u6001 \\([i, j]\\) \u5f00\u59cb\u641c\u7d22\uff0c\u4e0d\u65ad\u5206\u89e3\u4e3a\u66f4\u5c0f\u7684\u72b6\u6001 \\([i-1, j]\\) \u548c \\([i, j-1]\\) \uff0c\u9012\u5f52\u51fd\u6570\u5305\u62ec\u4ee5\u4e0b\u8981\u7d20\u3002

    • \u9012\u5f52\u53c2\u6570\uff1a\u72b6\u6001 \\([i, j]\\) \u3002
    • \u8fd4\u56de\u503c\uff1a\u4ece \\([0, 0]\\) \u5230 \\([i, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c \\(dp[i, j]\\) \u3002
    • \u7ec8\u6b62\u6761\u4ef6\uff1a\u5f53 \\(i = 0\\) \u4e14 \\(j = 0\\) \u65f6\uff0c\u8fd4\u56de\u4ee3\u4ef7 \\(grid[0, 0]\\) \u3002
    • \u526a\u679d\uff1a\u5f53 \\(i < 0\\) \u65f6\u6216 \\(j < 0\\) \u65f6\u7d22\u5f15\u8d8a\u754c\uff0c\u6b64\u65f6\u8fd4\u56de\u4ee3\u4ef7 \\(+\\infty\\) \uff0c\u4ee3\u8868\u4e0d\u53ef\u884c\u3002

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dfs(grid: list[list[int]], i: int, j: int) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22\"\"\"\n    # \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 and j == 0:\n        return grid[0][0]\n    # \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 or j < 0:\n        return inf\n    # \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up = min_path_sum_dfs(grid, i - 1, j)\n    left = min_path_sum_dfs(grid, i, j - 1)\n    # \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(vector<vector<int>> &grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(int[][] grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Integer.MAX_VALUE;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint MinPathSumDFS(int[][] grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return int.MaxValue;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = MinPathSumDFS(grid, i - 1, j);\n    int left = MinPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.Min(left, up) + grid[i][j];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc minPathSumDFS(grid [][]int, i, j int) int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return math.MaxInt\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up := minPathSumDFS(grid, i-1, j)\n    left := minPathSumDFS(grid, i, j-1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return int(math.Min(float64(left), float64(up))) + grid[i][j]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc minPathSumDFS(grid: [[Int]], i: Int, j: Int) -> Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0, j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return .max\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = minPathSumDFS(grid: grid, i: i - 1, j: j)\n    let left = minPathSumDFS(grid: grid, i: i, j: j - 1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction minPathSumDFS(grid, i, j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFS(grid, i - 1, j);\n    const left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction minPathSumDFS(\n    grid: Array<Array<number>>,\n    i: number,\n    j: number\n): number {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFS(grid, i - 1, j);\n    const left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(List<List<int>> grid, int i, int j) {\n  // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n  if (i == 0 && j == 0) {\n    return grid[0][0];\n  }\n  // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n  if (i < 0 || j < 0) {\n    // \u5728 Dart \u4e2d\uff0cint \u7c7b\u578b\u662f\u56fa\u5b9a\u8303\u56f4\u7684\u6574\u6570\uff0c\u4e0d\u5b58\u5728\u8868\u793a\u201c\u65e0\u7a77\u5927\u201d\u7684\u503c\n    return BigInt.from(2).pow(31).toInt();\n  }\n  // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  int up = minPathSumDFS(grid, i - 1, j);\n  int left = minPathSumDFS(grid, i, j - 1);\n  // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  return min(left, up) + grid[i][j];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfn min_path_sum_dfs(grid: &Vec<Vec<i32>>, i: i32, j: i32) -> i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return i32::MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = min_path_sum_dfs(grid, i - 1, j);\n    let left = min_path_sum_dfs(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    std::cmp::min(left, up) + grid[i as usize][j as usize]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(int grid[MAX_SIZE][MAX_SIZE], int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfun minPathSumDFS(grid: Array<IntArray>, i: Int, j: Int): Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Int.MAX_VALUE\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    val up = minPathSumDFS(grid, i - 1, j)\n    val left = minPathSumDFS(grid, i, j - 1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22\nfn minPathSumDFS(grid: anytype, i: i32, j: i32) i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 and j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 or j < 0) {\n        return std.math.maxInt(i32);\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    var up = minPathSumDFS(grid, i - 1, j);\n    var left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-14 \u7ed9\u51fa\u4e86\u4ee5 \\(dp[2, 1]\\) \u4e3a\u6839\u8282\u70b9\u7684\u9012\u5f52\u6811\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e9b\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u5176\u6570\u91cf\u4f1a\u968f\u7740\u7f51\u683c grid \u7684\u5c3a\u5bf8\u53d8\u5927\u800c\u6025\u5267\u589e\u591a\u3002

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u9020\u6210\u91cd\u53e0\u5b50\u95ee\u9898\u7684\u539f\u56e0\u4e3a\uff1a\u5b58\u5728\u591a\u6761\u8def\u5f84\u53ef\u4ee5\u4ece\u5de6\u4e0a\u89d2\u5230\u8fbe\u67d0\u4e00\u5355\u5143\u683c\u3002

    \u56fe 14-14 \u00a0 \u66b4\u529b\u641c\u7d22\u9012\u5f52\u6811

    \u6bcf\u4e2a\u72b6\u6001\u90fd\u6709\u5411\u4e0b\u548c\u5411\u53f3\u4e24\u79cd\u9009\u62e9\uff0c\u4ece\u5de6\u4e0a\u89d2\u8d70\u5230\u53f3\u4e0b\u89d2\u603b\u5171\u9700\u8981 \\(m + n - 2\\) \u6b65\uff0c\u6240\u4ee5\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^{m + n})\\) \u3002\u8bf7\u6ce8\u610f\uff0c\u8fd9\u79cd\u8ba1\u7b97\u65b9\u5f0f\u672a\u8003\u8651\u4e34\u8fd1\u7f51\u683c\u8fb9\u754c\u7684\u60c5\u51b5\uff0c\u5f53\u5230\u8fbe\u7f51\u7edc\u8fb9\u754c\u65f6\u53ea\u5269\u4e0b\u4e00\u79cd\u9009\u62e9\uff0c\u56e0\u6b64\u5b9e\u9645\u7684\u8def\u5f84\u6570\u91cf\u4f1a\u5c11\u4e00\u4e9b\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#2","title":"2. \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22","text":"

    \u6211\u4eec\u5f15\u5165\u4e00\u4e2a\u548c\u7f51\u683c grid \u76f8\u540c\u5c3a\u5bf8\u7684\u8bb0\u5fc6\u5217\u8868 mem \uff0c\u7528\u4e8e\u8bb0\u5f55\u5404\u4e2a\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5e76\u5c06\u91cd\u53e0\u5b50\u95ee\u9898\u8fdb\u884c\u526a\u679d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dfs_mem(\n    grid: list[list[int]], mem: list[list[int]], i: int, j: int\n) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 and j == 0:\n        return grid[0][0]\n    # \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 or j < 0:\n        return inf\n    # \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1:\n        return mem[i][j]\n    # \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up = min_path_sum_dfs_mem(grid, mem, i - 1, j)\n    left = min_path_sum_dfs_mem(grid, mem, i, j - 1)\n    # \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(vector<vector<int>> &grid, vector<vector<int>> &mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;\n    return mem[i][j];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Integer.MAX_VALUE;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint MinPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return int.MaxValue;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = MinPathSumDFSMem(grid, mem, i - 1, j);\n    int left = MinPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.Min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc minPathSumDFSMem(grid, mem [][]int, i, j int) int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return math.MaxInt\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1 {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up := minPathSumDFSMem(grid, mem, i-1, j)\n    left := minPathSumDFSMem(grid, mem, i, j-1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = int(math.Min(float64(left), float64(up))) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc minPathSumDFSMem(grid: [[Int]], mem: inout [[Int]], i: Int, j: Int) -> Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0, j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return .max\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1 {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = minPathSumDFSMem(grid: grid, mem: &mem, i: i - 1, j: j)\n    let left = minPathSumDFSMem(grid: grid, mem: &mem, i: i, j: j - 1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction minPathSumDFSMem(grid, mem, i, j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] !== -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFSMem(grid, mem, i - 1, j);\n    const left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction minPathSumDFSMem(\n    grid: Array<Array<number>>,\n    mem: Array<Array<number>>,\n    i: number,\n    j: number\n): number {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFSMem(grid, mem, i - 1, j);\n    const left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(List<List<int>> grid, List<List<int>> mem, int i, int j) {\n  // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n  if (i == 0 && j == 0) {\n    return grid[0][0];\n  }\n  // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n  if (i < 0 || j < 0) {\n    // \u5728 Dart \u4e2d\uff0cint \u7c7b\u578b\u662f\u56fa\u5b9a\u8303\u56f4\u7684\u6574\u6570\uff0c\u4e0d\u5b58\u5728\u8868\u793a\u201c\u65e0\u7a77\u5927\u201d\u7684\u503c\n    return BigInt.from(2).pow(31).toInt();\n  }\n  // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  if (mem[i][j] != -1) {\n    return mem[i][j];\n  }\n  // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  int up = minPathSumDFSMem(grid, mem, i - 1, j);\n  int left = minPathSumDFSMem(grid, mem, i, j - 1);\n  // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  mem[i][j] = min(left, up) + grid[i][j];\n  return mem[i][j];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn min_path_sum_dfs_mem(grid: &Vec<Vec<i32>>, mem: &mut Vec<Vec<i32>>, i: i32, j: i32) -> i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return i32::MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i as usize][j as usize] != -1 {\n        return mem[i as usize][j as usize];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = min_path_sum_dfs_mem(grid, mem, i - 1, j);\n    let left = min_path_sum_dfs_mem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i as usize][j as usize] = std::cmp::min(left, up) + grid[i as usize][j as usize];\n    mem[i as usize][j as usize]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(int grid[MAX_SIZE][MAX_SIZE], int mem[MAX_SIZE][MAX_SIZE], int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;\n    return mem[i][j];\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun minPathSumDFSMem(\n    grid: Array<IntArray>,\n    mem: Array<IntArray>,\n    i: Int,\n    j: Int\n): Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Int.MAX_VALUE\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    val up = minPathSumDFSMem(grid, mem, i - 1, j)\n    val left = minPathSumDFSMem(grid, mem, i, j - 1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs_mem}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn minPathSumDFSMem(grid: anytype, mem: anytype, i: i32, j: i32) i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 and j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 or j < 0) {\n        return std.math.maxInt(i32);\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] != -1) {\n        return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    var up = minPathSumDFSMem(grid, mem, i - 1, j);\n    var left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] = @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n    return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-15 \u6240\u793a\uff0c\u5728\u5f15\u5165\u8bb0\u5fc6\u5316\u540e\uff0c\u6240\u6709\u5b50\u95ee\u9898\u7684\u89e3\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u72b6\u6001\u603b\u6570\uff0c\u5373\u7f51\u683c\u5c3a\u5bf8 \\(O(nm)\\) \u3002

    \u56fe 14-15 \u00a0 \u8bb0\u5fc6\u5316\u641c\u7d22\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#3","title":"3. \u00a0 \u65b9\u6cd5\u4e09\uff1a\u52a8\u6001\u89c4\u5212","text":"

    \u57fa\u4e8e\u8fed\u4ee3\u5b9e\u73b0\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dp(grid: list[list[int]]) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(grid), len(grid[0])\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * m for _ in range(n)]\n    dp[0][0] = grid[0][0]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in range(1, m):\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in range(1, n):\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n):\n        for j in range(1, m):\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n    return dp[n - 1][m - 1]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(vector<vector<int>> &grid) {\n    int n = grid.size(), m = grid[0].size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n, vector<int>(m));\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(int[][] grid) {\n    int n = grid.length, m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n][m];\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint MinPathSumDP(int[][] grid) {\n    int n = grid.Length, m = grid[0].Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n, m];\n    dp[0, 0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0, j] = dp[0, j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i, 0] = dp[i - 1, 0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i, j] = Math.Min(dp[i, j - 1], dp[i - 1, j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1, m - 1];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDP(grid [][]int) int {\n    n, m := len(grid), len(grid[0])\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n)\n    for i := 0; i < n; i++ {\n        dp[i] = make([]int, m)\n    }\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j := 1; j < m; j++ {\n        dp[0][j] = dp[0][j-1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i := 1; i < n; i++ {\n        dp[i][0] = dp[i-1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i < n; i++ {\n        for j := 1; j < m; j++ {\n            dp[i][j] = int(math.Min(float64(dp[i][j-1]), float64(dp[i-1][j]))) + grid[i][j]\n        }\n    }\n    return dp[n-1][m-1]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDP(grid: [[Int]]) -> Int {\n    let n = grid.count\n    let m = grid[0].count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: m), count: n)\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1 ..< m {\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in 1 ..< n {\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ..< n {\n        for j in 1 ..< m {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n        }\n    }\n    return dp[n - 1][m - 1]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDP(grid) {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n }, () =>\n        Array.from({ length: m }, () => 0)\n    );\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (let i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i < n; i++) {\n        for (let j = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDP(grid: Array<Array<number>>): number {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n }, () =>\n        Array.from({ length: m }, () => 0)\n    );\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (let i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i < n; i++) {\n        for (let j: number = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(List<List<int>> grid) {\n  int n = grid.length, m = grid[0].length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n, (i) => List.filled(m, 0));\n  dp[0][0] = grid[0][0];\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n  for (int j = 1; j < m; j++) {\n    dp[0][j] = dp[0][j - 1] + grid[0][j];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n  for (int i = 1; i < n; i++) {\n    dp[i][0] = dp[i - 1][0] + grid[i][0];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i < n; i++) {\n    for (int j = 1; j < m; j++) {\n      dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n    }\n  }\n  return dp[n - 1][m - 1];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfn min_path_sum_dp(grid: &Vec<Vec<i32>>) -> i32 {\n    let (n, m) = (grid.len(), grid[0].len());\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; m]; n];\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1..m {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in 1..n {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..n {\n        for j in 1..m {\n            dp[i][j] = std::cmp::min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    dp[n - 1][m - 1]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc(n * sizeof(int *));\n    for (int i = 0; i < n; i++) {\n        dp[i] = calloc(m, sizeof(int));\n    }\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = myMin(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    int res = dp[n - 1][m - 1];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i < n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfun minPathSumDP(grid: Array<IntArray>): Int {\n    val n = grid.size\n    val m = grid[0].size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n) { IntArray(m) }\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (j in 1..<m) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (i in 1..<n) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..<n) {\n        for (j in 1..<m) {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n        }\n    }\n    return dp[n - 1][m - 1]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212\nfn minPathSumDP(comptime grid: anytype) i32 {\n    comptime var n = grid.len;\n    comptime var m = grid[0].len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][m]i32{[_]i32{0} ** m} ** n;\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (1..m) |j| {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (1..n) |i| {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n) |i| {\n        for (1..m) |j| {\n            dp[i][j] = @min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-16 \u5c55\u793a\u4e86\u6700\u5c0f\u8def\u5f84\u548c\u7684\u72b6\u6001\u8f6c\u79fb\u8fc7\u7a0b\uff0c\u5176\u904d\u5386\u4e86\u6574\u4e2a\u7f51\u683c\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nm)\\) \u3002

    \u6570\u7ec4 dp \u5927\u5c0f\u4e3a \\(n \\times m\\) \uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nm)\\) \u3002

    <1><2><3><4><5><6><7><8><9><10><11><12>

    \u56fe 14-16 \u00a0 \u6700\u5c0f\u8def\u5f84\u548c\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#4","title":"4. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e\u6bcf\u4e2a\u683c\u5b50\u53ea\u4e0e\u5176\u5de6\u8fb9\u548c\u4e0a\u8fb9\u7684\u683c\u5b50\u6709\u5173\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u53ea\u7528\u4e00\u4e2a\u5355\u884c\u6570\u7ec4\u6765\u5b9e\u73b0 \\(dp\\) \u8868\u3002

    \u8bf7\u6ce8\u610f\uff0c\u56e0\u4e3a\u6570\u7ec4 dp \u53ea\u80fd\u8868\u793a\u4e00\u884c\u7684\u72b6\u6001\uff0c\u6240\u4ee5\u6211\u4eec\u65e0\u6cd5\u63d0\u524d\u521d\u59cb\u5316\u9996\u5217\u72b6\u6001\uff0c\u800c\u662f\u5728\u904d\u5386\u6bcf\u884c\u65f6\u66f4\u65b0\u5b83\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dp_comp(grid: list[list[int]]) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(grid), len(grid[0])\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * m\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j in range(1, m):\n        dp[j] = dp[j - 1] + grid[0][j]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in range(1, n):\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in range(1, m):\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n    return dp[m - 1]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(vector<vector<int>> &grid) {\n    int n = grid.size(), m = grid[0].size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(int[][] grid) {\n    int n = grid.length, m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[m];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint MinPathSumDPComp(int[][] grid) {\n    int n = grid.Length, m = grid[0].Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[m];\n    dp[0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = Math.Min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDPComp(grid [][]int) int {\n    n, m := len(grid), len(grid[0])\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j := 1; j < m; j++ {\n        dp[j] = dp[j-1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i < n; i++ {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j := 1; j < m; j++ {\n            dp[j] = int(math.Min(float64(dp[j-1]), float64(dp[j]))) + grid[i][j]\n        }\n    }\n    return dp[m-1]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDPComp(grid: [[Int]]) -> Int {\n    let n = grid.count\n    let m = grid[0].count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j in 1 ..< m {\n        dp[j] = dp[j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1 ..< n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1 ..< m {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n        }\n    }\n    return dp[m - 1]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDPComp(grid) {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = new Array(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (let j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDPComp(grid: Array<Array<number>>): number {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = new Array(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (let j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(List<List<int>> grid) {\n  int n = grid.length, m = grid[0].length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(m, 0);\n  dp[0] = grid[0][0];\n  for (int j = 1; j < m; j++) {\n    dp[j] = dp[j - 1] + grid[0][j];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n  for (int i = 1; i < n; i++) {\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    dp[0] = dp[0] + grid[i][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n    for (int j = 1; j < m; j++) {\n      dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];\n    }\n  }\n  return dp[m - 1];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn min_path_sum_dp_comp(grid: &Vec<Vec<i32>>) -> i32 {\n    let (n, m) = (grid.len(), grid[0].len());\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; m];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for j in 1..m {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1..n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1..m {\n            dp[j] = std::cmp::min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    dp[m - 1]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(m, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = myMin(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    int res = dp[m - 1];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun minPathSumDPComp(grid: Array<IntArray>): Int {\n    val n = grid.size\n    val m = grid[0].size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for (j in 1..<m) {\n        dp[j] = dp[j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (i in 1..<n) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (j in 1..<m) {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n        }\n    }\n    return dp[m - 1]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp_comp}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn minPathSumDPComp(comptime grid: anytype) i32 {\n    comptime var n = grid.len;\n    comptime var m = grid[0].len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** m;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (1..m) |j| {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (1..n) |i| {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        for (1..m) |j| {\n            dp[j] = @min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/","title":"14.6 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898","text":"

    \u7f16\u8f91\u8ddd\u79bb\uff0c\u4e5f\u79f0 Levenshtein \u8ddd\u79bb\uff0c\u6307\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e4b\u95f4\u4e92\u76f8\u8f6c\u6362\u7684\u6700\u5c11\u4fee\u6539\u6b21\u6570\uff0c\u901a\u5e38\u7528\u4e8e\u5728\u4fe1\u606f\u68c0\u7d22\u548c\u81ea\u7136\u8bed\u8a00\u5904\u7406\u4e2d\u5ea6\u91cf\u4e24\u4e2a\u5e8f\u5217\u7684\u76f8\u4f3c\u5ea6\u3002

    Question

    \u8f93\u5165\u4e24\u4e2a\u5b57\u7b26\u4e32 \\(s\\) \u548c \\(t\\) \uff0c\u8fd4\u56de\u5c06 \\(s\\) \u8f6c\u6362\u4e3a \\(t\\) \u6240\u9700\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u3002

    \u4f60\u53ef\u4ee5\u5728\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u8fdb\u884c\u4e09\u79cd\u7f16\u8f91\u64cd\u4f5c\uff1a\u63d2\u5165\u4e00\u4e2a\u5b57\u7b26\u3001\u5220\u9664\u4e00\u4e2a\u5b57\u7b26\u3001\u5c06\u5b57\u7b26\u66ff\u6362\u4e3a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26\u3002

    \u5982\u56fe 14-27 \u6240\u793a\uff0c\u5c06 kitten \u8f6c\u6362\u4e3a sitting \u9700\u8981\u7f16\u8f91 3 \u6b65\uff0c\u5305\u62ec 2 \u6b21\u66ff\u6362\u64cd\u4f5c\u4e0e 1 \u6b21\u6dfb\u52a0\u64cd\u4f5c\uff1b\u5c06 hello \u8f6c\u6362\u4e3a algo \u9700\u8981 3 \u6b65\uff0c\u5305\u62ec 2 \u6b21\u66ff\u6362\u64cd\u4f5c\u548c 1 \u6b21\u5220\u9664\u64cd\u4f5c\u3002

    \u56fe 14-27 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u7684\u793a\u4f8b\u6570\u636e

    \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898\u53ef\u4ee5\u5f88\u81ea\u7136\u5730\u7528\u51b3\u7b56\u6811\u6a21\u578b\u6765\u89e3\u91ca\u3002\u5b57\u7b26\u4e32\u5bf9\u5e94\u6811\u8282\u70b9\uff0c\u4e00\u8f6e\u51b3\u7b56\uff08\u4e00\u6b21\u7f16\u8f91\u64cd\u4f5c\uff09\u5bf9\u5e94\u6811\u7684\u4e00\u6761\u8fb9\u3002

    \u5982\u56fe 14-28 \u6240\u793a\uff0c\u5728\u4e0d\u9650\u5236\u64cd\u4f5c\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u8282\u70b9\u90fd\u53ef\u4ee5\u6d3e\u751f\u51fa\u8bb8\u591a\u6761\u8fb9\uff0c\u6bcf\u6761\u8fb9\u5bf9\u5e94\u4e00\u79cd\u64cd\u4f5c\uff0c\u8fd9\u610f\u5473\u7740\u4ece hello \u8f6c\u6362\u5230 algo \u6709\u8bb8\u591a\u79cd\u53ef\u80fd\u7684\u8def\u5f84\u3002

    \u4ece\u51b3\u7b56\u6811\u7684\u89d2\u5ea6\u770b\uff0c\u672c\u9898\u7684\u76ee\u6807\u662f\u6c42\u89e3\u8282\u70b9 hello \u548c\u8282\u70b9 algo \u4e4b\u95f4\u7684\u6700\u77ed\u8def\u5f84\u3002

    \u56fe 14-28 \u00a0 \u57fa\u4e8e\u51b3\u7b56\u6811\u6a21\u578b\u8868\u793a\u7f16\u8f91\u8ddd\u79bb\u95ee\u9898

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#1","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u6bcf\u4e00\u8f6e\u7684\u51b3\u7b56\u662f\u5bf9\u5b57\u7b26\u4e32 \\(s\\) \u8fdb\u884c\u4e00\u6b21\u7f16\u8f91\u64cd\u4f5c\u3002

    \u6211\u4eec\u5e0c\u671b\u5728\u7f16\u8f91\u64cd\u4f5c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u95ee\u9898\u7684\u89c4\u6a21\u9010\u6e10\u7f29\u5c0f\uff0c\u8fd9\u6837\u624d\u80fd\u6784\u5efa\u5b50\u95ee\u9898\u3002\u8bbe\u5b57\u7b26\u4e32 \\(s\\) \u548c \\(t\\) \u7684\u957f\u5ea6\u5206\u522b\u4e3a \\(n\\) \u548c \\(m\\) \uff0c\u6211\u4eec\u5148\u8003\u8651\u4e24\u5b57\u7b26\u4e32\u5c3e\u90e8\u7684\u5b57\u7b26 \\(s[n-1]\\) \u548c \\(t[m-1]\\) \u3002

    • \u82e5 \\(s[n-1]\\) \u548c \\(t[m-1]\\) \u76f8\u540c\uff0c\u6211\u4eec\u53ef\u4ee5\u8df3\u8fc7\u5b83\u4eec\uff0c\u76f4\u63a5\u8003\u8651 \\(s[n-2]\\) \u548c \\(t[m-2]\\) \u3002
    • \u82e5 \\(s[n-1]\\) \u548c \\(t[m-1]\\) \u4e0d\u540c\uff0c\u6211\u4eec\u9700\u8981\u5bf9 \\(s\\) \u8fdb\u884c\u4e00\u6b21\u7f16\u8f91\uff08\u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\uff09\uff0c\u4f7f\u5f97\u4e24\u5b57\u7b26\u4e32\u5c3e\u90e8\u7684\u5b57\u7b26\u76f8\u540c\uff0c\u4ece\u800c\u53ef\u4ee5\u8df3\u8fc7\u5b83\u4eec\uff0c\u8003\u8651\u89c4\u6a21\u66f4\u5c0f\u7684\u95ee\u9898\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u6211\u4eec\u5728\u5b57\u7b26\u4e32 \\(s\\) \u4e2d\u8fdb\u884c\u7684\u6bcf\u4e00\u8f6e\u51b3\u7b56\uff08\u7f16\u8f91\u64cd\u4f5c\uff09\uff0c\u90fd\u4f1a\u4f7f\u5f97 \\(s\\) \u548c \\(t\\) \u4e2d\u5269\u4f59\u7684\u5f85\u5339\u914d\u5b57\u7b26\u53d1\u751f\u53d8\u5316\u3002\u56e0\u6b64\uff0c\u72b6\u6001\u4e3a\u5f53\u524d\u5728 \\(s\\) \u548c \\(t\\) \u4e2d\u8003\u8651\u7684\u7b2c \\(i\\) \u548c\u7b2c \\(j\\) \u4e2a\u5b57\u7b26\uff0c\u8bb0\u4e3a \\([i, j]\\) \u3002

    \u72b6\u6001 \\([i, j]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\uff1a\u5c06 \\(s\\) \u7684\u524d \\(i\\) \u4e2a\u5b57\u7b26\u66f4\u6539\u4e3a \\(t\\) \u7684\u524d \\(j\\) \u4e2a\u5b57\u7b26\u6240\u9700\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u3002

    \u81f3\u6b64\uff0c\u5f97\u5230\u4e00\u4e2a\u5c3a\u5bf8\u4e3a \\((i+1) \\times (j+1)\\) \u7684\u4e8c\u7ef4 \\(dp\\) \u8868\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u8003\u8651\u5b50\u95ee\u9898 \\(dp[i, j]\\) \uff0c\u5176\u5bf9\u5e94\u7684\u4e24\u4e2a\u5b57\u7b26\u4e32\u7684\u5c3e\u90e8\u5b57\u7b26\u4e3a \\(s[i-1]\\) \u548c \\(t[j-1]\\) \uff0c\u53ef\u6839\u636e\u4e0d\u540c\u7f16\u8f91\u64cd\u4f5c\u5206\u4e3a\u56fe 14-29 \u6240\u793a\u7684\u4e09\u79cd\u60c5\u51b5\u3002

    1. \u5728 \\(s[i-1]\\) \u4e4b\u540e\u6dfb\u52a0 \\(t[j-1]\\) \uff0c\u5219\u5269\u4f59\u5b50\u95ee\u9898 \\(dp[i, j-1]\\) \u3002
    2. \u5220\u9664 \\(s[i-1]\\) \uff0c\u5219\u5269\u4f59\u5b50\u95ee\u9898 \\(dp[i-1, j]\\) \u3002
    3. \u5c06 \\(s[i-1]\\) \u66ff\u6362\u4e3a \\(t[j-1]\\) \uff0c\u5219\u5269\u4f59\u5b50\u95ee\u9898 \\(dp[i-1, j-1]\\) \u3002

    \u56fe 14-29 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u7684\u72b6\u6001\u8f6c\u79fb

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u53ef\u5f97\u6700\u4f18\u5b50\u7ed3\u6784\uff1a\\(dp[i, j]\\) \u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u7b49\u4e8e \\(dp[i, j-1]\\)\u3001\\(dp[i-1, j]\\)\u3001\\(dp[i-1, j-1]\\) \u4e09\u8005\u4e2d\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\uff0c\u518d\u52a0\u4e0a\u672c\u6b21\u7684\u7f16\u8f91\u6b65\u6570 \\(1\\) \u3002\u5bf9\u5e94\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ dp[i, j] = \\min(dp[i, j-1], dp[i-1, j], dp[i-1, j-1]) + 1 \\]

    \u8bf7\u6ce8\u610f\uff0c\u5f53 \\(s[i-1]\\) \u548c \\(t[j-1]\\) \u76f8\u540c\u65f6\uff0c\u65e0\u987b\u7f16\u8f91\u5f53\u524d\u5b57\u7b26\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ dp[i, j] = dp[i-1, j-1] \\]

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5f53\u4e24\u5b57\u7b26\u4e32\u90fd\u4e3a\u7a7a\u65f6\uff0c\u7f16\u8f91\u6b65\u6570\u4e3a \\(0\\) \uff0c\u5373 \\(dp[0, 0] = 0\\) \u3002\u5f53 \\(s\\) \u4e3a\u7a7a\u4f46 \\(t\\) \u4e0d\u4e3a\u7a7a\u65f6\uff0c\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u7b49\u4e8e \\(t\\) \u7684\u957f\u5ea6\uff0c\u5373\u9996\u884c \\(dp[0, j] = j\\) \u3002\u5f53 \\(s\\) \u4e0d\u4e3a\u7a7a\u4f46 \\(t\\) \u4e3a\u7a7a\u65f6\uff0c\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u7b49\u4e8e \\(s\\) \u7684\u957f\u5ea6\uff0c\u5373\u9996\u5217 \\(dp[i, 0] = i\\) \u3002

    \u89c2\u5bdf\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff0c\u89e3 \\(dp[i, j]\\) \u4f9d\u8d56\u5de6\u65b9\u3001\u4e0a\u65b9\u3001\u5de6\u4e0a\u65b9\u7684\u89e3\uff0c\u56e0\u6b64\u901a\u8fc7\u4e24\u5c42\u5faa\u73af\u6b63\u5e8f\u904d\u5386\u6574\u4e2a \\(dp\\) \u8868\u5373\u53ef\u3002

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig edit_distance.py
    def edit_distance_dp(s: str, t: str) -> int:\n    \"\"\"\u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(s), len(t)\n    dp = [[0] * (m + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in range(1, n + 1):\n        dp[i][0] = i\n    for j in range(1, m + 1):\n        dp[0][j] = j\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n + 1):\n        for j in range(1, m + 1):\n            if s[i - 1] == t[j - 1]:\n                # \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            else:\n                # \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1\n    return dp[n][m]\n
    edit_distance.cpp
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(string s, string t) {\n    int n = s.length(), m = t.length();\n    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.java
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(String s, String t) {\n    int n = s.length(), m = t.length();\n    int[][] dp = new int[n + 1][m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) == t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.cs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint EditDistanceDP(string s, string t) {\n    int n = s.Length, m = t.Length;\n    int[,] dp = new int[n + 1, m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i, 0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0, j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i, j] = dp[i - 1, j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i, j] = Math.Min(Math.Min(dp[i, j - 1], dp[i - 1, j]), dp[i - 1, j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n, m];\n}\n
    edit_distance.go
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDP(s string, t string) int {\n    n := len(s)\n    m := len(t)\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, m+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i := 1; i <= n; i++ {\n        dp[i][0] = i\n    }\n    for j := 1; j <= m; j++ {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= m; j++ {\n            if s[i-1] == t[j-1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i-1][j-1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = MinInt(MinInt(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.swift
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDP(s: String, t: String) -> Int {\n    let n = s.utf8CString.count\n    let m = t.utf8CString.count\n    var dp = Array(repeating: Array(repeating: 0, count: m + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in 1 ... n {\n        dp[i][0] = i\n    }\n    for j in 1 ... m {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ... n {\n        for j in 1 ... m {\n            if s.utf8CString[i - 1] == t.utf8CString[j - 1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.js
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDP(s, t) {\n    const n = s.length,\n        m = t.length;\n    const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (let j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.ts
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDP(s: string, t: string): number {\n    const n = s.length,\n        m = t.length;\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: m + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (let j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.dart
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(String s, String t) {\n  int n = s.length, m = t.length;\n  List<List<int>> dp = List.generate(n + 1, (_) => List.filled(m + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n  for (int i = 1; i <= n; i++) {\n    dp[i][0] = i;\n  }\n  for (int j = 1; j <= m; j++) {\n    dp[0][j] = j;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i <= n; i++) {\n    for (int j = 1; j <= m; j++) {\n      if (s[i - 1] == t[j - 1]) {\n        // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n        dp[i][j] = dp[i - 1][j - 1];\n      } else {\n        // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n        dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n      }\n    }\n  }\n  return dp[n][m];\n}\n
    edit_distance.rs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfn edit_distance_dp(s: &str, t: &str) -> i32 {\n    let (n, m) = (s.len(), t.len());\n    let mut dp = vec![vec![0; m + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in 1..=n {\n        dp[i][0] = i as i32;\n    }\n    for j in 1..m {\n        dp[0][j] = j as i32;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..=n {\n        for j in 1..=m {\n            if s.chars().nth(i - 1) == t.chars().nth(j - 1) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    std::cmp::min(std::cmp::min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    dp[n][m]\n}\n
    edit_distance.c
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(char *s, char *t, int n, int m) {\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(m + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = myMin(myMin(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    int res = dp[n][m];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    edit_distance.kt
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfun editDistanceDP(s: String, t: String): Int {\n    val n = s.length\n    val m = t.length\n    val dp = Array(n + 1) { IntArray(m + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (i in 1..n) {\n        dp[i][0] = i\n    }\n    for (j in 1..m) {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..n) {\n        for (j in 1..m) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.rb
    [class]{}-[func]{edit_distance_dp}\n
    edit_distance.zig
    // \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212\nfn editDistanceDP(comptime s: []const u8, comptime t: []const u8) i32 {\n    comptime var n = s.len;\n    comptime var m = t.len;\n    var dp = [_][m + 1]i32{[_]i32{0} ** (m + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (1..n + 1) |i| {\n        dp[i][0] = @intCast(i);\n    }\n    for (1..m + 1) |j| {\n        dp[0][j] = @intCast(j);\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n + 1) |i| {\n        for (1..m + 1) |j| {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = @min(@min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-30 \u6240\u793a\uff0c\u7f16\u8f91\u8ddd\u79bb\u95ee\u9898\u7684\u72b6\u6001\u8f6c\u79fb\u8fc7\u7a0b\u4e0e\u80cc\u5305\u95ee\u9898\u975e\u5e38\u7c7b\u4f3c\uff0c\u90fd\u53ef\u4ee5\u770b\u4f5c\u586b\u5199\u4e00\u4e2a\u4e8c\u7ef4\u7f51\u683c\u7684\u8fc7\u7a0b\u3002

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>

    \u56fe 14-30 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#3","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e \\(dp[i,j]\\) \u662f\u7531\u4e0a\u65b9 \\(dp[i-1, j]\\)\u3001\u5de6\u65b9 \\(dp[i, j-1]\\)\u3001\u5de6\u4e0a\u65b9 \\(dp[i-1, j-1]\\) \u8f6c\u79fb\u800c\u6765\u7684\uff0c\u800c\u6b63\u5e8f\u904d\u5386\u4f1a\u4e22\u5931\u5de6\u4e0a\u65b9 \\(dp[i-1, j-1]\\) \uff0c\u5012\u5e8f\u904d\u5386\u65e0\u6cd5\u63d0\u524d\u6784\u5efa \\(dp[i, j-1]\\) \uff0c\u56e0\u6b64\u4e24\u79cd\u904d\u5386\u987a\u5e8f\u90fd\u4e0d\u53ef\u53d6\u3002

    \u4e3a\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u53d8\u91cf leftup \u6765\u6682\u5b58\u5de6\u4e0a\u65b9\u7684\u89e3 \\(dp[i-1, j-1]\\) \uff0c\u4ece\u800c\u53ea\u9700\u8003\u8651\u5de6\u65b9\u548c\u4e0a\u65b9\u7684\u89e3\u3002\u6b64\u65f6\u7684\u60c5\u51b5\u4e0e\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u76f8\u540c\uff0c\u53ef\u4f7f\u7528\u6b63\u5e8f\u904d\u5386\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig edit_distance.py
    def edit_distance_dp_comp(s: str, t: str) -> int:\n    \"\"\"\u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(s), len(t)\n    dp = [0] * (m + 1)\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in range(1, m + 1):\n        dp[j] = j\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in range(1, n + 1):\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        leftup = dp[0]  # \u6682\u5b58 dp[i-1, j-1]\n        dp[0] += 1\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in range(1, m + 1):\n            temp = dp[j]\n            if s[i - 1] == t[j - 1]:\n                # \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            else:\n                # \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(dp[j - 1], dp[j], leftup) + 1\n            leftup = temp  # \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n    return dp[m]\n
    edit_distance.cpp
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(string s, string t) {\n    int n = s.length(), m = t.length();\n    vector<int> dp(m + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.java
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(String s, String t) {\n    int n = s.length(), m = t.length();\n    int[] dp = new int[m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s.charAt(i - 1) == t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(Math.min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.cs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint EditDistanceDPComp(string s, string t) {\n    int n = s.Length, m = t.Length;\n    int[] dp = new int[m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.Min(Math.Min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.go
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDPComp(s string, t string) int {\n    n := len(s)\n    m := len(t)\n    dp := make([]int, m+1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j := 1; j <= m; j++ {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i := 1; i <= n; i++ {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        leftUp := dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j := 1; j <= m; j++ {\n            temp := dp[j]\n            if s[i-1] == t[j-1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftUp\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = MinInt(MinInt(dp[j-1], dp[j]), leftUp) + 1\n            }\n            leftUp = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.swift
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDPComp(s: String, t: String) -> Int {\n    let n = s.utf8CString.count\n    let m = t.utf8CString.count\n    var dp = Array(repeating: 0, count: m + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1 ... m {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1 ... n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1 ... m {\n            let temp = dp[j]\n            if s.utf8CString[i - 1] == t.utf8CString[j - 1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1\n            }\n            leftup = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.js
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDPComp(s, t) {\n    const n = s.length,\n        m = t.length;\n    const dp = new Array(m + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j <= m; j++) {\n            const temp = dp[j];\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(dp[j - 1], dp[j], leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.ts
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDPComp(s: string, t: string): number {\n    const n = s.length,\n        m = t.length;\n    const dp = new Array(m + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j <= m; j++) {\n            const temp = dp[j];\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(dp[j - 1], dp[j], leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.dart
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(String s, String t) {\n  int n = s.length, m = t.length;\n  List<int> dp = List.filled(m + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n  for (int j = 1; j <= m; j++) {\n    dp[j] = j;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n  for (int i = 1; i <= n; i++) {\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n    dp[0] = i;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n    for (int j = 1; j <= m; j++) {\n      int temp = dp[j];\n      if (s[i - 1] == t[j - 1]) {\n        // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n        dp[j] = leftup;\n      } else {\n        // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n        dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1;\n      }\n      leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n    }\n  }\n  return dp[m];\n}\n
    edit_distance.rs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn edit_distance_dp_comp(s: &str, t: &str) -> i32 {\n    let (n, m) = (s.len(), t.len());\n    let mut dp = vec![0; m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1..m {\n        dp[j] = j as i32;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1..=n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let mut leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i as i32;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1..=m {\n            let temp = dp[j];\n            if s.chars().nth(i - 1) == t.chars().nth(j - 1) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = std::cmp::min(std::cmp::min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    dp[m]\n}\n
    edit_distance.c
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(char *s, char *t, int n, int m) {\n    int *dp = calloc(m + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = myMin(myMin(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    int res = dp[m];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    edit_distance.kt
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun editDistanceDPComp(s: String, t: String): Int {\n    val n = s.length\n    val m = t.length\n    val dp = IntArray(m + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (j in 1..m) {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (i in 1..n) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (j in 1..m) {\n            val temp = dp[j]\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1\n            }\n            leftup = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.rb
    [class]{}-[func]{edit_distance_dp_comp}\n
    edit_distance.zig
    // \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn editDistanceDPComp(comptime s: []const u8, comptime t: []const u8) i32 {\n    comptime var n = s.len;\n    comptime var m = t.len;\n    var dp = [_]i32{0} ** (m + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (1..m + 1) |j| {\n        dp[j] = @intCast(j);\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (1..n + 1) |i| {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = @intCast(i);\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (1..m + 1) |j| {\n            var temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = @min(@min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/","title":"14.1 \u00a0 \u521d\u63a2\u52a8\u6001\u89c4\u5212","text":"

    \u52a8\u6001\u89c4\u5212\uff08dynamic programming\uff09\u662f\u4e00\u4e2a\u91cd\u8981\u7684\u7b97\u6cd5\u8303\u5f0f\uff0c\u5b83\u5c06\u4e00\u4e2a\u95ee\u9898\u5206\u89e3\u4e3a\u4e00\u7cfb\u5217\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u5e76\u901a\u8fc7\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\u6765\u907f\u514d\u91cd\u590d\u8ba1\u7b97\uff0c\u4ece\u800c\u5927\u5e45\u63d0\u5347\u65f6\u95f4\u6548\u7387\u3002

    \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u4ece\u4e00\u4e2a\u7ecf\u5178\u4f8b\u9898\u5165\u624b\uff0c\u5148\u7ed9\u51fa\u5b83\u7684\u66b4\u529b\u56de\u6eaf\u89e3\u6cd5\uff0c\u89c2\u5bdf\u5176\u4e2d\u5305\u542b\u7684\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u518d\u9010\u6b65\u5bfc\u51fa\u66f4\u9ad8\u6548\u7684\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\u3002

    \u722c\u697c\u68af

    \u7ed9\u5b9a\u4e00\u4e2a\u5171\u6709 \\(n\\) \u9636\u7684\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\uff0c\u8bf7\u95ee\u6709\u591a\u5c11\u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\uff1f

    \u5982\u56fe 14-1 \u6240\u793a\uff0c\u5bf9\u4e8e\u4e00\u4e2a \\(3\\) \u9636\u697c\u68af\uff0c\u5171\u6709 \\(3\\) \u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\u3002

    \u56fe 14-1 \u00a0 \u722c\u5230\u7b2c 3 \u9636\u7684\u65b9\u6848\u6570\u91cf

    \u672c\u9898\u7684\u76ee\u6807\u662f\u6c42\u89e3\u65b9\u6848\u6570\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u8003\u8651\u901a\u8fc7\u56de\u6eaf\u6765\u7a77\u4e3e\u6240\u6709\u53ef\u80fd\u6027\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u5c06\u722c\u697c\u68af\u60f3\u8c61\u4e3a\u4e00\u4e2a\u591a\u8f6e\u9009\u62e9\u7684\u8fc7\u7a0b\uff1a\u4ece\u5730\u9762\u51fa\u53d1\uff0c\u6bcf\u8f6e\u9009\u62e9\u4e0a \\(1\\) \u9636\u6216 \\(2\\) \u9636\uff0c\u6bcf\u5f53\u5230\u8fbe\u697c\u68af\u9876\u90e8\u65f6\u5c31\u5c06\u65b9\u6848\u6570\u91cf\u52a0 \\(1\\) \uff0c\u5f53\u8d8a\u8fc7\u697c\u68af\u9876\u90e8\u65f6\u5c31\u5c06\u5176\u526a\u679d\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_backtrack.py
    def backtrack(choices: list[int], state: int, n: int, res: list[int]) -> int:\n    \"\"\"\u56de\u6eaf\"\"\"\n    # \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n:\n        res[0] += 1\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res)\n        # \u56de\u9000\n\ndef climbing_stairs_backtrack(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u56de\u6eaf\"\"\"\n    choices = [1, 2]  # \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    state = 0  # \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    res = [0]  # \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res)\n    return res[0]\n
    climbing_stairs_backtrack.cpp
    /* \u56de\u6eaf */\nvoid backtrack(vector<int> &choices, int state, int n, vector<int> &res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (auto &choice : choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    vector<int> choices = {1, 2}; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0;                // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    vector<int> res = {0};        // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res[0];\n}\n
    climbing_stairs_backtrack.java
    /* \u56de\u6eaf */\nvoid backtrack(List<Integer> choices, int state, int n, List<Integer> res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Integer choice : choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    List<Integer> choices = Arrays.asList(1, 2); // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    List<Integer> res = new ArrayList<>();\n    res.add(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.cs
    /* \u56de\u6eaf */\nvoid Backtrack(List<int> choices, int state, int n, List<int> res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (int choice in choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        Backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint ClimbingStairsBacktrack(int n) {\n    List<int> choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    List<int> res = [0]; // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    Backtrack(choices, state, n, res);\n    return res[0];\n}\n
    climbing_stairs_backtrack.go
    /* \u56de\u6eaf */\nfunc backtrack(choices []int, state, n int, res []int) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] = res[0] + 1\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state+choice > n {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state+choice, n, res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunc climbingStairsBacktrack(n int) int {\n    // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    choices := []int{1, 2}\n    // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    state := 0\n    res := make([]int, 1)\n    // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    res[0] = 0\n    backtrack(choices, state, n, res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.swift
    /* \u56de\u6eaf */\nfunc backtrack(choices: [Int], state: Int, n: Int, res: inout [Int]) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] += 1\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices: choices, state: state + choice, n: n, res: &res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunc climbingStairsBacktrack(n: Int) -> Int {\n    let choices = [1, 2] // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    let state = 0 // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    var res: [Int] = []\n    res.append(0) // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices: choices, state: state, n: n, res: &res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.js
    /* \u56de\u6eaf */\nfunction backtrack(choices, state, n, res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state === n) res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunction climbingStairsBacktrack(n) {\n    const choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    const state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    const res = new Map();\n    res.set(0, 0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.ts
    /* \u56de\u6eaf */\nfunction backtrack(\n    choices: number[],\n    state: number,\n    n: number,\n    res: Map<0, any>\n): void {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state === n) res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunction climbingStairsBacktrack(n: number): number {\n    const choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    const state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    const res = new Map();\n    res.set(0, 0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.dart
    /* \u56de\u6eaf */\nvoid backtrack(List<int> choices, int state, int n, List<int> res) {\n  // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n  if (state == n) {\n    res[0]++;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int choice in choices) {\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n    if (state + choice > n) continue;\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n    backtrack(choices, state + choice, n, res);\n    // \u56de\u9000\n  }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n  List<int> choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n  int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n  List<int> res = [];\n  res.add(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n  backtrack(choices, state, n, res);\n  return res[0];\n}\n
    climbing_stairs_backtrack.rs
    /* \u56de\u6eaf */\nfn backtrack(choices: &[i32], state: i32, n: i32, res: &mut [i32]) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] = res[0] + 1;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for &choice in choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfn climbing_stairs_backtrack(n: usize) -> i32 {\n    let choices = vec![1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    let state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    let mut res = Vec::new();\n    res.push(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(&choices, state, n as i32, &mut res);\n    res[0]\n}\n
    climbing_stairs_backtrack.c
    /* \u56de\u6eaf */\nvoid backtrack(int *choices, int state, int n, int *res, int len) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < len; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res, len);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    int choices[2] = {1, 2}; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0;           // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    int *res = (int *)malloc(sizeof(int));\n    *res = 0; // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    int len = sizeof(choices) / sizeof(int);\n    backtrack(choices, state, n, res, len);\n    int result = *res;\n    free(res);\n    return result;\n}\n
    climbing_stairs_backtrack.kt
    /* \u56de\u6eaf */\nfun backtrack(\n    choices: MutableList<Int>,\n    state: Int,\n    n: Int,\n    res: MutableList<Int>\n) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0] = res[0] + 1\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfun climbingStairsBacktrack(n: Int): Int {\n    val choices = mutableListOf(1, 2) // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    val state = 0 // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    val res = mutableListOf<Int>()\n    res.add(0) // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{climbing_stairs_backtrack}\n
    climbing_stairs_backtrack.zig
    // \u56de\u6eaf\nfn backtrack(choices: []i32, state: i32, n: i32, res: std.ArrayList(i32)) void {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n) {\n        res.items[0] = res.items[0] + 1;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choices) |choice| {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n// \u722c\u697c\u68af\uff1a\u56de\u6eaf\nfn climbingStairsBacktrack(n: usize) !i32 {\n    var choices = [_]i32{ 1, 2 }; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    var state: i32 = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    var res = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer res.deinit();\n    try res.append(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(&choices, state, @intCast(n), res);\n    return res.items[0];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1411","title":"14.1.1 \u00a0 \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u641c\u7d22","text":"

    \u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u5e76\u4e0d\u663e\u5f0f\u5730\u5bf9\u95ee\u9898\u8fdb\u884c\u62c6\u89e3\uff0c\u800c\u662f\u5c06\u6c42\u89e3\u95ee\u9898\u770b\u4f5c\u4e00\u7cfb\u5217\u51b3\u7b56\u6b65\u9aa4\uff0c\u901a\u8fc7\u8bd5\u63a2\u548c\u526a\u679d\uff0c\u641c\u7d22\u6240\u6709\u53ef\u80fd\u7684\u89e3\u3002

    \u6211\u4eec\u53ef\u4ee5\u5c1d\u8bd5\u4ece\u95ee\u9898\u5206\u89e3\u7684\u89d2\u5ea6\u5206\u6790\u8fd9\u9053\u9898\u3002\u8bbe\u722c\u5230\u7b2c \\(i\\) \u9636\u5171\u6709 \\(dp[i]\\) \u79cd\u65b9\u6848\uff0c\u90a3\u4e48 \\(dp[i]\\) \u5c31\u662f\u539f\u95ee\u9898\uff0c\u5176\u5b50\u95ee\u9898\u5305\u62ec\uff1a

    \\[ dp[i-1], dp[i-2], \\dots, dp[2], dp[1] \\]

    \u7531\u4e8e\u6bcf\u8f6e\u53ea\u80fd\u4e0a \\(1\\) \u9636\u6216 \\(2\\) \u9636\uff0c\u56e0\u6b64\u5f53\u6211\u4eec\u7ad9\u5728\u7b2c \\(i\\) \u9636\u697c\u68af\u4e0a\u65f6\uff0c\u4e0a\u4e00\u8f6e\u53ea\u53ef\u80fd\u7ad9\u5728\u7b2c \\(i - 1\\) \u9636\u6216\u7b2c \\(i - 2\\) \u9636\u4e0a\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6211\u4eec\u53ea\u80fd\u4ece\u7b2c \\(i -1\\) \u9636\u6216\u7b2c \\(i - 2\\) \u9636\u8fc8\u5411\u7b2c \\(i\\) \u9636\u3002

    \u7531\u6b64\u4fbf\u53ef\u5f97\u51fa\u4e00\u4e2a\u91cd\u8981\u63a8\u8bba\uff1a\u722c\u5230\u7b2c \\(i - 1\\) \u9636\u7684\u65b9\u6848\u6570\u52a0\u4e0a\u722c\u5230\u7b2c \\(i - 2\\) \u9636\u7684\u65b9\u6848\u6570\u5c31\u7b49\u4e8e\u722c\u5230\u7b2c \\(i\\) \u9636\u7684\u65b9\u6848\u6570\u3002\u516c\u5f0f\u5982\u4e0b\uff1a

    \\[ dp[i] = dp[i-1] + dp[i-2] \\]

    \u8fd9\u610f\u5473\u7740\u5728\u722c\u697c\u68af\u95ee\u9898\u4e2d\uff0c\u5404\u4e2a\u5b50\u95ee\u9898\u4e4b\u95f4\u5b58\u5728\u9012\u63a8\u5173\u7cfb\uff0c\u539f\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u7531\u5b50\u95ee\u9898\u7684\u89e3\u6784\u5efa\u5f97\u6765\u3002\u56fe 14-2 \u5c55\u793a\u4e86\u8be5\u9012\u63a8\u5173\u7cfb\u3002

    \u56fe 14-2 \u00a0 \u65b9\u6848\u6570\u91cf\u9012\u63a8\u5173\u7cfb

    \u6211\u4eec\u53ef\u4ee5\u6839\u636e\u9012\u63a8\u516c\u5f0f\u5f97\u5230\u66b4\u529b\u641c\u7d22\u89e3\u6cd5\u3002\u4ee5 \\(dp[n]\\) \u4e3a\u8d77\u59cb\u70b9\uff0c\u9012\u5f52\u5730\u5c06\u4e00\u4e2a\u8f83\u5927\u95ee\u9898\u62c6\u89e3\u4e3a\u4e24\u4e2a\u8f83\u5c0f\u95ee\u9898\u7684\u548c\uff0c\u76f4\u81f3\u5230\u8fbe\u6700\u5c0f\u5b50\u95ee\u9898 \\(dp[1]\\) \u548c \\(dp[2]\\) \u65f6\u8fd4\u56de\u3002\u5176\u4e2d\uff0c\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\u662f\u5df2\u77e5\u7684\uff0c\u5373 \\(dp[1] = 1\\)\u3001\\(dp[2] = 2\\) \uff0c\u8868\u793a\u722c\u5230\u7b2c \\(1\\)\u3001\\(2\\) \u9636\u5206\u522b\u6709 \\(1\\)\u3001\\(2\\) \u79cd\u65b9\u6848\u3002

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u5b83\u548c\u6807\u51c6\u56de\u6eaf\u4ee3\u7801\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\uff0c\u4f46\u66f4\u52a0\u7b80\u6d01\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dfs.py
    def dfs(i: int) -> int:\n    \"\"\"\u641c\u7d22\"\"\"\n    # \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 or i == 2:\n        return i\n    # dp[i] = dp[i-1] + dp[i-2]\n    count = dfs(i - 1) + dfs(i - 2)\n    return count\n\ndef climbing_stairs_dfs(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u641c\u7d22\"\"\"\n    return dfs(n)\n
    climbing_stairs_dfs.cpp
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.java
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.cs
    /* \u641c\u7d22 */\nint DFS(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = DFS(i - 1) + DFS(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint ClimbingStairsDFS(int n) {\n    return DFS(n);\n}\n
    climbing_stairs_dfs.go
    /* \u641c\u7d22 */\nfunc dfs(i int) int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    count := dfs(i-1) + dfs(i-2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunc climbingStairsDFS(n int) int {\n    return dfs(n)\n}\n
    climbing_stairs_dfs.swift
    /* \u641c\u7d22 */\nfunc dfs(i: Int) -> Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i: i - 1) + dfs(i: i - 2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunc climbingStairsDFS(n: Int) -> Int {\n    dfs(i: n)\n}\n
    climbing_stairs_dfs.js
    /* \u641c\u7d22 */\nfunction dfs(i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunction climbingStairsDFS(n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.ts
    /* \u641c\u7d22 */\nfunction dfs(i: number): number {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunction climbingStairsDFS(n: number): number {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.dart
    /* \u641c\u7d22 */\nint dfs(int i) {\n  // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n  if (i == 1 || i == 2) return i;\n  // dp[i] = dp[i-1] + dp[i-2]\n  int count = dfs(i - 1) + dfs(i - 2);\n  return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n  return dfs(n);\n}\n
    climbing_stairs_dfs.rs
    /* \u641c\u7d22 */\nfn dfs(i: usize) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i as i32;\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i - 1) + dfs(i - 2);\n    count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfn climbing_stairs_dfs(n: usize) -> i32 {\n    dfs(n)\n}\n
    climbing_stairs_dfs.c
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.kt
    /* \u641c\u7d22 */\nfun dfs(i: Int): Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2) return i\n    // dp[i] = dp[i-1] + dp[i-2]\n    val count = dfs(i - 1) + dfs(i - 2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfun climbingStairsDFS(n: Int): Int {\n    return dfs(n)\n}\n
    climbing_stairs_dfs.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{climbing_stairs_dfs}\n
    climbing_stairs_dfs.zig
    // \u641c\u7d22\nfn dfs(i: usize) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 or i == 2) {\n        return @intCast(i);\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    var count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n// \u722c\u697c\u68af\uff1a\u641c\u7d22\nfn climbingStairsDFS(comptime n: usize) i32 {\n    return dfs(n);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-3 \u5c55\u793a\u4e86\u66b4\u529b\u641c\u7d22\u5f62\u6210\u7684\u9012\u5f52\u6811\u3002\u5bf9\u4e8e\u95ee\u9898 \\(dp[n]\\) \uff0c\u5176\u9012\u5f52\u6811\u7684\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \u3002\u6307\u6570\u9636\u5c5e\u4e8e\u7206\u70b8\u5f0f\u589e\u957f\uff0c\u5982\u679c\u6211\u4eec\u8f93\u5165\u4e00\u4e2a\u6bd4\u8f83\u5927\u7684 \\(n\\) \uff0c\u5219\u4f1a\u9677\u5165\u6f2b\u957f\u7684\u7b49\u5f85\u4e4b\u4e2d\u3002

    \u56fe 14-3 \u00a0 \u722c\u697c\u68af\u5bf9\u5e94\u9012\u5f52\u6811

    \u89c2\u5bdf\u56fe 14-3 \uff0c\u6307\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u201c\u91cd\u53e0\u5b50\u95ee\u9898\u201d\u5bfc\u81f4\u7684\u3002\u4f8b\u5982 \\(dp[9]\\) \u88ab\u5206\u89e3\u4e3a \\(dp[8]\\) \u548c \\(dp[7]\\) \uff0c\\(dp[8]\\) \u88ab\u5206\u89e3\u4e3a \\(dp[7]\\) \u548c \\(dp[6]\\) \uff0c\u4e24\u8005\u90fd\u5305\u542b\u5b50\u95ee\u9898 \\(dp[7]\\) \u3002

    \u4ee5\u6b64\u7c7b\u63a8\uff0c\u5b50\u95ee\u9898\u4e2d\u5305\u542b\u66f4\u5c0f\u7684\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u5b50\u5b50\u5b59\u5b59\u65e0\u7a77\u5c3d\u4e5f\u3002\u7edd\u5927\u90e8\u5206\u8ba1\u7b97\u8d44\u6e90\u90fd\u6d6a\u8d39\u5728\u8fd9\u4e9b\u91cd\u53e0\u7684\u5b50\u95ee\u9898\u4e0a\u3002

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1412","title":"14.1.2 \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22","text":"

    \u4e3a\u4e86\u63d0\u5347\u7b97\u6cd5\u6548\u7387\uff0c\u6211\u4eec\u5e0c\u671b\u6240\u6709\u7684\u91cd\u53e0\u5b50\u95ee\u9898\u90fd\u53ea\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u6570\u7ec4 mem \u6765\u8bb0\u5f55\u6bcf\u4e2a\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5e76\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u5c06\u91cd\u53e0\u5b50\u95ee\u9898\u526a\u679d\u3002

    1. \u5f53\u9996\u6b21\u8ba1\u7b97 \\(dp[i]\\) \u65f6\uff0c\u6211\u4eec\u5c06\u5176\u8bb0\u5f55\u81f3 mem[i] \uff0c\u4ee5\u4fbf\u4e4b\u540e\u4f7f\u7528\u3002
    2. \u5f53\u518d\u6b21\u9700\u8981\u8ba1\u7b97 \\(dp[i]\\) \u65f6\uff0c\u6211\u4eec\u4fbf\u53ef\u76f4\u63a5\u4ece mem[i] \u4e2d\u83b7\u53d6\u7ed3\u679c\uff0c\u4ece\u800c\u907f\u514d\u91cd\u590d\u8ba1\u7b97\u8be5\u5b50\u95ee\u9898\u3002

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dfs_mem.py
    def dfs(i: int, mem: list[int]) -> int:\n    \"\"\"\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 or i == 2:\n        return i\n    # \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1:\n        return mem[i]\n    # dp[i] = dp[i-1] + dp[i-2]\n    count = dfs(i - 1, mem) + dfs(i - 2, mem)\n    # \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n\ndef climbing_stairs_dfs_mem(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    mem = [-1] * (n + 1)\n    return dfs(n, mem)\n
    climbing_stairs_dfs_mem.cpp
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, vector<int> &mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    vector<int> mem(n + 1, -1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.java
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, int[] mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int[] mem = new int[n + 1];\n    Arrays.fill(mem, -1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.cs
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint DFS(int i, int[] mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = DFS(i - 1, mem) + DFS(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint ClimbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int[] mem = new int[n + 1];\n    Array.Fill(mem, -1);\n    return DFS(n, mem);\n}\n
    climbing_stairs_dfs_mem.go
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc dfsMem(i int, mem []int) int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i]\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    count := dfsMem(i-1, mem) + dfsMem(i-2, mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc climbingStairsDFSMem(n int) int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    mem := make([]int, n+1)\n    for i := range mem {\n        mem[i] = -1\n    }\n    return dfsMem(n, mem)\n}\n
    climbing_stairs_dfs_mem.swift
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc dfs(i: Int, mem: inout [Int]) -> Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i]\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i: i - 1, mem: &mem) + dfs(i: i - 2, mem: &mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc climbingStairsDFSMem(n: Int) -> Int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    var mem = Array(repeating: -1, count: n + 1)\n    return dfs(i: n, mem: &mem)\n}\n
    climbing_stairs_dfs_mem.js
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction dfs(i, mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction climbingStairsDFSMem(n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    const mem = new Array(n + 1).fill(-1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.ts
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction dfs(i: number, mem: number[]): number {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction climbingStairsDFSMem(n: number): number {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    const mem = new Array(n + 1).fill(-1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.dart
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, List<int> mem) {\n  // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n  if (i == 1 || i == 2) return i;\n  // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n  if (mem[i] != -1) return mem[i];\n  // dp[i] = dp[i-1] + dp[i-2]\n  int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n  // \u8bb0\u5f55 dp[i]\n  mem[i] = count;\n  return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n  // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n  List<int> mem = List.filled(n + 1, -1);\n  return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.rs
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn dfs(i: usize, mem: &mut [i32]) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i as i32;\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i];\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn climbing_stairs_dfs_mem(n: usize) -> i32 {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    let mut mem = vec![-1; n + 1];\n    dfs(n, &mut mem)\n}\n
    climbing_stairs_dfs_mem.c
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, int *mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int *mem = (int *)malloc((n + 1) * sizeof(int));\n    for (int i = 0; i <= n; i++) {\n        mem[i] = -1;\n    }\n    int result = dfs(n, mem);\n    free(mem);\n    return result;\n}\n
    climbing_stairs_dfs_mem.kt
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun dfs(i: Int, mem: IntArray): Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2) return i\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i]\n    // dp[i] = dp[i-1] + dp[i-2]\n    val count = dfs(i - 1, mem) + dfs(i - 2, mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun climbingStairsDFSMem(n: Int): Int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    val mem = IntArray(n + 1)\n    mem.fill(-1)\n    return dfs(n, mem)\n}\n
    climbing_stairs_dfs_mem.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{climbing_stairs_dfs_mem}\n
    climbing_stairs_dfs_mem.zig
    // \u8bb0\u5fc6\u5316\u641c\u7d22\nfn dfs(i: usize, mem: []i32) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 or i == 2) {\n        return @intCast(i);\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) {\n        return mem[i];\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    var count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n// \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn climbingStairsDFSMem(comptime n: usize) i32 {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    var mem = [_]i32{ -1 } ** (n + 1);\n    return dfs(n, &mem);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u56fe 14-4 \uff0c\u7ecf\u8fc7\u8bb0\u5fc6\u5316\u5904\u7406\u540e\uff0c\u6240\u6709\u91cd\u53e0\u5b50\u95ee\u9898\u90fd\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(n)\\) \uff0c\u8fd9\u662f\u4e00\u4e2a\u5de8\u5927\u7684\u98de\u8dc3\u3002

    \u56fe 14-4 \u00a0 \u8bb0\u5fc6\u5316\u641c\u7d22\u5bf9\u5e94\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1413","title":"14.1.3 \u00a0 \u65b9\u6cd5\u4e09\uff1a\u52a8\u6001\u89c4\u5212","text":"

    \u8bb0\u5fc6\u5316\u641c\u7d22\u662f\u4e00\u79cd\u201c\u4ece\u9876\u81f3\u5e95\u201d\u7684\u65b9\u6cd5\uff1a\u6211\u4eec\u4ece\u539f\u95ee\u9898\uff08\u6839\u8282\u70b9\uff09\u5f00\u59cb\uff0c\u9012\u5f52\u5730\u5c06\u8f83\u5927\u5b50\u95ee\u9898\u5206\u89e3\u4e3a\u8f83\u5c0f\u5b50\u95ee\u9898\uff0c\u76f4\u81f3\u89e3\u5df2\u77e5\u7684\u6700\u5c0f\u5b50\u95ee\u9898\uff08\u53f6\u8282\u70b9\uff09\u3002\u4e4b\u540e\uff0c\u901a\u8fc7\u56de\u6eaf\u9010\u5c42\u6536\u96c6\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u6784\u5efa\u51fa\u539f\u95ee\u9898\u7684\u89e3\u3002

    \u4e0e\u4e4b\u76f8\u53cd\uff0c\u52a8\u6001\u89c4\u5212\u662f\u4e00\u79cd\u201c\u4ece\u5e95\u81f3\u9876\u201d\u7684\u65b9\u6cd5\uff1a\u4ece\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\u5f00\u59cb\uff0c\u8fed\u4ee3\u5730\u6784\u5efa\u66f4\u5927\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u76f4\u81f3\u5f97\u5230\u539f\u95ee\u9898\u7684\u89e3\u3002

    \u7531\u4e8e\u52a8\u6001\u89c4\u5212\u4e0d\u5305\u542b\u56de\u6eaf\u8fc7\u7a0b\uff0c\u56e0\u6b64\u53ea\u9700\u4f7f\u7528\u5faa\u73af\u8fed\u4ee3\u5b9e\u73b0\uff0c\u65e0\u987b\u4f7f\u7528\u9012\u5f52\u3002\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u521d\u59cb\u5316\u4e00\u4e2a\u6570\u7ec4 dp \u6765\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5b83\u8d77\u5230\u4e86\u4e0e\u8bb0\u5fc6\u5316\u641c\u7d22\u4e2d\u6570\u7ec4 mem \u76f8\u540c\u7684\u8bb0\u5f55\u4f5c\u7528\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dp.py
    def climbing_stairs_dp(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return n\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [0] * (n + 1)\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1], dp[2] = 1, 2\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i] = dp[i - 1] + dp[i - 2]\n    return dp[n]\n
    climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<int> dp(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.java
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.go
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDP(n int) int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i] = dp[i-1] + dp[i-2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDP(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: 0, count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i] = dp[i - 1] + dp[i - 2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.js
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDP(n) {\n    if (n === 1 || n === 2) return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1).fill(-1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDP(n: number): number {\n    if (n === 1 || n === 2) return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1).fill(-1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n  if (n == 1 || n == 2) return n;\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<int> dp = List.filled(n + 1, 0);\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1] = 1;\n  dp[2] = 2;\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i] = dp[i - 1] + dp[i - 2];\n  }\n  return dp[n];\n}\n
    climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_dp(n: usize) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if n == 1 || n == 2 {\n        return n as i32;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![-1; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    dp[n]\n}\n
    climbing_stairs_dp.c
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int *dp = (int *)malloc((n + 1) * sizeof(int));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    int result = dp[n];\n    free(dp);\n    return result;\n}\n
    climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsDP(n: Int): Int {\n    if (n == 1 || n == 2) return n\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = IntArray(n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i] = dp[i - 1] + dp[i - 2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.rb
    [class]{}-[func]{climbing_stairs_dp}\n
    climbing_stairs_dp.zig
    // \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\nfn climbingStairsDP(comptime n: usize) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (n == 1 or n == 2) {\n        return @intCast(n);\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_]i32{-1} ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-5 \u6a21\u62df\u4e86\u4ee5\u4e0a\u4ee3\u7801\u7684\u6267\u884c\u8fc7\u7a0b\u3002

    \u56fe 14-5 \u00a0 \u722c\u697c\u68af\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u4e0e\u56de\u6eaf\u7b97\u6cd5\u4e00\u6837\uff0c\u52a8\u6001\u89c4\u5212\u4e5f\u4f7f\u7528\u201c\u72b6\u6001\u201d\u6982\u5ff5\u6765\u8868\u793a\u95ee\u9898\u6c42\u89e3\u7684\u7279\u5b9a\u9636\u6bb5\uff0c\u6bcf\u4e2a\u72b6\u6001\u90fd\u5bf9\u5e94\u4e00\u4e2a\u5b50\u95ee\u9898\u4ee5\u53ca\u76f8\u5e94\u7684\u5c40\u90e8\u6700\u4f18\u89e3\u3002\u4f8b\u5982\uff0c\u722c\u697c\u68af\u95ee\u9898\u7684\u72b6\u6001\u5b9a\u4e49\u4e3a\u5f53\u524d\u6240\u5728\u697c\u68af\u9636\u6570 \\(i\\) \u3002

    \u6839\u636e\u4ee5\u4e0a\u5185\u5bb9\uff0c\u6211\u4eec\u53ef\u4ee5\u603b\u7ed3\u51fa\u52a8\u6001\u89c4\u5212\u7684\u5e38\u7528\u672f\u8bed\u3002

    • \u5c06\u6570\u7ec4 dp \u79f0\u4e3a dp \u8868\uff0c\\(dp[i]\\) \u8868\u793a\u72b6\u6001 \\(i\\) \u5bf9\u5e94\u5b50\u95ee\u9898\u7684\u89e3\u3002
    • \u5c06\u6700\u5c0f\u5b50\u95ee\u9898\u5bf9\u5e94\u7684\u72b6\u6001\uff08\u7b2c \\(1\\) \u9636\u548c\u7b2c \\(2\\) \u9636\u697c\u68af\uff09\u79f0\u4e3a\u521d\u59cb\u72b6\u6001\u3002
    • \u5c06\u9012\u63a8\u516c\u5f0f \\(dp[i] = dp[i-1] + dp[i-2]\\) \u79f0\u4e3a\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002
    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1414","title":"14.1.4 \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7ec6\u5fc3\u7684\u8bfb\u8005\u53ef\u80fd\u53d1\u73b0\u4e86\uff0c\u7531\u4e8e \\(dp[i]\\) \u53ea\u4e0e \\(dp[i-1]\\) \u548c \\(dp[i-2]\\) \u6709\u5173\uff0c\u56e0\u6b64\u6211\u4eec\u65e0\u987b\u4f7f\u7528\u4e00\u4e2a\u6570\u7ec4 dp \u6765\u5b58\u50a8\u6240\u6709\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u800c\u53ea\u9700\u4e24\u4e2a\u53d8\u91cf\u6eda\u52a8\u524d\u8fdb\u5373\u53ef\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dp.py
    def climbing_stairs_dp_comp(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return n\n    a, b = 1, 2\n    for _ in range(3, n + 1):\n        a, b = b, a + b\n    return b\n
    climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.java
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.go
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDPComp(n int) int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    a, b := 1, 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        a, b = b, a+b\n    }\n    return b\n}\n
    climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDPComp(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    var a = 1\n    var b = 2\n    for _ in 3 ... n {\n        (a, b) = (b, a + b)\n    }\n    return b\n}\n
    climbing_stairs_dp.js
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDPComp(n) {\n    if (n === 1 || n === 2) return n;\n    let a = 1,\n        b = 2;\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDPComp(n: number): number {\n    if (n === 1 || n === 2) return n;\n    let a = 1,\n        b = 2;\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n  if (n == 1 || n == 2) return n;\n  int a = 1, b = 2;\n  for (int i = 3; i <= n; i++) {\n    int tmp = b;\n    b = a + b;\n    a = tmp;\n  }\n  return b;\n}\n
    climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_dp_comp(n: usize) -> i32 {\n    if n == 1 || n == 2 {\n        return n as i32;\n    }\n    let (mut a, mut b) = (1, 2);\n    for _ in 3..=n {\n        let tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    b\n}\n
    climbing_stairs_dp.c
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsDPComp(n: Int): Int {\n    if (n == 1 || n == 2) return n\n    var a = 1\n    var b = 2\n    for (i in 3..n) {\n        val temp = b\n        b += a\n        a = temp\n    }\n    return b\n}\n
    climbing_stairs_dp.rb
    [class]{}-[func]{climbing_stairs_dp_comp}\n
    climbing_stairs_dp.zig
    // \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn climbingStairsDPComp(comptime n: usize) i32 {\n    if (n == 1 or n == 2) {\n        return @intCast(n);\n    }\n    var a: i32 = 1;\n    var b: i32 = 2;\n    for (3..n + 1) |_| {\n        var tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u4ee5\u4e0a\u4ee3\u7801\uff0c\u7531\u4e8e\u7701\u53bb\u4e86\u6570\u7ec4 dp \u5360\u7528\u7684\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n)\\) \u964d\u81f3 \\(O(1)\\) \u3002

    \u5728\u52a8\u6001\u89c4\u5212\u95ee\u9898\u4e2d\uff0c\u5f53\u524d\u72b6\u6001\u5f80\u5f80\u4ec5\u4e0e\u524d\u9762\u6709\u9650\u4e2a\u72b6\u6001\u6709\u5173\uff0c\u8fd9\u65f6\u6211\u4eec\u53ef\u4ee5\u53ea\u4fdd\u7559\u5fc5\u8981\u7684\u72b6\u6001\uff0c\u901a\u8fc7\u201c\u964d\u7ef4\u201d\u6765\u8282\u7701\u5185\u5b58\u7a7a\u95f4\u3002\u8fd9\u79cd\u7a7a\u95f4\u4f18\u5316\u6280\u5de7\u88ab\u79f0\u4e3a\u201c\u6eda\u52a8\u53d8\u91cf\u201d\u6216\u201c\u6eda\u52a8\u6570\u7ec4\u201d\u3002

    "},{"location":"chapter_dynamic_programming/knapsack_problem/","title":"14.4 \u00a0 0-1 \u80cc\u5305\u95ee\u9898","text":"

    \u80cc\u5305\u95ee\u9898\u662f\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u52a8\u6001\u89c4\u5212\u5165\u95e8\u9898\u76ee\uff0c\u662f\u52a8\u6001\u89c4\u5212\u4e2d\u6700\u5e38\u89c1\u7684\u95ee\u9898\u5f62\u5f0f\u3002\u5176\u5177\u6709\u5f88\u591a\u53d8\u79cd\uff0c\u4f8b\u5982 0-1 \u80cc\u5305\u95ee\u9898\u3001\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u3001\u591a\u91cd\u80cc\u5305\u95ee\u9898\u7b49\u3002

    \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5148\u6765\u6c42\u89e3\u6700\u5e38\u89c1\u7684 0-1 \u80cc\u5305\u95ee\u9898\u3002

    Question

    \u7ed9\u5b9a \\(n\\) \u4e2a\u7269\u54c1\uff0c\u7b2c \\(i\\) \u4e2a\u7269\u54c1\u7684\u91cd\u91cf\u4e3a \\(wgt[i-1]\\)\u3001\u4ef7\u503c\u4e3a \\(val[i-1]\\) \uff0c\u548c\u4e00\u4e2a\u5bb9\u91cf\u4e3a \\(cap\\) \u7684\u80cc\u5305\u3002\u6bcf\u4e2a\u7269\u54c1\u53ea\u80fd\u9009\u62e9\u4e00\u6b21\uff0c\u95ee\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80fd\u653e\u5165\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u3002

    \u89c2\u5bdf\u56fe 14-17 \uff0c\u7531\u4e8e\u7269\u54c1\u7f16\u53f7 \\(i\\) \u4ece \\(1\\) \u5f00\u59cb\u8ba1\u6570\uff0c\u6570\u7ec4\u7d22\u5f15\u4ece \\(0\\) \u5f00\u59cb\u8ba1\u6570\uff0c\u56e0\u6b64\u7269\u54c1 \\(i\\) \u5bf9\u5e94\u91cd\u91cf \\(wgt[i-1]\\) \u548c\u4ef7\u503c \\(val[i-1]\\) \u3002

    \u56fe 14-17 \u00a0 0-1 \u80cc\u5305\u7684\u793a\u4f8b\u6570\u636e

    \u6211\u4eec\u53ef\u4ee5\u5c06 0-1 \u80cc\u5305\u95ee\u9898\u770b\u4f5c\u4e00\u4e2a\u7531 \\(n\\) \u8f6e\u51b3\u7b56\u7ec4\u6210\u7684\u8fc7\u7a0b\uff0c\u5bf9\u4e8e\u6bcf\u4e2a\u7269\u4f53\u90fd\u6709\u4e0d\u653e\u5165\u548c\u653e\u5165\u4e24\u79cd\u51b3\u7b56\uff0c\u56e0\u6b64\u8be5\u95ee\u9898\u6ee1\u8db3\u51b3\u7b56\u6811\u6a21\u578b\u3002

    \u8be5\u95ee\u9898\u7684\u76ee\u6807\u662f\u6c42\u89e3\u201c\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80fd\u653e\u5165\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u201d\uff0c\u56e0\u6b64\u8f83\u5927\u6982\u7387\u662f\u4e00\u4e2a\u52a8\u6001\u89c4\u5212\u95ee\u9898\u3002

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u5bf9\u4e8e\u6bcf\u4e2a\u7269\u54c1\u6765\u8bf4\uff0c\u4e0d\u653e\u5165\u80cc\u5305\uff0c\u80cc\u5305\u5bb9\u91cf\u4e0d\u53d8\uff1b\u653e\u5165\u80cc\u5305\uff0c\u80cc\u5305\u5bb9\u91cf\u51cf\u5c0f\u3002\u7531\u6b64\u53ef\u5f97\u72b6\u6001\u5b9a\u4e49\uff1a\u5f53\u524d\u7269\u54c1\u7f16\u53f7 \\(i\\) \u548c\u80cc\u5305\u5bb9\u91cf \\(c\\) \uff0c\u8bb0\u4e3a \\([i, c]\\) \u3002

    \u72b6\u6001 \\([i, c]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u4e3a\uff1a\u524d \\(i\\) \u4e2a\u7269\u54c1\u5728\u5bb9\u91cf\u4e3a \\(c\\) \u7684\u80cc\u5305\u4e2d\u7684\u6700\u5927\u4ef7\u503c\uff0c\u8bb0\u4e3a \\(dp[i, c]\\) \u3002

    \u5f85\u6c42\u89e3\u7684\u662f \\(dp[n, cap]\\) \uff0c\u56e0\u6b64\u9700\u8981\u4e00\u4e2a\u5c3a\u5bf8\u4e3a \\((n+1) \\times (cap+1)\\) \u7684\u4e8c\u7ef4 \\(dp\\) \u8868\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u5f53\u6211\u4eec\u505a\u51fa\u7269\u54c1 \\(i\\) \u7684\u51b3\u7b56\u540e\uff0c\u5269\u4f59\u7684\u662f\u524d \\(i-1\\) \u4e2a\u7269\u54c1\u51b3\u7b56\u7684\u5b50\u95ee\u9898\uff0c\u53ef\u5206\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u60c5\u51b5\u3002

    • \u4e0d\u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u80cc\u5305\u5bb9\u91cf\u4e0d\u53d8\uff0c\u72b6\u6001\u53d8\u5316\u4e3a \\([i-1, c]\\) \u3002
    • \u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u80cc\u5305\u5bb9\u91cf\u51cf\u5c11 \\(wgt[i-1]\\) \uff0c\u4ef7\u503c\u589e\u52a0 \\(val[i-1]\\) \uff0c\u72b6\u6001\u53d8\u5316\u4e3a \\([i-1, c-wgt[i-1]]\\) \u3002

    \u4e0a\u8ff0\u5206\u6790\u5411\u6211\u4eec\u63ed\u793a\u4e86\u672c\u9898\u7684\u6700\u4f18\u5b50\u7ed3\u6784\uff1a\u6700\u5927\u4ef7\u503c \\(dp[i, c]\\) \u7b49\u4e8e\u4e0d\u653e\u5165\u7269\u54c1 \\(i\\) \u548c\u653e\u5165\u7269\u54c1 \\(i\\) \u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\u3002\u7531\u6b64\u53ef\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff1a

    \\[ dp[i, c] = \\max(dp[i-1, c], dp[i-1, c - wgt[i-1]] + val[i-1]) \\]

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u82e5\u5f53\u524d\u7269\u54c1\u91cd\u91cf \\(wgt[i - 1]\\) \u8d85\u51fa\u5269\u4f59\u80cc\u5305\u5bb9\u91cf \\(c\\) \uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\u3002

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5f53\u65e0\u7269\u54c1\u6216\u80cc\u5305\u5bb9\u91cf\u4e3a \\(0\\) \u65f6\u6700\u5927\u4ef7\u503c\u4e3a \\(0\\) \uff0c\u5373\u9996\u5217 \\(dp[i, 0]\\) \u548c\u9996\u884c \\(dp[0, c]\\) \u90fd\u7b49\u4e8e \\(0\\) \u3002

    \u5f53\u524d\u72b6\u6001 \\([i, c]\\) \u4ece\u4e0a\u65b9\u7684\u72b6\u6001 \\([i-1, c]\\) \u548c\u5de6\u4e0a\u65b9\u7684\u72b6\u6001 \\([i-1, c-wgt[i-1]]\\) \u8f6c\u79fb\u800c\u6765\uff0c\u56e0\u6b64\u901a\u8fc7\u4e24\u5c42\u5faa\u73af\u6b63\u5e8f\u904d\u5386\u6574\u4e2a \\(dp\\) \u8868\u5373\u53ef\u3002

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u6211\u4eec\u63a5\u4e0b\u6765\u6309\u987a\u5e8f\u5b9e\u73b0\u66b4\u529b\u641c\u7d22\u3001\u8bb0\u5fc6\u5316\u641c\u7d22\u3001\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\u3002

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#1","title":"1. \u00a0 \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u641c\u7d22","text":"

    \u641c\u7d22\u4ee3\u7801\u5305\u542b\u4ee5\u4e0b\u8981\u7d20\u3002

    • \u9012\u5f52\u53c2\u6570\uff1a\u72b6\u6001 \\([i, c]\\) \u3002
    • \u8fd4\u56de\u503c\uff1a\u5b50\u95ee\u9898\u7684\u89e3 \\(dp[i, c]\\) \u3002
    • \u7ec8\u6b62\u6761\u4ef6\uff1a\u5f53\u7269\u54c1\u7f16\u53f7\u8d8a\u754c \\(i = 0\\) \u6216\u80cc\u5305\u5269\u4f59\u5bb9\u91cf\u4e3a \\(0\\) \u65f6\uff0c\u7ec8\u6b62\u9012\u5f52\u5e76\u8fd4\u56de\u4ef7\u503c \\(0\\) \u3002
    • \u526a\u679d\uff1a\u82e5\u5f53\u524d\u7269\u54c1\u91cd\u91cf\u8d85\u51fa\u80cc\u5305\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dfs(wgt: list[int], val: list[int], i: int, c: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22\"\"\"\n    # \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 or c == 0:\n        return 0\n    # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c:\n        return knapsack_dfs(wgt, val, i - 1, c)\n    # \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no = knapsack_dfs(wgt, val, i - 1, c)\n    yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]\n    # \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(vector<int> &wgt, vector<int> &val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes);\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(int[] wgt, int[] val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint KnapsackDFS(int[] weight, int[] val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (weight[i - 1] > c) {\n        return KnapsackDFS(weight, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = KnapsackDFS(weight, val, i - 1, c);\n    int yes = KnapsackDFS(weight, val, i - 1, c - weight[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.Max(no, yes);\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc knapsackDFS(wgt, val []int, i, c int) int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i-1] > c {\n        return knapsackDFS(wgt, val, i-1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no := knapsackDFS(wgt, val, i-1, c)\n    yes := knapsackDFS(wgt, val, i-1, c-wgt[i-1]) + val[i-1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return int(math.Max(float64(no), float64(yes)))\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc knapsackDFS(wgt: [Int], val: [Int], i: Int, c: Int) -> Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c {\n        return knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c)\n    let yes = knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c - wgt[i - 1]) + val[i - 1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction knapsackDFS(wgt, val, i, c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFS(wgt, val, i - 1, c);\n    const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction knapsackDFS(\n    wgt: Array<number>,\n    val: Array<number>,\n    i: number,\n    c: number\n): number {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFS(wgt, val, i - 1, c);\n    const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(List<int> wgt, List<int> val, int i, int c) {\n  // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n  if (i == 0 || c == 0) {\n    return 0;\n  }\n  // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n  if (wgt[i - 1] > c) {\n    return knapsackDFS(wgt, val, i - 1, c);\n  }\n  // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n  int no = knapsackDFS(wgt, val, i - 1, c);\n  int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n  // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n  return max(no, yes);\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfn knapsack_dfs(wgt: &[i32], val: &[i32], i: usize, c: usize) -> i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c as i32 {\n        return knapsack_dfs(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsack_dfs(wgt, val, i - 1, c);\n    let yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1] as usize) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    std::cmp::max(no, yes)\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(int wgt[], int val[], int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return myMax(no, yes);\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfun knapsackDFS(\n    wgt: IntArray,\n    _val: IntArray,\n    i: Int,\n    c: Int\n): Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, _val, i - 1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    val no = knapsackDFS(wgt, _val, i - 1, c)\n    val yes = knapsackDFS(wgt, _val, i - 1, c - wgt[i - 1]) + _val[i - 1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dfs}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22\nfn knapsackDFS(wgt: []i32, val: []i32, i: usize, c: usize) i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 or c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    var no = knapsackDFS(wgt, val, i - 1, c);\n    var yes = knapsackDFS(wgt, val, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return @max(no, yes);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-18 \u6240\u793a\uff0c\u7531\u4e8e\u6bcf\u4e2a\u7269\u54c1\u90fd\u4f1a\u4ea7\u751f\u4e0d\u9009\u548c\u9009\u4e24\u6761\u641c\u7d22\u5206\u652f\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \u3002

    \u89c2\u5bdf\u9012\u5f52\u6811\uff0c\u5bb9\u6613\u53d1\u73b0\u5176\u4e2d\u5b58\u5728\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u4f8b\u5982 \\(dp[1, 10]\\) \u7b49\u3002\u800c\u5f53\u7269\u54c1\u8f83\u591a\u3001\u80cc\u5305\u5bb9\u91cf\u8f83\u5927\uff0c\u5c24\u5176\u662f\u76f8\u540c\u91cd\u91cf\u7684\u7269\u54c1\u8f83\u591a\u65f6\uff0c\u91cd\u53e0\u5b50\u95ee\u9898\u7684\u6570\u91cf\u5c06\u4f1a\u5927\u5e45\u589e\u591a\u3002

    \u56fe 14-18 \u00a0 0-1 \u80cc\u5305\u95ee\u9898\u7684\u66b4\u529b\u641c\u7d22\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#2","title":"2. \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22","text":"

    \u4e3a\u4e86\u4fdd\u8bc1\u91cd\u53e0\u5b50\u95ee\u9898\u53ea\u88ab\u8ba1\u7b97\u4e00\u6b21\uff0c\u6211\u4eec\u501f\u52a9\u8bb0\u5fc6\u5217\u8868 mem \u6765\u8bb0\u5f55\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5176\u4e2d mem[i][c] \u5bf9\u5e94 \\(dp[i, c]\\) \u3002

    \u5f15\u5165\u8bb0\u5fc6\u5316\u4e4b\u540e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5b50\u95ee\u9898\u6570\u91cf\uff0c\u4e5f\u5c31\u662f \\(O(n \\times cap)\\) \u3002\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dfs_mem(\n    wgt: list[int], val: list[int], mem: list[list[int]], i: int, c: int\n) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 or c == 0:\n        return 0\n    # \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1:\n        return mem[i][c]\n    # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c:\n        return knapsack_dfs_mem(wgt, val, mem, i - 1, c)\n    # \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no = knapsack_dfs_mem(wgt, val, mem, i - 1, c)\n    yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1]\n    # \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(vector<int> &wgt, vector<int> &val, vector<vector<int>> &mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(int[] wgt, int[] val, int[][] mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint KnapsackDFSMem(int[] weight, int[] val, int[][] mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (weight[i - 1] > c) {\n        return KnapsackDFSMem(weight, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = KnapsackDFSMem(weight, val, mem, i - 1, c);\n    int yes = KnapsackDFSMem(weight, val, mem, i - 1, c - weight[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.Max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc knapsackDFSMem(wgt, val []int, mem [][]int, i, c int) int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i-1] > c {\n        return knapsackDFSMem(wgt, val, mem, i-1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no := knapsackDFSMem(wgt, val, mem, i-1, c)\n    yes := knapsackDFSMem(wgt, val, mem, i-1, c-wgt[i-1]) + val[i-1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = int(math.Max(float64(no), float64(yes)))\n    return mem[i][c]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc knapsackDFSMem(wgt: [Int], val: [Int], mem: inout [[Int]], i: Int, c: Int) -> Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c {\n        return knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c)\n    let yes = knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c - wgt[i - 1]) + val[i - 1]\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction knapsackDFSMem(wgt, val, mem, i, c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] !== -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    const yes =\n        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction knapsackDFSMem(\n    wgt: Array<number>,\n    val: Array<number>,\n    mem: Array<Array<number>>,\n    i: number,\n    c: number\n): number {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] !== -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    const yes =\n        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(\n  List<int> wgt,\n  List<int> val,\n  List<List<int>> mem,\n  int i,\n  int c,\n) {\n  // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n  if (i == 0 || c == 0) {\n    return 0;\n  }\n  // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  if (mem[i][c] != -1) {\n    return mem[i][c];\n  }\n  // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n  if (wgt[i - 1] > c) {\n    return knapsackDFSMem(wgt, val, mem, i - 1, c);\n  }\n  // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n  int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n  int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n  // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n  mem[i][c] = max(no, yes);\n  return mem[i][c];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn knapsack_dfs_mem(wgt: &[i32], val: &[i32], mem: &mut Vec<Vec<i32>>, i: usize, c: usize) -> i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c as i32 {\n        return knapsack_dfs_mem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsack_dfs_mem(wgt, val, mem, i - 1, c);\n    let yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1] as usize) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = std::cmp::max(no, yes);\n    mem[i][c]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(int wgt[], int val[], int memCols, int **mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, memCols, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = myMax(no, yes);\n    return mem[i][c];\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun knapsackDFSMem(\n    wgt: IntArray,\n    _val: IntArray,\n    mem: Array<IntArray>,\n    i: Int,\n    c: Int\n): Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, _val, mem, i - 1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    val no = knapsackDFSMem(wgt, _val, mem, i - 1, c)\n    val yes = knapsackDFSMem(wgt, _val, mem, i - 1, c - wgt[i - 1]) + _val[i - 1]\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dfs_mem}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn knapsackDFSMem(wgt: []i32, val: []i32, mem: anytype, i: usize, c: usize) i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 or c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    var no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    var yes = knapsackDFSMem(wgt, val, mem, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = @max(no, yes);\n    return mem[i][c];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-19 \u5c55\u793a\u4e86\u5728\u8bb0\u5fc6\u5316\u641c\u7d22\u4e2d\u88ab\u526a\u6389\u7684\u641c\u7d22\u5206\u652f\u3002

    \u56fe 14-19 \u00a0 0-1 \u80cc\u5305\u95ee\u9898\u7684\u8bb0\u5fc6\u5316\u641c\u7d22\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#3","title":"3. \u00a0 \u65b9\u6cd5\u4e09\uff1a\u52a8\u6001\u89c4\u5212","text":"

    \u52a8\u6001\u89c4\u5212\u5b9e\u8d28\u4e0a\u5c31\u662f\u5728\u72b6\u6001\u8f6c\u79fb\u4e2d\u586b\u5145 \\(dp\\) \u8868\u7684\u8fc7\u7a0b\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (cap + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1])\n    return dp[n][cap]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint KnapsackDP(int[] weight, int[] val, int cap) {\n    int n = weight.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (weight[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i, c] = dp[i - 1, c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i, c] = Math.Max(dp[i - 1, c - weight[i - 1]] + val[i - 1], dp[i - 1, c]);\n            }\n        }\n    }\n    return dp[n, cap];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDP(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, cap+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i-1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = int(math.Max(float64(dp[i-1][c]), float64(dp[i-1][c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDP(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(n + 1)\n        .fill(0)\n        .map(() => Array(cap + 1).fill(0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDP(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(cap + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[i][c] = dp[i - 1][c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[n][cap];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfn knapsack_dp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; cap + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = std::cmp::max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1] as usize] + val[i - 1],\n                );\n            }\n        }\n    }\n    dp[n][cap]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(cap + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = myMax(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[n][cap];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfun knapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(cap + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dp}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\nfn knapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = @max(dp[i - 1][c], dp[i - 1][c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-20 \u6240\u793a\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u7531\u6570\u7ec4 dp \u5927\u5c0f\u51b3\u5b9a\uff0c\u5373 \\(O(n \\times cap)\\) \u3002

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14>

    \u56fe 14-20 \u00a0 0-1 \u80cc\u5305\u95ee\u9898\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#4","title":"4. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e\u6bcf\u4e2a\u72b6\u6001\u90fd\u53ea\u4e0e\u5176\u4e0a\u4e00\u884c\u7684\u72b6\u6001\u6709\u5173\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e24\u4e2a\u6570\u7ec4\u6eda\u52a8\u524d\u8fdb\uff0c\u5c06\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n^2)\\) \u964d\u81f3 \\(O(n)\\) \u3002

    \u8fdb\u4e00\u6b65\u601d\u8003\uff0c\u6211\u4eec\u80fd\u5426\u4ec5\u7528\u4e00\u4e2a\u6570\u7ec4\u5b9e\u73b0\u7a7a\u95f4\u4f18\u5316\u5462\uff1f\u89c2\u5bdf\u53ef\u77e5\uff0c\u6bcf\u4e2a\u72b6\u6001\u90fd\u662f\u7531\u6b63\u4e0a\u65b9\u6216\u5de6\u4e0a\u65b9\u7684\u683c\u5b50\u8f6c\u79fb\u8fc7\u6765\u7684\u3002\u5047\u8bbe\u53ea\u6709\u4e00\u4e2a\u6570\u7ec4\uff0c\u5f53\u5f00\u59cb\u904d\u5386\u7b2c \\(i\\) \u884c\u65f6\uff0c\u8be5\u6570\u7ec4\u5b58\u50a8\u7684\u4ecd\u7136\u662f\u7b2c \\(i-1\\) \u884c\u7684\u72b6\u6001\u3002

    • \u5982\u679c\u91c7\u53d6\u6b63\u5e8f\u904d\u5386\uff0c\u90a3\u4e48\u904d\u5386\u5230 \\(dp[i, j]\\) \u65f6\uff0c\u5de6\u4e0a\u65b9 \\(dp[i-1, 1]\\) ~ \\(dp[i-1, j-1]\\) \u503c\u53ef\u80fd\u5df2\u7ecf\u88ab\u8986\u76d6\uff0c\u6b64\u65f6\u5c31\u65e0\u6cd5\u5f97\u5230\u6b63\u786e\u7684\u72b6\u6001\u8f6c\u79fb\u7ed3\u679c\u3002
    • \u5982\u679c\u91c7\u53d6\u5012\u5e8f\u904d\u5386\uff0c\u5219\u4e0d\u4f1a\u53d1\u751f\u8986\u76d6\u95ee\u9898\uff0c\u72b6\u6001\u8f6c\u79fb\u53ef\u4ee5\u6b63\u786e\u8fdb\u884c\u3002

    \u56fe 14-21 \u5c55\u793a\u4e86\u5728\u5355\u4e2a\u6570\u7ec4\u4e0b\u4ece\u7b2c \\(i = 1\\) \u884c\u8f6c\u6362\u81f3\u7b2c \\(i = 2\\) \u884c\u7684\u8fc7\u7a0b\u3002\u8bf7\u601d\u8003\u6b63\u5e8f\u904d\u5386\u548c\u5012\u5e8f\u904d\u5386\u7684\u533a\u522b\u3002

    <1><2><3><4><5><6>

    \u56fe 14-21 \u00a0 0-1 \u80cc\u5305\u7684\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u5728\u4ee3\u7801\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u4ec5\u9700\u5c06\u6570\u7ec4 dp \u7684\u7b2c\u4e00\u7ef4 \\(i\\) \u76f4\u63a5\u5220\u9664\uff0c\u5e76\u4e14\u628a\u5185\u5faa\u73af\u66f4\u6539\u4e3a\u5012\u5e8f\u904d\u5386\u5373\u53ef\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (cap + 1)\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u5012\u5e8f\u904d\u5386\n        for c in range(cap, 0, -1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n    return dp[cap]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(cap + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint KnapsackDPComp(int[] weight, int[] val, int cap) {\n    int n = weight.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c > 0; c--) {\n            if (weight[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.Max(dp[c], dp[c - weight[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDPComp(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, cap+1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u5012\u5e8f\u904d\u5386\n        for c := cap; c >= 1; c-- {\n            if wgt[i-1] <= c {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = int(math.Max(float64(dp[c]), float64(dp[c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        // \u5012\u5e8f\u904d\u5386\n        for c in (1 ... cap).reversed() {\n            if wgt[i - 1] <= c {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDPComp(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(cap + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (let c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDPComp(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(cap + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (let c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(cap + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    // \u5012\u5e8f\u904d\u5386\n    for (int c = cap; c >= 1; c--) {\n      if (wgt[i - 1] <= c) {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[cap];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn knapsack_dp_comp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        // \u5012\u5e8f\u904d\u5386\n        for c in (1..=cap).rev() {\n            if wgt[i - 1] <= c as i32 {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = std::cmp::max(dp[c], dp[c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    dp[cap]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(cap + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = myMax(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[cap];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun knapsackDPComp(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        // \u5012\u5e8f\u904d\u5386\n        for (c in cap downTo 1) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dp_comp}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn knapsackDPComp(wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (cap + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        // \u5012\u5e8f\u904d\u5386\n        var c = cap;\n        while (c > 0) : (c -= 1) {\n            if (wgt[i - 1] < c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = @max(dp[c], dp[c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/summary/","title":"14.7 \u00a0 \u5c0f\u7ed3","text":"
    • \u52a8\u6001\u89c4\u5212\u5bf9\u95ee\u9898\u8fdb\u884c\u5206\u89e3\uff0c\u5e76\u901a\u8fc7\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\u6765\u89c4\u907f\u91cd\u590d\u8ba1\u7b97\uff0c\u63d0\u9ad8\u8ba1\u7b97\u6548\u7387\u3002
    • \u4e0d\u8003\u8651\u65f6\u95f4\u7684\u524d\u63d0\u4e0b\uff0c\u6240\u6709\u52a8\u6001\u89c4\u5212\u95ee\u9898\u90fd\u53ef\u4ee5\u7528\u56de\u6eaf\uff08\u66b4\u529b\u641c\u7d22\uff09\u8fdb\u884c\u6c42\u89e3\uff0c\u4f46\u9012\u5f52\u6811\u4e2d\u5b58\u5728\u5927\u91cf\u7684\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u6548\u7387\u6781\u4f4e\u3002\u901a\u8fc7\u5f15\u5165\u8bb0\u5fc6\u5316\u5217\u8868\uff0c\u53ef\u4ee5\u5b58\u50a8\u6240\u6709\u8ba1\u7b97\u8fc7\u7684\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u4ece\u800c\u4fdd\u8bc1\u91cd\u53e0\u5b50\u95ee\u9898\u53ea\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002
    • \u8bb0\u5fc6\u5316\u641c\u7d22\u662f\u4e00\u79cd\u4ece\u9876\u81f3\u5e95\u7684\u9012\u5f52\u5f0f\u89e3\u6cd5\uff0c\u800c\u4e0e\u4e4b\u5bf9\u5e94\u7684\u52a8\u6001\u89c4\u5212\u662f\u4e00\u79cd\u4ece\u5e95\u81f3\u9876\u7684\u9012\u63a8\u5f0f\u89e3\u6cd5\uff0c\u5176\u5982\u540c\u201c\u586b\u5199\u8868\u683c\u201d\u4e00\u6837\u3002\u7531\u4e8e\u5f53\u524d\u72b6\u6001\u4ec5\u4f9d\u8d56\u67d0\u4e9b\u5c40\u90e8\u72b6\u6001\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u6d88\u9664 \\(dp\\) \u8868\u7684\u4e00\u4e2a\u7ef4\u5ea6\uff0c\u4ece\u800c\u964d\u4f4e\u7a7a\u95f4\u590d\u6742\u5ea6\u3002
    • \u5b50\u95ee\u9898\u5206\u89e3\u662f\u4e00\u79cd\u901a\u7528\u7684\u7b97\u6cd5\u601d\u8def\uff0c\u5728\u5206\u6cbb\u3001\u52a8\u6001\u89c4\u5212\u3001\u56de\u6eaf\u4e2d\u5177\u6709\u4e0d\u540c\u7684\u6027\u8d28\u3002
    • \u52a8\u6001\u89c4\u5212\u95ee\u9898\u6709\u4e09\u5927\u7279\u6027\uff1a\u91cd\u53e0\u5b50\u95ee\u9898\u3001\u6700\u4f18\u5b50\u7ed3\u6784\u3001\u65e0\u540e\u6548\u6027\u3002
    • \u5982\u679c\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u53ef\u4ee5\u4ece\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u6784\u5efa\u5f97\u6765\uff0c\u5219\u5b83\u5c31\u5177\u6709\u6700\u4f18\u5b50\u7ed3\u6784\u3002
    • \u65e0\u540e\u6548\u6027\u6307\u5bf9\u4e8e\u4e00\u4e2a\u72b6\u6001\uff0c\u5176\u672a\u6765\u53d1\u5c55\u53ea\u4e0e\u8be5\u72b6\u6001\u6709\u5173\uff0c\u800c\u4e0e\u8fc7\u53bb\u7ecf\u5386\u7684\u6240\u6709\u72b6\u6001\u65e0\u5173\u3002\u8bb8\u591a\u7ec4\u5408\u4f18\u5316\u95ee\u9898\u4e0d\u5177\u6709\u65e0\u540e\u6548\u6027\uff0c\u65e0\u6cd5\u4f7f\u7528\u52a8\u6001\u89c4\u5212\u5feb\u901f\u6c42\u89e3\u3002

    \u80cc\u5305\u95ee\u9898

    • \u80cc\u5305\u95ee\u9898\u662f\u6700\u5178\u578b\u7684\u52a8\u6001\u89c4\u5212\u95ee\u9898\u4e4b\u4e00\uff0c\u5177\u6709 0-1 \u80cc\u5305\u3001\u5b8c\u5168\u80cc\u5305\u3001\u591a\u91cd\u80cc\u5305\u7b49\u53d8\u79cd\u3002
    • 0-1 \u80cc\u5305\u7684\u72b6\u6001\u5b9a\u4e49\u4e3a\u524d \\(i\\) \u4e2a\u7269\u54c1\u5728\u5bb9\u91cf\u4e3a \\(c\\) \u7684\u80cc\u5305\u4e2d\u7684\u6700\u5927\u4ef7\u503c\u3002\u6839\u636e\u4e0d\u653e\u5165\u80cc\u5305\u548c\u653e\u5165\u80cc\u5305\u4e24\u79cd\u51b3\u7b56\uff0c\u53ef\u5f97\u5230\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u5e76\u6784\u5efa\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002\u5728\u7a7a\u95f4\u4f18\u5316\u4e2d\uff0c\u7531\u4e8e\u6bcf\u4e2a\u72b6\u6001\u4f9d\u8d56\u6b63\u4e0a\u65b9\u548c\u5de6\u4e0a\u65b9\u7684\u72b6\u6001\uff0c\u56e0\u6b64\u9700\u8981\u5012\u5e8f\u904d\u5386\u5217\u8868\uff0c\u907f\u514d\u5de6\u4e0a\u65b9\u72b6\u6001\u88ab\u8986\u76d6\u3002
    • \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u6bcf\u79cd\u7269\u54c1\u7684\u9009\u53d6\u6570\u91cf\u65e0\u9650\u5236\uff0c\u56e0\u6b64\u9009\u62e9\u653e\u5165\u7269\u54c1\u7684\u72b6\u6001\u8f6c\u79fb\u4e0e 0-1 \u80cc\u5305\u95ee\u9898\u4e0d\u540c\u3002\u7531\u4e8e\u72b6\u6001\u4f9d\u8d56\u6b63\u4e0a\u65b9\u548c\u6b63\u5de6\u65b9\u7684\u72b6\u6001\uff0c\u56e0\u6b64\u5728\u7a7a\u95f4\u4f18\u5316\u4e2d\u5e94\u5f53\u6b63\u5e8f\u904d\u5386\u3002
    • \u96f6\u94b1\u5151\u6362\u95ee\u9898\u662f\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u4e00\u4e2a\u53d8\u79cd\u3002\u5b83\u4ece\u6c42\u201c\u6700\u5927\u201d\u4ef7\u503c\u53d8\u4e3a\u6c42\u201c\u6700\u5c0f\u201d\u786c\u5e01\u6570\u91cf\uff0c\u56e0\u6b64\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e2d\u7684 \\(\\max()\\) \u5e94\u6539\u4e3a \\(\\min()\\) \u3002\u4ece\u8ffd\u6c42\u201c\u4e0d\u8d85\u8fc7\u201d\u80cc\u5305\u5bb9\u91cf\u5230\u8ffd\u6c42\u201c\u6070\u597d\u201d\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u56e0\u6b64\u4f7f\u7528 \\(amt + 1\\) \u6765\u8868\u793a\u201c\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u201d\u7684\u65e0\u6548\u89e3\u3002
    • \u96f6\u94b1\u5151\u6362\u95ee\u9898 II \u4ece\u6c42\u201c\u6700\u5c11\u786c\u5e01\u6570\u91cf\u201d\u6539\u4e3a\u6c42\u201c\u786c\u5e01\u7ec4\u5408\u6570\u91cf\u201d\uff0c\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u76f8\u5e94\u5730\u4ece \\(\\min()\\) \u6539\u4e3a\u6c42\u548c\u8fd0\u7b97\u7b26\u3002

    \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898

    • \u7f16\u8f91\u8ddd\u79bb\uff08Levenshtein \u8ddd\u79bb\uff09\u7528\u4e8e\u8861\u91cf\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e4b\u95f4\u7684\u76f8\u4f3c\u5ea6\uff0c\u5176\u5b9a\u4e49\u4e3a\u4ece\u4e00\u4e2a\u5b57\u7b26\u4e32\u5230\u53e6\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\uff0c\u7f16\u8f91\u64cd\u4f5c\u5305\u62ec\u6dfb\u52a0\u3001\u5220\u9664\u3001\u66ff\u6362\u3002
    • \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898\u7684\u72b6\u6001\u5b9a\u4e49\u4e3a\u5c06 \\(s\\) \u7684\u524d \\(i\\) \u4e2a\u5b57\u7b26\u66f4\u6539\u4e3a \\(t\\) \u7684\u524d \\(j\\) \u4e2a\u5b57\u7b26\u6240\u9700\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u3002\u5f53 \\(s[i] \\ne t[j]\\) \u65f6\uff0c\u5177\u6709\u4e09\u79cd\u51b3\u7b56\uff1a\u6dfb\u52a0\u3001\u5220\u9664\u3001\u66ff\u6362\uff0c\u5b83\u4eec\u90fd\u6709\u76f8\u5e94\u7684\u5269\u4f59\u5b50\u95ee\u9898\u3002\u636e\u6b64\u4fbf\u53ef\u4ee5\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\u4e0e\u6784\u5efa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002\u800c\u5f53 \\(s[i] = t[j]\\) \u65f6\uff0c\u65e0\u987b\u7f16\u8f91\u5f53\u524d\u5b57\u7b26\u3002
    • \u5728\u7f16\u8f91\u8ddd\u79bb\u4e2d\uff0c\u72b6\u6001\u4f9d\u8d56\u5176\u6b63\u4e0a\u65b9\u3001\u6b63\u5de6\u65b9\u3001\u5de6\u4e0a\u65b9\u7684\u72b6\u6001\uff0c\u56e0\u6b64\u7a7a\u95f4\u4f18\u5316\u540e\u6b63\u5e8f\u6216\u5012\u5e8f\u904d\u5386\u90fd\u65e0\u6cd5\u6b63\u786e\u5730\u8fdb\u884c\u72b6\u6001\u8f6c\u79fb\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u5229\u7528\u4e00\u4e2a\u53d8\u91cf\u6682\u5b58\u5de6\u4e0a\u65b9\u72b6\u6001\uff0c\u4ece\u800c\u8f6c\u5316\u5230\u4e0e\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7b49\u4ef7\u7684\u60c5\u51b5\uff0c\u53ef\u4ee5\u5728\u7a7a\u95f4\u4f18\u5316\u540e\u8fdb\u884c\u6b63\u5e8f\u904d\u5386\u3002
    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/","title":"14.5 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898","text":"

    \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5148\u6c42\u89e3\u53e6\u4e00\u4e2a\u5e38\u89c1\u7684\u80cc\u5305\u95ee\u9898\uff1a\u5b8c\u5168\u80cc\u5305\uff0c\u518d\u4e86\u89e3\u5b83\u7684\u4e00\u79cd\u7279\u4f8b\uff1a\u96f6\u94b1\u5151\u6362\u3002

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1451","title":"14.5.1 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a \\(n\\) \u4e2a\u7269\u54c1\uff0c\u7b2c \\(i\\) \u4e2a\u7269\u54c1\u7684\u91cd\u91cf\u4e3a \\(wgt[i-1]\\)\u3001\u4ef7\u503c\u4e3a \\(val[i-1]\\) \uff0c\u548c\u4e00\u4e2a\u5bb9\u91cf\u4e3a \\(cap\\) \u7684\u80cc\u5305\u3002\u6bcf\u4e2a\u7269\u54c1\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80fd\u653e\u5165\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u3002\u793a\u4f8b\u5982\u56fe 14-22 \u6240\u793a\u3002

    \u56fe 14-22 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u548c 0-1 \u80cc\u5305\u95ee\u9898\u975e\u5e38\u76f8\u4f3c\uff0c\u533a\u522b\u4ec5\u5728\u4e8e\u4e0d\u9650\u5236\u7269\u54c1\u7684\u9009\u62e9\u6b21\u6570\u3002

    • \u5728 0-1 \u80cc\u5305\u95ee\u9898\u4e2d\uff0c\u6bcf\u79cd\u7269\u54c1\u53ea\u6709\u4e00\u4e2a\uff0c\u56e0\u6b64\u5c06\u7269\u54c1 \\(i\\) \u653e\u5165\u80cc\u5305\u540e\uff0c\u53ea\u80fd\u4ece\u524d \\(i-1\\) \u4e2a\u7269\u54c1\u4e2d\u9009\u62e9\u3002
    • \u5728\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u4e2d\uff0c\u6bcf\u79cd\u7269\u54c1\u7684\u6570\u91cf\u662f\u65e0\u9650\u7684\uff0c\u56e0\u6b64\u5c06\u7269\u54c1 \\(i\\) \u653e\u5165\u80cc\u5305\u540e\uff0c\u4ecd\u53ef\u4ee5\u4ece\u524d \\(i\\) \u4e2a\u7269\u54c1\u4e2d\u9009\u62e9\u3002

    \u5728\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u89c4\u5b9a\u4e0b\uff0c\u72b6\u6001 \\([i, c]\\) \u7684\u53d8\u5316\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\u3002

    • \u4e0d\u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u4e0e 0-1 \u80cc\u5305\u95ee\u9898\u76f8\u540c\uff0c\u8f6c\u79fb\u81f3 \\([i-1, c]\\) \u3002
    • \u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u4e0e 0-1 \u80cc\u5305\u95ee\u9898\u4e0d\u540c\uff0c\u8f6c\u79fb\u81f3 \\([i, c-wgt[i-1]]\\) \u3002

    \u4ece\u800c\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u53d8\u4e3a\uff1a

    \\[ dp[i, c] = \\max(dp[i-1, c], dp[i, c - wgt[i-1]] + val[i-1]) \\]"},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5bf9\u6bd4\u4e24\u9053\u9898\u76ee\u7684\u4ee3\u7801\uff0c\u72b6\u6001\u8f6c\u79fb\u4e2d\u6709\u4e00\u5904\u4ece \\(i-1\\) \u53d8\u4e3a \\(i\\) \uff0c\u5176\u4f59\u5b8c\u5168\u4e00\u81f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig unbounded_knapsack.py
    def unbounded_knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (cap + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1])\n    return dp[n][cap]\n
    unbounded_knapsack.cpp
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.java
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.cs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint UnboundedKnapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i, c] = dp[i - 1, c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i, c] = Math.Max(dp[i - 1, c], dp[i, c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n, cap];\n}\n
    unbounded_knapsack.go
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDP(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, cap+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i-1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = int(math.Max(float64(dp[i-1][c]), float64(dp[i][c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.swift
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.js
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDP(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.ts
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDP(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.dart
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(cap + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[i][c] = dp[i - 1][c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[n][cap];\n}\n
    unbounded_knapsack.rs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfn unbounded_knapsack_dp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; cap + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = std::cmp::max(dp[i - 1][c], dp[i][c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.c
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(cap + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = myMax(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[n][cap];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    unbounded_knapsack.kt
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfun unboundedKnapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(cap + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.rb
    [class]{}-[func]{unbounded_knapsack_dp}\n
    unbounded_knapsack.zig
    // \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\nfn unboundedKnapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = @max(dp[i - 1][c], dp[i][c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e\u5f53\u524d\u72b6\u6001\u662f\u4ece\u5de6\u8fb9\u548c\u4e0a\u8fb9\u7684\u72b6\u6001\u8f6c\u79fb\u800c\u6765\u7684\uff0c\u56e0\u6b64\u7a7a\u95f4\u4f18\u5316\u540e\u5e94\u8be5\u5bf9 \\(dp\\) \u8868\u4e2d\u7684\u6bcf\u4e00\u884c\u8fdb\u884c\u6b63\u5e8f\u904d\u5386\u3002

    \u8fd9\u4e2a\u904d\u5386\u987a\u5e8f\u4e0e 0-1 \u80cc\u5305\u6b63\u597d\u76f8\u53cd\u3002\u8bf7\u501f\u52a9\u56fe 14-23 \u6765\u7406\u89e3\u4e24\u8005\u7684\u533a\u522b\u3002

    <1><2><3><4><5><6>

    \u56fe 14-23 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u5728\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u4ee3\u7801\u5b9e\u73b0\u6bd4\u8f83\u7b80\u5355\uff0c\u4ec5\u9700\u5c06\u6570\u7ec4 dp \u7684\u7b2c\u4e00\u7ef4\u5220\u9664\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig unbounded_knapsack.py
    def unbounded_knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (cap + 1)\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n    return dp[cap]\n
    unbounded_knapsack.cpp
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(cap + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.java
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.cs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint UnboundedKnapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.Max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.go
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDPComp(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, cap+1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = int(math.Max(float64(dp[c]), float64(dp[c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.swift
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.js
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDPComp(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: cap + 1 }, () => 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.ts
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDPComp(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: cap + 1 }, () => 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.dart
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(cap + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[c] = dp[c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[cap];\n}\n
    unbounded_knapsack.rs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn unbounded_knapsack_dp_comp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = std::cmp::max(dp[c], dp[c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    dp[cap]\n}\n
    unbounded_knapsack.c
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(cap + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = myMax(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[cap];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    unbounded_knapsack.kt
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun unboundedKnapsackDPComp(\n    wgt: IntArray,\n    _val: IntArray,\n    cap: Int\n): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.rb
    [class]{}-[func]{unbounded_knapsack_dp_comp}\n
    unbounded_knapsack.zig
    // \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn unboundedKnapsackDPComp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (cap + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = @max(dp[c], dp[c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1452","title":"14.5.2 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898","text":"

    \u80cc\u5305\u95ee\u9898\u662f\u4e00\u5927\u7c7b\u52a8\u6001\u89c4\u5212\u95ee\u9898\u7684\u4ee3\u8868\uff0c\u5176\u62e5\u6709\u5f88\u591a\u53d8\u79cd\uff0c\u4f8b\u5982\u96f6\u94b1\u5151\u6362\u95ee\u9898\u3002

    Question

    \u7ed9\u5b9a \\(n\\) \u79cd\u786c\u5e01\uff0c\u7b2c \\(i\\) \u79cd\u786c\u5e01\u7684\u9762\u503c\u4e3a \\(coins[i - 1]\\) \uff0c\u76ee\u6807\u91d1\u989d\u4e3a \\(amt\\) \uff0c\u6bcf\u79cd\u786c\u5e01\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u80fd\u591f\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\u3002\u5982\u679c\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002\u793a\u4f8b\u5982\u56fe 14-24 \u6240\u793a\u3002

    \u56fe 14-24 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1_1","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u96f6\u94b1\u5151\u6362\u53ef\u4ee5\u770b\u4f5c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\uff0c\u4e24\u8005\u5177\u6709\u4ee5\u4e0b\u8054\u7cfb\u4e0e\u4e0d\u540c\u70b9\u3002

    • \u4e24\u9053\u9898\u53ef\u4ee5\u76f8\u4e92\u8f6c\u6362\uff0c\u201c\u7269\u54c1\u201d\u5bf9\u5e94\u201c\u786c\u5e01\u201d\u3001\u201c\u7269\u54c1\u91cd\u91cf\u201d\u5bf9\u5e94\u201c\u786c\u5e01\u9762\u503c\u201d\u3001\u201c\u80cc\u5305\u5bb9\u91cf\u201d\u5bf9\u5e94\u201c\u76ee\u6807\u91d1\u989d\u201d\u3002
    • \u4f18\u5316\u76ee\u6807\u76f8\u53cd\uff0c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u662f\u8981\u6700\u5927\u5316\u7269\u54c1\u4ef7\u503c\uff0c\u96f6\u94b1\u5151\u6362\u95ee\u9898\u662f\u8981\u6700\u5c0f\u5316\u786c\u5e01\u6570\u91cf\u3002
    • \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u662f\u6c42\u201c\u4e0d\u8d85\u8fc7\u201d\u80cc\u5305\u5bb9\u91cf\u4e0b\u7684\u89e3\uff0c\u96f6\u94b1\u5151\u6362\u662f\u6c42\u201c\u6070\u597d\u201d\u51d1\u5230\u76ee\u6807\u91d1\u989d\u7684\u89e3\u3002

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u72b6\u6001 \\([i, a]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u4e3a\uff1a\u524d \\(i\\) \u79cd\u786c\u5e01\u80fd\u591f\u51d1\u51fa\u91d1\u989d \\(a\\) \u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\uff0c\u8bb0\u4e3a \\(dp[i, a]\\) \u3002

    \u4e8c\u7ef4 \\(dp\\) \u8868\u7684\u5c3a\u5bf8\u4e3a \\((n+1) \\times (amt+1)\\) \u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u672c\u9898\u4e0e\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u5b58\u5728\u4ee5\u4e0b\u4e24\u70b9\u5dee\u5f02\u3002

    • \u672c\u9898\u8981\u6c42\u6700\u5c0f\u503c\uff0c\u56e0\u6b64\u9700\u5c06\u8fd0\u7b97\u7b26 \\(\\max()\\) \u66f4\u6539\u4e3a \\(\\min()\\) \u3002
    • \u4f18\u5316\u4e3b\u4f53\u662f\u786c\u5e01\u6570\u91cf\u800c\u975e\u5546\u54c1\u4ef7\u503c\uff0c\u56e0\u6b64\u5728\u9009\u4e2d\u786c\u5e01\u65f6\u6267\u884c \\(+1\\) \u5373\u53ef\u3002
    \\[ dp[i, a] = \\min(dp[i-1, a], dp[i, a - coins[i-1]] + 1) \\]

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5f53\u76ee\u6807\u91d1\u989d\u4e3a \\(0\\) \u65f6\uff0c\u51d1\u51fa\u5b83\u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\u4e3a \\(0\\) \uff0c\u5373\u9996\u5217\u6240\u6709 \\(dp[i, 0]\\) \u90fd\u7b49\u4e8e \\(0\\) \u3002

    \u5f53\u65e0\u786c\u5e01\u65f6\uff0c\u65e0\u6cd5\u51d1\u51fa\u4efb\u610f \\(> 0\\) \u7684\u76ee\u6807\u91d1\u989d\uff0c\u5373\u662f\u65e0\u6548\u89e3\u3002\u4e3a\u4f7f\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e2d\u7684 \\(\\min()\\) \u51fd\u6570\u80fd\u591f\u8bc6\u522b\u5e76\u8fc7\u6ee4\u65e0\u6548\u89e3\uff0c\u6211\u4eec\u8003\u8651\u4f7f\u7528 \\(+ \\infty\\) \u6765\u8868\u793a\u5b83\u4eec\uff0c\u5373\u4ee4\u9996\u884c\u6240\u6709 \\(dp[0, a]\\) \u90fd\u7b49\u4e8e \\(+ \\infty\\) \u3002

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2_1","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u5e76\u672a\u63d0\u4f9b \\(+ \\infty\\) \u53d8\u91cf\uff0c\u53ea\u80fd\u4f7f\u7528\u6574\u578b int \u7684\u6700\u5927\u503c\u6765\u4ee3\u66ff\u3002\u800c\u8fd9\u53c8\u4f1a\u5bfc\u81f4\u5927\u6570\u8d8a\u754c\uff1a\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e2d\u7684 \\(+ 1\\) \u64cd\u4f5c\u53ef\u80fd\u53d1\u751f\u6ea2\u51fa\u3002

    \u4e3a\u6b64\uff0c\u6211\u4eec\u91c7\u7528\u6570\u5b57 \\(amt + 1\\) \u6765\u8868\u793a\u65e0\u6548\u89e3\uff0c\u56e0\u4e3a\u51d1\u51fa \\(amt\\) \u7684\u786c\u5e01\u6570\u91cf\u6700\u591a\u4e3a \\(amt\\) \u3002\u6700\u540e\u8fd4\u56de\u524d\uff0c\u5224\u65ad \\(dp[n, amt]\\) \u662f\u5426\u7b49\u4e8e \\(amt + 1\\) \uff0c\u82e5\u662f\u5219\u8fd4\u56de \\(-1\\) \uff0c\u4ee3\u8868\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change.py
    def coin_change_dp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    MAX = amt + 1\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (amt + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in range(1, amt + 1):\n        dp[0][a] = MAX\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n + 1):\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n    return dp[n][amt] if dp[n][amt] != MAX else -1\n
    coin_change.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(vector<int> &coins, int amt) {\n    int n = coins.size();\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(amt + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(int[] coins, int amt) {\n    int n = coins.length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][amt + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint CoinChangeDP(int[] coins, int amt) {\n    int n = coins.Length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, amt + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0, a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i, a] = dp[i - 1, a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i, a] = Math.Min(dp[i - 1, a], dp[i, a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n, amt] != MAX ? dp[n, amt] : -1;\n}\n
    coin_change.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDP(coins []int, amt int) int {\n    n := len(coins)\n    max := amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, amt+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a := 1; a <= amt; a++ {\n        dp[0][a] = max\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i-1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = int(math.Min(float64(dp[i-1][a]), float64(dp[i][a-coins[i-1]]+1)))\n            }\n        }\n    }\n    if dp[n][amt] != max {\n        return dp[n][amt]\n    }\n    return -1\n}\n
    coin_change.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDP(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    let MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in 1 ... amt {\n        dp[0][a] = MAX\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1\n}\n
    coin_change.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDP(coins, amt) {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] !== MAX ? dp[n][amt] : -1;\n}\n
    coin_change.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDP(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] !== MAX ? dp[n][amt] : -1;\n}\n
    coin_change.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(List<int> coins, int amt) {\n  int n = coins.length;\n  int MAX = amt + 1;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(amt + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n  for (int a = 1; a <= amt; a++) {\n    dp[0][a] = MAX;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[i][a] = dp[i - 1][a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n        dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n      }\n    }\n  }\n  return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfn coin_change_dp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    let max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; amt + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in 1..=amt {\n        dp[0][a] = max;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = std::cmp::min(dp[i - 1][a], dp[i][a - coins[i - 1] as usize] + 1);\n            }\n        }\n    }\n    if dp[n][amt] != max {\n        return dp[n][amt] as i32;\n    } else {\n        -1\n    }\n}\n
    coin_change.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(amt + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = myMin(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    int res = dp[n][amt] != MAX ? dp[n][amt] : -1;\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    coin_change.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfun coinChangeDP(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    val MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(amt + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (a in 1..amt) {\n        dp[0][a] = MAX\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return if (dp[n][amt] != MAX) dp[n][amt] else -1\n}\n
    coin_change.rb
    [class]{}-[func]{coin_change_dp}\n
    coin_change.zig
    // \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212\nfn coinChangeDP(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    comptime var max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (1..amt + 1) |a| {\n        dp[0][a] = max;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = @min(dp[i - 1][a], dp[i][a - @as(usize, @intCast(coins[i - 1]))] + 1);\n            }\n        }\n    }\n    if (dp[n][amt] != max) {\n        return @intCast(dp[n][amt]);\n    } else {\n        return -1;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-25 \u5c55\u793a\u4e86\u96f6\u94b1\u5151\u6362\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b\uff0c\u548c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u975e\u5e38\u76f8\u4f3c\u3002

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>

    \u56fe 14-25 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3_1","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u96f6\u94b1\u5151\u6362\u7684\u7a7a\u95f4\u4f18\u5316\u7684\u5904\u7406\u65b9\u5f0f\u548c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u4e00\u81f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change.py
    def coin_change_dp_comp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    MAX = amt + 1\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [MAX] * (amt + 1)\n    dp[0] = 0\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n    return dp[amt] if dp[amt] != MAX else -1\n
    coin_change.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(vector<int> &coins, int amt) {\n    int n = coins.size();\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(amt + 1, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(int[] coins, int amt) {\n    int n = coins.length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    Arrays.fill(dp, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint CoinChangeDPComp(int[] coins, int amt) {\n    int n = coins.Length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    Array.Fill(dp, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.Min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDPComp(coins []int, amt int) int {\n    n := len(coins)\n    max := amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, amt+1)\n    for i := 1; i <= amt; i++ {\n        dp[i] = max\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u6b63\u5e8f\u904d\u5386\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = int(math.Min(float64(dp[a]), float64(dp[a-coins[i-1]]+1)))\n            }\n        }\n    }\n    if dp[amt] != max {\n        return dp[amt]\n    }\n    return -1\n}\n
    coin_change.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDPComp(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    let MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: MAX, count: amt + 1)\n    dp[0] = 0\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1\n}\n
    coin_change.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDPComp(coins, amt) {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] !== MAX ? dp[amt] : -1;\n}\n
    coin_change.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDPComp(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] !== MAX ? dp[amt] : -1;\n}\n
    coin_change.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(List<int> coins, int amt) {\n  int n = coins.length;\n  int MAX = amt + 1;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(amt + 1, MAX);\n  dp[0] = 0;\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[a] = dp[a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n        dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1);\n      }\n    }\n  }\n  return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn coin_change_dp_comp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    let max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; amt + 1];\n    dp.fill(max);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = std::cmp::min(dp[a], dp[a - coins[i - 1] as usize] + 1);\n            }\n        }\n    }\n    if dp[amt] != max {\n        return dp[amt] as i32;\n    } else {\n        -1\n    }\n}\n
    coin_change.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = malloc((amt + 1) * sizeof(int));\n    for (int j = 1; j <= amt; j++) {\n        dp[j] = MAX;\n    } \n    dp[0] = 0;\n\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = myMin(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    int res = dp[amt] != MAX ? dp[amt] : -1;\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    coin_change.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun coinChangeDPComp(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    val MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(amt + 1)\n    dp.fill(MAX)\n    dp[0] = 0\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return if (dp[amt] != MAX) dp[amt] else -1\n}\n
    coin_change.rb
    [class]{}-[func]{coin_change_dp_comp}\n
    coin_change.zig
    // \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn coinChangeDPComp(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    comptime var max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (amt + 1);\n    @memset(&dp, max);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = @min(dp[a], dp[a - @as(usize, @intCast(coins[i - 1]))] + 1);\n            }\n        }\n    }\n    if (dp[amt] != max) {\n        return @intCast(dp[amt]);\n    } else {\n        return -1;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1453-ii","title":"14.5.3 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898 II","text":"

    Question

    \u7ed9\u5b9a \\(n\\) \u79cd\u786c\u5e01\uff0c\u7b2c \\(i\\) \u79cd\u786c\u5e01\u7684\u9762\u503c\u4e3a \\(coins[i - 1]\\) \uff0c\u76ee\u6807\u91d1\u989d\u4e3a \\(amt\\) \uff0c\u6bcf\u79cd\u786c\u5e01\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u7684\u786c\u5e01\u7ec4\u5408\u6570\u91cf\u3002\u793a\u4f8b\u5982\u56fe 14-26 \u6240\u793a\u3002

    \u56fe 14-26 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898 II \u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1_2","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u76f8\u6bd4\u4e8e\u4e0a\u4e00\u9898\uff0c\u672c\u9898\u76ee\u6807\u662f\u6c42\u7ec4\u5408\u6570\u91cf\uff0c\u56e0\u6b64\u5b50\u95ee\u9898\u53d8\u4e3a\uff1a\u524d \\(i\\) \u79cd\u786c\u5e01\u80fd\u591f\u51d1\u51fa\u91d1\u989d \\(a\\) \u7684\u7ec4\u5408\u6570\u91cf\u3002\u800c \\(dp\\) \u8868\u4ecd\u7136\u662f\u5c3a\u5bf8\u4e3a \\((n+1) \\times (amt + 1)\\) \u7684\u4e8c\u7ef4\u77e9\u9635\u3002

    \u5f53\u524d\u72b6\u6001\u7684\u7ec4\u5408\u6570\u91cf\u7b49\u4e8e\u4e0d\u9009\u5f53\u524d\u786c\u5e01\u4e0e\u9009\u5f53\u524d\u786c\u5e01\u8fd9\u4e24\u79cd\u51b3\u7b56\u7684\u7ec4\u5408\u6570\u91cf\u4e4b\u548c\u3002\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ dp[i, a] = dp[i-1, a] + dp[i, a - coins[i-1]] \\]

    \u5f53\u76ee\u6807\u91d1\u989d\u4e3a \\(0\\) \u65f6\uff0c\u65e0\u987b\u9009\u62e9\u4efb\u4f55\u786c\u5e01\u5373\u53ef\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u56e0\u6b64\u5e94\u5c06\u9996\u5217\u6240\u6709 \\(dp[i, 0]\\) \u90fd\u521d\u59cb\u5316\u4e3a \\(1\\) \u3002\u5f53\u65e0\u786c\u5e01\u65f6\uff0c\u65e0\u6cd5\u51d1\u51fa\u4efb\u4f55 \\(>0\\) \u7684\u76ee\u6807\u91d1\u989d\uff0c\u56e0\u6b64\u9996\u884c\u6240\u6709 \\(dp[0, a]\\) \u90fd\u7b49\u4e8e \\(0\\) \u3002

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2_2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_ii.py
    def coin_change_ii_dp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (amt + 1) for _ in range(n + 1)]\n    # \u521d\u59cb\u5316\u9996\u5217\n    for i in range(n + 1):\n        dp[i][0] = 1\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n    return dp[n][amt]\n
    coin_change_ii.cpp
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(vector<int> &coins, int amt) {\n    int n = coins.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(amt + 1, 0));\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.java
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(int[] coins, int amt) {\n    int n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][amt + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.cs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint CoinChangeIIDP(int[] coins, int amt) {\n    int n = coins.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, amt + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i, 0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i, a] = dp[i - 1, a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i, a] = dp[i - 1, a] + dp[i, a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n, amt];\n}\n
    coin_change_ii.go
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDP(coins []int, amt int) int {\n    n := len(coins)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, amt+1)\n    }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i := 0; i <= n; i++ {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i-1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i-1][a] + dp[i][a-coins[i-1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.swift
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDP(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i in 0 ... n {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.js
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDP(coins, amt) {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (let i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.ts
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDP(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (let i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.dart
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(List<int> coins, int amt) {\n  int n = coins.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(amt + 1, 0));\n  // \u521d\u59cb\u5316\u9996\u5217\n  for (int i = 0; i <= n; i++) {\n    dp[i][0] = 1;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[i][a] = dp[i - 1][a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n        dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n      }\n    }\n  }\n  return dp[n][amt];\n}\n
    coin_change_ii.rs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfn coin_change_ii_dp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; amt + 1]; n + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i in 0..=n {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1] as usize];\n            }\n        }\n    }\n    dp[n][amt]\n}\n
    coin_change_ii.c
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(amt + 1, sizeof(int));\n    }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    int res = dp[n][amt];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    coin_change_ii.kt
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfun coinChangeIIDP(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(amt + 1) }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (i in 0..n) {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.rb
    [class]{}-[func]{coin_change_ii_dp}\n
    coin_change_ii.zig
    // \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212\nfn coinChangeIIDP(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1);\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (0..n + 1) |i| {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - @as(usize, @intCast(coins[i - 1]))];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3_2","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7a7a\u95f4\u4f18\u5316\u5904\u7406\u65b9\u5f0f\u76f8\u540c\uff0c\u5220\u9664\u786c\u5e01\u7ef4\u5ea6\u5373\u53ef\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_ii.py
    def coin_change_ii_dp_comp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (amt + 1)\n    dp[0] = 1\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n    return dp[amt]\n
    coin_change_ii.cpp
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(vector<int> &coins, int amt) {\n    int n = coins.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(amt + 1, 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.java
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(int[] coins, int amt) {\n    int n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.cs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint CoinChangeIIDPComp(int[] coins, int amt) {\n    int n = coins.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.go
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDPComp(coins []int, amt int) int {\n    n := len(coins)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, amt+1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u6b63\u5e8f\u904d\u5386\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a-coins[i-1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.swift
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDPComp(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: amt + 1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.js
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDPComp(coins, amt) {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.ts
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDPComp(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.dart
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(List<int> coins, int amt) {\n  int n = coins.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(amt + 1, 0);\n  dp[0] = 1;\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[a] = dp[a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n        dp[a] = dp[a] + dp[a - coins[i - 1]];\n      }\n    }\n  }\n  return dp[amt];\n}\n
    coin_change_ii.rs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn coin_change_ii_dp_comp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1] as usize];\n            }\n        }\n    }\n    dp[amt]\n}\n
    coin_change_ii.c
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(amt + 1, sizeof(int));\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    int res = dp[amt];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    coin_change_ii.kt
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun coinChangeIIDPComp(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(amt + 1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.rb
    [class]{}-[func]{coin_change_ii_dp_comp}\n
    coin_change_ii.zig
    // \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn coinChangeIIDPComp(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (amt + 1);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = dp[a] + dp[a - @as(usize, @intCast(coins[i - 1]))];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_graph/","title":"\u7b2c 9 \u7ae0 \u00a0 \u56fe","text":"

    Abstract

    \u5728\u751f\u547d\u65c5\u9014\u4e2d\uff0c\u6211\u4eec\u5c31\u50cf\u662f\u4e00\u4e2a\u4e2a\u8282\u70b9\uff0c\u88ab\u65e0\u6570\u770b\u4e0d\u89c1\u7684\u8fb9\u76f8\u8fde\u3002

    \u6bcf\u4e00\u6b21\u7684\u76f8\u8bc6\u4e0e\u76f8\u79bb\uff0c\u90fd\u5728\u8fd9\u5f20\u5de8\u5927\u7684\u7f51\u7edc\u56fe\u4e2d\u7559\u4e0b\u72ec\u7279\u7684\u5370\u8bb0\u3002

    "},{"location":"chapter_graph/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 9.1 \u00a0 \u56fe
    • 9.2 \u00a0 \u56fe\u57fa\u7840\u64cd\u4f5c
    • 9.3 \u00a0 \u56fe\u7684\u904d\u5386
    • 9.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_graph/graph/","title":"9.1 \u00a0 \u56fe","text":"

    \u56fe\uff08graph\uff09\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u7531\u9876\u70b9\uff08vertex\uff09\u548c\u8fb9\uff08edge\uff09\u7ec4\u6210\u3002\u6211\u4eec\u53ef\u4ee5\u5c06\u56fe \\(G\\) \u62bd\u8c61\u5730\u8868\u793a\u4e3a\u4e00\u7ec4\u9876\u70b9 \\(V\\) \u548c\u4e00\u7ec4\u8fb9 \\(E\\) \u7684\u96c6\u5408\u3002\u4ee5\u4e0b\u793a\u4f8b\u5c55\u793a\u4e86\u4e00\u4e2a\u5305\u542b 5 \u4e2a\u9876\u70b9\u548c 7 \u6761\u8fb9\u7684\u56fe\u3002

    \\[ \\begin{aligned} V & = \\{ 1, 2, 3, 4, 5 \\} \\newline E & = \\{ (1,2), (1,3), (1,5), (2,3), (2,4), (2,5), (4,5) \\} \\newline G & = \\{ V, E \\} \\newline \\end{aligned} \\]

    \u5982\u679c\u5c06\u9876\u70b9\u770b\u4f5c\u8282\u70b9\uff0c\u5c06\u8fb9\u770b\u4f5c\u8fde\u63a5\u5404\u4e2a\u8282\u70b9\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5c06\u56fe\u770b\u4f5c\u4e00\u79cd\u4ece\u94fe\u8868\u62d3\u5c55\u800c\u6765\u7684\u6570\u636e\u7ed3\u6784\u3002\u5982\u56fe 9-1 \u6240\u793a\uff0c\u76f8\u8f83\u4e8e\u7ebf\u6027\u5173\u7cfb\uff08\u94fe\u8868\uff09\u548c\u5206\u6cbb\u5173\u7cfb\uff08\u6811\uff09\uff0c\u7f51\u7edc\u5173\u7cfb\uff08\u56fe\uff09\u7684\u81ea\u7531\u5ea6\u66f4\u9ad8\uff0c\u56e0\u800c\u66f4\u4e3a\u590d\u6742\u3002

    \u56fe 9-1 \u00a0 \u94fe\u8868\u3001\u6811\u3001\u56fe\u4e4b\u95f4\u7684\u5173\u7cfb

    "},{"location":"chapter_graph/graph/#911","title":"9.1.1 \u00a0 \u56fe\u7684\u5e38\u89c1\u7c7b\u578b\u4e0e\u672f\u8bed","text":"

    \u6839\u636e\u8fb9\u662f\u5426\u5177\u6709\u65b9\u5411\uff0c\u53ef\u5206\u4e3a\u65e0\u5411\u56fe\uff08undirected graph\uff09\u548c\u6709\u5411\u56fe\uff08directed graph\uff09\uff0c\u5982\u56fe 9-2 \u6240\u793a\u3002

    • \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u8fb9\u8868\u793a\u4e24\u9876\u70b9\u4e4b\u95f4\u7684\u201c\u53cc\u5411\u201d\u8fde\u63a5\u5173\u7cfb\uff0c\u4f8b\u5982\u5fae\u4fe1\u6216 QQ \u4e2d\u7684\u201c\u597d\u53cb\u5173\u7cfb\u201d\u3002
    • \u5728\u6709\u5411\u56fe\u4e2d\uff0c\u8fb9\u5177\u6709\u65b9\u5411\u6027\uff0c\u5373 \\(A \\rightarrow B\\) \u548c \\(A \\leftarrow B\\) \u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u662f\u76f8\u4e92\u72ec\u7acb\u7684\uff0c\u4f8b\u5982\u5fae\u535a\u6216\u6296\u97f3\u4e0a\u7684\u201c\u5173\u6ce8\u201d\u4e0e\u201c\u88ab\u5173\u6ce8\u201d\u5173\u7cfb\u3002

    \u56fe 9-2 \u00a0 \u6709\u5411\u56fe\u4e0e\u65e0\u5411\u56fe

    \u6839\u636e\u6240\u6709\u9876\u70b9\u662f\u5426\u8fde\u901a\uff0c\u53ef\u5206\u4e3a\u8fde\u901a\u56fe\uff08connected graph\uff09\u548c\u975e\u8fde\u901a\u56fe\uff08disconnected graph\uff09\uff0c\u5982\u56fe 9-3 \u6240\u793a\u3002

    • \u5bf9\u4e8e\u8fde\u901a\u56fe\uff0c\u4ece\u67d0\u4e2a\u9876\u70b9\u51fa\u53d1\uff0c\u53ef\u4ee5\u5230\u8fbe\u5176\u4f59\u4efb\u610f\u9876\u70b9\u3002
    • \u5bf9\u4e8e\u975e\u8fde\u901a\u56fe\uff0c\u4ece\u67d0\u4e2a\u9876\u70b9\u51fa\u53d1\uff0c\u81f3\u5c11\u6709\u4e00\u4e2a\u9876\u70b9\u65e0\u6cd5\u5230\u8fbe\u3002

    \u56fe 9-3 \u00a0 \u8fde\u901a\u56fe\u4e0e\u975e\u8fde\u901a\u56fe

    \u6211\u4eec\u8fd8\u53ef\u4ee5\u4e3a\u8fb9\u6dfb\u52a0\u201c\u6743\u91cd\u201d\u53d8\u91cf\uff0c\u4ece\u800c\u5f97\u5230\u5982\u56fe 9-4 \u6240\u793a\u7684\u6709\u6743\u56fe\uff08weighted graph\uff09\u3002\u4f8b\u5982\u5728\u300a\u738b\u8005\u8363\u8000\u300b\u7b49\u624b\u6e38\u4e2d\uff0c\u7cfb\u7edf\u4f1a\u6839\u636e\u5171\u540c\u6e38\u620f\u65f6\u95f4\u6765\u8ba1\u7b97\u73a9\u5bb6\u4e4b\u95f4\u7684\u201c\u4eb2\u5bc6\u5ea6\u201d\uff0c\u8fd9\u79cd\u4eb2\u5bc6\u5ea6\u7f51\u7edc\u5c31\u53ef\u4ee5\u7528\u6709\u6743\u56fe\u6765\u8868\u793a\u3002

    \u56fe 9-4 \u00a0 \u6709\u6743\u56fe\u4e0e\u65e0\u6743\u56fe

    \u56fe\u6570\u636e\u7ed3\u6784\u5305\u542b\u4ee5\u4e0b\u5e38\u7528\u672f\u8bed\u3002

    • \u90bb\u63a5\uff08adjacency\uff09\uff1a\u5f53\u4e24\u9876\u70b9\u4e4b\u95f4\u5b58\u5728\u8fb9\u76f8\u8fde\u65f6\uff0c\u79f0\u8fd9\u4e24\u9876\u70b9\u201c\u90bb\u63a5\u201d\u3002\u5728\u56fe 9-4 \u4e2d\uff0c\u9876\u70b9 1 \u7684\u90bb\u63a5\u9876\u70b9\u4e3a\u9876\u70b9 2\u30013\u30015\u3002
    • \u8def\u5f84\uff08path\uff09\uff1a\u4ece\u9876\u70b9 A \u5230\u9876\u70b9 B \u7ecf\u8fc7\u7684\u8fb9\u6784\u6210\u7684\u5e8f\u5217\u88ab\u79f0\u4e3a\u4ece A \u5230 B \u7684\u201c\u8def\u5f84\u201d\u3002\u5728\u56fe 9-4 \u4e2d\uff0c\u8fb9\u5e8f\u5217 1-5-2-4 \u662f\u9876\u70b9 1 \u5230\u9876\u70b9 4 \u7684\u4e00\u6761\u8def\u5f84\u3002
    • \u5ea6\uff08degree\uff09\uff1a\u4e00\u4e2a\u9876\u70b9\u62e5\u6709\u7684\u8fb9\u6570\u3002\u5bf9\u4e8e\u6709\u5411\u56fe\uff0c\u5165\u5ea6\uff08in-degree\uff09\u8868\u793a\u6709\u591a\u5c11\u6761\u8fb9\u6307\u5411\u8be5\u9876\u70b9\uff0c\u51fa\u5ea6\uff08out-degree\uff09\u8868\u793a\u6709\u591a\u5c11\u6761\u8fb9\u4ece\u8be5\u9876\u70b9\u6307\u51fa\u3002
    "},{"location":"chapter_graph/graph/#912","title":"9.1.2 \u00a0 \u56fe\u7684\u8868\u793a","text":"

    \u56fe\u7684\u5e38\u7528\u8868\u793a\u65b9\u5f0f\u5305\u62ec\u201c\u90bb\u63a5\u77e9\u9635\u201d\u548c\u201c\u90bb\u63a5\u8868\u201d\u3002\u4ee5\u4e0b\u4f7f\u7528\u65e0\u5411\u56fe\u8fdb\u884c\u4e3e\u4f8b\u3002

    "},{"location":"chapter_graph/graph/#1","title":"1. \u00a0 \u90bb\u63a5\u77e9\u9635","text":"

    \u8bbe\u56fe\u7684\u9876\u70b9\u6570\u91cf\u4e3a \\(n\\) \uff0c\u90bb\u63a5\u77e9\u9635\uff08adjacency matrix\uff09\u4f7f\u7528\u4e00\u4e2a \\(n \\times n\\) \u5927\u5c0f\u7684\u77e9\u9635\u6765\u8868\u793a\u56fe\uff0c\u6bcf\u4e00\u884c\uff08\u5217\uff09\u4ee3\u8868\u4e00\u4e2a\u9876\u70b9\uff0c\u77e9\u9635\u5143\u7d20\u4ee3\u8868\u8fb9\uff0c\u7528 \\(1\\) \u6216 \\(0\\) \u8868\u793a\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u662f\u5426\u5b58\u5728\u8fb9\u3002

    \u5982\u56fe 9-5 \u6240\u793a\uff0c\u8bbe\u90bb\u63a5\u77e9\u9635\u4e3a \\(M\\)\u3001\u9876\u70b9\u5217\u8868\u4e3a \\(V\\) \uff0c\u90a3\u4e48\u77e9\u9635\u5143\u7d20 \\(M[i, j] = 1\\) \u8868\u793a\u9876\u70b9 \\(V[i]\\) \u5230\u9876\u70b9 \\(V[j]\\) \u4e4b\u95f4\u5b58\u5728\u8fb9\uff0c\u53cd\u4e4b \\(M[i, j] = 0\\) \u8868\u793a\u4e24\u9876\u70b9\u4e4b\u95f4\u65e0\u8fb9\u3002

    \u56fe 9-5 \u00a0 \u56fe\u7684\u90bb\u63a5\u77e9\u9635\u8868\u793a

    \u90bb\u63a5\u77e9\u9635\u5177\u6709\u4ee5\u4e0b\u7279\u6027\u3002

    • \u9876\u70b9\u4e0d\u80fd\u4e0e\u81ea\u8eab\u76f8\u8fde\uff0c\u56e0\u6b64\u90bb\u63a5\u77e9\u9635\u4e3b\u5bf9\u89d2\u7ebf\u5143\u7d20\u6ca1\u6709\u610f\u4e49\u3002
    • \u5bf9\u4e8e\u65e0\u5411\u56fe\uff0c\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u7b49\u4ef7\uff0c\u6b64\u65f6\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\u3002
    • \u5c06\u90bb\u63a5\u77e9\u9635\u7684\u5143\u7d20\u4ece \\(1\\) \u548c \\(0\\) \u66ff\u6362\u4e3a\u6743\u91cd\uff0c\u5219\u53ef\u8868\u793a\u6709\u6743\u56fe\u3002

    \u4f7f\u7528\u90bb\u63a5\u77e9\u9635\u8868\u793a\u56fe\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee\u77e9\u9635\u5143\u7d20\u4ee5\u83b7\u53d6\u8fb9\uff0c\u56e0\u6b64\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u7684\u6548\u7387\u5f88\u9ad8\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(1)\\) \u3002\u7136\u800c\uff0c\u77e9\u9635\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u5185\u5b58\u5360\u7528\u8f83\u591a\u3002

    "},{"location":"chapter_graph/graph/#2","title":"2. \u00a0 \u90bb\u63a5\u8868","text":"

    \u90bb\u63a5\u8868\uff08adjacency list\uff09\u4f7f\u7528 \\(n\\) \u4e2a\u94fe\u8868\u6765\u8868\u793a\u56fe\uff0c\u94fe\u8868\u8282\u70b9\u8868\u793a\u9876\u70b9\u3002\u7b2c \\(i\\) \u4e2a\u94fe\u8868\u5bf9\u5e94\u9876\u70b9 \\(i\\) \uff0c\u5176\u4e2d\u5b58\u50a8\u4e86\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\uff08\u4e0e\u8be5\u9876\u70b9\u76f8\u8fde\u7684\u9876\u70b9\uff09\u3002\u56fe 9-6 \u5c55\u793a\u4e86\u4e00\u4e2a\u4f7f\u7528\u90bb\u63a5\u8868\u5b58\u50a8\u7684\u56fe\u7684\u793a\u4f8b\u3002

    \u56fe 9-6 \u00a0 \u56fe\u7684\u90bb\u63a5\u8868\u8868\u793a

    \u90bb\u63a5\u8868\u4ec5\u5b58\u50a8\u5b9e\u9645\u5b58\u5728\u7684\u8fb9\uff0c\u800c\u8fb9\u7684\u603b\u6570\u901a\u5e38\u8fdc\u5c0f\u4e8e \\(n^2\\) \uff0c\u56e0\u6b64\u5b83\u66f4\u52a0\u8282\u7701\u7a7a\u95f4\u3002\u7136\u800c\uff0c\u5728\u90bb\u63a5\u8868\u4e2d\u9700\u8981\u901a\u8fc7\u904d\u5386\u94fe\u8868\u6765\u67e5\u627e\u8fb9\uff0c\u56e0\u6b64\u5176\u65f6\u95f4\u6548\u7387\u4e0d\u5982\u90bb\u63a5\u77e9\u9635\u3002

    \u89c2\u5bdf\u56fe 9-6 \uff0c\u90bb\u63a5\u8868\u7ed3\u6784\u4e0e\u54c8\u5e0c\u8868\u4e2d\u7684\u201c\u94fe\u5f0f\u5730\u5740\u201d\u975e\u5e38\u76f8\u4f3c\uff0c\u56e0\u6b64\u6211\u4eec\u4e5f\u53ef\u4ee5\u91c7\u7528\u7c7b\u4f3c\u7684\u65b9\u6cd5\u6765\u4f18\u5316\u6548\u7387\u3002\u6bd4\u5982\u5f53\u94fe\u8868\u8f83\u957f\u65f6\uff0c\u53ef\u4ee5\u5c06\u94fe\u8868\u8f6c\u5316\u4e3a AVL \u6811\u6216\u7ea2\u9ed1\u6811\uff0c\u4ece\u800c\u5c06\u65f6\u95f4\u6548\u7387\u4ece \\(O(n)\\) \u4f18\u5316\u81f3 \\(O(\\log n)\\) \uff1b\u8fd8\u53ef\u4ee5\u628a\u94fe\u8868\u8f6c\u6362\u4e3a\u54c8\u5e0c\u8868\uff0c\u4ece\u800c\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u964d\u81f3 \\(O(1)\\) \u3002

    "},{"location":"chapter_graph/graph/#913","title":"9.1.3 \u00a0 \u56fe\u7684\u5e38\u89c1\u5e94\u7528","text":"

    \u5982\u8868 9-1 \u6240\u793a\uff0c\u8bb8\u591a\u73b0\u5b9e\u7cfb\u7edf\u53ef\u4ee5\u7528\u56fe\u6765\u5efa\u6a21\uff0c\u76f8\u5e94\u7684\u95ee\u9898\u4e5f\u53ef\u4ee5\u7ea6\u5316\u4e3a\u56fe\u8ba1\u7b97\u95ee\u9898\u3002

    \u8868 9-1 \u00a0 \u73b0\u5b9e\u751f\u6d3b\u4e2d\u5e38\u89c1\u7684\u56fe

    \u9876\u70b9 \u8fb9 \u56fe\u8ba1\u7b97\u95ee\u9898 \u793e\u4ea4\u7f51\u7edc \u7528\u6237 \u597d\u53cb\u5173\u7cfb \u6f5c\u5728\u597d\u53cb\u63a8\u8350 \u5730\u94c1\u7ebf\u8def \u7ad9\u70b9 \u7ad9\u70b9\u95f4\u7684\u8fde\u901a\u6027 \u6700\u77ed\u8def\u7ebf\u63a8\u8350 \u592a\u9633\u7cfb \u661f\u4f53 \u661f\u4f53\u95f4\u7684\u4e07\u6709\u5f15\u529b\u4f5c\u7528 \u884c\u661f\u8f68\u9053\u8ba1\u7b97"},{"location":"chapter_graph/graph_operations/","title":"9.2 \u00a0 \u56fe\u7684\u57fa\u7840\u64cd\u4f5c","text":"

    \u56fe\u7684\u57fa\u7840\u64cd\u4f5c\u53ef\u5206\u4e3a\u5bf9\u201c\u8fb9\u201d\u7684\u64cd\u4f5c\u548c\u5bf9\u201c\u9876\u70b9\u201d\u7684\u64cd\u4f5c\u3002\u5728\u201c\u90bb\u63a5\u77e9\u9635\u201d\u548c\u201c\u90bb\u63a5\u8868\u201d\u4e24\u79cd\u8868\u793a\u65b9\u6cd5\u4e0b\uff0c\u5b9e\u73b0\u65b9\u5f0f\u6709\u6240\u4e0d\u540c\u3002

    "},{"location":"chapter_graph/graph_operations/#921","title":"9.2.1 \u00a0 \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u7684\u5b9e\u73b0","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u9876\u70b9\u6570\u91cf\u4e3a \\(n\\) \u7684\u65e0\u5411\u56fe\uff0c\u5219\u5404\u79cd\u64cd\u4f5c\u7684\u5b9e\u73b0\u65b9\u5f0f\u5982\u56fe 9-7 \u6240\u793a\u3002

    • \u6dfb\u52a0\u6216\u5220\u9664\u8fb9\uff1a\u76f4\u63a5\u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u4fee\u6539\u6307\u5b9a\u7684\u8fb9\u5373\u53ef\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002\u800c\u7531\u4e8e\u662f\u65e0\u5411\u56fe\uff0c\u56e0\u6b64\u9700\u8981\u540c\u65f6\u66f4\u65b0\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u3002
    • \u6dfb\u52a0\u9876\u70b9\uff1a\u5728\u90bb\u63a5\u77e9\u9635\u7684\u5c3e\u90e8\u6dfb\u52a0\u4e00\u884c\u4e00\u5217\uff0c\u5e76\u5168\u90e8\u586b \\(0\\) \u5373\u53ef\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002
    • \u5220\u9664\u9876\u70b9\uff1a\u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u4e00\u884c\u4e00\u5217\u3002\u5f53\u5220\u9664\u9996\u884c\u9996\u5217\u65f6\u8fbe\u5230\u6700\u5dee\u60c5\u51b5\uff0c\u9700\u8981\u5c06 \\((n-1)^2\\) \u4e2a\u5143\u7d20\u201c\u5411\u5de6\u4e0a\u79fb\u52a8\u201d\uff0c\u4ece\u800c\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    • \u521d\u59cb\u5316\uff1a\u4f20\u5165 \\(n\\) \u4e2a\u9876\u70b9\uff0c\u521d\u59cb\u5316\u957f\u5ea6\u4e3a \\(n\\) \u7684\u9876\u70b9\u5217\u8868 vertices \uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\uff1b\u521d\u59cb\u5316 \\(n \\times n\\) \u5927\u5c0f\u7684\u90bb\u63a5\u77e9\u9635 adjMat \uff0c\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    \u521d\u59cb\u5316\u90bb\u63a5\u77e9\u9635\u6dfb\u52a0\u8fb9\u5220\u9664\u8fb9\u6dfb\u52a0\u9876\u70b9\u5220\u9664\u9876\u70b9

    \u56fe 9-7 \u00a0 \u90bb\u63a5\u77e9\u9635\u7684\u521d\u59cb\u5316\u3001\u589e\u5220\u8fb9\u3001\u589e\u5220\u9876\u70b9

    \u4ee5\u4e0b\u662f\u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u8868\u793a\u56fe\u7684\u5b9e\u73b0\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_matrix.py
    class GraphAdjMat:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, vertices: list[int], edges: list[list[int]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.vertices: list[int] = []\n        # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.adj_mat: list[list[int]] = []\n        # \u6dfb\u52a0\u9876\u70b9\n        for val in vertices:\n            self.add_vertex(val)\n        # \u6dfb\u52a0\u8fb9\n        # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges:\n            self.add_edge(e[0], e[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.vertices)\n\n    def add_vertex(self, val: int):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        n = self.size()\n        # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.append(val)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        new_row = [0] * n\n        self.adj_mat.append(new_row)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in self.adj_mat:\n            row.append(0)\n\n    def remove_vertex(self, index: int):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if index >= self.size():\n            raise IndexError()\n        # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in self.adj_mat:\n            row.pop(index)\n\n    def add_edge(self, i: int, j: int):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1\n        self.adj_mat[j][i] = 1\n\n    def remove_edge(self, i: int, j: int):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        self.adj_mat[i][j] = 0\n        self.adj_mat[j][i] = 0\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u77e9\u9635\"\"\"\n        print(\"\u9876\u70b9\u5217\u8868 =\", self.vertices)\n        print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        print_matrix(self.adj_mat)\n
    graph_adjacency_matrix.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vector<int> vertices;       // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vector<vector<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjMat(const vector<int> &vertices, const vector<vector<int>> &edges) {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const vector<int> &edge : edges) {\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() const {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.push_back(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        adjMat.emplace_back(vector<int>(n, 0));\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (vector<int> &row : adjMat) {\n            row.push_back(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(int index) {\n        if (index >= size()) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.erase(vertices.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.erase(adjMat.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (vector<int> &row : adjMat) {\n            row.erase(row.begin() + index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    void print() {\n        cout << \"\u9876\u70b9\u5217\u8868 = \";\n        printVector(vertices);\n        cout << \"\u90bb\u63a5\u77e9\u9635 =\" << endl;\n        printVectorMatrix(adjMat);\n    }\n};\n
    graph_adjacency_matrix.java
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<Integer> vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<Integer>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = new ArrayList<>();\n        this.adjMat = new ArrayList<>();\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (int[] e : edges) {\n            addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<Integer> newRow = new ArrayList<>(n);\n        for (int j = 0; j < n; j++) {\n            newRow.add(0);\n        }\n        adjMat.add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (List<Integer> row : adjMat) {\n            row.add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(int index) {\n        if (index >= size())\n            throw new IndexOutOfBoundsException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (List<Integer> row : adjMat) {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat.get(i).set(j, 1);\n        adjMat.get(j).set(i, 1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        adjMat.get(i).set(j, 0);\n        adjMat.get(j).set(i, 0);\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void print() {\n        System.out.print(\"\u9876\u70b9\u5217\u8868 = \");\n        System.out.println(vertices);\n        System.out.println(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.printMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<int> vertices;     // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        foreach (int val in vertices) {\n            AddVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        foreach (int[] e in edges) {\n            AddEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return vertices.Count;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(int val) {\n        int n = Size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.Add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<int> newRow = new(n);\n        for (int j = 0; j < n; j++) {\n            newRow.Add(0);\n        }\n        adjMat.Add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        foreach (List<int> row in adjMat) {\n            row.Add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(int index) {\n        if (index >= Size())\n            throw new IndexOutOfRangeException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        foreach (List<int> row in adjMat) {\n            row.RemoveAt(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void AddEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void RemoveEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void Print() {\n        Console.Write(\"\u9876\u70b9\u5217\u8868 = \");\n        PrintUtil.PrintList(vertices);\n        Console.WriteLine(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.PrintMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.go
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjMat struct {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vertices []int\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat [][]int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjMat(vertices []int, edges [][]int) *graphAdjMat {\n    // \u6dfb\u52a0\u9876\u70b9\n    n := len(vertices)\n    adjMat := make([][]int, n)\n    for i := range adjMat {\n        adjMat[i] = make([]int, n)\n    }\n    // \u521d\u59cb\u5316\u56fe\n    g := &graphAdjMat{\n        vertices: vertices,\n        adjMat:   adjMat,\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for i := range edges {\n        g.addEdge(edges[i][0], edges[i][1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjMat) size() int {\n    return len(g.vertices)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjMat) addVertex(val int) {\n    n := g.size()\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    g.vertices = append(g.vertices, val)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    newRow := make([]int, n)\n    g.adjMat = append(g.adjMat, newRow)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i], 0)\n    }\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjMat) removeVertex(index int) {\n    if index >= g.size() {\n        return\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    g.vertices = append(g.vertices[:index], g.vertices[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    g.adjMat = append(g.adjMat[:index], g.adjMat[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i][:index], g.adjMat[i][index+1:]...)\n    }\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) addEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    g.adjMat[i][j] = 1\n    g.adjMat[j][i] = 1\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) removeEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    g.adjMat[i][j] = 0\n    g.adjMat[j][i] = 0\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nfunc (g *graphAdjMat) print() {\n    fmt.Printf(\"\\t\u9876\u70b9\u5217\u8868 = %v\\n\", g.vertices)\n    fmt.Printf(\"\\t\u90bb\u63a5\u77e9\u9635 = \\n\")\n    for i := range g.adjMat {\n        fmt.Printf(\"\\t\\t\\t%v\\n\", g.adjMat[i])\n    }\n}\n
    graph_adjacency_matrix.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    private var vertices: [Int] // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    private var adjMat: [[Int]] // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(vertices: [Int], edges: [[Int]]) {\n        self.vertices = []\n        adjMat = []\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            addVertex(val: val)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges {\n            addEdge(i: e[0], j: e[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    func size() -> Int {\n        vertices.count\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    func addVertex(val: Int) {\n        let n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.append(val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        let newRow = Array(repeating: 0, count: n)\n        adjMat.append(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for i in adjMat.indices {\n            adjMat[i].append(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    func removeVertex(index: Int) {\n        if index >= size() {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for i in adjMat.indices {\n            adjMat[i].remove(at: index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    func print() {\n        Swift.print(\"\u9876\u70b9\u5217\u8868 = \", terminator: \"\")\n        Swift.print(vertices)\n        Swift.print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        PrintUtil.printMatrix(matrix: adjMat)\n    }\n}\n
    graph_adjacency_matrix.js
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices, edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val) {\n        const n = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow = [];\n        for (let j = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index) {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print() {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices: number[]; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat: number[][]; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices: number[], edges: number[][]) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val: number): void {\n        const n: number = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow: number[] = [];\n        for (let j: number = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index: number): void {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print(): void {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n  List<int> vertices = []; // \u9876\u70b9\u5143\u7d20\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n  List<List<int>> adjMat = []; //\u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjMat(List<int> vertices, List<List<int>> edges) {\n    this.vertices = [];\n    this.adjMat = [];\n    // \u6dfb\u52a0\u9876\u70b9\n    for (int val in vertices) {\n      addVertex(val);\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for (List<int> e in edges) {\n      addEdge(e[0], e[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return vertices.length;\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(int val) {\n    int n = size();\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    vertices.add(val);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    List<int> newRow = List.filled(n, 0, growable: true);\n    adjMat.add(newRow);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for (List<int> row in adjMat) {\n      row.add(0);\n    }\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(int index) {\n    if (index >= size()) {\n      throw IndexError;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    vertices.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    adjMat.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (List<int> row in adjMat) {\n      row.removeAt(index);\n    }\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void addEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    adjMat[i][j] = 1;\n    adjMat[j][i] = 1;\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void removeEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    adjMat[i][j] = 0;\n    adjMat[j][i] = 0;\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n  void printAdjMat() {\n    print(\"\u9876\u70b9\u5217\u8868 = $vertices\");\n    print(\"\u90bb\u63a5\u77e9\u9635 = \");\n    printMatrix(adjMat);\n  }\n}\n
    graph_adjacency_matrix.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjMat {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub vertices: Vec<i32>,\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub adj_mat: Vec<Vec<i32>>,\n}\n\nimpl GraphAdjMat {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(vertices: Vec<i32>, edges: Vec<[usize; 2]>) -> Self {\n        let mut graph = GraphAdjMat {\n            vertices: vec![],\n            adj_mat: vec![],\n        };\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            graph.add_vertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for edge in edges {\n            graph.add_edge(edge[0], edge[1])\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    pub fn size(&self) -> usize {\n        self.vertices.len()\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, val: i32) {\n        let n = self.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        self.adj_mat.push(vec![0; n]);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in &mut self.adj_mat {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    pub fn remove_vertex(&mut self, index: usize) {\n        if index >= self.size() {\n            panic!(\"index error\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in &mut self.adj_mat {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1;\n        self.adj_mat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    pub fn remove_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        self.adj_mat[i][j] = 0;\n        self.adj_mat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    pub fn print(&self) {\n        println!(\"\u9876\u70b9\u5217\u8868 = {:?}\", self.vertices);\n        println!(\"\u90bb\u63a5\u77e9\u9635 =\");\n        println!(\"[\");\n        for row in &self.adj_mat {\n            println!(\"  {:?},\", row);\n        }\n        println!(\"]\")\n    }\n}\n
    graph_adjacency_matrix.c
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int vertices[MAX_SIZE];\n    int adjMat[MAX_SIZE][MAX_SIZE];\n    int size;\n} GraphAdjMat;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjMat *newGraphAdjMat() {\n    GraphAdjMat *graph = (GraphAdjMat *)malloc(sizeof(GraphAdjMat));\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        for (int j = 0; j < MAX_SIZE; j++) {\n            graph->adjMat[i][j] = 0;\n        }\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjMat(GraphAdjMat *graph) {\n    free(graph);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjMat *graph, int val) {\n    if (graph->size == MAX_SIZE) {\n        fprintf(stderr, \"\u56fe\u7684\u9876\u70b9\u6570\u91cf\u5df2\u8fbe\u6700\u5927\u503c\\n\");\n        return;\n    }\n    // \u6dfb\u52a0\u7b2c n \u4e2a\u9876\u70b9\uff0c\u5e76\u5c06\u7b2c n \u884c\u548c\u5217\u7f6e\u96f6\n    int n = graph->size;\n    graph->vertices[n] = val;\n    for (int i = 0; i <= n; i++) {\n        graph->adjMat[n][i] = graph->adjMat[i][n] = 0;\n    }\n    graph->size++;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjMat *graph, int index) {\n    if (index < 0 || index >= graph->size) {\n        fprintf(stderr, \"\u9876\u70b9\u7d22\u5f15\u8d8a\u754c\\n\");\n        return;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    for (int i = index; i < graph->size - 1; i++) {\n        graph->vertices[i] = graph->vertices[i + 1];\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    for (int i = index; i < graph->size - 1; i++) {\n        for (int j = 0; j < graph->size; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i + 1][j];\n        }\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (int i = 0; i < graph->size; i++) {\n        for (int j = index; j < graph->size - 1; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i][j + 1];\n        }\n    }\n    graph->size--;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid addEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 1;\n    graph->adjMat[j][i] = 1;\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid removeEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 0;\n    graph->adjMat[j][i] = 0;\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nvoid printGraphAdjMat(GraphAdjMat *graph) {\n    printf(\"\u9876\u70b9\u5217\u8868 = \");\n    printArray(graph->vertices, graph->size);\n    printf(\"\u90bb\u63a5\u77e9\u9635 =\\n\");\n    for (int i = 0; i < graph->size; i++) {\n        printArray(graph->adjMat[i], graph->size);\n    }\n}\n
    graph_adjacency_matrix.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat(vertices: IntArray, edges: Array<IntArray>) {\n    val vertices = mutableListOf<Int>() // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    val adjMat = mutableListOf<MutableList<Int>>() // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (vertex in vertices) {\n            addVertex(vertex)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (edge in edges) {\n            addEdge(edge[0], edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return vertices.size\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(_val: Int) {\n        val n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(_val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        val newRow = mutableListOf<Int>()\n        for (j in 0..<n) {\n            newRow.add(0)\n        }\n        adjMat.add(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (row in adjMat) {\n            row.add(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(index: Int) {\n        if (index >= size())\n            throw IndexOutOfBoundsException()\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (row in adjMat) {\n            row.removeAt(index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    fun print() {\n        print(\"\u9876\u70b9\u5217\u8868 = \")\n        println(vertices)\n        println(\"\u90bb\u63a5\u77e9\u9635 =\")\n        printMatrix(adjMat)\n    }\n}\n
    graph_adjacency_matrix.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjMat\n  def initialize(vertices, edges)\n    ### \u6784\u9020\u65b9\u6cd5 ###\n    # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @vertices = []\n    # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @adj_mat = []\n    # \u6dfb\u52a0\u9876\u70b9\n    vertices.each { |val| add_vertex(val) }\n    # \u6dfb\u52a0\u8fb9\n    # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    edges.each { |e| add_edge(e[0], e[1]) }\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @vertices.length\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(val)\n    n = size\n    # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    @vertices << val\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    new_row = Array.new(n, 0)\n    @adj_mat << new_row\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    @adj_mat.each { |row| row << 0 }\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(index)\n    raise IndexError if index >= size\n\n    # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    @vertices.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    @adj_mat.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    @adj_mat.each { |row| row.delete_at(index) }\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    @adj_mat[i][j] = 1\n    @adj_mat[j][i] = 1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    @adj_mat[i][j] = 0\n    @adj_mat[j][i] = 0\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u77e9\u9635 ###\n  def __print__\n    puts \"\u9876\u70b9\u5217\u8868 = #{@vertices}\"\n    puts '\u90bb\u63a5\u77e9\u9635 ='\n    print_matrix(@adj_mat)\n  end\nend\n
    graph_adjacency_matrix.zig
    [class]{GraphAdjMat}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_graph/graph_operations/#922","title":"9.2.2 \u00a0 \u57fa\u4e8e\u90bb\u63a5\u8868\u7684\u5b9e\u73b0","text":"

    \u8bbe\u65e0\u5411\u56fe\u7684\u9876\u70b9\u603b\u6570\u4e3a \\(n\\)\u3001\u8fb9\u603b\u6570\u4e3a \\(m\\) \uff0c\u5219\u53ef\u6839\u636e\u56fe 9-8 \u6240\u793a\u7684\u65b9\u6cd5\u5b9e\u73b0\u5404\u79cd\u64cd\u4f5c\u3002

    • \u6dfb\u52a0\u8fb9\uff1a\u5728\u9876\u70b9\u5bf9\u5e94\u94fe\u8868\u7684\u672b\u5c3e\u6dfb\u52a0\u8fb9\u5373\u53ef\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002\u56e0\u4e3a\u662f\u65e0\u5411\u56fe\uff0c\u6240\u4ee5\u9700\u8981\u540c\u65f6\u6dfb\u52a0\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u3002
    • \u5220\u9664\u8fb9\uff1a\u5728\u9876\u70b9\u5bf9\u5e94\u94fe\u8868\u4e2d\u67e5\u627e\u5e76\u5220\u9664\u6307\u5b9a\u8fb9\uff0c\u4f7f\u7528 \\(O(m)\\) \u65f6\u95f4\u3002\u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u9700\u8981\u540c\u65f6\u5220\u9664\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u3002
    • \u6dfb\u52a0\u9876\u70b9\uff1a\u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u94fe\u8868\uff0c\u5e76\u5c06\u65b0\u589e\u9876\u70b9\u4f5c\u4e3a\u94fe\u8868\u5934\u8282\u70b9\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002
    • \u5220\u9664\u9876\u70b9\uff1a\u9700\u904d\u5386\u6574\u4e2a\u90bb\u63a5\u8868\uff0c\u5220\u9664\u5305\u542b\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u8fb9\uff0c\u4f7f\u7528 \\(O(n + m)\\) \u65f6\u95f4\u3002
    • \u521d\u59cb\u5316\uff1a\u5728\u90bb\u63a5\u8868\u4e2d\u521b\u5efa \\(n\\) \u4e2a\u9876\u70b9\u548c \\(2m\\) \u6761\u8fb9\uff0c\u4f7f\u7528 \\(O(n + m)\\) \u65f6\u95f4\u3002
    \u521d\u59cb\u5316\u90bb\u63a5\u8868\u6dfb\u52a0\u8fb9\u5220\u9664\u8fb9\u6dfb\u52a0\u9876\u70b9\u5220\u9664\u9876\u70b9

    \u56fe 9-8 \u00a0 \u90bb\u63a5\u8868\u7684\u521d\u59cb\u5316\u3001\u589e\u5220\u8fb9\u3001\u589e\u5220\u9876\u70b9

    \u4ee5\u4e0b\u662f\u90bb\u63a5\u8868\u7684\u4ee3\u7801\u5b9e\u73b0\u3002\u5bf9\u6bd4\u56fe 9-8 \uff0c\u5b9e\u9645\u4ee3\u7801\u6709\u4ee5\u4e0b\u4e0d\u540c\u3002

    • \u4e3a\u4e86\u65b9\u4fbf\u6dfb\u52a0\u4e0e\u5220\u9664\u9876\u70b9\uff0c\u4ee5\u53ca\u7b80\u5316\u4ee3\u7801\uff0c\u6211\u4eec\u4f7f\u7528\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\u6765\u4ee3\u66ff\u94fe\u8868\u3002
    • \u4f7f\u7528\u54c8\u5e0c\u8868\u6765\u5b58\u50a8\u90bb\u63a5\u8868\uff0ckey \u4e3a\u9876\u70b9\u5b9e\u4f8b\uff0cvalue \u4e3a\u8be5\u9876\u70b9\u7684\u90bb\u63a5\u9876\u70b9\u5217\u8868\uff08\u94fe\u8868\uff09\u3002

    \u53e6\u5916\uff0c\u6211\u4eec\u5728\u90bb\u63a5\u8868\u4e2d\u4f7f\u7528 Vertex \u7c7b\u6765\u8868\u793a\u9876\u70b9\uff0c\u8fd9\u6837\u505a\u7684\u539f\u56e0\u662f\uff1a\u5982\u679c\u4e0e\u90bb\u63a5\u77e9\u9635\u4e00\u6837\uff0c\u7528\u5217\u8868\u7d22\u5f15\u6765\u533a\u5206\u4e0d\u540c\u9876\u70b9\uff0c\u90a3\u4e48\u5047\u8bbe\u8981\u5220\u9664\u7d22\u5f15\u4e3a \\(i\\) \u7684\u9876\u70b9\uff0c\u5219\u9700\u904d\u5386\u6574\u4e2a\u90bb\u63a5\u8868\uff0c\u5c06\u6240\u6709\u5927\u4e8e \\(i\\) \u7684\u7d22\u5f15\u5168\u90e8\u51cf \\(1\\) \uff0c\u6548\u7387\u5f88\u4f4e\u3002\u800c\u5982\u679c\u6bcf\u4e2a\u9876\u70b9\u90fd\u662f\u552f\u4e00\u7684 Vertex \u5b9e\u4f8b\uff0c\u5220\u9664\u67d0\u4e00\u9876\u70b9\u4e4b\u540e\u5c31\u65e0\u987b\u6539\u52a8\u5176\u4ed6\u9876\u70b9\u4e86\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_list.py
    class GraphAdjList:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, edges: list[list[Vertex]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        self.adj_list = dict[Vertex, list[Vertex]]()\n        # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges:\n            self.add_vertex(edge[0])\n            self.add_vertex(edge[1])\n            self.add_edge(edge[0], edge[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.adj_list)\n\n    def add_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list[vet1].append(vet2)\n        self.adj_list[vet2].append(vet1)\n\n    def remove_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list[vet1].remove(vet2)\n        self.adj_list[vet2].remove(vet1)\n\n    def add_vertex(self, vet: Vertex):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        if vet in self.adj_list:\n            return\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list[vet] = []\n\n    def remove_vertex(self, vet: Vertex):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if vet not in self.adj_list:\n            raise ValueError()\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.pop(vet)\n        # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for vertex in self.adj_list:\n            if vet in self.adj_list[vertex]:\n                self.adj_list[vertex].remove(vet)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u8868\"\"\"\n        print(\"\u90bb\u63a5\u8868 =\")\n        for vertex in self.adj_list:\n            tmp = [v.val for v in self.adj_list[vertex]]\n            print(f\"{vertex.val}: {tmp},\")\n
    graph_adjacency_list.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  public:\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    unordered_map<Vertex *, vector<Vertex *>> adjList;\n\n    /* \u5728 vector \u4e2d\u5220\u9664\u6307\u5b9a\u8282\u70b9 */\n    void remove(vector<Vertex *> &vec, Vertex *vet) {\n        for (int i = 0; i < vec.size(); i++) {\n            if (vec[i] == vet) {\n                vec.erase(vec.begin() + i);\n                break;\n            }\n        }\n    }\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjList(const vector<vector<Vertex *>> &edges) {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const vector<Vertex *> &edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    void addEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].push_back(vet2);\n        adjList[vet2].push_back(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    void removeEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        remove(adjList[vet1], vet2);\n        remove(adjList[vet2], vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(Vertex *vet) {\n        if (adjList.count(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = vector<Vertex *>();\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(Vertex *vet) {\n        if (!adjList.count(vet))\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.erase(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (auto &adj : adjList) {\n            remove(adj.second, vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    void print() {\n        cout << \"\u90bb\u63a5\u8868 =\" << endl;\n        for (auto &adj : adjList) {\n            const auto &key = adj.first;\n            const auto &vec = adj.second;\n            cout << key->val << \": \";\n            printVector(vetsToVals(vec));\n        }\n    }\n};\n
    graph_adjacency_list.java
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    Map<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjList(Vertex[][] edges) {\n        this.adjList = new HashMap<>();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (Vertex[] edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void addEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList.get(vet1).add(vet2);\n        adjList.get(vet2).add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void removeEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList.get(vet1).remove(vet2);\n        adjList.get(vet2).remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(Vertex vet) {\n        if (adjList.containsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.put(vet, new ArrayList<>());\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(Vertex vet) {\n        if (!adjList.containsKey(vet))\n            throw new IllegalArgumentException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (List<Vertex> list : adjList.values()) {\n            list.remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void print() {\n        System.out.println(\"\u90bb\u63a5\u8868 =\");\n        for (Map.Entry<Vertex, List<Vertex>> pair : adjList.entrySet()) {\n            List<Integer> tmp = new ArrayList<>();\n            for (Vertex vertex : pair.getValue())\n                tmp.add(vertex.val);\n            System.out.println(pair.getKey().val + \": \" + tmp + \",\");\n        }\n    }\n}\n
    graph_adjacency_list.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public Dictionary<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjList(Vertex[][] edges) {\n        adjList = [];\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        foreach (Vertex[] edge in edges) {\n            AddVertex(edge[0]);\n            AddVertex(edge[1]);\n            AddEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return adjList.Count;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void AddEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].Add(vet2);\n        adjList[vet2].Add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void RemoveEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1].Remove(vet2);\n        adjList[vet2].Remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(Vertex vet) {\n        if (adjList.ContainsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.Add(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(Vertex vet) {\n        if (!adjList.ContainsKey(vet))\n            throw new InvalidOperationException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.Remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        foreach (List<Vertex> list in adjList.Values) {\n            list.Remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void Print() {\n        Console.WriteLine(\"\u90bb\u63a5\u8868 =\");\n        foreach (KeyValuePair<Vertex, List<Vertex>> pair in adjList) {\n            List<int> tmp = [];\n            foreach (Vertex vertex in pair.Value)\n                tmp.Add(vertex.val);\n            Console.WriteLine(pair.Key.val + \": [\" + string.Join(\", \", tmp) + \"],\");\n        }\n    }\n}\n
    graph_adjacency_list.go
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjList struct {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList map[Vertex][]Vertex\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjList(edges [][]Vertex) *graphAdjList {\n    g := &graphAdjList{\n        adjList: make(map[Vertex][]Vertex),\n    }\n    // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for _, edge := range edges {\n        g.addVertex(edge[0])\n        g.addVertex(edge[1])\n        g.addEdge(edge[0], edge[1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjList) size() int {\n    return len(g.adjList)\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nfunc (g *graphAdjList) addEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2, \u6dfb\u52a0\u533f\u540d struct{},\n    g.adjList[vet1] = append(g.adjList[vet1], vet2)\n    g.adjList[vet2] = append(g.adjList[vet2], vet1)\n}\n\n/* \u5220\u9664\u8fb9 */\nfunc (g *graphAdjList) removeEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    g.adjList[vet1] = DeleteSliceElms(g.adjList[vet1], vet2)\n    g.adjList[vet2] = DeleteSliceElms(g.adjList[vet2], vet1)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjList) addVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if ok {\n        return\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    g.adjList[vet] = make([]Vertex, 0)\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjList) removeVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if !ok {\n        panic(\"error\")\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    delete(g.adjList, vet)\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for v, list := range g.adjList {\n        g.adjList[v] = DeleteSliceElms(list, vet)\n    }\n}\n\n/* \u6253\u5370\u90bb\u63a5\u8868 */\nfunc (g *graphAdjList) print() {\n    var builder strings.Builder\n    fmt.Printf(\"\u90bb\u63a5\u8868 = \\n\")\n    for k, v := range g.adjList {\n        builder.WriteString(\"\\t\\t\" + strconv.Itoa(k.Val) + \": \")\n        for _, vet := range v {\n            builder.WriteString(strconv.Itoa(vet.Val) + \" \")\n        }\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    graph_adjacency_list.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public private(set) var adjList: [Vertex: [Vertex]]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public init(edges: [[Vertex]]) {\n        adjList = [:]\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            addVertex(vet: edge[0])\n            addVertex(vet: edge[1])\n            addEdge(vet1: edge[0], vet2: edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public func size() -> Int {\n        adjList.count\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public func addEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.append(vet2)\n        adjList[vet2]?.append(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public func removeEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.removeAll { $0 == vet2 }\n        adjList[vet2]?.removeAll { $0 == vet1 }\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public func addVertex(vet: Vertex) {\n        if adjList[vet] != nil {\n            return\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = []\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public func removeVertex(vet: Vertex) {\n        if adjList[vet] == nil {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.removeValue(forKey: vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for key in adjList.keys {\n            adjList[key]?.removeAll { $0 == vet }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public func print() {\n        Swift.print(\"\u90bb\u63a5\u8868 =\")\n        for (vertex, list) in adjList {\n            let list = list.map { $0.val }\n            Swift.print(\"\\(vertex.val): \\(list),\")\n        }\n    }\n}\n
    graph_adjacency_list.js
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet) {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet) {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print() {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList: Map<Vertex, Vertex[]>;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges: Vertex[][]) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet: Vertex): void {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet: Vertex): void {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index: number = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print(): void {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList.entries()) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  Map<Vertex, List<Vertex>> adjList = {};\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjList(List<List<Vertex>> edges) {\n    for (List<Vertex> edge in edges) {\n      addVertex(edge[0]);\n      addVertex(edge[1]);\n      addEdge(edge[0], edge[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return adjList.length;\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  void addEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    adjList[vet1]!.add(vet2);\n    adjList[vet2]!.add(vet1);\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  void removeEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    adjList[vet1]!.remove(vet2);\n    adjList[vet2]!.remove(vet1);\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(Vertex vet) {\n    if (adjList.containsKey(vet)) return;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    adjList[vet] = [];\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(Vertex vet) {\n    if (!adjList.containsKey(vet)) {\n      throw ArgumentError;\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    adjList.remove(vet);\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    adjList.forEach((key, value) {\n      value.remove(vet);\n    });\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u8868 */\n  void printAdjList() {\n    print(\"\u90bb\u63a5\u8868 =\");\n    adjList.forEach((key, value) {\n      List<int> tmp = [];\n      for (Vertex vertex in value) {\n        tmp.add(vertex.val);\n      }\n      print(\"${key.val}: $tmp,\");\n    });\n  }\n}\n
    graph_adjacency_list.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    pub adj_list: HashMap<Vertex, Vec<Vertex>>,\n}\n\nimpl GraphAdjList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(edges: Vec<[Vertex; 2]>) -> Self {\n        let mut graph = GraphAdjList {\n            adj_list: HashMap::new(),\n        };\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            graph.add_vertex(edge[0]);\n            graph.add_vertex(edge[1]);\n            graph.add_edge(edge[0], edge[1]);\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    #[allow(unused)]\n    pub fn size(&self) -> usize {\n        self.adj_list.len()\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list.get_mut(&vet1).unwrap().push(vet2);\n        self.adj_list.get_mut(&vet2).unwrap().push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    #[allow(unused)]\n    pub fn remove_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list\n            .get_mut(&vet1)\n            .unwrap()\n            .retain(|&vet| vet != vet2);\n        self.adj_list\n            .get_mut(&vet2)\n            .unwrap()\n            .retain(|&vet| vet != vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, vet: Vertex) {\n        if self.adj_list.contains_key(&vet) {\n            return;\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list.insert(vet, vec![]);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    #[allow(unused)]\n    pub fn remove_vertex(&mut self, vet: Vertex) {\n        if !self.adj_list.contains_key(&vet) {\n            panic!(\"value error\");\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.remove(&vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for list in self.adj_list.values_mut() {\n            list.retain(|&v| v != vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    pub fn print(&self) {\n        println!(\"\u90bb\u63a5\u8868 =\");\n        for (vertex, list) in &self.adj_list {\n            let list = list.iter().map(|vertex| vertex.val).collect::<Vec<i32>>();\n            println!(\"{}: {:?},\", vertex.val, list);\n        }\n    }\n}\n
    graph_adjacency_list.c
    /* \u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct AdjListNode {\n    Vertex *vertex;           // \u9876\u70b9\n    struct AdjListNode *next; // \u540e\u7ee7\u8282\u70b9\n} AdjListNode;\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid addEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *node = (AdjListNode *)malloc(sizeof(AdjListNode));\n    node->vertex = vet;\n    // \u5934\u63d2\u6cd5\n    node->next = head->next;\n    head->next = node;\n}\n\n/* \u5220\u9664\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid removeEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *pre = head;\n    AdjListNode *cur = head->next;\n    // \u5728\u94fe\u8868\u4e2d\u641c\u7d22 vet \u5bf9\u5e94\u8282\u70b9\n    while (cur != NULL && cur->vertex != vet) {\n        pre = cur;\n        cur = cur->next;\n    }\n    if (cur == NULL)\n        return;\n    // \u5c06 vet \u5bf9\u5e94\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u5220\u9664\n    pre->next = cur->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(cur);\n}\n\n/* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntypedef struct {\n    AdjListNode *heads[MAX_SIZE]; // \u8282\u70b9\u6570\u7ec4\n    int size;                     // \u8282\u70b9\u6570\u91cf\n} GraphAdjList;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjList *newGraphAdjList() {\n    GraphAdjList *graph = (GraphAdjList *)malloc(sizeof(GraphAdjList));\n    if (!graph) {\n        return NULL;\n    }\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        graph->heads[i] = NULL;\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjList(GraphAdjList *graph) {\n    for (int i = 0; i < graph->size; i++) {\n        AdjListNode *cur = graph->heads[i];\n        while (cur != NULL) {\n            AdjListNode *next = cur->next;\n            if (cur != graph->heads[i]) {\n                free(cur);\n            }\n            cur = next;\n        }\n        free(graph->heads[i]->vertex);\n        free(graph->heads[i]);\n    }\n    free(graph);\n}\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nvoid addEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL && head1 != head2);\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    addEdgeHelper(head1, vet2);\n    addEdgeHelper(head2, vet1);\n}\n\n/* \u5220\u9664\u8fb9 */\nvoid removeEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL);\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    removeEdgeHelper(head1, head2->vertex);\n    removeEdgeHelper(head2, head1->vertex);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjList *graph, Vertex *vet) {\n    assert(graph != NULL && graph->size < MAX_SIZE);\n    AdjListNode *head = (AdjListNode *)malloc(sizeof(AdjListNode));\n    head->vertex = vet;\n    head->next = NULL;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    graph->heads[graph->size++] = head;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjList *graph, Vertex *vet) {\n    AdjListNode *node = findNode(graph, vet);\n    assert(node != NULL);\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    AdjListNode *cur = node, *pre = NULL;\n    while (cur) {\n        pre = cur;\n        cur = cur->next;\n        free(pre);\n    }\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for (int i = 0; i < graph->size; i++) {\n        cur = graph->heads[i];\n        pre = NULL;\n        while (cur) {\n            pre = cur;\n            cur = cur->next;\n            if (cur && cur->vertex == vet) {\n                pre->next = cur->next;\n                free(cur);\n                break;\n            }\n        }\n    }\n    // \u5c06\u8be5\u9876\u70b9\u4e4b\u540e\u7684\u9876\u70b9\u5411\u524d\u79fb\u52a8\uff0c\u4ee5\u586b\u8865\u7a7a\u7f3a\n    int i;\n    for (i = 0; i < graph->size; i++) {\n        if (graph->heads[i] == node)\n            break;\n    }\n    for (int j = i; j < graph->size - 1; j++) {\n        graph->heads[j] = graph->heads[j + 1];\n    }\n    graph->size--;\n    free(vet);\n}\n
    graph_adjacency_list.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList(edges: Array<Array<Vertex?>>) {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    val adjList = HashMap<Vertex, MutableList<Vertex>>()\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (edge in edges) {\n            addVertex(edge[0]!!)\n            addVertex(edge[1]!!)\n            addEdge(edge[0]!!, edge[1]!!)\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return adjList.size\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    fun addEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.add(vet2)\n        adjList[vet2]?.add(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    fun removeEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.remove(vet2)\n        adjList[vet2]?.remove(vet1)\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(vet: Vertex) {\n        if (adjList.containsKey(vet))\n            return\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = mutableListOf()\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(vet: Vertex) {\n        if (!adjList.containsKey(vet))\n            throw IllegalArgumentException()\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (list in adjList.values) {\n            list.remove(vet)\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    fun print() {\n        println(\"\u90bb\u63a5\u8868 =\")\n        for (pair in adjList.entries) {\n            val tmp = mutableListOf<Int>()\n            for (vertex in pair.value) {\n                tmp.add(vertex._val)\n            }\n            println(\"${pair.key._val}: $tmp,\")\n        }\n    }\n}\n
    graph_adjacency_list.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjList\n  attr_reader :adj_list\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(edges)\n    # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    @adj_list = {}\n    # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for edge in edges\n      add_vertex(edge[0])\n      add_vertex(edge[1])\n      add_edge(edge[0], edge[1])\n    end\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @adj_list.length\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    @adj_list[vet1] << vet2\n    @adj_list[vet2] << vet1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    # \u5220\u9664\u8fb9 vet1 - vet2\n    @adj_list[vet1].delete(vet2)\n    @adj_list[vet2].delete(vet1)\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(vet)\n    return if @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    @adj_list[vet] = []\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(vet)\n    raise ArgumentError unless @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    @adj_list.delete(vet)\n    # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for vertex in @adj_list\n      @adj_list[vertex.first].delete(vet) if @adj_list[vertex.first].include?(vet)\n    end\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u8868 ###\n  def __print__\n    puts '\u90bb\u63a5\u8868 ='\n    for vertex in @adj_list\n      tmp = @adj_list[vertex.first].map { |v| v.val }\n      puts \"#{vertex.first.val}: #{tmp},\"\n    end\n  end\nend\n
    graph_adjacency_list.zig
    [class]{GraphAdjList}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_graph/graph_operations/#923","title":"9.2.3 \u00a0 \u6548\u7387\u5bf9\u6bd4","text":"

    \u8bbe\u56fe\u4e2d\u5171\u6709 \\(n\\) \u4e2a\u9876\u70b9\u548c \\(m\\) \u6761\u8fb9\uff0c\u8868 9-2 \u5bf9\u6bd4\u4e86\u90bb\u63a5\u77e9\u9635\u548c\u90bb\u63a5\u8868\u7684\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u3002

    \u8868 9-2 \u00a0 \u90bb\u63a5\u77e9\u9635\u4e0e\u90bb\u63a5\u8868\u5bf9\u6bd4

    \u90bb\u63a5\u77e9\u9635 \u90bb\u63a5\u8868\uff08\u94fe\u8868\uff09 \u90bb\u63a5\u8868\uff08\u54c8\u5e0c\u8868\uff09 \u5224\u65ad\u662f\u5426\u90bb\u63a5 \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) \u6dfb\u52a0\u8fb9 \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) \u5220\u9664\u8fb9 \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) \u6dfb\u52a0\u9876\u70b9 \\(O(n)\\) \\(O(1)\\) \\(O(1)\\) \u5220\u9664\u9876\u70b9 \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n)\\) \u5185\u5b58\u7a7a\u95f4\u5360\u7528 \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n + m)\\)

    \u89c2\u5bdf\u8868 9-2 \uff0c\u4f3c\u4e4e\u90bb\u63a5\u8868\uff08\u54c8\u5e0c\u8868\uff09\u7684\u65f6\u95f4\u6548\u7387\u4e0e\u7a7a\u95f4\u6548\u7387\u6700\u4f18\u3002\u4f46\u5b9e\u9645\u4e0a\uff0c\u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u64cd\u4f5c\u8fb9\u7684\u6548\u7387\u66f4\u9ad8\uff0c\u53ea\u9700\u4e00\u6b21\u6570\u7ec4\u8bbf\u95ee\u6216\u8d4b\u503c\u64cd\u4f5c\u5373\u53ef\u3002\u7efc\u5408\u6765\u770b\uff0c\u90bb\u63a5\u77e9\u9635\u4f53\u73b0\u4e86\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\u7684\u539f\u5219\uff0c\u800c\u90bb\u63a5\u8868\u4f53\u73b0\u4e86\u201c\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4\u201d\u7684\u539f\u5219\u3002

    "},{"location":"chapter_graph/graph_traversal/","title":"9.3 \u00a0 \u56fe\u7684\u904d\u5386","text":"

    \u6811\u4ee3\u8868\u7684\u662f\u201c\u4e00\u5bf9\u591a\u201d\u7684\u5173\u7cfb\uff0c\u800c\u56fe\u5219\u5177\u6709\u66f4\u9ad8\u7684\u81ea\u7531\u5ea6\uff0c\u53ef\u4ee5\u8868\u793a\u4efb\u610f\u7684\u201c\u591a\u5bf9\u591a\u201d\u5173\u7cfb\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u6811\u770b\u4f5c\u56fe\u7684\u4e00\u79cd\u7279\u4f8b\u3002\u663e\u7136\uff0c\u6811\u7684\u904d\u5386\u64cd\u4f5c\u4e5f\u662f\u56fe\u7684\u904d\u5386\u64cd\u4f5c\u7684\u4e00\u79cd\u7279\u4f8b\u3002

    \u56fe\u548c\u6811\u90fd\u9700\u8981\u5e94\u7528\u641c\u7d22\u7b97\u6cd5\u6765\u5b9e\u73b0\u904d\u5386\u64cd\u4f5c\u3002\u56fe\u7684\u904d\u5386\u65b9\u5f0f\u4e5f\u53ef\u5206\u4e3a\u4e24\u79cd\uff1a\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u548c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u3002

    "},{"location":"chapter_graph/graph_traversal/#931","title":"9.3.1 \u00a0 \u5e7f\u5ea6\u4f18\u5148\u904d\u5386","text":"

    \u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u7531\u8fd1\u53ca\u8fdc\u7684\u904d\u5386\u65b9\u5f0f\uff0c\u4ece\u67d0\u4e2a\u8282\u70b9\u51fa\u53d1\uff0c\u59cb\u7ec8\u4f18\u5148\u8bbf\u95ee\u8ddd\u79bb\u6700\u8fd1\u7684\u9876\u70b9\uff0c\u5e76\u4e00\u5c42\u5c42\u5411\u5916\u6269\u5f20\u3002\u5982\u56fe 9-9 \u6240\u793a\uff0c\u4ece\u5de6\u4e0a\u89d2\u9876\u70b9\u51fa\u53d1\uff0c\u9996\u5148\u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\uff0c\u7136\u540e\u904d\u5386\u4e0b\u4e00\u4e2a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u6240\u6709\u9876\u70b9\u8bbf\u95ee\u5b8c\u6bd5\u3002

    \u56fe 9-9 \u00a0 \u56fe\u7684\u5e7f\u5ea6\u4f18\u5148\u904d\u5386

    "},{"location":"chapter_graph/graph_traversal/#1","title":"1. \u00a0 \u7b97\u6cd5\u5b9e\u73b0","text":"

    BFS \u901a\u5e38\u501f\u52a9\u961f\u5217\u6765\u5b9e\u73b0\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\u3002\u961f\u5217\u5177\u6709\u201c\u5148\u5165\u5148\u51fa\u201d\u7684\u6027\u8d28\uff0c\u8fd9\u4e0e BFS \u7684\u201c\u7531\u8fd1\u53ca\u8fdc\u201d\u7684\u601d\u60f3\u5f02\u66f2\u540c\u5de5\u3002

    1. \u5c06\u904d\u5386\u8d77\u59cb\u9876\u70b9 startVet \u52a0\u5165\u961f\u5217\uff0c\u5e76\u5f00\u542f\u5faa\u73af\u3002
    2. \u5728\u5faa\u73af\u7684\u6bcf\u8f6e\u8fed\u4ee3\u4e2d\uff0c\u5f39\u51fa\u961f\u9996\u9876\u70b9\u5e76\u8bb0\u5f55\u8bbf\u95ee\uff0c\u7136\u540e\u5c06\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\u52a0\u5165\u5230\u961f\u5217\u5c3e\u90e8\u3002
    3. \u5faa\u73af\u6b65\u9aa4 2. \uff0c\u76f4\u5230\u6240\u6709\u9876\u70b9\u88ab\u8bbf\u95ee\u5b8c\u6bd5\u540e\u7ed3\u675f\u3002

    \u4e3a\u4e86\u9632\u6b62\u91cd\u590d\u904d\u5386\u9876\u70b9\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408 visited \u6765\u8bb0\u5f55\u54ea\u4e9b\u8282\u70b9\u5df2\u88ab\u8bbf\u95ee\u3002

    Tip

    \u54c8\u5e0c\u96c6\u5408\u53ef\u4ee5\u770b\u4f5c\u4e00\u4e2a\u53ea\u5b58\u50a8 key \u800c\u4e0d\u5b58\u50a8 value \u7684\u54c8\u5e0c\u8868\uff0c\u5b83\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u590d\u6742\u5ea6\u4e0b\u8fdb\u884c key \u7684\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u3002\u6839\u636e key \u7684\u552f\u4e00\u6027\uff0c\u54c8\u5e0c\u96c6\u5408\u901a\u5e38\u7528\u4e8e\u6570\u636e\u53bb\u91cd\u7b49\u573a\u666f\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_bfs.py
    def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]([start_vet])\n    # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    que = deque[Vertex]([start_vet])\n    # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while len(que) > 0:\n        vet = que.popleft()  # \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adj_vet in graph.adj_list[vet]:\n            if adj_vet in visited:\n                continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.append(adj_vet)  # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adj_vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n
    graph_bfs.cpp
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphBFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited = {startVet};\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    queue<Vertex *> que;\n    que.push(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.empty()) {\n        Vertex *vet = que.front();\n        que.pop();          // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push_back(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (auto adjVet : graph.adjList[vet]) {\n            if (visited.count(adjVet))\n                continue;            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.push(adjVet);        // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.emplace(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.java
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new LinkedList<>();\n    que.offer(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        Vertex vet = que.poll(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet);            // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (Vertex adjVet : graph.adjList.get(vet)) {\n            if (visited.contains(adjVet))\n                continue;        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.cs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [startVet];\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new();\n    que.Enqueue(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.Count > 0) {\n        Vertex vet = que.Dequeue(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.Add(vet);               // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        foreach (Vertex adjVet in graph.adjList[vet]) {\n            if (visited.Contains(adjVet)) {\n                continue;          // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.Enqueue(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.Add(adjVet);   // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.go
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    visited[startVet] = struct{}{}\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS, \u4f7f\u7528\u5207\u7247\u6a21\u62df\u961f\u5217\n    queue := make([]Vertex, 0)\n    queue = append(queue, startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    for len(queue) > 0 {\n        // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        vet := queue[0]\n        queue = queue[1:]\n        // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        res = append(res, vet)\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for _, adjVet := range g.adjList[vet] {\n            _, isExist := visited[adjVet]\n            // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            if !isExist {\n                queue = append(queue, adjVet)\n                visited[adjVet] = struct{}{}\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.swift
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = [startVet]\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    var que: [Vertex] = [startVet]\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.isEmpty {\n        let vet = que.removeFirst() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adjVet in graph.adjList[vet] ?? [] {\n            if visited.contains(adjVet) {\n                continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.append(adjVet) // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.insert(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.js
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.ts
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.dart
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n  // \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  visited.add(startVet);\n  // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  Queue<Vertex> que = Queue();\n  que.add(startVet);\n  // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while (que.isNotEmpty) {\n    Vertex vet = que.removeFirst(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet in graph.adjList[vet]!) {\n      if (visited.contains(adjVet)) {\n        continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      }\n      que.add(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    }\n  }\n  // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  return res;\n}\n
    graph_bfs.rs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    visited.insert(start_vet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    let mut que = VecDeque::new();\n    que.push_back(start_vet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.is_empty() {\n        let vet = que.pop_front().unwrap(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        if let Some(adj_vets) = graph.adj_list.get(&vet) {\n            for &adj_vet in adj_vets {\n                if visited.contains(&adj_vet) {\n                    continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n                }\n                que.push_back(adj_vet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited.insert(adj_vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res\n}\n
    graph_bfs.c
    /* \u8282\u70b9\u961f\u5217\u7ed3\u6784\u4f53 */\ntypedef struct {\n    Vertex *vertices[MAX_SIZE];\n    int front, rear, size;\n} Queue;\n\n/* \u6784\u9020\u51fd\u6570 */\nQueue *newQueue() {\n    Queue *q = (Queue *)malloc(sizeof(Queue));\n    q->front = q->rear = q->size = 0;\n    return q;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nint isEmpty(Queue *q) {\n    return q->size == 0;\n}\n\n/* \u5165\u961f\u64cd\u4f5c */\nvoid enqueue(Queue *q, Vertex *vet) {\n    q->vertices[q->rear] = vet;\n    q->rear = (q->rear + 1) % MAX_SIZE;\n    q->size++;\n}\n\n/* \u51fa\u961f\u64cd\u4f5c */\nVertex *dequeue(Queue *q) {\n    Vertex *vet = q->vertices[q->front];\n    q->front = (q->front + 1) % MAX_SIZE;\n    q->size--;\n    return vet;\n}\n\n/* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **visited, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (visited[i] == vet)\n            return 1;\n    }\n    return 0;\n}\n\n/* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphBFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize, Vertex **visited, int *visitedSize) {\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue *queue = newQueue();\n    enqueue(queue, startVet);\n    visited[(*visitedSize)++] = startVet;\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!isEmpty(queue)) {\n        Vertex *vet = dequeue(queue); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res[(*resSize)++] = vet;      // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        AdjListNode *node = findNode(graph, vet);\n        while (node != NULL) {\n            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            if (!isVisited(visited, *visitedSize, node->vertex)) {\n                enqueue(queue, node->vertex);             // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited[(*visitedSize)++] = node->vertex; // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n            node = node->next;\n        }\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(queue);\n}\n
    graph_bfs.kt
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphBFS(graph: GraphAdjList, startVet: Vertex): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex>()\n    visited.add(startVet)\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    val que = LinkedList<Vertex>()\n    que.offer(startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        val vet = que.poll() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet)         // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (adjVet in graph.adjList[vet]!!) {\n            if (visited.contains(adjVet))\n                continue        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet)   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.rb
    ### \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_bfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new([start_vet])\n  # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  que = [start_vet]\n  # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while que.length > 0\n    vet = que.shift # \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adj_vet in graph.adj_list[vet]\n      next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      que << adj_vet # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adj_vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    end\n  end\n  # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res\nend\n
    graph_bfs.zig
    [class]{}-[func]{graphBFS}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4ee3\u7801\u76f8\u5bf9\u62bd\u8c61\uff0c\u5efa\u8bae\u5bf9\u7167\u56fe 9-10 \u6765\u52a0\u6df1\u7406\u89e3\u3002

    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 9-10 \u00a0 \u56fe\u7684\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u6b65\u9aa4

    \u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u7684\u5e8f\u5217\u662f\u5426\u552f\u4e00\uff1f

    \u4e0d\u552f\u4e00\u3002\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u53ea\u8981\u6c42\u6309\u201c\u7531\u8fd1\u53ca\u8fdc\u201d\u7684\u987a\u5e8f\u904d\u5386\uff0c\u800c\u591a\u4e2a\u76f8\u540c\u8ddd\u79bb\u7684\u9876\u70b9\u7684\u904d\u5386\u987a\u5e8f\u5141\u8bb8\u88ab\u4efb\u610f\u6253\u4e71\u3002\u4ee5\u56fe 9-10 \u4e3a\u4f8b\uff0c\u9876\u70b9 \\(1\\)\u3001\\(3\\) \u7684\u8bbf\u95ee\u987a\u5e8f\u53ef\u4ee5\u4ea4\u6362\uff0c\u9876\u70b9 \\(2\\)\u3001\\(4\\)\u3001\\(6\\) \u7684\u8bbf\u95ee\u987a\u5e8f\u4e5f\u53ef\u4ee5\u4efb\u610f\u4ea4\u6362\u3002

    "},{"location":"chapter_graph/graph_traversal/#2","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u6240\u6709\u9876\u70b9\u90fd\u4f1a\u5165\u961f\u5e76\u51fa\u961f\u4e00\u6b21\uff0c\u4f7f\u7528 \\(O(|V|)\\) \u65f6\u95f4\uff1b\u5728\u904d\u5386\u90bb\u63a5\u9876\u70b9\u7684\u8fc7\u7a0b\u4e2d\uff0c\u7531\u4e8e\u662f\u65e0\u5411\u56fe\uff0c\u56e0\u6b64\u6240\u6709\u8fb9\u90fd\u4f1a\u88ab\u8bbf\u95ee \\(2\\) \u6b21\uff0c\u4f7f\u7528 \\(O(2|E|)\\) \u65f6\u95f4\uff1b\u603b\u4f53\u4f7f\u7528 \\(O(|V| + |E|)\\) \u65f6\u95f4\u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5217\u8868 res \uff0c\u54c8\u5e0c\u96c6\u5408 visited \uff0c\u961f\u5217 que \u4e2d\u7684\u9876\u70b9\u6570\u91cf\u6700\u591a\u4e3a \\(|V|\\) \uff0c\u4f7f\u7528 \\(O(|V|)\\) \u7a7a\u95f4\u3002

    "},{"location":"chapter_graph/graph_traversal/#932","title":"9.3.2 \u00a0 \u6df1\u5ea6\u4f18\u5148\u904d\u5386","text":"

    \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u4f18\u5148\u8d70\u5230\u5e95\u3001\u65e0\u8def\u53ef\u8d70\u518d\u56de\u5934\u7684\u904d\u5386\u65b9\u5f0f\u3002\u5982\u56fe 9-11 \u6240\u793a\uff0c\u4ece\u5de6\u4e0a\u89d2\u9876\u70b9\u51fa\u53d1\uff0c\u8bbf\u95ee\u5f53\u524d\u9876\u70b9\u7684\u67d0\u4e2a\u90bb\u63a5\u9876\u70b9\uff0c\u76f4\u5230\u8d70\u5230\u5c3d\u5934\u65f6\u8fd4\u56de\uff0c\u518d\u7ee7\u7eed\u8d70\u5230\u5c3d\u5934\u5e76\u8fd4\u56de\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u6240\u6709\u9876\u70b9\u904d\u5386\u5b8c\u6210\u3002

    \u56fe 9-11 \u00a0 \u56fe\u7684\u6df1\u5ea6\u4f18\u5148\u904d\u5386

    "},{"location":"chapter_graph/graph_traversal/#1_1","title":"1. \u00a0 \u7b97\u6cd5\u5b9e\u73b0","text":"

    \u8fd9\u79cd\u201c\u8d70\u5230\u5c3d\u5934\u518d\u8fd4\u56de\u201d\u7684\u7b97\u6cd5\u8303\u5f0f\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u6765\u5b9e\u73b0\u3002\u4e0e\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u7c7b\u4f3c\uff0c\u5728\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u4e2d\uff0c\u6211\u4eec\u4e5f\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408 visited \u6765\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\uff0c\u4ee5\u907f\u514d\u91cd\u590d\u8bbf\u95ee\u9876\u70b9\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_dfs.py
    def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570\"\"\"\n    res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adj_list[vet]:\n        if adjVet in visited:\n            continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n\ndef graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]()\n    dfs(graph, visited, res, start_vet)\n    return res\n
    graph_dfs.cpp
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList &graph, unordered_set<Vertex *> &visited, vector<Vertex *> &res, Vertex *vet) {\n    res.push_back(vet);   // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.emplace(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex *adjVet : graph.adjList[vet]) {\n        if (visited.count(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphDFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited;\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.java
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList graph, Set<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet : graph.adjList.get(vet)) {\n        if (visited.contains(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.cs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid DFS(GraphAdjList graph, HashSet<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.Add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.Add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    foreach (Vertex adjVet in graph.adjList[vet]) {\n        if (visited.Contains(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9                             \n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        DFS(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [];\n    DFS(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.go
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(g *graphAdjList, visited map[Vertex]struct{}, res *[]Vertex, vet Vertex) {\n    // append \u64cd\u4f5c\u4f1a\u8fd4\u56de\u65b0\u7684\u7684\u5f15\u7528\uff0c\u5fc5\u987b\u8ba9\u539f\u5f15\u7528\u91cd\u65b0\u8d4b\u503c\u4e3a\u65b0slice\u7684\u5f15\u7528\n    *res = append(*res, vet)\n    visited[vet] = struct{}{}\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for _, adjVet := range g.adjList[vet] {\n        _, isExist := visited[adjVet]\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        if !isExist {\n            dfs(g, visited, res, adjVet)\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    dfs(g, visited, &res, startVet)\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_dfs.swift
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], vet: Vertex) {\n    res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adjList[vet] ?? [] {\n        if visited.contains(adjVet) {\n            continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph: graph, visited: &visited, res: &res, vet: adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = []\n    dfs(graph: graph, visited: &visited, res: &res, vet: startVet)\n    return res\n}\n
    graph_dfs.js
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction dfs(graph, visited, res, vet) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.ts
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunction dfs(\n    graph: GraphAdjList,\n    visited: Set<Vertex>,\n    res: Vertex[],\n    vet: Vertex\n): void {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.dart
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(\n  GraphAdjList graph,\n  Set<Vertex> visited,\n  List<Vertex> res,\n  Vertex vet,\n) {\n  res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for (Vertex adjVet in graph.adjList[vet]!) {\n    if (visited.contains(adjVet)) {\n      continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    }\n    // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adjVet);\n  }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  dfs(graph, visited, res, startVet);\n  return res;\n}\n
    graph_dfs.rs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex>, vet: Vertex) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n                         // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    if let Some(adj_vets) = graph.adj_list.get(&vet) {\n        for &adj_vet in adj_vets {\n            if visited.contains(&adj_vet) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, visited, res, adj_vet);\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    dfs(&graph, &mut visited, &mut res, start_vet);\n\n    res\n}\n
    graph_dfs.c
    /* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **res, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (res[i] == vet) {\n            return 1;\n        }\n    }\n    return 0;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList *graph, Vertex **res, int *resSize, Vertex *vet) {\n    // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    res[(*resSize)++] = vet;\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    AdjListNode *node = findNode(graph, vet);\n    while (node != NULL) {\n        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        if (!isVisited(res, *resSize, node->vertex)) {\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, res, resSize, node->vertex);\n        }\n        node = node->next;\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphDFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize) {\n    dfs(graph, res, resSize, startVet);\n}\n
    graph_dfs.kt
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfun dfs(\n    graph: GraphAdjList,\n    visited: MutableSet<Vertex?>,\n    res: MutableList<Vertex?>,\n    vet: Vertex?\n) {\n    res.add(vet)     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (adjVet in graph.adjList[vet]!!) {\n        if (visited.contains(adjVet))\n            continue  // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphDFS(graph: GraphAdjList, startVet: Vertex?): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex?>()\n    dfs(graph, visited, res, startVet)\n    return res\n}\n
    graph_dfs.rb
    ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 ###\ndef dfs(graph, visited, res, vet)\n  res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for adj_vet in graph.adj_list[vet]\n    next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adj_vet)\n  end\nend\n\n### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_dfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new\n  dfs(graph, visited, res, start_vet)\n  res\nend\n
    graph_dfs.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{graphDFS}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u7684\u7b97\u6cd5\u6d41\u7a0b\u5982\u56fe 9-12 \u6240\u793a\u3002

    • \u76f4\u865a\u7ebf\u4ee3\u8868\u5411\u4e0b\u9012\u63a8\uff0c\u8868\u793a\u5f00\u542f\u4e86\u4e00\u4e2a\u65b0\u7684\u9012\u5f52\u65b9\u6cd5\u6765\u8bbf\u95ee\u65b0\u9876\u70b9\u3002
    • \u66f2\u865a\u7ebf\u4ee3\u8868\u5411\u4e0a\u56de\u6eaf\uff0c\u8868\u793a\u6b64\u9012\u5f52\u65b9\u6cd5\u5df2\u7ecf\u8fd4\u56de\uff0c\u56de\u6eaf\u5230\u4e86\u5f00\u542f\u6b64\u65b9\u6cd5\u7684\u4f4d\u7f6e\u3002

    \u4e3a\u4e86\u52a0\u6df1\u7406\u89e3\uff0c\u5efa\u8bae\u5c06\u56fe 9-12 \u4e0e\u4ee3\u7801\u7ed3\u5408\u8d77\u6765\uff0c\u5728\u8111\u4e2d\u6a21\u62df\uff08\u6216\u8005\u7528\u7b14\u753b\u4e0b\u6765\uff09\u6574\u4e2a DFS \u8fc7\u7a0b\uff0c\u5305\u62ec\u6bcf\u4e2a\u9012\u5f52\u65b9\u6cd5\u4f55\u65f6\u5f00\u542f\u3001\u4f55\u65f6\u8fd4\u56de\u3002

    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 9-12 \u00a0 \u56fe\u7684\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u6b65\u9aa4

    \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u7684\u5e8f\u5217\u662f\u5426\u552f\u4e00\uff1f

    \u4e0e\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u7c7b\u4f3c\uff0c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u5e8f\u5217\u7684\u987a\u5e8f\u4e5f\u4e0d\u662f\u552f\u4e00\u7684\u3002\u7ed9\u5b9a\u67d0\u9876\u70b9\uff0c\u5148\u5f80\u54ea\u4e2a\u65b9\u5411\u63a2\u7d22\u90fd\u53ef\u4ee5\uff0c\u5373\u90bb\u63a5\u9876\u70b9\u7684\u987a\u5e8f\u53ef\u4ee5\u4efb\u610f\u6253\u4e71\uff0c\u90fd\u662f\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u3002

    \u4ee5\u6811\u7684\u904d\u5386\u4e3a\u4f8b\uff0c\u201c\u6839 \\(\\rightarrow\\) \u5de6 \\(\\rightarrow\\) \u53f3\u201d\u201c\u5de6 \\(\\rightarrow\\) \u6839 \\(\\rightarrow\\) \u53f3\u201d\u201c\u5de6 \\(\\rightarrow\\) \u53f3 \\(\\rightarrow\\) \u6839\u201d\u5206\u522b\u5bf9\u5e94\u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386\uff0c\u5b83\u4eec\u5c55\u793a\u4e86\u4e09\u79cd\u904d\u5386\u4f18\u5148\u7ea7\uff0c\u7136\u800c\u8fd9\u4e09\u8005\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u3002

    "},{"location":"chapter_graph/graph_traversal/#2_1","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u6240\u6709\u9876\u70b9\u90fd\u4f1a\u88ab\u8bbf\u95ee \\(1\\) \u6b21\uff0c\u4f7f\u7528 \\(O(|V|)\\) \u65f6\u95f4\uff1b\u6240\u6709\u8fb9\u90fd\u4f1a\u88ab\u8bbf\u95ee \\(2\\) \u6b21\uff0c\u4f7f\u7528 \\(O(2|E|)\\) \u65f6\u95f4\uff1b\u603b\u4f53\u4f7f\u7528 \\(O(|V| + |E|)\\) \u65f6\u95f4\u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5217\u8868 res \uff0c\u54c8\u5e0c\u96c6\u5408 visited \u9876\u70b9\u6570\u91cf\u6700\u591a\u4e3a \\(|V|\\) \uff0c\u9012\u5f52\u6df1\u5ea6\u6700\u5927\u4e3a \\(|V|\\) \uff0c\u56e0\u6b64\u4f7f\u7528 \\(O(|V|)\\) \u7a7a\u95f4\u3002

    "},{"location":"chapter_graph/summary/","title":"9.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_graph/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u56fe\u7531\u9876\u70b9\u548c\u8fb9\u7ec4\u6210\uff0c\u53ef\u4ee5\u8868\u793a\u4e3a\u4e00\u7ec4\u9876\u70b9\u548c\u4e00\u7ec4\u8fb9\u6784\u6210\u7684\u96c6\u5408\u3002
    • \u76f8\u8f83\u4e8e\u7ebf\u6027\u5173\u7cfb\uff08\u94fe\u8868\uff09\u548c\u5206\u6cbb\u5173\u7cfb\uff08\u6811\uff09\uff0c\u7f51\u7edc\u5173\u7cfb\uff08\u56fe\uff09\u5177\u6709\u66f4\u9ad8\u7684\u81ea\u7531\u5ea6\uff0c\u56e0\u800c\u66f4\u4e3a\u590d\u6742\u3002
    • \u6709\u5411\u56fe\u7684\u8fb9\u5177\u6709\u65b9\u5411\u6027\uff0c\u8fde\u901a\u56fe\u4e2d\u7684\u4efb\u610f\u9876\u70b9\u5747\u53ef\u8fbe\uff0c\u6709\u6743\u56fe\u7684\u6bcf\u6761\u8fb9\u90fd\u5305\u542b\u6743\u91cd\u53d8\u91cf\u3002
    • \u90bb\u63a5\u77e9\u9635\u5229\u7528\u77e9\u9635\u6765\u8868\u793a\u56fe\uff0c\u6bcf\u4e00\u884c\uff08\u5217\uff09\u4ee3\u8868\u4e00\u4e2a\u9876\u70b9\uff0c\u77e9\u9635\u5143\u7d20\u4ee3\u8868\u8fb9\uff0c\u7528 \\(1\\) \u6216 \\(0\\) \u8868\u793a\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u6709\u8fb9\u6216\u65e0\u8fb9\u3002\u90bb\u63a5\u77e9\u9635\u5728\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u4e0a\u6548\u7387\u5f88\u9ad8\uff0c\u4f46\u7a7a\u95f4\u5360\u7528\u8f83\u591a\u3002
    • \u90bb\u63a5\u8868\u4f7f\u7528\u591a\u4e2a\u94fe\u8868\u6765\u8868\u793a\u56fe\uff0c\u7b2c \\(i\\) \u4e2a\u94fe\u8868\u5bf9\u5e94\u9876\u70b9 \\(i\\) \uff0c\u5176\u4e2d\u5b58\u50a8\u4e86\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\u3002\u90bb\u63a5\u8868\u76f8\u5bf9\u4e8e\u90bb\u63a5\u77e9\u9635\u66f4\u52a0\u8282\u7701\u7a7a\u95f4\uff0c\u4f46\u7531\u4e8e\u9700\u8981\u904d\u5386\u94fe\u8868\u6765\u67e5\u627e\u8fb9\uff0c\u56e0\u6b64\u65f6\u95f4\u6548\u7387\u8f83\u4f4e\u3002
    • \u5f53\u90bb\u63a5\u8868\u4e2d\u7684\u94fe\u8868\u8fc7\u957f\u65f6\uff0c\u53ef\u4ee5\u5c06\u5176\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u6216\u54c8\u5e0c\u8868\uff0c\u4ece\u800c\u63d0\u5347\u67e5\u8be2\u6548\u7387\u3002
    • \u4ece\u7b97\u6cd5\u601d\u60f3\u7684\u89d2\u5ea6\u5206\u6790\uff0c\u90bb\u63a5\u77e9\u9635\u4f53\u73b0\u4e86\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\uff0c\u90bb\u63a5\u8868\u4f53\u73b0\u4e86\u201c\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4\u201d\u3002
    • \u56fe\u53ef\u7528\u4e8e\u5efa\u6a21\u5404\u7c7b\u73b0\u5b9e\u7cfb\u7edf\uff0c\u5982\u793e\u4ea4\u7f51\u7edc\u3001\u5730\u94c1\u7ebf\u8def\u7b49\u3002
    • \u6811\u662f\u56fe\u7684\u4e00\u79cd\u7279\u4f8b\uff0c\u6811\u7684\u904d\u5386\u4e5f\u662f\u56fe\u7684\u904d\u5386\u7684\u4e00\u79cd\u7279\u4f8b\u3002
    • \u56fe\u7684\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u7531\u8fd1\u53ca\u8fdc\u3001\u5c42\u5c42\u6269\u5f20\u7684\u641c\u7d22\u65b9\u5f0f\uff0c\u901a\u5e38\u501f\u52a9\u961f\u5217\u5b9e\u73b0\u3002
    • \u56fe\u7684\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u4f18\u5148\u8d70\u5230\u5e95\u3001\u65e0\u8def\u53ef\u8d70\u65f6\u518d\u56de\u6eaf\u7684\u641c\u7d22\u65b9\u5f0f\uff0c\u5e38\u57fa\u4e8e\u9012\u5f52\u6765\u5b9e\u73b0\u3002
    "},{"location":"chapter_graph/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u8def\u5f84\u7684\u5b9a\u4e49\u662f\u9876\u70b9\u5e8f\u5217\u8fd8\u662f\u8fb9\u5e8f\u5217\uff1f

    \u7ef4\u57fa\u767e\u79d1\u4e0a\u4e0d\u540c\u8bed\u8a00\u7248\u672c\u7684\u5b9a\u4e49\u4e0d\u4e00\u81f4\uff1a\u82f1\u6587\u7248\u662f\u201c\u8def\u5f84\u662f\u4e00\u4e2a\u8fb9\u5e8f\u5217\u201d\uff0c\u800c\u4e2d\u6587\u7248\u662f\u201c\u8def\u5f84\u662f\u4e00\u4e2a\u9876\u70b9\u5e8f\u5217\u201d\u3002\u4ee5\u4e0b\u662f\u82f1\u6587\u7248\u539f\u6587\uff1aIn graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices.

    \u5728\u672c\u6587\u4e2d\uff0c\u8def\u5f84\u88ab\u89c6\u4e3a\u4e00\u4e2a\u8fb9\u5e8f\u5217\uff0c\u800c\u4e0d\u662f\u4e00\u4e2a\u9876\u70b9\u5e8f\u5217\u3002\u8fd9\u662f\u56e0\u4e3a\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u53ef\u80fd\u5b58\u5728\u591a\u6761\u8fb9\u8fde\u63a5\uff0c\u6b64\u65f6\u6bcf\u6761\u8fb9\u90fd\u5bf9\u5e94\u4e00\u6761\u8def\u5f84\u3002

    Q\uff1a\u975e\u8fde\u901a\u56fe\u4e2d\u662f\u5426\u4f1a\u6709\u65e0\u6cd5\u904d\u5386\u5230\u7684\u70b9\uff1f

    \u5728\u975e\u8fde\u901a\u56fe\u4e2d\uff0c\u4ece\u67d0\u4e2a\u9876\u70b9\u51fa\u53d1\uff0c\u81f3\u5c11\u6709\u4e00\u4e2a\u9876\u70b9\u65e0\u6cd5\u5230\u8fbe\u3002\u904d\u5386\u975e\u8fde\u901a\u56fe\u9700\u8981\u8bbe\u7f6e\u591a\u4e2a\u8d77\u70b9\uff0c\u4ee5\u904d\u5386\u5230\u56fe\u7684\u6240\u6709\u8fde\u901a\u5206\u91cf\u3002

    Q\uff1a\u5728\u90bb\u63a5\u8868\u4e2d\uff0c\u201c\u4e0e\u8be5\u9876\u70b9\u76f8\u8fde\u7684\u6240\u6709\u9876\u70b9\u201d\u7684\u9876\u70b9\u987a\u5e8f\u662f\u5426\u6709\u8981\u6c42\uff1f

    \u53ef\u4ee5\u662f\u4efb\u610f\u987a\u5e8f\u3002\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u53ef\u80fd\u9700\u8981\u6309\u7167\u6307\u5b9a\u89c4\u5219\u6765\u6392\u5e8f\uff0c\u6bd4\u5982\u6309\u7167\u9876\u70b9\u6dfb\u52a0\u7684\u6b21\u5e8f\uff0c\u6216\u8005\u6309\u7167\u9876\u70b9\u503c\u5927\u5c0f\u7684\u987a\u5e8f\u7b49\uff0c\u8fd9\u6837\u6709\u52a9\u4e8e\u5feb\u901f\u67e5\u627e\u201c\u5e26\u6709\u67d0\u79cd\u6781\u503c\u201d\u7684\u9876\u70b9\u3002

    "},{"location":"chapter_greedy/","title":"\u7b2c 15 \u7ae0 \u00a0 \u8d2a\u5fc3","text":"

    Abstract

    \u5411\u65e5\u8475\u671d\u7740\u592a\u9633\u8f6c\u52a8\uff0c\u65f6\u523b\u8ffd\u6c42\u81ea\u8eab\u6210\u957f\u7684\u6700\u5927\u53ef\u80fd\u3002

    \u8d2a\u5fc3\u7b56\u7565\u5728\u4e00\u8f6e\u8f6e\u7684\u7b80\u5355\u9009\u62e9\u4e2d\uff0c\u9010\u6b65\u5bfc\u5411\u6700\u4f73\u7b54\u6848\u3002

    "},{"location":"chapter_greedy/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 15.1 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5
    • 15.2 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898
    • 15.3 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898
    • 15.4 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u95ee\u9898
    • 15.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_greedy/fractional_knapsack_problem/","title":"15.2 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a \\(n\\) \u4e2a\u7269\u54c1\uff0c\u7b2c \\(i\\) \u4e2a\u7269\u54c1\u7684\u91cd\u91cf\u4e3a \\(wgt[i-1]\\)\u3001\u4ef7\u503c\u4e3a \\(val[i-1]\\) \uff0c\u548c\u4e00\u4e2a\u5bb9\u91cf\u4e3a \\(cap\\) \u7684\u80cc\u5305\u3002\u6bcf\u4e2a\u7269\u54c1\u53ea\u80fd\u9009\u62e9\u4e00\u6b21\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u7269\u54c1\u7684\u4e00\u90e8\u5206\uff0c\u4ef7\u503c\u6839\u636e\u9009\u62e9\u7684\u91cd\u91cf\u6bd4\u4f8b\u8ba1\u7b97\uff0c\u95ee\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80cc\u5305\u4e2d\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u3002\u793a\u4f8b\u5982\u56fe 15-3 \u6240\u793a\u3002

    \u56fe 15-3 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    \u5206\u6570\u80cc\u5305\u95ee\u9898\u548c 0-1 \u80cc\u5305\u95ee\u9898\u6574\u4f53\u4e0a\u975e\u5e38\u76f8\u4f3c\uff0c\u72b6\u6001\u5305\u542b\u5f53\u524d\u7269\u54c1 \\(i\\) \u548c\u5bb9\u91cf \\(c\\) \uff0c\u76ee\u6807\u662f\u6c42\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u7684\u6700\u5927\u4ef7\u503c\u3002

    \u4e0d\u540c\u70b9\u5728\u4e8e\uff0c\u672c\u9898\u5141\u8bb8\u53ea\u9009\u62e9\u7269\u54c1\u7684\u4e00\u90e8\u5206\u3002\u5982\u56fe 15-4 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u7269\u54c1\u4efb\u610f\u5730\u8fdb\u884c\u5207\u5206\uff0c\u5e76\u6309\u7167\u91cd\u91cf\u6bd4\u4f8b\u6765\u8ba1\u7b97\u76f8\u5e94\u4ef7\u503c\u3002

    1. \u5bf9\u4e8e\u7269\u54c1 \\(i\\) \uff0c\u5b83\u5728\u5355\u4f4d\u91cd\u91cf\u4e0b\u7684\u4ef7\u503c\u4e3a \\(val[i-1] / wgt[i-1]\\) \uff0c\u7b80\u79f0\u5355\u4f4d\u4ef7\u503c\u3002
    2. \u5047\u8bbe\u653e\u5165\u4e00\u90e8\u5206\u7269\u54c1 \\(i\\) \uff0c\u91cd\u91cf\u4e3a \\(w\\) \uff0c\u5219\u80cc\u5305\u589e\u52a0\u7684\u4ef7\u503c\u4e3a \\(w \\times val[i-1] / wgt[i-1]\\) \u3002

    \u56fe 15-4 \u00a0 \u7269\u54c1\u5728\u5355\u4f4d\u91cd\u91cf\u4e0b\u7684\u4ef7\u503c

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#1","title":"1. \u00a0 \u8d2a\u5fc3\u7b56\u7565\u786e\u5b9a","text":"

    \u6700\u5927\u5316\u80cc\u5305\u5185\u7269\u54c1\u603b\u4ef7\u503c\uff0c\u672c\u8d28\u4e0a\u662f\u6700\u5927\u5316\u5355\u4f4d\u91cd\u91cf\u4e0b\u7684\u7269\u54c1\u4ef7\u503c\u3002\u7531\u6b64\u4fbf\u53ef\u63a8\u7406\u51fa\u56fe 15-5 \u6240\u793a\u7684\u8d2a\u5fc3\u7b56\u7565\u3002

    1. \u5c06\u7269\u54c1\u6309\u7167\u5355\u4f4d\u4ef7\u503c\u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\u3002
    2. \u904d\u5386\u6240\u6709\u7269\u54c1\uff0c\u6bcf\u8f6e\u8d2a\u5fc3\u5730\u9009\u62e9\u5355\u4f4d\u4ef7\u503c\u6700\u9ad8\u7684\u7269\u54c1\u3002
    3. \u82e5\u5269\u4f59\u80cc\u5305\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u586b\u6ee1\u80cc\u5305\u3002

    \u56fe 15-5 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898\u7684\u8d2a\u5fc3\u7b56\u7565

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u6211\u4eec\u5efa\u7acb\u4e86\u4e00\u4e2a\u7269\u54c1\u7c7b Item \uff0c\u4ee5\u4fbf\u5c06\u7269\u54c1\u6309\u7167\u5355\u4f4d\u4ef7\u503c\u8fdb\u884c\u6392\u5e8f\u3002\u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u5f53\u80cc\u5305\u5df2\u6ee1\u65f6\u8df3\u51fa\u5e76\u8fd4\u56de\u89e3\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig fractional_knapsack.py
    class Item:\n    \"\"\"\u7269\u54c1\"\"\"\n\n    def __init__(self, w: int, v: int):\n        self.w = w  # \u7269\u54c1\u91cd\u91cf\n        self.v = v  # \u7269\u54c1\u4ef7\u503c\n\ndef fractional_knapsack(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3\"\"\"\n    # \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    items = [Item(w, v) for w, v in zip(wgt, val)]\n    # \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort(key=lambda item: item.v / item.w, reverse=True)\n    # \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    res = 0\n    for item in items:\n        if item.w <= cap:\n            # \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v\n            cap -= item.w\n        else:\n            # \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap\n            # \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n    return res\n
    fractional_knapsack.cpp
    /* \u7269\u54c1 */\nclass Item {\n  public:\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n\n    Item(int w, int v) : w(w), v(v) {\n    }\n};\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(vector<int> &wgt, vector<int> &val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    vector<Item> items;\n    for (int i = 0; i < wgt.size(); i++) {\n        items.push_back(Item(wgt[i], val[i]));\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    sort(items.begin(), items.end(), [](Item &a, Item &b) { return (double)a.v / a.w > (double)b.v / b.w; });\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    for (auto &item : items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double)item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.java
    /* \u7269\u54c1 */\nclass Item {\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n\n    public Item(int w, int v) {\n        this.w = w;\n        this.v = v;\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(int[] wgt, int[] val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item[] items = new Item[wgt.length];\n    for (int i = 0; i < wgt.length; i++) {\n        items[i] = new Item(wgt[i], val[i]);\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    Arrays.sort(items, Comparator.comparingDouble(item -> -((double) item.v / item.w)));\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    for (Item item : items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double) item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.cs
    /* \u7269\u54c1 */\nclass Item(int w, int v) {\n    public int w = w; // \u7269\u54c1\u91cd\u91cf\n    public int v = v; // \u7269\u54c1\u4ef7\u503c\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble FractionalKnapsack(int[] wgt, int[] val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item[] items = new Item[wgt.Length];\n    for (int i = 0; i < wgt.Length; i++) {\n        items[i] = new Item(wgt[i], val[i]);\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    Array.Sort(items, (x, y) => (y.v / y.w).CompareTo(x.v / x.w));\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    foreach (Item item in items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double)item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.go
    /* \u7269\u54c1 */\ntype Item struct {\n    w int // \u7269\u54c1\u91cd\u91cf\n    v int // \u7269\u54c1\u4ef7\u503c\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunc fractionalKnapsack(wgt []int, val []int, cap int) float64 {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    items := make([]Item, len(wgt))\n    for i := 0; i < len(wgt); i++ {\n        items[i] = Item{wgt[i], val[i]}\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    sort.Slice(items, func(i, j int) bool {\n        return float64(items[i].v)/float64(items[i].w) > float64(items[j].v)/float64(items[j].w)\n    })\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    res := 0.0\n    for _, item := range items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += float64(item.v)\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += float64(item.v) / float64(item.w) * float64(cap)\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.swift
    /* \u7269\u54c1 */\nclass Item {\n    var w: Int // \u7269\u54c1\u91cd\u91cf\n    var v: Int // \u7269\u54c1\u4ef7\u503c\n\n    init(w: Int, v: Int) {\n        self.w = w\n        self.v = v\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunc fractionalKnapsack(wgt: [Int], val: [Int], cap: Int) -> Double {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    var items = zip(wgt, val).map { Item(w: $0, v: $1) }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    var res = 0.0\n    var cap = cap\n    for item in items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += Double(item.v)\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += Double(item.v) / Double(item.w) * Double(cap)\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.js
    /* \u7269\u54c1 */\nclass Item {\n    constructor(w, v) {\n        this.w = w; // \u7269\u54c1\u91cd\u91cf\n        this.v = v; // \u7269\u54c1\u4ef7\u503c\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunction fractionalKnapsack(wgt, val, cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    const items = wgt.map((w, i) => new Item(w, val[i]));\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort((a, b) => b.v / b.w - a.v / a.w);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let res = 0;\n    for (const item of items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.ts
    /* \u7269\u54c1 */\nclass Item {\n    w: number; // \u7269\u54c1\u91cd\u91cf\n    v: number; // \u7269\u54c1\u4ef7\u503c\n\n    constructor(w: number, v: number) {\n        this.w = w;\n        this.v = v;\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunction fractionalKnapsack(wgt: number[], val: number[], cap: number): number {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    const items: Item[] = wgt.map((w, i) => new Item(w, val[i]));\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort((a, b) => b.v / b.w - a.v / a.w);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let res = 0;\n    for (const item of items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.dart
    /* \u7269\u54c1 */\nclass Item {\n  int w; // \u7269\u54c1\u91cd\u91cf\n  int v; // \u7269\u54c1\u4ef7\u503c\n\n  Item(this.w, this.v);\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(List<int> wgt, List<int> val, int cap) {\n  // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n  List<Item> items = List.generate(wgt.length, (i) => Item(wgt[i], val[i]));\n  // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n  items.sort((a, b) => (b.v / b.w).compareTo(a.v / a.w));\n  // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n  double res = 0;\n  for (Item item in items) {\n    if (item.w <= cap) {\n      // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n      res += item.v;\n      cap -= item.w;\n    } else {\n      // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n      res += item.v / item.w * cap;\n      // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n      break;\n    }\n  }\n  return res;\n}\n
    fractional_knapsack.rs
    /* \u7269\u54c1 */\nstruct Item {\n    w: i32, // \u7269\u54c1\u91cd\u91cf\n    v: i32, // \u7269\u54c1\u4ef7\u503c\n}\n\nimpl Item {\n    fn new(w: i32, v: i32) -> Self {\n        Self { w, v }\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfn fractional_knapsack(wgt: &[i32], val: &[i32], mut cap: i32) -> f64 {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    let mut items = wgt\n        .iter()\n        .zip(val.iter())\n        .map(|(&w, &v)| Item::new(w, v))\n        .collect::<Vec<Item>>();\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort_by(|a, b| {\n        (b.v as f64 / b.w as f64)\n            .partial_cmp(&(a.v as f64 / a.w as f64))\n            .unwrap()\n    });\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let mut res = 0.0;\n    for item in &items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v as f64;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += item.v as f64 / item.w as f64 * cap as f64;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    res\n}\n
    fractional_knapsack.c
    /* \u7269\u54c1 */\ntypedef struct {\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n} Item;\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfloat fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item *items = malloc(sizeof(Item) * itemCount);\n    for (int i = 0; i < itemCount; i++) {\n        items[i] = (Item){.w = wgt[i], .v = val[i]};\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    qsort(items, (size_t)itemCount, sizeof(Item), sortByValueDensity);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    float res = 0.0;\n    for (int i = 0; i < itemCount; i++) {\n        if (items[i].w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += items[i].v;\n            cap -= items[i].w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (float)cap / items[i].w * items[i].v;\n            cap = 0;\n            break;\n        }\n    }\n    free(items);\n    return res;\n}\n
    fractional_knapsack.kt
    /* \u7269\u54c1 */\nclass Item(\n    val w: Int, // \u7269\u54c1\n    val v: Int  // \u7269\u54c1\u4ef7\u503c\n)\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfun fractionalKnapsack(wgt: IntArray, _val: IntArray, c: Int): Double {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    var cap = c\n    val items = arrayOfNulls<Item>(wgt.size)\n    for (i in wgt.indices) {\n        items[i] = Item(wgt[i], _val[i])\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sortBy { item: Item? -> -(item!!.v.toDouble() / item.w) }\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    var res = 0.0\n    for (item in items) {\n        if (item!!.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += item.v.toDouble() / item.w * cap\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.rb
    [class]{Item}-[func]{}\n\n[class]{}-[func]{fractional_knapsack}\n
    fractional_knapsack.zig
    [class]{Item}-[func]{}\n\n[class]{}-[func]{fractionalKnapsack}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u9664\u6392\u5e8f\u4e4b\u5916\uff0c\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u9700\u8981\u904d\u5386\u6574\u4e2a\u7269\u54c1\u5217\u8868\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u7269\u54c1\u6570\u91cf\u3002

    \u7531\u4e8e\u521d\u59cb\u5316\u4e86\u4e00\u4e2a Item \u5bf9\u8c61\u5217\u8868\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#3","title":"3. \u00a0 \u6b63\u786e\u6027\u8bc1\u660e","text":"

    \u91c7\u7528\u53cd\u8bc1\u6cd5\u3002\u5047\u8bbe\u7269\u54c1 \\(x\\) \u662f\u5355\u4f4d\u4ef7\u503c\u6700\u9ad8\u7684\u7269\u54c1\uff0c\u4f7f\u7528\u67d0\u7b97\u6cd5\u6c42\u5f97\u6700\u5927\u4ef7\u503c\u4e3a res \uff0c\u4f46\u8be5\u89e3\u4e2d\u4e0d\u5305\u542b\u7269\u54c1 \\(x\\) \u3002

    \u73b0\u5728\u4ece\u80cc\u5305\u4e2d\u62ff\u51fa\u5355\u4f4d\u91cd\u91cf\u7684\u4efb\u610f\u7269\u54c1\uff0c\u5e76\u66ff\u6362\u4e3a\u5355\u4f4d\u91cd\u91cf\u7684\u7269\u54c1 \\(x\\) \u3002\u7531\u4e8e\u7269\u54c1 \\(x\\) \u7684\u5355\u4f4d\u4ef7\u503c\u6700\u9ad8\uff0c\u56e0\u6b64\u66ff\u6362\u540e\u7684\u603b\u4ef7\u503c\u4e00\u5b9a\u5927\u4e8e res \u3002\u8fd9\u4e0e res \u662f\u6700\u4f18\u89e3\u77db\u76fe\uff0c\u8bf4\u660e\u6700\u4f18\u89e3\u4e2d\u5fc5\u987b\u5305\u542b\u7269\u54c1 \\(x\\) \u3002

    \u5bf9\u4e8e\u8be5\u89e3\u4e2d\u7684\u5176\u4ed6\u7269\u54c1\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u6784\u5efa\u51fa\u4e0a\u8ff0\u77db\u76fe\u3002\u603b\u800c\u8a00\u4e4b\uff0c\u5355\u4f4d\u4ef7\u503c\u66f4\u5927\u7684\u7269\u54c1\u603b\u662f\u66f4\u4f18\u9009\u62e9\uff0c\u8fd9\u8bf4\u660e\u8d2a\u5fc3\u7b56\u7565\u662f\u6709\u6548\u7684\u3002

    \u5982\u56fe 15-6 \u6240\u793a\uff0c\u5982\u679c\u5c06\u7269\u54c1\u91cd\u91cf\u548c\u7269\u54c1\u5355\u4f4d\u4ef7\u503c\u5206\u522b\u770b\u4f5c\u4e00\u5f20\u4e8c\u7ef4\u56fe\u8868\u7684\u6a2a\u8f74\u548c\u7eb5\u8f74\uff0c\u5219\u5206\u6570\u80cc\u5305\u95ee\u9898\u53ef\u8f6c\u5316\u4e3a\u201c\u6c42\u5728\u6709\u9650\u6a2a\u8f74\u533a\u95f4\u4e0b\u56f4\u6210\u7684\u6700\u5927\u9762\u79ef\u201d\u3002\u8fd9\u4e2a\u7c7b\u6bd4\u53ef\u4ee5\u5e2e\u52a9\u6211\u4eec\u4ece\u51e0\u4f55\u89d2\u5ea6\u7406\u89e3\u8d2a\u5fc3\u7b56\u7565\u7684\u6709\u6548\u6027\u3002

    \u56fe 15-6 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898\u7684\u51e0\u4f55\u8868\u793a

    "},{"location":"chapter_greedy/greedy_algorithm/","title":"15.1 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5","text":"

    \u8d2a\u5fc3\u7b97\u6cd5\uff08greedy algorithm\uff09\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u89e3\u51b3\u4f18\u5316\u95ee\u9898\u7684\u7b97\u6cd5\uff0c\u5176\u57fa\u672c\u601d\u60f3\u662f\u5728\u95ee\u9898\u7684\u6bcf\u4e2a\u51b3\u7b56\u9636\u6bb5\uff0c\u90fd\u9009\u62e9\u5f53\u524d\u770b\u8d77\u6765\u6700\u4f18\u7684\u9009\u62e9\uff0c\u5373\u8d2a\u5fc3\u5730\u505a\u51fa\u5c40\u90e8\u6700\u4f18\u7684\u51b3\u7b56\uff0c\u4ee5\u671f\u83b7\u5f97\u5168\u5c40\u6700\u4f18\u89e3\u3002\u8d2a\u5fc3\u7b97\u6cd5\u7b80\u6d01\u4e14\u9ad8\u6548\uff0c\u5728\u8bb8\u591a\u5b9e\u9645\u95ee\u9898\u4e2d\u6709\u7740\u5e7f\u6cdb\u7684\u5e94\u7528\u3002

    \u8d2a\u5fc3\u7b97\u6cd5\u548c\u52a8\u6001\u89c4\u5212\u90fd\u5e38\u7528\u4e8e\u89e3\u51b3\u4f18\u5316\u95ee\u9898\u3002\u5b83\u4eec\u4e4b\u95f4\u5b58\u5728\u4e00\u4e9b\u76f8\u4f3c\u4e4b\u5904\uff0c\u6bd4\u5982\u90fd\u4f9d\u8d56\u6700\u4f18\u5b50\u7ed3\u6784\u6027\u8d28\uff0c\u4f46\u5de5\u4f5c\u539f\u7406\u4e0d\u540c\u3002

    • \u52a8\u6001\u89c4\u5212\u4f1a\u6839\u636e\u4e4b\u524d\u9636\u6bb5\u7684\u6240\u6709\u51b3\u7b56\u6765\u8003\u8651\u5f53\u524d\u51b3\u7b56\uff0c\u5e76\u4f7f\u7528\u8fc7\u53bb\u5b50\u95ee\u9898\u7684\u89e3\u6765\u6784\u5efa\u5f53\u524d\u5b50\u95ee\u9898\u7684\u89e3\u3002
    • \u8d2a\u5fc3\u7b97\u6cd5\u4e0d\u4f1a\u8003\u8651\u8fc7\u53bb\u7684\u51b3\u7b56\uff0c\u800c\u662f\u4e00\u8def\u5411\u524d\u5730\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u4e0d\u65ad\u7f29\u5c0f\u95ee\u9898\u8303\u56f4\uff0c\u76f4\u81f3\u95ee\u9898\u88ab\u89e3\u51b3\u3002

    \u6211\u4eec\u5148\u901a\u8fc7\u4f8b\u9898\u201c\u96f6\u94b1\u5151\u6362\u201d\u4e86\u89e3\u8d2a\u5fc3\u7b97\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u3002\u8fd9\u9053\u9898\u5df2\u7ecf\u5728\u201c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u201d\u7ae0\u8282\u4e2d\u4ecb\u7ecd\u8fc7\uff0c\u76f8\u4fe1\u4f60\u5bf9\u5b83\u5e76\u4e0d\u964c\u751f\u3002

    Question

    \u7ed9\u5b9a \\(n\\) \u79cd\u786c\u5e01\uff0c\u7b2c \\(i\\) \u79cd\u786c\u5e01\u7684\u9762\u503c\u4e3a \\(coins[i - 1]\\) \uff0c\u76ee\u6807\u91d1\u989d\u4e3a \\(amt\\) \uff0c\u6bcf\u79cd\u786c\u5e01\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u80fd\u591f\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\u3002\u5982\u679c\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002

    \u672c\u9898\u91c7\u53d6\u7684\u8d2a\u5fc3\u7b56\u7565\u5982\u56fe 15-1 \u6240\u793a\u3002\u7ed9\u5b9a\u76ee\u6807\u91d1\u989d\uff0c\u6211\u4eec\u8d2a\u5fc3\u5730\u9009\u62e9\u4e0d\u5927\u4e8e\u4e14\u6700\u63a5\u8fd1\u5b83\u7684\u786c\u5e01\uff0c\u4e0d\u65ad\u5faa\u73af\u8be5\u6b65\u9aa4\uff0c\u76f4\u81f3\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u4e3a\u6b62\u3002

    \u56fe 15-1 \u00a0 \u96f6\u94b1\u5151\u6362\u7684\u8d2a\u5fc3\u7b56\u7565

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_greedy.py
    def coin_change_greedy(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3\"\"\"\n    # \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    i = len(coins) - 1\n    count = 0\n    # \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0:\n        # \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 and coins[i] > amt:\n            i -= 1\n        # \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count += 1\n    # \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return count if amt == 0 else -1\n
    coin_change_greedy.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(vector<int> &coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.size() - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(int[] coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.length - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint CoinChangeGreedy(int[] coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.Length - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunc coinChangeGreedy(coins []int, amt int) int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    i := len(coins) - 1\n    count := 0\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    for amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        for i > 0 && coins[i] > amt {\n            i--\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count++\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    if amt != 0 {\n        return -1\n    }\n    return count\n}\n
    coin_change_greedy.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunc coinChangeGreedy(coins: [Int], amt: Int) -> Int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    var i = coins.count - 1\n    var count = 0\n    var amt = amt\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 && coins[i] > amt {\n            i -= 1\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count += 1\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1\n}\n
    coin_change_greedy.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunction coinChangeGreedy(coins, amt) {\n    // \u5047\u8bbe coins \u6570\u7ec4\u6709\u5e8f\n    let i = coins.length - 1;\n    let count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt === 0 ? count : -1;\n}\n
    coin_change_greedy.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunction coinChangeGreedy(coins: number[], amt: number): number {\n    // \u5047\u8bbe coins \u6570\u7ec4\u6709\u5e8f\n    let i = coins.length - 1;\n    let count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt === 0 ? count : -1;\n}\n
    coin_change_greedy.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(List<int> coins, int amt) {\n  // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n  int i = coins.length - 1;\n  int count = 0;\n  // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n  while (amt > 0) {\n    // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n    while (i > 0 && coins[i] > amt) {\n      i--;\n    }\n    // \u9009\u62e9 coins[i]\n    amt -= coins[i];\n    count++;\n  }\n  // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n  return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfn coin_change_greedy(coins: &[i32], mut amt: i32) -> i32 {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    let mut i = coins.len() - 1;\n    let mut count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 && coins[i] > amt {\n            i -= 1;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count += 1;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    if amt == 0 {\n        count\n    } else {\n        -1\n    }\n}\n
    coin_change_greedy.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(int *coins, int size, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = size - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfun coinChangeGreedy(coins: IntArray, amt: Int): Int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    var am = amt\n    var i = coins.size - 1\n    var count = 0\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (am > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > am) {\n            i--\n        }\n        // \u9009\u62e9 coins[i]\n        am -= coins[i]\n        count++\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return if (am == 0) count else -1\n}\n
    coin_change_greedy.rb
    [class]{}-[func]{coin_change_greedy}\n
    coin_change_greedy.zig
    [class]{}-[func]{coinChangeGreedy}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4f60\u53ef\u80fd\u4f1a\u4e0d\u7531\u5730\u53d1\u51fa\u611f\u53f9\uff1aSo clean \uff01\u8d2a\u5fc3\u7b97\u6cd5\u4ec5\u7528\u7ea6\u5341\u884c\u4ee3\u7801\u5c31\u89e3\u51b3\u4e86\u96f6\u94b1\u5151\u6362\u95ee\u9898\u3002

    "},{"location":"chapter_greedy/greedy_algorithm/#1511","title":"15.1.1 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u7684\u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u8d2a\u5fc3\u7b97\u6cd5\u4e0d\u4ec5\u64cd\u4f5c\u76f4\u63a5\u3001\u5b9e\u73b0\u7b80\u5355\uff0c\u800c\u4e14\u901a\u5e38\u6548\u7387\u4e5f\u5f88\u9ad8\u3002\u5728\u4ee5\u4e0a\u4ee3\u7801\u4e2d\uff0c\u8bb0\u786c\u5e01\u6700\u5c0f\u9762\u503c\u4e3a \\(\\min(coins)\\) \uff0c\u5219\u8d2a\u5fc3\u9009\u62e9\u6700\u591a\u5faa\u73af \\(amt / \\min(coins)\\) \u6b21\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(amt / \\min(coins))\\) \u3002\u8fd9\u6bd4\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n \\times amt)\\) \u5c0f\u4e86\u4e00\u4e2a\u6570\u91cf\u7ea7\u3002

    \u7136\u800c\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u786c\u5e01\u9762\u503c\u7ec4\u5408\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u5e76\u4e0d\u80fd\u627e\u5230\u6700\u4f18\u89e3\u3002\u56fe 15-2 \u7ed9\u51fa\u4e86\u4e24\u4e2a\u793a\u4f8b\u3002

    • \u6b63\u4f8b \\(coins = [1, 5, 10, 20, 50, 100]\\)\uff1a\u5728\u8be5\u786c\u5e01\u7ec4\u5408\u4e0b\uff0c\u7ed9\u5b9a\u4efb\u610f \\(amt\\) \uff0c\u8d2a\u5fc3\u7b97\u6cd5\u90fd\u53ef\u4ee5\u627e\u5230\u6700\u4f18\u89e3\u3002
    • \u53cd\u4f8b \\(coins = [1, 20, 50]\\)\uff1a\u5047\u8bbe \\(amt = 60\\) \uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ea\u80fd\u627e\u5230 \\(50 + 1 \\times 10\\) \u7684\u5151\u6362\u7ec4\u5408\uff0c\u5171\u8ba1 \\(11\\) \u679a\u786c\u5e01\uff0c\u4f46\u52a8\u6001\u89c4\u5212\u53ef\u4ee5\u627e\u5230\u6700\u4f18\u89e3 \\(20 + 20 + 20\\) \uff0c\u4ec5\u9700 \\(3\\) \u679a\u786c\u5e01\u3002
    • \u53cd\u4f8b \\(coins = [1, 49, 50]\\)\uff1a\u5047\u8bbe \\(amt = 98\\) \uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ea\u80fd\u627e\u5230 \\(50 + 1 \\times 48\\) \u7684\u5151\u6362\u7ec4\u5408\uff0c\u5171\u8ba1 \\(49\\) \u679a\u786c\u5e01\uff0c\u4f46\u52a8\u6001\u89c4\u5212\u53ef\u4ee5\u627e\u5230\u6700\u4f18\u89e3 \\(49 + 49\\) \uff0c\u4ec5\u9700 \\(2\\) \u679a\u786c\u5e01\u3002

    \u56fe 15-2 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u65e0\u6cd5\u627e\u51fa\u6700\u4f18\u89e3\u7684\u793a\u4f8b

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5bf9\u4e8e\u96f6\u94b1\u5151\u6362\u95ee\u9898\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u65e0\u6cd5\u4fdd\u8bc1\u627e\u5230\u5168\u5c40\u6700\u4f18\u89e3\uff0c\u5e76\u4e14\u6709\u53ef\u80fd\u627e\u5230\u975e\u5e38\u5dee\u7684\u89e3\u3002\u5b83\u66f4\u9002\u5408\u7528\u52a8\u6001\u89c4\u5212\u89e3\u51b3\u3002

    \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u7684\u9002\u7528\u60c5\u51b5\u5206\u4ee5\u4e0b\u4e24\u79cd\u3002

    1. \u53ef\u4ee5\u4fdd\u8bc1\u627e\u5230\u6700\u4f18\u89e3\uff1a\u8d2a\u5fc3\u7b97\u6cd5\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5f80\u5f80\u662f\u6700\u4f18\u9009\u62e9\uff0c\u56e0\u4e3a\u5b83\u5f80\u5f80\u6bd4\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\u66f4\u9ad8\u6548\u3002
    2. \u53ef\u4ee5\u627e\u5230\u8fd1\u4f3c\u6700\u4f18\u89e3\uff1a\u8d2a\u5fc3\u7b97\u6cd5\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u4e5f\u662f\u53ef\u7528\u7684\u3002\u5bf9\u4e8e\u5f88\u591a\u590d\u6742\u95ee\u9898\u6765\u8bf4\uff0c\u5bfb\u627e\u5168\u5c40\u6700\u4f18\u89e3\u975e\u5e38\u56f0\u96be\uff0c\u80fd\u4ee5\u8f83\u9ad8\u6548\u7387\u627e\u5230\u6b21\u4f18\u89e3\u4e5f\u662f\u975e\u5e38\u4e0d\u9519\u7684\u3002
    "},{"location":"chapter_greedy/greedy_algorithm/#1512","title":"15.1.2 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u7279\u6027","text":"

    \u90a3\u4e48\u95ee\u9898\u6765\u4e86\uff0c\u4ec0\u4e48\u6837\u7684\u95ee\u9898\u9002\u5408\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\u5462\uff1f\u6216\u8005\u8bf4\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4fdd\u8bc1\u627e\u5230\u6700\u4f18\u89e3\uff1f

    \u76f8\u8f83\u4e8e\u52a8\u6001\u89c4\u5212\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u7684\u4f7f\u7528\u6761\u4ef6\u66f4\u52a0\u82db\u523b\uff0c\u5176\u4e3b\u8981\u5173\u6ce8\u95ee\u9898\u7684\u4e24\u4e2a\u6027\u8d28\u3002

    • \u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\uff1a\u53ea\u6709\u5f53\u5c40\u90e8\u6700\u4f18\u9009\u62e9\u59cb\u7ec8\u53ef\u4ee5\u5bfc\u81f4\u5168\u5c40\u6700\u4f18\u89e3\u65f6\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u624d\u80fd\u4fdd\u8bc1\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u6700\u4f18\u5b50\u7ed3\u6784\uff1a\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u5305\u542b\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u3002

    \u6700\u4f18\u5b50\u7ed3\u6784\u5df2\u7ecf\u5728\u201c\u52a8\u6001\u89c4\u5212\u201d\u7ae0\u8282\u4e2d\u4ecb\u7ecd\u8fc7\uff0c\u8fd9\u91cc\u4e0d\u518d\u8d58\u8ff0\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u4e00\u4e9b\u95ee\u9898\u7684\u6700\u4f18\u5b50\u7ed3\u6784\u5e76\u4e0d\u660e\u663e\uff0c\u4f46\u4ecd\u7136\u53ef\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u89e3\u51b3\u3002

    \u6211\u4eec\u4e3b\u8981\u63a2\u7a76\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u7684\u5224\u65ad\u65b9\u6cd5\u3002\u867d\u7136\u5b83\u7684\u63cf\u8ff0\u770b\u4e0a\u53bb\u6bd4\u8f83\u7b80\u5355\uff0c\u4f46\u5b9e\u9645\u4e0a\u5bf9\u4e8e\u8bb8\u591a\u95ee\u9898\uff0c\u8bc1\u660e\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u5e76\u975e\u6613\u4e8b\u3002

    \u4f8b\u5982\u96f6\u94b1\u5151\u6362\u95ee\u9898\uff0c\u6211\u4eec\u867d\u7136\u80fd\u591f\u5bb9\u6613\u5730\u4e3e\u51fa\u53cd\u4f8b\uff0c\u5bf9\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u8fdb\u884c\u8bc1\u4f2a\uff0c\u4f46\u8bc1\u5b9e\u7684\u96be\u5ea6\u8f83\u5927\u3002\u5982\u679c\u95ee\uff1a\u6ee1\u8db3\u4ec0\u4e48\u6761\u4ef6\u7684\u786c\u5e01\u7ec4\u5408\u53ef\u4ee5\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\uff1f\u6211\u4eec\u5f80\u5f80\u53ea\u80fd\u51ed\u501f\u76f4\u89c9\u6216\u4e3e\u4f8b\u5b50\u6765\u7ed9\u51fa\u4e00\u4e2a\u6a21\u68f1\u4e24\u53ef\u7684\u7b54\u6848\uff0c\u800c\u96be\u4ee5\u7ed9\u51fa\u4e25\u8c28\u7684\u6570\u5b66\u8bc1\u660e\u3002

    Quote

    \u6709\u4e00\u7bc7\u8bba\u6587\u7ed9\u51fa\u4e86\u4e00\u4e2a \\(O(n^3)\\) \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u7b97\u6cd5\uff0c\u7528\u4e8e\u5224\u65ad\u4e00\u4e2a\u786c\u5e01\u7ec4\u5408\u80fd\u5426\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u627e\u51fa\u4efb\u610f\u91d1\u989d\u7684\u6700\u4f18\u89e3\u3002

    Pearson, D. A polynomial-time algorithm for the change-making problem[J]. Operations Research Letters, 2005, 33(3): 231-234.

    "},{"location":"chapter_greedy/greedy_algorithm/#1513","title":"15.1.3 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u89e3\u9898\u6b65\u9aa4","text":"

    \u8d2a\u5fc3\u95ee\u9898\u7684\u89e3\u51b3\u6d41\u7a0b\u5927\u4f53\u53ef\u5206\u4e3a\u4ee5\u4e0b\u4e09\u6b65\u3002

    1. \u95ee\u9898\u5206\u6790\uff1a\u68b3\u7406\u4e0e\u7406\u89e3\u95ee\u9898\u7279\u6027\uff0c\u5305\u62ec\u72b6\u6001\u5b9a\u4e49\u3001\u4f18\u5316\u76ee\u6807\u548c\u7ea6\u675f\u6761\u4ef6\u7b49\u3002\u8fd9\u4e00\u6b65\u5728\u56de\u6eaf\u548c\u52a8\u6001\u89c4\u5212\u4e2d\u90fd\u6709\u6d89\u53ca\u3002
    2. \u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\uff1a\u786e\u5b9a\u5982\u4f55\u5728\u6bcf\u4e00\u6b65\u4e2d\u505a\u51fa\u8d2a\u5fc3\u9009\u62e9\u3002\u8fd9\u4e2a\u7b56\u7565\u80fd\u591f\u5728\u6bcf\u4e00\u6b65\u51cf\u5c0f\u95ee\u9898\u7684\u89c4\u6a21\uff0c\u5e76\u6700\u7ec8\u89e3\u51b3\u6574\u4e2a\u95ee\u9898\u3002
    3. \u6b63\u786e\u6027\u8bc1\u660e\uff1a\u901a\u5e38\u9700\u8981\u8bc1\u660e\u95ee\u9898\u5177\u6709\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u548c\u6700\u4f18\u5b50\u7ed3\u6784\u3002\u8fd9\u4e2a\u6b65\u9aa4\u53ef\u80fd\u9700\u8981\u7528\u5230\u6570\u5b66\u8bc1\u660e\uff0c\u4f8b\u5982\u5f52\u7eb3\u6cd5\u6216\u53cd\u8bc1\u6cd5\u7b49\u3002

    \u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\u662f\u6c42\u89e3\u95ee\u9898\u7684\u6838\u5fc3\u6b65\u9aa4\uff0c\u4f46\u5b9e\u65bd\u8d77\u6765\u53ef\u80fd\u5e76\u4e0d\u5bb9\u6613\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u4e0d\u540c\u95ee\u9898\u7684\u8d2a\u5fc3\u7b56\u7565\u7684\u5dee\u5f02\u8f83\u5927\u3002\u5bf9\u4e8e\u8bb8\u591a\u95ee\u9898\u6765\u8bf4\uff0c\u8d2a\u5fc3\u7b56\u7565\u6bd4\u8f83\u6d45\u663e\uff0c\u6211\u4eec\u901a\u8fc7\u4e00\u4e9b\u5927\u6982\u7684\u601d\u8003\u4e0e\u5c1d\u8bd5\u5c31\u80fd\u5f97\u51fa\u3002\u800c\u5bf9\u4e8e\u4e00\u4e9b\u590d\u6742\u95ee\u9898\uff0c\u8d2a\u5fc3\u7b56\u7565\u53ef\u80fd\u975e\u5e38\u9690\u853d\uff0c\u8fd9\u79cd\u60c5\u51b5\u5c31\u975e\u5e38\u8003\u9a8c\u4e2a\u4eba\u7684\u89e3\u9898\u7ecf\u9a8c\u4e0e\u7b97\u6cd5\u80fd\u529b\u4e86\u3002
    • \u67d0\u4e9b\u8d2a\u5fc3\u7b56\u7565\u5177\u6709\u8f83\u5f3a\u7684\u8ff7\u60d1\u6027\u3002\u5f53\u6211\u4eec\u6ee1\u6000\u4fe1\u5fc3\u8bbe\u8ba1\u597d\u8d2a\u5fc3\u7b56\u7565\uff0c\u5199\u51fa\u89e3\u9898\u4ee3\u7801\u5e76\u63d0\u4ea4\u8fd0\u884c\uff0c\u5f88\u53ef\u80fd\u53d1\u73b0\u90e8\u5206\u6d4b\u8bd5\u6837\u4f8b\u65e0\u6cd5\u901a\u8fc7\u3002\u8fd9\u662f\u56e0\u4e3a\u8bbe\u8ba1\u7684\u8d2a\u5fc3\u7b56\u7565\u53ea\u662f\u201c\u90e8\u5206\u6b63\u786e\u201d\u7684\uff0c\u4e0a\u6587\u4ecb\u7ecd\u7684\u96f6\u94b1\u5151\u6362\u5c31\u662f\u4e00\u4e2a\u5178\u578b\u6848\u4f8b\u3002

    \u4e3a\u4e86\u4fdd\u8bc1\u6b63\u786e\u6027\uff0c\u6211\u4eec\u5e94\u8be5\u5bf9\u8d2a\u5fc3\u7b56\u7565\u8fdb\u884c\u4e25\u8c28\u7684\u6570\u5b66\u8bc1\u660e\uff0c\u901a\u5e38\u9700\u8981\u7528\u5230\u53cd\u8bc1\u6cd5\u6216\u6570\u5b66\u5f52\u7eb3\u6cd5\u3002

    \u7136\u800c\uff0c\u6b63\u786e\u6027\u8bc1\u660e\u4e5f\u5f88\u53ef\u80fd\u4e0d\u662f\u4e00\u4ef6\u6613\u4e8b\u3002\u5982\u82e5\u6ca1\u6709\u5934\u7eea\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u9009\u62e9\u9762\u5411\u6d4b\u8bd5\u7528\u4f8b\u8fdb\u884c\u4ee3\u7801\u8c03\u8bd5\uff0c\u4e00\u6b65\u6b65\u4fee\u6539\u4e0e\u9a8c\u8bc1\u8d2a\u5fc3\u7b56\u7565\u3002

    "},{"location":"chapter_greedy/greedy_algorithm/#1514","title":"15.1.4 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u5178\u578b\u4f8b\u9898","text":"

    \u8d2a\u5fc3\u7b97\u6cd5\u5e38\u5e38\u5e94\u7528\u5728\u6ee1\u8db3\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u548c\u6700\u4f18\u5b50\u7ed3\u6784\u7684\u4f18\u5316\u95ee\u9898\u4e2d\uff0c\u4ee5\u4e0b\u5217\u4e3e\u4e86\u4e00\u4e9b\u5178\u578b\u7684\u8d2a\u5fc3\u7b97\u6cd5\u95ee\u9898\u3002

    • \u786c\u5e01\u627e\u96f6\u95ee\u9898\uff1a\u5728\u67d0\u4e9b\u786c\u5e01\u7ec4\u5408\u4e0b\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u603b\u662f\u53ef\u4ee5\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u533a\u95f4\u8c03\u5ea6\u95ee\u9898\uff1a\u5047\u8bbe\u4f60\u6709\u4e00\u4e9b\u4efb\u52a1\uff0c\u6bcf\u4e2a\u4efb\u52a1\u5728\u4e00\u6bb5\u65f6\u95f4\u5185\u8fdb\u884c\uff0c\u4f60\u7684\u76ee\u6807\u662f\u5b8c\u6210\u5c3d\u53ef\u80fd\u591a\u7684\u4efb\u52a1\u3002\u5982\u679c\u6bcf\u6b21\u90fd\u9009\u62e9\u7ed3\u675f\u65f6\u95f4\u6700\u65e9\u7684\u4efb\u52a1\uff0c\u90a3\u4e48\u8d2a\u5fc3\u7b97\u6cd5\u5c31\u53ef\u4ee5\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u5206\u6570\u80cc\u5305\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u7269\u54c1\u548c\u4e00\u4e2a\u8f7d\u91cd\u91cf\uff0c\u4f60\u7684\u76ee\u6807\u662f\u9009\u62e9\u4e00\u7ec4\u7269\u54c1\uff0c\u4f7f\u5f97\u603b\u91cd\u91cf\u4e0d\u8d85\u8fc7\u8f7d\u91cd\u91cf\uff0c\u4e14\u603b\u4ef7\u503c\u6700\u5927\u3002\u5982\u679c\u6bcf\u6b21\u90fd\u9009\u62e9\u6027\u4ef7\u6bd4\u6700\u9ad8\uff08\u4ef7\u503c / \u91cd\u91cf\uff09\u7684\u7269\u54c1\uff0c\u90a3\u4e48\u8d2a\u5fc3\u7b97\u6cd5\u5728\u4e00\u4e9b\u60c5\u51b5\u4e0b\u53ef\u4ee5\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u80a1\u7968\u4e70\u5356\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u80a1\u7968\u7684\u5386\u53f2\u4ef7\u683c\uff0c\u4f60\u53ef\u4ee5\u8fdb\u884c\u591a\u6b21\u4e70\u5356\uff0c\u4f46\u5982\u679c\u4f60\u5df2\u7ecf\u6301\u6709\u80a1\u7968\uff0c\u90a3\u4e48\u5728\u5356\u51fa\u4e4b\u524d\u4e0d\u80fd\u518d\u4e70\uff0c\u76ee\u6807\u662f\u83b7\u53d6\u6700\u5927\u5229\u6da6\u3002
    • \u970d\u592b\u66fc\u7f16\u7801\uff1a\u970d\u592b\u66fc\u7f16\u7801\u662f\u4e00\u79cd\u7528\u4e8e\u65e0\u635f\u6570\u636e\u538b\u7f29\u7684\u8d2a\u5fc3\u7b97\u6cd5\u3002\u901a\u8fc7\u6784\u5efa\u970d\u592b\u66fc\u6811\uff0c\u6bcf\u6b21\u9009\u62e9\u51fa\u73b0\u9891\u7387\u6700\u4f4e\u7684\u4e24\u4e2a\u8282\u70b9\u5408\u5e76\uff0c\u6700\u540e\u5f97\u5230\u7684\u970d\u592b\u66fc\u6811\u7684\u5e26\u6743\u8def\u5f84\u957f\u5ea6\uff08\u7f16\u7801\u957f\u5ea6\uff09\u6700\u5c0f\u3002
    • Dijkstra \u7b97\u6cd5\uff1a\u5b83\u662f\u4e00\u79cd\u89e3\u51b3\u7ed9\u5b9a\u6e90\u9876\u70b9\u5230\u5176\u4f59\u5404\u9876\u70b9\u7684\u6700\u77ed\u8def\u5f84\u95ee\u9898\u7684\u8d2a\u5fc3\u7b97\u6cd5\u3002
    "},{"location":"chapter_greedy/max_capacity_problem/","title":"15.3 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898","text":"

    Question

    \u8f93\u5165\u4e00\u4e2a\u6570\u7ec4 \\(ht\\) \uff0c\u5176\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u4ee3\u8868\u4e00\u4e2a\u5782\u76f4\u9694\u677f\u7684\u9ad8\u5ea6\u3002\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u4e24\u4e2a\u9694\u677f\uff0c\u4ee5\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u7a7a\u95f4\u53ef\u4ee5\u7ec4\u6210\u4e00\u4e2a\u5bb9\u5668\u3002

    \u5bb9\u5668\u7684\u5bb9\u91cf\u7b49\u4e8e\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u7684\u4e58\u79ef\uff08\u9762\u79ef\uff09\uff0c\u5176\u4e2d\u9ad8\u5ea6\u7531\u8f83\u77ed\u7684\u9694\u677f\u51b3\u5b9a\uff0c\u5bbd\u5ea6\u662f\u4e24\u4e2a\u9694\u677f\u7684\u6570\u7ec4\u7d22\u5f15\u4e4b\u5dee\u3002

    \u8bf7\u5728\u6570\u7ec4\u4e2d\u9009\u62e9\u4e24\u4e2a\u9694\u677f\uff0c\u4f7f\u5f97\u7ec4\u6210\u7684\u5bb9\u5668\u7684\u5bb9\u91cf\u6700\u5927\uff0c\u8fd4\u56de\u6700\u5927\u5bb9\u91cf\u3002\u793a\u4f8b\u5982\u56fe 15-7 \u6240\u793a\u3002

    \u56fe 15-7 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    \u5bb9\u5668\u7531\u4efb\u610f\u4e24\u4e2a\u9694\u677f\u56f4\u6210\uff0c\u56e0\u6b64\u672c\u9898\u7684\u72b6\u6001\u4e3a\u4e24\u4e2a\u9694\u677f\u7684\u7d22\u5f15\uff0c\u8bb0\u4e3a \\([i, j]\\) \u3002

    \u6839\u636e\u9898\u610f\uff0c\u5bb9\u91cf\u7b49\u4e8e\u9ad8\u5ea6\u4e58\u4ee5\u5bbd\u5ea6\uff0c\u5176\u4e2d\u9ad8\u5ea6\u7531\u77ed\u677f\u51b3\u5b9a\uff0c\u5bbd\u5ea6\u662f\u4e24\u9694\u677f\u7684\u6570\u7ec4\u7d22\u5f15\u4e4b\u5dee\u3002\u8bbe\u5bb9\u91cf\u4e3a \\(cap[i, j]\\) \uff0c\u5219\u53ef\u5f97\u8ba1\u7b97\u516c\u5f0f\uff1a

    \\[ cap[i, j] = \\min(ht[i], ht[j]) \\times (j - i) \\]

    \u8bbe\u6570\u7ec4\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u4e24\u4e2a\u9694\u677f\u7684\u7ec4\u5408\u6570\u91cf\uff08\u72b6\u6001\u603b\u6570\uff09\u4e3a \\(C_n^2 = \\frac{n(n - 1)}{2}\\) \u4e2a\u3002\u6700\u76f4\u63a5\u5730\uff0c\u6211\u4eec\u53ef\u4ee5\u7a77\u4e3e\u6240\u6709\u72b6\u6001\uff0c\u4ece\u800c\u6c42\u5f97\u6700\u5927\u5bb9\u91cf\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_greedy/max_capacity_problem/#1","title":"1. \u00a0 \u8d2a\u5fc3\u7b56\u7565\u786e\u5b9a","text":"

    \u8fd9\u9053\u9898\u8fd8\u6709\u66f4\u9ad8\u6548\u7387\u7684\u89e3\u6cd5\u3002\u5982\u56fe 15-8 \u6240\u793a\uff0c\u73b0\u9009\u53d6\u4e00\u4e2a\u72b6\u6001 \\([i, j]\\) \uff0c\u5176\u6ee1\u8db3\u7d22\u5f15 \\(i < j\\) \u4e14\u9ad8\u5ea6 \\(ht[i] < ht[j]\\) \uff0c\u5373 \\(i\\) \u4e3a\u77ed\u677f\u3001\\(j\\) \u4e3a\u957f\u677f\u3002

    \u56fe 15-8 \u00a0 \u521d\u59cb\u72b6\u6001

    \u5982\u56fe 15-9 \u6240\u793a\uff0c\u82e5\u6b64\u65f6\u5c06\u957f\u677f \\(j\\) \u5411\u77ed\u677f \\(i\\) \u9760\u8fd1\uff0c\u5219\u5bb9\u91cf\u4e00\u5b9a\u53d8\u5c0f\u3002

    \u8fd9\u662f\u56e0\u4e3a\u5728\u79fb\u52a8\u957f\u677f \\(j\\) \u540e\uff0c\u5bbd\u5ea6 \\(j-i\\) \u80af\u5b9a\u53d8\u5c0f\uff1b\u800c\u9ad8\u5ea6\u7531\u77ed\u677f\u51b3\u5b9a\uff0c\u56e0\u6b64\u9ad8\u5ea6\u53ea\u53ef\u80fd\u4e0d\u53d8\uff08 \\(i\\) \u4ecd\u4e3a\u77ed\u677f\uff09\u6216\u53d8\u5c0f\uff08\u79fb\u52a8\u540e\u7684 \\(j\\) \u6210\u4e3a\u77ed\u677f\uff09\u3002

    \u56fe 15-9 \u00a0 \u5411\u5185\u79fb\u52a8\u957f\u677f\u540e\u7684\u72b6\u6001

    \u53cd\u5411\u601d\u8003\uff0c\u6211\u4eec\u53ea\u6709\u5411\u5185\u6536\u7f29\u77ed\u677f \\(i\\) \uff0c\u624d\u6709\u53ef\u80fd\u4f7f\u5bb9\u91cf\u53d8\u5927\u3002\u56e0\u4e3a\u867d\u7136\u5bbd\u5ea6\u4e00\u5b9a\u53d8\u5c0f\uff0c\u4f46\u9ad8\u5ea6\u53ef\u80fd\u4f1a\u53d8\u5927\uff08\u79fb\u52a8\u540e\u7684\u77ed\u677f \\(i\\) \u53ef\u80fd\u4f1a\u53d8\u957f\uff09\u3002\u4f8b\u5982\u5728\u56fe 15-10 \u4e2d\uff0c\u79fb\u52a8\u77ed\u677f\u540e\u9762\u79ef\u53d8\u5927\u3002

    \u56fe 15-10 \u00a0 \u5411\u5185\u79fb\u52a8\u77ed\u677f\u540e\u7684\u72b6\u6001

    \u7531\u6b64\u4fbf\u53ef\u63a8\u51fa\u672c\u9898\u7684\u8d2a\u5fc3\u7b56\u7565\uff1a\u521d\u59cb\u5316\u4e24\u6307\u9488\uff0c\u4f7f\u5176\u5206\u5217\u5bb9\u5668\u4e24\u7aef\uff0c\u6bcf\u8f6e\u5411\u5185\u6536\u7f29\u77ed\u677f\u5bf9\u5e94\u7684\u6307\u9488\uff0c\u76f4\u81f3\u4e24\u6307\u9488\u76f8\u9047\u3002

    \u56fe 15-11 \u5c55\u793a\u4e86\u8d2a\u5fc3\u7b56\u7565\u7684\u6267\u884c\u8fc7\u7a0b\u3002

    1. \u521d\u59cb\u72b6\u6001\u4e0b\uff0c\u6307\u9488 \\(i\\) \u548c \\(j\\) \u5206\u5217\u6570\u7ec4\u4e24\u7aef\u3002
    2. \u8ba1\u7b97\u5f53\u524d\u72b6\u6001\u7684\u5bb9\u91cf \\(cap[i, j]\\) \uff0c\u5e76\u66f4\u65b0\u6700\u5927\u5bb9\u91cf\u3002
    3. \u6bd4\u8f83\u677f \\(i\\) \u548c \u677f \\(j\\) \u7684\u9ad8\u5ea6\uff0c\u5e76\u5c06\u77ed\u677f\u5411\u5185\u79fb\u52a8\u4e00\u683c\u3002
    4. \u5faa\u73af\u6267\u884c\u7b2c 2. \u6b65\u548c\u7b2c 3. \u6b65\uff0c\u76f4\u81f3 \\(i\\) \u548c \\(j\\) \u76f8\u9047\u65f6\u7ed3\u675f\u3002
    <1><2><3><4><5><6><7><8><9>

    \u56fe 15-11 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898\u7684\u8d2a\u5fc3\u8fc7\u7a0b

    "},{"location":"chapter_greedy/max_capacity_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u4ee3\u7801\u5faa\u73af\u6700\u591a \\(n\\) \u8f6e\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    \u53d8\u91cf \\(i\\)\u3001\\(j\\)\u3001\\(res\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig max_capacity.py
    def max_capacity(ht: list[int]) -> int:\n    \"\"\"\u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3\"\"\"\n    # \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    i, j = 0, len(ht) - 1\n    # \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    res = 0\n    # \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j:\n        # \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        # \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j]:\n            i += 1\n        else:\n            j -= 1\n    return res\n
    max_capacity.cpp
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(vector<int> &ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.size() - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = min(ht[i], ht[j]) * (j - i);\n        res = max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.java
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(int[] ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.cs
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint MaxCapacity(int[] ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.Length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = Math.Min(ht[i], ht[j]) * (j - i);\n        res = Math.Max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.go
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunc maxCapacity(ht []int) int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    i, j := 0, len(ht)-1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    res := 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    for i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        capacity := int(math.Min(float64(ht[i]), float64(ht[j]))) * (j - i)\n        res = int(math.Max(float64(res), float64(capacity)))\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i++\n        } else {\n            j--\n        }\n    }\n    return res\n}\n
    max_capacity.swift
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunc maxCapacity(ht: [Int]) -> Int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    var i = ht.startIndex, j = ht.endIndex - 1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    var res = 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        let cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i += 1\n        } else {\n            j -= 1\n        }\n    }\n    return res\n}\n
    max_capacity.js
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunction maxCapacity(ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let i = 0,\n        j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        const cap = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    return res;\n}\n
    max_capacity.ts
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunction maxCapacity(ht: number[]): number {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let i = 0,\n        j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        const cap: number = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    return res;\n}\n
    max_capacity.dart
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(List<int> ht) {\n  // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n  int i = 0, j = ht.length - 1;\n  // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n  int res = 0;\n  // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n  while (i < j) {\n    // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n    int cap = min(ht[i], ht[j]) * (j - i);\n    res = max(res, cap);\n    // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n    if (ht[i] < ht[j]) {\n      i++;\n    } else {\n      j--;\n    }\n  }\n  return res;\n}\n
    max_capacity.rs
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfn max_capacity(ht: &[i32]) -> i32 {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let mut i = 0;\n    let mut j = ht.len() - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let mut res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        let cap = std::cmp::min(ht[i], ht[j]) * (j - i) as i32;\n        res = std::cmp::max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    res\n}\n
    max_capacity.c
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(int ht[], int htLength) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0;\n    int j = htLength - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int capacity = myMin(ht[i], ht[j]) * (j - i);\n        res = myMax(res, capacity);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.kt
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfun maxCapacity(ht: IntArray): Int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    var i = 0\n    var j = ht.size - 1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    var res = 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        val cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++\n        } else {\n            j--\n        }\n    }\n    return res\n}\n
    max_capacity.rb
    [class]{}-[func]{max_capacity}\n
    max_capacity.zig
    [class]{}-[func]{maxCapacity}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_greedy/max_capacity_problem/#3","title":"3. \u00a0 \u6b63\u786e\u6027\u8bc1\u660e","text":"

    \u4e4b\u6240\u4ee5\u8d2a\u5fc3\u6bd4\u7a77\u4e3e\u66f4\u5feb\uff0c\u662f\u56e0\u4e3a\u6bcf\u8f6e\u7684\u8d2a\u5fc3\u9009\u62e9\u90fd\u4f1a\u201c\u8df3\u8fc7\u201d\u4e00\u4e9b\u72b6\u6001\u3002

    \u6bd4\u5982\u5728\u72b6\u6001 \\(cap[i, j]\\) \u4e0b\uff0c\\(i\\) \u4e3a\u77ed\u677f\u3001\\(j\\) \u4e3a\u957f\u677f\u3002\u82e5\u8d2a\u5fc3\u5730\u5c06\u77ed\u677f \\(i\\) \u5411\u5185\u79fb\u52a8\u4e00\u683c\uff0c\u4f1a\u5bfc\u81f4\u56fe 15-12 \u6240\u793a\u7684\u72b6\u6001\u88ab\u201c\u8df3\u8fc7\u201d\u3002\u8fd9\u610f\u5473\u7740\u4e4b\u540e\u65e0\u6cd5\u9a8c\u8bc1\u8fd9\u4e9b\u72b6\u6001\u7684\u5bb9\u91cf\u5927\u5c0f\u3002

    \\[ cap[i, i+1], cap[i, i+2], \\dots, cap[i, j-2], cap[i, j-1] \\]

    \u56fe 15-12 \u00a0 \u79fb\u52a8\u77ed\u677f\u5bfc\u81f4\u88ab\u8df3\u8fc7\u7684\u72b6\u6001

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u8fd9\u4e9b\u88ab\u8df3\u8fc7\u7684\u72b6\u6001\u5b9e\u9645\u4e0a\u5c31\u662f\u5c06\u957f\u677f \\(j\\) \u5411\u5185\u79fb\u52a8\u7684\u6240\u6709\u72b6\u6001\u3002\u524d\u9762\u6211\u4eec\u5df2\u7ecf\u8bc1\u660e\u5185\u79fb\u957f\u677f\u4e00\u5b9a\u4f1a\u5bfc\u81f4\u5bb9\u91cf\u53d8\u5c0f\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u88ab\u8df3\u8fc7\u7684\u72b6\u6001\u90fd\u4e0d\u53ef\u80fd\u662f\u6700\u4f18\u89e3\uff0c\u8df3\u8fc7\u5b83\u4eec\u4e0d\u4f1a\u5bfc\u81f4\u9519\u8fc7\u6700\u4f18\u89e3\u3002

    \u4ee5\u4e0a\u5206\u6790\u8bf4\u660e\uff0c\u79fb\u52a8\u77ed\u677f\u7684\u64cd\u4f5c\u662f\u201c\u5b89\u5168\u201d\u7684\uff0c\u8d2a\u5fc3\u7b56\u7565\u662f\u6709\u6548\u7684\u3002

    "},{"location":"chapter_greedy/max_product_cutting_problem/","title":"15.4 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6b63\u6574\u6570 \\(n\\) \uff0c\u5c06\u5176\u5207\u5206\u4e3a\u81f3\u5c11\u4e24\u4e2a\u6b63\u6574\u6570\u7684\u548c\uff0c\u6c42\u5207\u5206\u540e\u6240\u6709\u6574\u6570\u7684\u4e58\u79ef\u6700\u5927\u662f\u591a\u5c11\uff0c\u5982\u56fe 15-13 \u6240\u793a\u3002

    \u56fe 15-13 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u7684\u95ee\u9898\u5b9a\u4e49

    \u5047\u8bbe\u6211\u4eec\u5c06 \\(n\\) \u5207\u5206\u4e3a \\(m\\) \u4e2a\u6574\u6570\u56e0\u5b50\uff0c\u5176\u4e2d\u7b2c \\(i\\) \u4e2a\u56e0\u5b50\u8bb0\u4e3a \\(n_i\\) \uff0c\u5373

    \\[ n = \\sum_{i=1}^{m}n_i \\]

    \u672c\u9898\u7684\u76ee\u6807\u662f\u6c42\u5f97\u6240\u6709\u6574\u6570\u56e0\u5b50\u7684\u6700\u5927\u4e58\u79ef\uff0c\u5373

    \\[ \\max(\\prod_{i=1}^{m}n_i) \\]

    \u6211\u4eec\u9700\u8981\u601d\u8003\u7684\u662f\uff1a\u5207\u5206\u6570\u91cf \\(m\\) \u5e94\u8be5\u591a\u5927\uff0c\u6bcf\u4e2a \\(n_i\\) \u5e94\u8be5\u662f\u591a\u5c11\uff1f

    "},{"location":"chapter_greedy/max_product_cutting_problem/#1","title":"1. \u00a0 \u8d2a\u5fc3\u7b56\u7565\u786e\u5b9a","text":"

    \u6839\u636e\u7ecf\u9a8c\uff0c\u4e24\u4e2a\u6574\u6570\u7684\u4e58\u79ef\u5f80\u5f80\u6bd4\u5b83\u4eec\u7684\u52a0\u548c\u66f4\u5927\u3002\u5047\u8bbe\u4ece \\(n\\) \u4e2d\u5206\u51fa\u4e00\u4e2a\u56e0\u5b50 \\(2\\) \uff0c\u5219\u5b83\u4eec\u7684\u4e58\u79ef\u4e3a \\(2(n-2)\\) \u3002\u6211\u4eec\u5c06\u8be5\u4e58\u79ef\u4e0e \\(n\\) \u4f5c\u6bd4\u8f83\uff1a

    \\[ \\begin{aligned} 2(n-2) & \\geq n \\newline 2n - n - 4 & \\geq 0 \\newline n & \\geq 4 \\end{aligned} \\]

    \u5982\u56fe 15-14 \u6240\u793a\uff0c\u5f53 \\(n \\geq 4\\) \u65f6\uff0c\u5207\u5206\u51fa\u4e00\u4e2a \\(2\\) \u540e\u4e58\u79ef\u4f1a\u53d8\u5927\uff0c\u8fd9\u8bf4\u660e\u5927\u4e8e\u7b49\u4e8e \\(4\\) \u7684\u6574\u6570\u90fd\u5e94\u8be5\u88ab\u5207\u5206\u3002

    \u8d2a\u5fc3\u7b56\u7565\u4e00\uff1a\u5982\u679c\u5207\u5206\u65b9\u6848\u4e2d\u5305\u542b \\(\\geq 4\\) \u7684\u56e0\u5b50\uff0c\u90a3\u4e48\u5b83\u5c31\u5e94\u8be5\u88ab\u7ee7\u7eed\u5207\u5206\u3002\u6700\u7ec8\u7684\u5207\u5206\u65b9\u6848\u53ea\u5e94\u51fa\u73b0 \\(1\\)\u3001\\(2\\)\u3001\\(3\\) \u8fd9\u4e09\u79cd\u56e0\u5b50\u3002

    \u56fe 15-14 \u00a0 \u5207\u5206\u5bfc\u81f4\u4e58\u79ef\u53d8\u5927

    \u63a5\u4e0b\u6765\u601d\u8003\u54ea\u4e2a\u56e0\u5b50\u662f\u6700\u4f18\u7684\u3002\u5728 \\(1\\)\u3001\\(2\\)\u3001\\(3\\) \u8fd9\u4e09\u4e2a\u56e0\u5b50\u4e2d\uff0c\u663e\u7136 \\(1\\) \u662f\u6700\u5dee\u7684\uff0c\u56e0\u4e3a \\(1 \\times (n-1) < n\\) \u6052\u6210\u7acb\uff0c\u5373\u5207\u5206\u51fa \\(1\\) \u53cd\u800c\u4f1a\u5bfc\u81f4\u4e58\u79ef\u51cf\u5c0f\u3002

    \u5982\u56fe 15-15 \u6240\u793a\uff0c\u5f53 \\(n = 6\\) \u65f6\uff0c\u6709 \\(3 \\times 3 > 2 \\times 2 \\times 2\\) \u3002\u8fd9\u610f\u5473\u7740\u5207\u5206\u51fa \\(3\\) \u6bd4\u5207\u5206\u51fa \\(2\\) \u66f4\u4f18\u3002

    \u8d2a\u5fc3\u7b56\u7565\u4e8c\uff1a\u5728\u5207\u5206\u65b9\u6848\u4e2d\uff0c\u6700\u591a\u53ea\u5e94\u5b58\u5728\u4e24\u4e2a \\(2\\) \u3002\u56e0\u4e3a\u4e09\u4e2a \\(2\\) \u603b\u662f\u53ef\u4ee5\u66ff\u6362\u4e3a\u4e24\u4e2a \\(3\\) \uff0c\u4ece\u800c\u83b7\u5f97\u66f4\u5927\u7684\u4e58\u79ef\u3002

    \u56fe 15-15 \u00a0 \u6700\u4f18\u5207\u5206\u56e0\u5b50

    \u7efc\u4e0a\u6240\u8ff0\uff0c\u53ef\u63a8\u7406\u51fa\u4ee5\u4e0b\u8d2a\u5fc3\u7b56\u7565\u3002

    1. \u8f93\u5165\u6574\u6570 \\(n\\) \uff0c\u4ece\u5176\u4e0d\u65ad\u5730\u5207\u5206\u51fa\u56e0\u5b50 \\(3\\) \uff0c\u76f4\u81f3\u4f59\u6570\u4e3a \\(0\\)\u3001\\(1\\)\u3001\\(2\\) \u3002
    2. \u5f53\u4f59\u6570\u4e3a \\(0\\) \u65f6\uff0c\u4ee3\u8868 \\(n\\) \u662f \\(3\\) \u7684\u500d\u6570\uff0c\u56e0\u6b64\u4e0d\u505a\u4efb\u4f55\u5904\u7406\u3002
    3. \u5f53\u4f59\u6570\u4e3a \\(2\\) \u65f6\uff0c\u4e0d\u7ee7\u7eed\u5212\u5206\uff0c\u4fdd\u7559\u3002
    4. \u5f53\u4f59\u6570\u4e3a \\(1\\) \u65f6\uff0c\u7531\u4e8e \\(2 \\times 2 > 1 \\times 3\\) \uff0c\u56e0\u6b64\u5e94\u5c06\u6700\u540e\u4e00\u4e2a \\(3\\) \u66ff\u6362\u4e3a \\(2\\) \u3002
    "},{"location":"chapter_greedy/max_product_cutting_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5982\u56fe 15-16 \u6240\u793a\uff0c\u6211\u4eec\u65e0\u987b\u901a\u8fc7\u5faa\u73af\u6765\u5207\u5206\u6574\u6570\uff0c\u800c\u53ef\u4ee5\u5229\u7528\u5411\u4e0b\u6574\u9664\u8fd0\u7b97\u5f97\u5230 \\(3\\) \u7684\u4e2a\u6570 \\(a\\) \uff0c\u7528\u53d6\u6a21\u8fd0\u7b97\u5f97\u5230\u4f59\u6570 \\(b\\) \uff0c\u6b64\u65f6\u6709\uff1a

    \\[ n = 3 a + b \\]

    \u8bf7\u6ce8\u610f\uff0c\u5bf9\u4e8e \\(n \\leq 3\\) \u7684\u8fb9\u754c\u60c5\u51b5\uff0c\u5fc5\u987b\u62c6\u5206\u51fa\u4e00\u4e2a \\(1\\) \uff0c\u4e58\u79ef\u4e3a \\(1 \\times (n - 1)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig max_product_cutting.py
    def max_product_cutting(n: int) -> int:\n    \"\"\"\u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3\"\"\"\n    # \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3:\n        return 1 * (n - 1)\n    # \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    a, b = n // 3, n % 3\n    if b == 1:\n        # \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return int(math.pow(3, a - 1)) * 2 * 2\n    if b == 2:\n        # \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return int(math.pow(3, a)) * 2\n    # \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return int(math.pow(3, a))\n
    max_product_cutting.cpp
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int)pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int)pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int)pow(3, a);\n}\n
    max_product_cutting.java
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int) Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int) Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int) Math.pow(3, a);\n}\n
    max_product_cutting.cs
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint MaxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int)Math.Pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int)Math.Pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int)Math.Pow(3, a);\n}\n
    max_product_cutting.go
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunc maxProductCutting(n int) int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    a := n / 3\n    b := n % 3\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return int(math.Pow(3, float64(a-1))) * 2 * 2\n    }\n    if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return int(math.Pow(3, float64(a))) * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return int(math.Pow(3, float64(a)))\n}\n
    max_product_cutting.swift
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunc maxProductCutting(n: Int) -> Int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = n / 3\n    let b = n % 3\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return pow(3, a - 1) * 2 * 2\n    }\n    if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return pow(3, a) * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return pow(3, a)\n}\n
    max_product_cutting.js
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunction maxProductCutting(n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = Math.floor(n / 3);\n    let b = n % 3;\n    if (b === 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b === 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return Math.pow(3, a);\n}\n
    max_product_cutting.ts
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunction maxProductCutting(n: number): number {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a: number = Math.floor(n / 3);\n    let b: number = n % 3;\n    if (b === 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b === 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return Math.pow(3, a);\n}\n
    max_product_cutting.dart
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n  // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n  if (n <= 3) {\n    return 1 * (n - 1);\n  }\n  // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n  int a = n ~/ 3;\n  int b = n % 3;\n  if (b == 1) {\n    // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n    return (pow(3, a - 1) * 2 * 2).toInt();\n  }\n  if (b == 2) {\n    // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (pow(3, a) * 2).toInt();\n  }\n  // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n  return pow(3, a).toInt();\n}\n
    max_product_cutting.rs
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfn max_product_cutting(n: i32) -> i32 {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = n / 3;\n    let b = n % 3;\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        3_i32.pow(a as u32 - 1) * 2 * 2\n    } else if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        3_i32.pow(a as u32) * 2\n    } else {\n        // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        3_i32.pow(a as u32)\n    }\n}\n
    max_product_cutting.c
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return pow(3, a);\n}\n
    max_product_cutting.kt
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfun maxProductCutting(n: Int): Int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    val a = n / 3\n    val b = n % 3\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return 3.0.pow((a - 1)).toInt() * 2 * 2\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return 3.0.pow(a).toInt() * 2 * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return 3.0.pow(a).toInt()\n}\n
    max_product_cutting.rb
    [class]{}-[func]{max_product_cutting}\n
    max_product_cutting.zig
    [class]{}-[func]{maxProductCutting}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 15-16 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u7684\u8ba1\u7b97\u65b9\u6cd5

    \u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u7f16\u7a0b\u8bed\u8a00\u7684\u5e42\u8fd0\u7b97\u7684\u5b9e\u73b0\u65b9\u6cd5\u3002\u4ee5 Python \u4e3a\u4f8b\uff0c\u5e38\u7528\u7684\u5e42\u8ba1\u7b97\u51fd\u6570\u6709\u4e09\u79cd\u3002

    • \u8fd0\u7b97\u7b26 ** \u548c\u51fd\u6570 pow() \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(\\log\u2061 a)\\) \u3002
    • \u51fd\u6570 math.pow() \u5185\u90e8\u8c03\u7528 C \u8bed\u8a00\u5e93\u7684 pow() \u51fd\u6570\uff0c\u5176\u6267\u884c\u6d6e\u70b9\u53d6\u5e42\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    \u53d8\u91cf \\(a\\) \u548c \\(b\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    "},{"location":"chapter_greedy/max_product_cutting_problem/#3","title":"3. \u00a0 \u6b63\u786e\u6027\u8bc1\u660e","text":"

    \u4f7f\u7528\u53cd\u8bc1\u6cd5\uff0c\u53ea\u5206\u6790 \\(n \\geq 3\\) \u7684\u60c5\u51b5\u3002

    1. \u6240\u6709\u56e0\u5b50 \\(\\leq 3\\) \uff1a\u5047\u8bbe\u6700\u4f18\u5207\u5206\u65b9\u6848\u4e2d\u5b58\u5728 \\(\\geq 4\\) \u7684\u56e0\u5b50 \\(x\\) \uff0c\u90a3\u4e48\u4e00\u5b9a\u53ef\u4ee5\u5c06\u5176\u7ee7\u7eed\u5212\u5206\u4e3a \\(2(x-2)\\) \uff0c\u4ece\u800c\u83b7\u5f97\u66f4\u5927\u7684\u4e58\u79ef\u3002\u8fd9\u4e0e\u5047\u8bbe\u77db\u76fe\u3002
    2. \u5207\u5206\u65b9\u6848\u4e0d\u5305\u542b \\(1\\) \uff1a\u5047\u8bbe\u6700\u4f18\u5207\u5206\u65b9\u6848\u4e2d\u5b58\u5728\u4e00\u4e2a\u56e0\u5b50 \\(1\\) \uff0c\u90a3\u4e48\u5b83\u4e00\u5b9a\u53ef\u4ee5\u5408\u5e76\u5165\u53e6\u5916\u4e00\u4e2a\u56e0\u5b50\u4e2d\uff0c\u4ee5\u83b7\u5f97\u66f4\u5927\u7684\u4e58\u79ef\u3002\u8fd9\u4e0e\u5047\u8bbe\u77db\u76fe\u3002
    3. \u5207\u5206\u65b9\u6848\u6700\u591a\u5305\u542b\u4e24\u4e2a \\(2\\) \uff1a\u5047\u8bbe\u6700\u4f18\u5207\u5206\u65b9\u6848\u4e2d\u5305\u542b\u4e09\u4e2a \\(2\\) \uff0c\u90a3\u4e48\u4e00\u5b9a\u53ef\u4ee5\u66ff\u6362\u4e3a\u4e24\u4e2a \\(3\\) \uff0c\u4e58\u79ef\u66f4\u5927\u3002\u8fd9\u4e0e\u5047\u8bbe\u77db\u76fe\u3002
    "},{"location":"chapter_greedy/summary/","title":"15.5 \u00a0 \u5c0f\u7ed3","text":"
    • \u8d2a\u5fc3\u7b97\u6cd5\u901a\u5e38\u7528\u4e8e\u89e3\u51b3\u6700\u4f18\u5316\u95ee\u9898\uff0c\u5176\u539f\u7406\u662f\u5728\u6bcf\u4e2a\u51b3\u7b56\u9636\u6bb5\u90fd\u505a\u51fa\u5c40\u90e8\u6700\u4f18\u7684\u51b3\u7b56\uff0c\u4ee5\u671f\u83b7\u5f97\u5168\u5c40\u6700\u4f18\u89e3\u3002
    • \u8d2a\u5fc3\u7b97\u6cd5\u4f1a\u8fed\u4ee3\u5730\u505a\u51fa\u4e00\u4e2a\u53c8\u4e00\u4e2a\u7684\u8d2a\u5fc3\u9009\u62e9\uff0c\u6bcf\u8f6e\u90fd\u5c06\u95ee\u9898\u8f6c\u5316\u6210\u4e00\u4e2a\u89c4\u6a21\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u76f4\u5230\u95ee\u9898\u88ab\u89e3\u51b3\u3002
    • \u8d2a\u5fc3\u7b97\u6cd5\u4e0d\u4ec5\u5b9e\u73b0\u7b80\u5355\uff0c\u8fd8\u5177\u6709\u5f88\u9ad8\u7684\u89e3\u9898\u6548\u7387\u3002\u76f8\u6bd4\u4e8e\u52a8\u6001\u89c4\u5212\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u66f4\u4f4e\u3002
    • \u5728\u96f6\u94b1\u5151\u6362\u95ee\u9898\u4e2d\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u786c\u5e01\u7ec4\u5408\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ef\u4ee5\u4fdd\u8bc1\u627e\u5230\u6700\u4f18\u89e3\uff1b\u5bf9\u4e8e\u53e6\u5916\u4e00\u4e9b\u786c\u5e01\u7ec4\u5408\u5219\u4e0d\u7136\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ef\u80fd\u627e\u5230\u5f88\u5dee\u7684\u89e3\u3002
    • \u9002\u5408\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\u7684\u95ee\u9898\u5177\u6709\u4e24\u5927\u6027\u8d28\uff1a\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u548c\u6700\u4f18\u5b50\u7ed3\u6784\u3002\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u4ee3\u8868\u8d2a\u5fc3\u7b56\u7565\u7684\u6709\u6548\u6027\u3002
    • \u5bf9\u4e8e\u67d0\u4e9b\u590d\u6742\u95ee\u9898\uff0c\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u7684\u8bc1\u660e\u5e76\u4e0d\u7b80\u5355\u3002\u76f8\u5bf9\u6765\u8bf4\uff0c\u8bc1\u4f2a\u66f4\u52a0\u5bb9\u6613\uff0c\u4f8b\u5982\u96f6\u94b1\u5151\u6362\u95ee\u9898\u3002
    • \u6c42\u89e3\u8d2a\u5fc3\u95ee\u9898\u4e3b\u8981\u5206\u4e3a\u4e09\u6b65\uff1a\u95ee\u9898\u5206\u6790\u3001\u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\u3001\u6b63\u786e\u6027\u8bc1\u660e\u3002\u5176\u4e2d\uff0c\u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\u662f\u6838\u5fc3\u6b65\u9aa4\uff0c\u6b63\u786e\u6027\u8bc1\u660e\u5f80\u5f80\u662f\u96be\u70b9\u3002
    • \u5206\u6570\u80cc\u5305\u95ee\u9898\u5728 0-1 \u80cc\u5305\u7684\u57fa\u7840\u4e0a\uff0c\u5141\u8bb8\u9009\u62e9\u7269\u54c1\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u53ef\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\u3002\u8d2a\u5fc3\u7b56\u7565\u7684\u6b63\u786e\u6027\u53ef\u4ee5\u4f7f\u7528\u53cd\u8bc1\u6cd5\u6765\u8bc1\u660e\u3002
    • \u6700\u5927\u5bb9\u91cf\u95ee\u9898\u53ef\u4f7f\u7528\u7a77\u4e3e\u6cd5\u6c42\u89e3\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002\u901a\u8fc7\u8bbe\u8ba1\u8d2a\u5fc3\u7b56\u7565\uff0c\u6bcf\u8f6e\u5411\u5185\u79fb\u52a8\u77ed\u677f\uff0c\u53ef\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(n)\\) \u3002
    • \u5728\u6700\u5927\u5207\u5206\u4e58\u79ef\u95ee\u9898\u4e2d\uff0c\u6211\u4eec\u5148\u540e\u63a8\u7406\u51fa\u4e24\u4e2a\u8d2a\u5fc3\u7b56\u7565\uff1a\\(\\geq 4\\) \u7684\u6574\u6570\u90fd\u5e94\u8be5\u7ee7\u7eed\u5207\u5206\uff0c\u6700\u4f18\u5207\u5206\u56e0\u5b50\u4e3a \\(3\\) \u3002\u4ee3\u7801\u4e2d\u5305\u542b\u5e42\u8fd0\u7b97\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5e42\u8fd0\u7b97\u5b9e\u73b0\u65b9\u6cd5\uff0c\u901a\u5e38\u4e3a \\(O(1)\\) \u6216 \\(O(\\log n)\\) \u3002
    "},{"location":"chapter_hashing/","title":"\u7b2c 6 \u7ae0 \u00a0 \u54c8\u5e0c\u8868","text":"

    Abstract

    \u5728\u8ba1\u7b97\u673a\u4e16\u754c\u4e2d\uff0c\u54c8\u5e0c\u8868\u5982\u540c\u4e00\u4f4d\u806a\u6167\u7684\u56fe\u4e66\u7ba1\u7406\u5458\u3002

    \u4ed6\u77e5\u9053\u5982\u4f55\u8ba1\u7b97\u7d22\u4e66\u53f7\uff0c\u4ece\u800c\u53ef\u4ee5\u5feb\u901f\u627e\u5230\u76ee\u6807\u56fe\u4e66\u3002

    "},{"location":"chapter_hashing/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 6.1 \u00a0 \u54c8\u5e0c\u8868
    • 6.2 \u00a0 \u54c8\u5e0c\u51b2\u7a81
    • 6.3 \u00a0 \u54c8\u5e0c\u7b97\u6cd5
    • 6.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_hashing/hash_algorithm/","title":"6.3 \u00a0 \u54c8\u5e0c\u7b97\u6cd5","text":"

    \u524d\u4e24\u8282\u4ecb\u7ecd\u4e86\u54c8\u5e0c\u8868\u7684\u5de5\u4f5c\u539f\u7406\u548c\u54c8\u5e0c\u51b2\u7a81\u7684\u5904\u7406\u65b9\u6cd5\u3002\u7136\u800c\u65e0\u8bba\u662f\u5f00\u653e\u5bfb\u5740\u8fd8\u662f\u94fe\u5f0f\u5730\u5740\uff0c\u5b83\u4eec\u53ea\u80fd\u4fdd\u8bc1\u54c8\u5e0c\u8868\u53ef\u4ee5\u5728\u53d1\u751f\u51b2\u7a81\u65f6\u6b63\u5e38\u5de5\u4f5c\uff0c\u800c\u65e0\u6cd5\u51cf\u5c11\u54c8\u5e0c\u51b2\u7a81\u7684\u53d1\u751f\u3002

    \u5982\u679c\u54c8\u5e0c\u51b2\u7a81\u8fc7\u4e8e\u9891\u7e41\uff0c\u54c8\u5e0c\u8868\u7684\u6027\u80fd\u5219\u4f1a\u6025\u5267\u52a3\u5316\u3002\u5982\u56fe 6-8 \u6240\u793a\uff0c\u5bf9\u4e8e\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\uff0c\u7406\u60f3\u60c5\u51b5\u4e0b\u952e\u503c\u5bf9\u5747\u5300\u5206\u5e03\u5728\u5404\u4e2a\u6876\u4e2d\uff0c\u8fbe\u5230\u6700\u4f73\u67e5\u8be2\u6548\u7387\uff1b\u6700\u5dee\u60c5\u51b5\u4e0b\u6240\u6709\u952e\u503c\u5bf9\u90fd\u5b58\u50a8\u5230\u540c\u4e00\u4e2a\u6876\u4e2d\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u9000\u5316\u81f3 \\(O(n)\\) \u3002

    \u56fe 6-8 \u00a0 \u54c8\u5e0c\u51b2\u7a81\u7684\u6700\u4f73\u60c5\u51b5\u4e0e\u6700\u5dee\u60c5\u51b5

    \u952e\u503c\u5bf9\u7684\u5206\u5e03\u60c5\u51b5\u7531\u54c8\u5e0c\u51fd\u6570\u51b3\u5b9a\u3002\u56de\u5fc6\u54c8\u5e0c\u51fd\u6570\u7684\u8ba1\u7b97\u6b65\u9aa4\uff0c\u5148\u8ba1\u7b97\u54c8\u5e0c\u503c\uff0c\u518d\u5bf9\u6570\u7ec4\u957f\u5ea6\u53d6\u6a21\uff1a

    index = hash(key) % capacity\n

    \u89c2\u5bdf\u4ee5\u4e0a\u516c\u5f0f\uff0c\u5f53\u54c8\u5e0c\u8868\u5bb9\u91cf capacity \u56fa\u5b9a\u65f6\uff0c\u54c8\u5e0c\u7b97\u6cd5 hash() \u51b3\u5b9a\u4e86\u8f93\u51fa\u503c\uff0c\u8fdb\u800c\u51b3\u5b9a\u4e86\u952e\u503c\u5bf9\u5728\u54c8\u5e0c\u8868\u4e2d\u7684\u5206\u5e03\u60c5\u51b5\u3002

    \u8fd9\u610f\u5473\u7740\uff0c\u4e3a\u4e86\u964d\u4f4e\u54c8\u5e0c\u51b2\u7a81\u7684\u53d1\u751f\u6982\u7387\uff0c\u6211\u4eec\u5e94\u5f53\u5c06\u6ce8\u610f\u529b\u96c6\u4e2d\u5728\u54c8\u5e0c\u7b97\u6cd5 hash() \u7684\u8bbe\u8ba1\u4e0a\u3002

    "},{"location":"chapter_hashing/hash_algorithm/#631","title":"6.3.1 \u00a0 \u54c8\u5e0c\u7b97\u6cd5\u7684\u76ee\u6807","text":"

    \u4e3a\u4e86\u5b9e\u73b0\u201c\u65e2\u5feb\u53c8\u7a33\u201d\u7684\u54c8\u5e0c\u8868\u6570\u636e\u7ed3\u6784\uff0c\u54c8\u5e0c\u7b97\u6cd5\u5e94\u5177\u5907\u4ee5\u4e0b\u7279\u70b9\u3002

    • \u786e\u5b9a\u6027\uff1a\u5bf9\u4e8e\u76f8\u540c\u7684\u8f93\u5165\uff0c\u54c8\u5e0c\u7b97\u6cd5\u5e94\u59cb\u7ec8\u4ea7\u751f\u76f8\u540c\u7684\u8f93\u51fa\u3002\u8fd9\u6837\u624d\u80fd\u786e\u4fdd\u54c8\u5e0c\u8868\u662f\u53ef\u9760\u7684\u3002
    • \u6548\u7387\u9ad8\uff1a\u8ba1\u7b97\u54c8\u5e0c\u503c\u7684\u8fc7\u7a0b\u5e94\u8be5\u8db3\u591f\u5feb\u3002\u8ba1\u7b97\u5f00\u9500\u8d8a\u5c0f\uff0c\u54c8\u5e0c\u8868\u7684\u5b9e\u7528\u6027\u8d8a\u9ad8\u3002
    • \u5747\u5300\u5206\u5e03\uff1a\u54c8\u5e0c\u7b97\u6cd5\u5e94\u4f7f\u5f97\u952e\u503c\u5bf9\u5747\u5300\u5206\u5e03\u5728\u54c8\u5e0c\u8868\u4e2d\u3002\u5206\u5e03\u8d8a\u5747\u5300\uff0c\u54c8\u5e0c\u51b2\u7a81\u7684\u6982\u7387\u5c31\u8d8a\u4f4e\u3002

    \u5b9e\u9645\u4e0a\uff0c\u54c8\u5e0c\u7b97\u6cd5\u9664\u4e86\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u54c8\u5e0c\u8868\uff0c\u8fd8\u5e7f\u6cdb\u5e94\u7528\u4e8e\u5176\u4ed6\u9886\u57df\u4e2d\u3002

    • \u5bc6\u7801\u5b58\u50a8\uff1a\u4e3a\u4e86\u4fdd\u62a4\u7528\u6237\u5bc6\u7801\u7684\u5b89\u5168\uff0c\u7cfb\u7edf\u901a\u5e38\u4e0d\u4f1a\u76f4\u63a5\u5b58\u50a8\u7528\u6237\u7684\u660e\u6587\u5bc6\u7801\uff0c\u800c\u662f\u5b58\u50a8\u5bc6\u7801\u7684\u54c8\u5e0c\u503c\u3002\u5f53\u7528\u6237\u8f93\u5165\u5bc6\u7801\u65f6\uff0c\u7cfb\u7edf\u4f1a\u5bf9\u8f93\u5165\u7684\u5bc6\u7801\u8ba1\u7b97\u54c8\u5e0c\u503c\uff0c\u7136\u540e\u4e0e\u5b58\u50a8\u7684\u54c8\u5e0c\u503c\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u8005\u5339\u914d\uff0c\u90a3\u4e48\u5bc6\u7801\u5c31\u88ab\u89c6\u4e3a\u6b63\u786e\u3002
    • \u6570\u636e\u5b8c\u6574\u6027\u68c0\u67e5\uff1a\u6570\u636e\u53d1\u9001\u65b9\u53ef\u4ee5\u8ba1\u7b97\u6570\u636e\u7684\u54c8\u5e0c\u503c\u5e76\u5c06\u5176\u4e00\u540c\u53d1\u9001\uff1b\u63a5\u6536\u65b9\u53ef\u4ee5\u91cd\u65b0\u8ba1\u7b97\u63a5\u6536\u5230\u7684\u6570\u636e\u7684\u54c8\u5e0c\u503c\uff0c\u5e76\u4e0e\u63a5\u6536\u5230\u7684\u54c8\u5e0c\u503c\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u8005\u5339\u914d\uff0c\u90a3\u4e48\u6570\u636e\u5c31\u88ab\u89c6\u4e3a\u5b8c\u6574\u3002

    \u5bf9\u4e8e\u5bc6\u7801\u5b66\u7684\u76f8\u5173\u5e94\u7528\uff0c\u4e3a\u4e86\u9632\u6b62\u4ece\u54c8\u5e0c\u503c\u63a8\u5bfc\u51fa\u539f\u59cb\u5bc6\u7801\u7b49\u9006\u5411\u5de5\u7a0b\uff0c\u54c8\u5e0c\u7b97\u6cd5\u9700\u8981\u5177\u5907\u66f4\u9ad8\u7b49\u7ea7\u7684\u5b89\u5168\u7279\u6027\u3002

    • \u5355\u5411\u6027\uff1a\u65e0\u6cd5\u901a\u8fc7\u54c8\u5e0c\u503c\u53cd\u63a8\u51fa\u5173\u4e8e\u8f93\u5165\u6570\u636e\u7684\u4efb\u4f55\u4fe1\u606f\u3002
    • \u6297\u78b0\u649e\u6027\uff1a\u5e94\u5f53\u6781\u96be\u627e\u5230\u4e24\u4e2a\u4e0d\u540c\u7684\u8f93\u5165\uff0c\u4f7f\u5f97\u5b83\u4eec\u7684\u54c8\u5e0c\u503c\u76f8\u540c\u3002
    • \u96ea\u5d29\u6548\u5e94\uff1a\u8f93\u5165\u7684\u5fae\u5c0f\u53d8\u5316\u5e94\u5f53\u5bfc\u81f4\u8f93\u51fa\u7684\u663e\u8457\u4e14\u4e0d\u53ef\u9884\u6d4b\u7684\u53d8\u5316\u3002

    \u8bf7\u6ce8\u610f\uff0c\u201c\u5747\u5300\u5206\u5e03\u201d\u4e0e\u201c\u6297\u78b0\u649e\u6027\u201d\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u6982\u5ff5\uff0c\u6ee1\u8db3\u5747\u5300\u5206\u5e03\u4e0d\u4e00\u5b9a\u6ee1\u8db3\u6297\u78b0\u649e\u6027\u3002\u4f8b\u5982\uff0c\u5728\u968f\u673a\u8f93\u5165 key \u4e0b\uff0c\u54c8\u5e0c\u51fd\u6570 key % 100 \u53ef\u4ee5\u4ea7\u751f\u5747\u5300\u5206\u5e03\u7684\u8f93\u51fa\u3002\u7136\u800c\u8be5\u54c8\u5e0c\u7b97\u6cd5\u8fc7\u4e8e\u7b80\u5355\uff0c\u6240\u6709\u540e\u4e24\u4f4d\u76f8\u7b49\u7684 key \u7684\u8f93\u51fa\u90fd\u76f8\u540c\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u4ece\u54c8\u5e0c\u503c\u53cd\u63a8\u51fa\u53ef\u7528\u7684 key \uff0c\u4ece\u800c\u7834\u89e3\u5bc6\u7801\u3002

    "},{"location":"chapter_hashing/hash_algorithm/#632","title":"6.3.2 \u00a0 \u54c8\u5e0c\u7b97\u6cd5\u7684\u8bbe\u8ba1","text":"

    \u54c8\u5e0c\u7b97\u6cd5\u7684\u8bbe\u8ba1\u662f\u4e00\u4e2a\u9700\u8981\u8003\u8651\u8bb8\u591a\u56e0\u7d20\u7684\u590d\u6742\u95ee\u9898\u3002\u7136\u800c\u5bf9\u4e8e\u67d0\u4e9b\u8981\u6c42\u4e0d\u9ad8\u7684\u573a\u666f\uff0c\u6211\u4eec\u4e5f\u80fd\u8bbe\u8ba1\u4e00\u4e9b\u7b80\u5355\u7684\u54c8\u5e0c\u7b97\u6cd5\u3002

    • \u52a0\u6cd5\u54c8\u5e0c\uff1a\u5bf9\u8f93\u5165\u7684\u6bcf\u4e2a\u5b57\u7b26\u7684 ASCII \u7801\u8fdb\u884c\u76f8\u52a0\uff0c\u5c06\u5f97\u5230\u7684\u603b\u548c\u4f5c\u4e3a\u54c8\u5e0c\u503c\u3002
    • \u4e58\u6cd5\u54c8\u5e0c\uff1a\u5229\u7528\u4e58\u6cd5\u7684\u4e0d\u76f8\u5173\u6027\uff0c\u6bcf\u8f6e\u4e58\u4ee5\u4e00\u4e2a\u5e38\u6570\uff0c\u5c06\u5404\u4e2a\u5b57\u7b26\u7684 ASCII \u7801\u7d2f\u79ef\u5230\u54c8\u5e0c\u503c\u4e2d\u3002
    • \u5f02\u6216\u54c8\u5e0c\uff1a\u5c06\u8f93\u5165\u6570\u636e\u7684\u6bcf\u4e2a\u5143\u7d20\u901a\u8fc7\u5f02\u6216\u64cd\u4f5c\u7d2f\u79ef\u5230\u4e00\u4e2a\u54c8\u5e0c\u503c\u4e2d\u3002
    • \u65cb\u8f6c\u54c8\u5e0c\uff1a\u5c06\u6bcf\u4e2a\u5b57\u7b26\u7684 ASCII \u7801\u7d2f\u79ef\u5230\u4e00\u4e2a\u54c8\u5e0c\u503c\u4e2d\uff0c\u6bcf\u6b21\u7d2f\u79ef\u4e4b\u524d\u90fd\u4f1a\u5bf9\u54c8\u5e0c\u503c\u8fdb\u884c\u65cb\u8f6c\u64cd\u4f5c\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig simple_hash.py
    def add_hash(key: str) -> int:\n    \"\"\"\u52a0\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash += ord(c)\n    return hash % modulus\n\ndef mul_hash(key: str) -> int:\n    \"\"\"\u4e58\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = 31 * hash + ord(c)\n    return hash % modulus\n\ndef xor_hash(key: str) -> int:\n    \"\"\"\u5f02\u6216\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash ^= ord(c)\n    return hash % modulus\n\ndef rot_hash(key: str) -> int:\n    \"\"\"\u65cb\u8f6c\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = (hash << 4) ^ (hash >> 28) ^ ord(c)\n    return hash % modulus\n
    simple_hash.cpp
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (31 * hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash ^= (int)c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.java
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (31 * hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n    int hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash ^= (int) c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n
    simple_hash.cs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint AddHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint MulHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (31 * hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint XorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash ^= c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint RotHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.go
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (31*hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key string) int {\n    hash := 0\n    modulus := 1000000007\n    for _, b := range []byte(key) {\n        fmt.Println(int(b))\n        hash ^= int(b)\n        hash = (31*hash + int(b)) % modulus\n    }\n    return hash & modulus\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ int64(b)) % modulus\n    }\n    return int(hash)\n}\n
    simple_hash.swift
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (31 * hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash ^= Int(scalar.value)\n        }\n    }\n    return hash & MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = ((hash << 4) ^ (hash >> 28) ^ Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n
    simple_hash.js
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.ts
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.dart
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (31 * hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash ^= key.codeUnitAt(i);\n  }\n  return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = ((hash << 4) ^ (hash >> 28) ^ key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n
    simple_hash.rs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfn add_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfn mul_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (31 * hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfn xor_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash ^= c as i64;\n    }\n\n    (hash & MODULUS) as i32\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfn rot_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n
    simple_hash.c
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (31 * hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(char *key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n\n    for (int i = 0; i < strlen(key); i++) {\n        hash ^= (unsigned char)key[i];\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (unsigned char)key[i]) % MODULUS;\n    }\n\n    return (int)hash;\n}\n
    simple_hash.kt
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfun addHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfun mulHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (31 * hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfun xorHash(key: String): Int {\n    var hash = 0\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = hash xor c.code\n    }\n    return hash and MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfun rotHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = ((hash shl 4) xor (hash shr 28) xor c.code.toLong()) % MODULUS\n    }\n    return hash.toInt()\n}\n
    simple_hash.rb
    ### \u52a0\u6cd5\u54c8\u5e0c ###\ndef add_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash += c.ord }\n\n  hash % modulus\nend\n\n### \u4e58\u6cd5\u54c8\u5e0c ###\ndef mul_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = 31 * hash + c.ord }\n\n  hash % modulus\nend\n\n### \u5f02\u6216\u54c8\u5e0c ###\ndef xor_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash ^= c.ord }\n\n  hash % modulus\nend\n\n### \u65cb\u8f6c\u54c8\u5e0c ###\ndef rot_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = (hash << 4) ^ (hash >> 28) ^ c.ord }\n\n  hash % modulus\nend\n
    simple_hash.zig
    [class]{}-[func]{addHash}\n\n[class]{}-[func]{mulHash}\n\n[class]{}-[func]{xorHash}\n\n[class]{}-[func]{rotHash}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u6bcf\u79cd\u54c8\u5e0c\u7b97\u6cd5\u7684\u6700\u540e\u4e00\u6b65\u90fd\u662f\u5bf9\u5927\u8d28\u6570 \\(1000000007\\) \u53d6\u6a21\uff0c\u4ee5\u786e\u4fdd\u54c8\u5e0c\u503c\u5728\u5408\u9002\u7684\u8303\u56f4\u5185\u3002\u503c\u5f97\u601d\u8003\u7684\u662f\uff0c\u4e3a\u4ec0\u4e48\u8981\u5f3a\u8c03\u5bf9\u8d28\u6570\u53d6\u6a21\uff0c\u6216\u8005\u8bf4\u5bf9\u5408\u6570\u53d6\u6a21\u7684\u5f0a\u7aef\u662f\u4ec0\u4e48\uff1f\u8fd9\u662f\u4e00\u4e2a\u6709\u8da3\u7684\u95ee\u9898\u3002

    \u5148\u629b\u51fa\u7ed3\u8bba\uff1a\u4f7f\u7528\u5927\u8d28\u6570\u4f5c\u4e3a\u6a21\u6570\uff0c\u53ef\u4ee5\u6700\u5927\u5316\u5730\u4fdd\u8bc1\u54c8\u5e0c\u503c\u7684\u5747\u5300\u5206\u5e03\u3002\u56e0\u4e3a\u8d28\u6570\u4e0d\u4e0e\u5176\u4ed6\u6570\u5b57\u5b58\u5728\u516c\u7ea6\u6570\uff0c\u53ef\u4ee5\u51cf\u5c11\u56e0\u53d6\u6a21\u64cd\u4f5c\u800c\u4ea7\u751f\u7684\u5468\u671f\u6027\u6a21\u5f0f\uff0c\u4ece\u800c\u907f\u514d\u54c8\u5e0c\u51b2\u7a81\u3002

    \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5047\u8bbe\u6211\u4eec\u9009\u62e9\u5408\u6570 \\(9\\) \u4f5c\u4e3a\u6a21\u6570\uff0c\u5b83\u53ef\u4ee5\u88ab \\(3\\) \u6574\u9664\uff0c\u90a3\u4e48\u6240\u6709\u53ef\u4ee5\u88ab \\(3\\) \u6574\u9664\u7684 key \u90fd\u4f1a\u88ab\u6620\u5c04\u5230 \\(0\\)\u3001\\(3\\)\u3001\\(6\\) \u8fd9\u4e09\u4e2a\u54c8\u5e0c\u503c\u3002

    \\[ \\begin{aligned} \\text{modulus} & = 9 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 0, 3, 6, 0, 3, 6, 0, 3, 6,\\dots \\} \\end{aligned} \\]

    \u5982\u679c\u8f93\u5165 key \u6070\u597d\u6ee1\u8db3\u8fd9\u79cd\u7b49\u5dee\u6570\u5217\u7684\u6570\u636e\u5206\u5e03\uff0c\u90a3\u4e48\u54c8\u5e0c\u503c\u5c31\u4f1a\u51fa\u73b0\u805a\u5806\uff0c\u4ece\u800c\u52a0\u91cd\u54c8\u5e0c\u51b2\u7a81\u3002\u73b0\u5728\uff0c\u5047\u8bbe\u5c06 modulus \u66ff\u6362\u4e3a\u8d28\u6570 \\(13\\) \uff0c\u7531\u4e8e key \u548c modulus \u4e4b\u95f4\u4e0d\u5b58\u5728\u516c\u7ea6\u6570\uff0c\u56e0\u6b64\u8f93\u51fa\u7684\u54c8\u5e0c\u503c\u7684\u5747\u5300\u6027\u4f1a\u660e\u663e\u63d0\u5347\u3002

    \\[ \\begin{aligned} \\text{modulus} & = 13 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 9, 12, 2, 5, 8, 11, 1, 4, 7, \\dots \\} \\end{aligned} \\]

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u5982\u679c\u80fd\u591f\u4fdd\u8bc1 key \u662f\u968f\u673a\u5747\u5300\u5206\u5e03\u7684\uff0c\u90a3\u4e48\u9009\u62e9\u8d28\u6570\u6216\u8005\u5408\u6570\u4f5c\u4e3a\u6a21\u6570\u90fd\u53ef\u4ee5\uff0c\u5b83\u4eec\u90fd\u80fd\u8f93\u51fa\u5747\u5300\u5206\u5e03\u7684\u54c8\u5e0c\u503c\u3002\u800c\u5f53 key \u7684\u5206\u5e03\u5b58\u5728\u67d0\u79cd\u5468\u671f\u6027\u65f6\uff0c\u5bf9\u5408\u6570\u53d6\u6a21\u66f4\u5bb9\u6613\u51fa\u73b0\u805a\u96c6\u73b0\u8c61\u3002

    \u603b\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u901a\u5e38\u9009\u53d6\u8d28\u6570\u4f5c\u4e3a\u6a21\u6570\uff0c\u5e76\u4e14\u8fd9\u4e2a\u8d28\u6570\u6700\u597d\u8db3\u591f\u5927\uff0c\u4ee5\u5c3d\u53ef\u80fd\u6d88\u9664\u5468\u671f\u6027\u6a21\u5f0f\uff0c\u63d0\u5347\u54c8\u5e0c\u7b97\u6cd5\u7684\u7a33\u5065\u6027\u3002

    "},{"location":"chapter_hashing/hash_algorithm/#633","title":"6.3.3 \u00a0 \u5e38\u89c1\u54c8\u5e0c\u7b97\u6cd5","text":"

    \u4e0d\u96be\u53d1\u73b0\uff0c\u4ee5\u4e0a\u4ecb\u7ecd\u7684\u7b80\u5355\u54c8\u5e0c\u7b97\u6cd5\u90fd\u6bd4\u8f83\u201c\u8106\u5f31\u201d\uff0c\u8fdc\u8fdc\u6ca1\u6709\u8fbe\u5230\u54c8\u5e0c\u7b97\u6cd5\u7684\u8bbe\u8ba1\u76ee\u6807\u3002\u4f8b\u5982\uff0c\u7531\u4e8e\u52a0\u6cd5\u548c\u5f02\u6216\u6ee1\u8db3\u4ea4\u6362\u5f8b\uff0c\u56e0\u6b64\u52a0\u6cd5\u54c8\u5e0c\u548c\u5f02\u6216\u54c8\u5e0c\u65e0\u6cd5\u533a\u5206\u5185\u5bb9\u76f8\u540c\u4f46\u987a\u5e8f\u4e0d\u540c\u7684\u5b57\u7b26\u4e32\uff0c\u8fd9\u53ef\u80fd\u4f1a\u52a0\u5267\u54c8\u5e0c\u51b2\u7a81\uff0c\u5e76\u5f15\u8d77\u4e00\u4e9b\u5b89\u5168\u95ee\u9898\u3002

    \u5728\u5b9e\u9645\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u7528\u4e00\u4e9b\u6807\u51c6\u54c8\u5e0c\u7b97\u6cd5\uff0c\u4f8b\u5982 MD5\u3001SHA-1\u3001SHA-2 \u548c SHA-3 \u7b49\u3002\u5b83\u4eec\u53ef\u4ee5\u5c06\u4efb\u610f\u957f\u5ea6\u7684\u8f93\u5165\u6570\u636e\u6620\u5c04\u5230\u6052\u5b9a\u957f\u5ea6\u7684\u54c8\u5e0c\u503c\u3002

    \u8fd1\u4e00\u4e2a\u4e16\u7eaa\u4ee5\u6765\uff0c\u54c8\u5e0c\u7b97\u6cd5\u5904\u5728\u4e0d\u65ad\u5347\u7ea7\u4e0e\u4f18\u5316\u7684\u8fc7\u7a0b\u4e2d\u3002\u4e00\u90e8\u5206\u7814\u7a76\u4eba\u5458\u52aa\u529b\u63d0\u5347\u54c8\u5e0c\u7b97\u6cd5\u7684\u6027\u80fd\uff0c\u53e6\u4e00\u90e8\u5206\u7814\u7a76\u4eba\u5458\u548c\u9ed1\u5ba2\u5219\u81f4\u529b\u4e8e\u5bfb\u627e\u54c8\u5e0c\u7b97\u6cd5\u7684\u5b89\u5168\u6027\u95ee\u9898\u3002\u8868 6-2 \u5c55\u793a\u4e86\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u5e38\u89c1\u7684\u54c8\u5e0c\u7b97\u6cd5\u3002

    • MD5 \u548c SHA-1 \u5df2\u591a\u6b21\u88ab\u6210\u529f\u653b\u51fb\uff0c\u56e0\u6b64\u5b83\u4eec\u88ab\u5404\u7c7b\u5b89\u5168\u5e94\u7528\u5f03\u7528\u3002
    • SHA-2 \u7cfb\u5217\u4e2d\u7684 SHA-256 \u662f\u6700\u5b89\u5168\u7684\u54c8\u5e0c\u7b97\u6cd5\u4e4b\u4e00\uff0c\u4ecd\u672a\u51fa\u73b0\u6210\u529f\u7684\u653b\u51fb\u6848\u4f8b\uff0c\u56e0\u6b64\u5e38\u7528\u5728\u5404\u7c7b\u5b89\u5168\u5e94\u7528\u4e0e\u534f\u8bae\u4e2d\u3002
    • SHA-3 \u76f8\u8f83 SHA-2 \u7684\u5b9e\u73b0\u5f00\u9500\u66f4\u4f4e\u3001\u8ba1\u7b97\u6548\u7387\u66f4\u9ad8\uff0c\u4f46\u76ee\u524d\u4f7f\u7528\u8986\u76d6\u5ea6\u4e0d\u5982 SHA-2 \u7cfb\u5217\u3002

    \u8868 6-2 \u00a0 \u5e38\u89c1\u7684\u54c8\u5e0c\u7b97\u6cd5

    MD5 SHA-1 SHA-2 SHA-3 \u63a8\u51fa\u65f6\u95f4 1992 1995 2002 2008 \u8f93\u51fa\u957f\u5ea6 128 bit 160 bit 256/512 bit 224/256/384/512 bit \u54c8\u5e0c\u51b2\u7a81 \u8f83\u591a \u8f83\u591a \u5f88\u5c11 \u5f88\u5c11 \u5b89\u5168\u7b49\u7ea7 \u4f4e\uff0c\u5df2\u88ab\u6210\u529f\u653b\u51fb \u4f4e\uff0c\u5df2\u88ab\u6210\u529f\u653b\u51fb \u9ad8 \u9ad8 \u5e94\u7528 \u5df2\u88ab\u5f03\u7528\uff0c\u4ecd\u7528\u4e8e\u6570\u636e\u5b8c\u6574\u6027\u68c0\u67e5 \u5df2\u88ab\u5f03\u7528 \u52a0\u5bc6\u8d27\u5e01\u4ea4\u6613\u9a8c\u8bc1\u3001\u6570\u5b57\u7b7e\u540d\u7b49 \u53ef\u7528\u4e8e\u66ff\u4ee3 SHA-2"},{"location":"chapter_hashing/hash_algorithm/#634","title":"6.3.4 \u00a0 \u6570\u636e\u7ed3\u6784\u7684\u54c8\u5e0c\u503c","text":"

    \u6211\u4eec\u77e5\u9053\uff0c\u54c8\u5e0c\u8868\u7684 key \u53ef\u4ee5\u662f\u6574\u6570\u3001\u5c0f\u6570\u6216\u5b57\u7b26\u4e32\u7b49\u6570\u636e\u7c7b\u578b\u3002\u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u4f1a\u4e3a\u8fd9\u4e9b\u6570\u636e\u7c7b\u578b\u63d0\u4f9b\u5185\u7f6e\u7684\u54c8\u5e0c\u7b97\u6cd5\uff0c\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u8868\u4e2d\u7684\u6876\u7d22\u5f15\u3002\u4ee5 Python \u4e3a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u8c03\u7528 hash() \u51fd\u6570\u6765\u8ba1\u7b97\u5404\u79cd\u6570\u636e\u7c7b\u578b\u7684\u54c8\u5e0c\u503c\u3002

    • \u6574\u6570\u548c\u5e03\u5c14\u91cf\u7684\u54c8\u5e0c\u503c\u5c31\u662f\u5176\u672c\u8eab\u3002
    • \u6d6e\u70b9\u6570\u548c\u5b57\u7b26\u4e32\u7684\u54c8\u5e0c\u503c\u8ba1\u7b97\u8f83\u4e3a\u590d\u6742\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u8bf7\u81ea\u884c\u5b66\u4e60\u3002
    • \u5143\u7ec4\u7684\u54c8\u5e0c\u503c\u662f\u5bf9\u5176\u4e2d\u6bcf\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u54c8\u5e0c\uff0c\u7136\u540e\u5c06\u8fd9\u4e9b\u54c8\u5e0c\u503c\u7ec4\u5408\u8d77\u6765\uff0c\u5f97\u5230\u5355\u4e00\u7684\u54c8\u5e0c\u503c\u3002
    • \u5bf9\u8c61\u7684\u54c8\u5e0c\u503c\u57fa\u4e8e\u5176\u5185\u5b58\u5730\u5740\u751f\u6210\u3002\u901a\u8fc7\u91cd\u5199\u5bf9\u8c61\u7684\u54c8\u5e0c\u65b9\u6cd5\uff0c\u53ef\u5b9e\u73b0\u57fa\u4e8e\u5185\u5bb9\u751f\u6210\u54c8\u5e0c\u503c\u3002

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u7684\u5185\u7f6e\u54c8\u5e0c\u503c\u8ba1\u7b97\u51fd\u6570\u7684\u5b9a\u4e49\u548c\u65b9\u6cd5\u4e0d\u540c\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig built_in_hash.py
    num = 3\nhash_num = hash(num)\n# \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nbol = True\nhash_bol = hash(bol)\n# \u5e03\u5c14\u91cf True \u7684\u54c8\u5e0c\u503c\u4e3a 1\n\ndec = 3.14159\nhash_dec = hash(dec)\n# \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 326484311674566659\n\nstr = \"Hello \u7b97\u6cd5\"\nhash_str = hash(str)\n# \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 4617003410720528961\n\ntup = (12836, \"\u5c0f\u54c8\")\nhash_tup = hash(tup)\n# \u5143\u7ec4 (12836, '\u5c0f\u54c8') \u7684\u54c8\u5e0c\u503c\u4e3a 1029005403108185979\n\nobj = ListNode(0)\nhash_obj = hash(obj)\n# \u8282\u70b9\u5bf9\u8c61 <ListNode object at 0x1058fd810> \u7684\u54c8\u5e0c\u503c\u4e3a 274267521\n
    built_in_hash.cpp
    int num = 3;\nsize_t hashNum = hash<int>()(num);\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nbool bol = true;\nsize_t hashBol = hash<bool>()(bol);\n// \u5e03\u5c14\u91cf 1 \u7684\u54c8\u5e0c\u503c\u4e3a 1\n\ndouble dec = 3.14159;\nsize_t hashDec = hash<double>()(dec);\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 4614256650576692846\n\nstring str = \"Hello \u7b97\u6cd5\";\nsize_t hashStr = hash<string>()(str);\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 15466937326284535026\n\n// \u5728 C++ \u4e2d\uff0c\u5185\u7f6e std:hash() \u4ec5\u63d0\u4f9b\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u54c8\u5e0c\u503c\u8ba1\u7b97\n// \u6570\u7ec4\u3001\u5bf9\u8c61\u7684\u54c8\u5e0c\u503c\u8ba1\u7b97\u9700\u8981\u81ea\u884c\u5b9e\u73b0\n
    built_in_hash.java
    int num = 3;\nint hashNum = Integer.hashCode(num);\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nboolean bol = true;\nint hashBol = Boolean.hashCode(bol);\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 1231\n\ndouble dec = 3.14159;\nint hashDec = Double.hashCode(dec);\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1340954729\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode();\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -727081396\n\nObject[] arr = { 12836, \"\u5c0f\u54c8\" };\nint hashTup = Arrays.hashCode(arr);\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 1151158\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode();\n// \u8282\u70b9\u5bf9\u8c61 utils.ListNode@7dc5e7b4 \u7684\u54c8\u5e0c\u503c\u4e3a 2110121908\n
    built_in_hash.cs
    int num = 3;\nint hashNum = num.GetHashCode();\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3;\n\nbool bol = true;\nint hashBol = bol.GetHashCode();\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 1;\n\ndouble dec = 3.14159;\nint hashDec = dec.GetHashCode();\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1340954729;\n\nstring str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.GetHashCode();\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -586107568;\n\nobject[] arr = [12836, \"\u5c0f\u54c8\"];\nint hashTup = arr.GetHashCode();\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 42931033;\n\nListNode obj = new(0);\nint hashObj = obj.GetHashCode();\n// \u8282\u70b9\u5bf9\u8c61 0 \u7684\u54c8\u5e0c\u503c\u4e3a 39053774;\n
    built_in_hash.go
    // Go \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.swift
    let num = 3\nlet hashNum = num.hashValue\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 9047044699613009734\n\nlet bol = true\nlet hashBol = bol.hashValue\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a -4431640247352757451\n\nlet dec = 3.14159\nlet hashDec = dec.hashValue\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -2465384235396674631\n\nlet str = \"Hello \u7b97\u6cd5\"\nlet hashStr = str.hashValue\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -7850626797806988787\n\nlet arr = [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")]\nlet hashTup = arr.hashValue\n// \u6570\u7ec4 [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")] \u7684\u54c8\u5e0c\u503c\u4e3a -2308633508154532996\n\nlet obj = ListNode(x: 0)\nlet hashObj = obj.hashValue\n// \u8282\u70b9\u5bf9\u8c61 utils.ListNode \u7684\u54c8\u5e0c\u503c\u4e3a -2434780518035996159\n
    built_in_hash.js
    // JavaScript \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.ts
    // TypeScript \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.dart
    int num = 3;\nint hashNum = num.hashCode;\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 34803\n\nbool bol = true;\nint hashBol = bol.hashCode;\n// \u5e03\u5c14\u503c true \u7684\u54c8\u5e0c\u503c\u4e3a 1231\n\ndouble dec = 3.14159;\nint hashDec = dec.hashCode;\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 2570631074981783\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode;\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 468167534\n\nList arr = [12836, \"\u5c0f\u54c8\"];\nint hashArr = arr.hashCode;\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 976512528\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode;\n// \u8282\u70b9\u5bf9\u8c61 Instance of 'ListNode' \u7684\u54c8\u5e0c\u503c\u4e3a 1033450432\n
    built_in_hash.rs
    use std::collections::hash_map::DefaultHasher;\nuse std::hash::{Hash, Hasher};\n\nlet num = 3;\nlet mut num_hasher = DefaultHasher::new();\nnum.hash(&mut num_hasher);\nlet hash_num = num_hasher.finish();\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 568126464209439262\n\nlet bol = true;\nlet mut bol_hasher = DefaultHasher::new();\nbol.hash(&mut bol_hasher);\nlet hash_bol = bol_hasher.finish();\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 4952851536318644461\n\nlet dec: f32 = 3.14159;\nlet mut dec_hasher = DefaultHasher::new();\ndec.to_bits().hash(&mut dec_hasher);\nlet hash_dec = dec_hasher.finish();\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 2566941990314602357\n\nlet str = \"Hello \u7b97\u6cd5\";\nlet mut str_hasher = DefaultHasher::new();\nstr.hash(&mut str_hasher);\nlet hash_str = str_hasher.finish();\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 16092673739211250988\n\nlet arr = (&12836, &\"\u5c0f\u54c8\");\nlet mut tup_hasher = DefaultHasher::new();\narr.hash(&mut tup_hasher);\nlet hash_tup = tup_hasher.finish();\n// \u5143\u7ec4 (12836, \"\u5c0f\u54c8\") \u7684\u54c8\u5e0c\u503c\u4e3a 1885128010422702749\n\nlet node = ListNode::new(42);\nlet mut hasher = DefaultHasher::new();\nnode.borrow().val.hash(&mut hasher);\nlet hash = hasher.finish();\n// \u8282\u70b9\u5bf9\u8c61 RefCell { value: ListNode { val: 42, next: None } } \u7684\u54c8\u5e0c\u503c\u4e3a15387811073369036852\n
    built_in_hash.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.kt
    val num = 3\nval hashNum = num.hashCode()\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nval bol = true\nval hashBol = bol.hashCode()\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 1231\n\nval dec = 3.14159\nval hashDec = dec.hashCode()\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1340954729\n\nval str = \"Hello \u7b97\u6cd5\"\nval hashStr = str.hashCode()\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -727081396\n\nval arr = arrayOf<Any>(12836, \"\u5c0f\u54c8\")\nval hashTup = arr.hashCode()\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 189568618\n\nval obj = ListNode(0)\nval hashObj = obj.hashCode()\n// \u8282\u70b9\u5bf9\u8c61 utils.ListNode@1d81eb93 \u7684\u54c8\u5e0c\u503c\u4e3a 495053715\n
    built_in_hash.rb
    num = 3\nhash_num = num.hash\n# \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a -4385856518450339636\n\nbol = true\nhash_bol = bol.hash\n# \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a -1617938112149317027\n\ndec = 3.14159\nhash_dec = dec.hash\n# \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1479186995943067893\n\nstr = \"Hello \u7b97\u6cd5\"\nhash_str = str.hash\n# \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -4075943250025831763\n\ntup = [12836, '\u5c0f\u54c8']\nhash_tup = tup.hash\n# \u5143\u7ec4 (12836, '\u5c0f\u54c8') \u7684\u54c8\u5e0c\u503c\u4e3a 1999544809202288822\n\nobj = ListNode.new(0)\nhash_obj = obj.hash\n# \u8282\u70b9\u5bf9\u8c61 #<ListNode:0x000078133140ab70> \u7684\u54c8\u5e0c\u503c\u4e3a 4302940560806366381\n
    built_in_hash.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5728\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u53ea\u6709\u4e0d\u53ef\u53d8\u5bf9\u8c61\u624d\u53ef\u4f5c\u4e3a\u54c8\u5e0c\u8868\u7684 key \u3002\u5047\u5982\u6211\u4eec\u5c06\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\u4f5c\u4e3a key \uff0c\u5f53\u5217\u8868\u7684\u5185\u5bb9\u53d1\u751f\u53d8\u5316\u65f6\uff0c\u5b83\u7684\u54c8\u5e0c\u503c\u4e5f\u968f\u4e4b\u6539\u53d8\uff0c\u6211\u4eec\u5c31\u65e0\u6cd5\u5728\u54c8\u5e0c\u8868\u4e2d\u67e5\u8be2\u5230\u539f\u5148\u7684 value \u4e86\u3002

    \u867d\u7136\u81ea\u5b9a\u4e49\u5bf9\u8c61\uff08\u6bd4\u5982\u94fe\u8868\u8282\u70b9\uff09\u7684\u6210\u5458\u53d8\u91cf\u662f\u53ef\u53d8\u7684\uff0c\u4f46\u5b83\u662f\u53ef\u54c8\u5e0c\u7684\u3002\u8fd9\u662f\u56e0\u4e3a\u5bf9\u8c61\u7684\u54c8\u5e0c\u503c\u901a\u5e38\u662f\u57fa\u4e8e\u5185\u5b58\u5730\u5740\u751f\u6210\u7684\uff0c\u5373\u4f7f\u5bf9\u8c61\u7684\u5185\u5bb9\u53d1\u751f\u4e86\u53d8\u5316\uff0c\u4f46\u5b83\u7684\u5185\u5b58\u5730\u5740\u4e0d\u53d8\uff0c\u54c8\u5e0c\u503c\u4ecd\u7136\u662f\u4e0d\u53d8\u7684\u3002

    \u7ec6\u5fc3\u7684\u4f60\u53ef\u80fd\u53d1\u73b0\u5728\u4e0d\u540c\u63a7\u5236\u53f0\u4e2d\u8fd0\u884c\u7a0b\u5e8f\u65f6\uff0c\u8f93\u51fa\u7684\u54c8\u5e0c\u503c\u662f\u4e0d\u540c\u7684\u3002\u8fd9\u662f\u56e0\u4e3a Python \u89e3\u91ca\u5668\u5728\u6bcf\u6b21\u542f\u52a8\u65f6\uff0c\u90fd\u4f1a\u4e3a\u5b57\u7b26\u4e32\u54c8\u5e0c\u51fd\u6570\u52a0\u5165\u4e00\u4e2a\u968f\u673a\u7684\u76d0\uff08salt\uff09\u503c\u3002\u8fd9\u79cd\u505a\u6cd5\u53ef\u4ee5\u6709\u6548\u9632\u6b62 HashDoS \u653b\u51fb\uff0c\u63d0\u5347\u54c8\u5e0c\u7b97\u6cd5\u7684\u5b89\u5168\u6027\u3002

    "},{"location":"chapter_hashing/hash_collision/","title":"6.2 \u00a0 \u54c8\u5e0c\u51b2\u7a81","text":"

    \u4e0a\u4e00\u8282\u63d0\u5230\uff0c\u901a\u5e38\u60c5\u51b5\u4e0b\u54c8\u5e0c\u51fd\u6570\u7684\u8f93\u5165\u7a7a\u95f4\u8fdc\u5927\u4e8e\u8f93\u51fa\u7a7a\u95f4\uff0c\u56e0\u6b64\u7406\u8bba\u4e0a\u54c8\u5e0c\u51b2\u7a81\u662f\u4e0d\u53ef\u907f\u514d\u7684\u3002\u6bd4\u5982\uff0c\u8f93\u5165\u7a7a\u95f4\u4e3a\u5168\u4f53\u6574\u6570\uff0c\u8f93\u51fa\u7a7a\u95f4\u4e3a\u6570\u7ec4\u5bb9\u91cf\u5927\u5c0f\uff0c\u5219\u5fc5\u7136\u6709\u591a\u4e2a\u6574\u6570\u6620\u5c04\u81f3\u540c\u4e00\u6876\u7d22\u5f15\u3002

    \u54c8\u5e0c\u51b2\u7a81\u4f1a\u5bfc\u81f4\u67e5\u8be2\u7ed3\u679c\u9519\u8bef\uff0c\u4e25\u91cd\u5f71\u54cd\u54c8\u5e0c\u8868\u7684\u53ef\u7528\u6027\u3002\u4e3a\u4e86\u89e3\u51b3\u8be5\u95ee\u9898\uff0c\u6bcf\u5f53\u9047\u5230\u54c8\u5e0c\u51b2\u7a81\u65f6\uff0c\u6211\u4eec\u5c31\u8fdb\u884c\u54c8\u5e0c\u8868\u6269\u5bb9\uff0c\u76f4\u81f3\u51b2\u7a81\u6d88\u5931\u4e3a\u6b62\u3002\u6b64\u65b9\u6cd5\u7b80\u5355\u7c97\u66b4\u4e14\u6709\u6548\uff0c\u4f46\u6548\u7387\u592a\u4f4e\uff0c\u56e0\u4e3a\u54c8\u5e0c\u8868\u6269\u5bb9\u9700\u8981\u8fdb\u884c\u5927\u91cf\u7684\u6570\u636e\u642c\u8fd0\u4e0e\u54c8\u5e0c\u503c\u8ba1\u7b97\u3002\u4e3a\u4e86\u63d0\u5347\u6548\u7387\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u4ee5\u4e0b\u7b56\u7565\u3002

    1. \u6539\u826f\u54c8\u5e0c\u8868\u6570\u636e\u7ed3\u6784\uff0c\u4f7f\u5f97\u54c8\u5e0c\u8868\u53ef\u4ee5\u5728\u51fa\u73b0\u54c8\u5e0c\u51b2\u7a81\u65f6\u6b63\u5e38\u5de5\u4f5c\u3002
    2. \u4ec5\u5728\u5fc5\u8981\u65f6\uff0c\u5373\u5f53\u54c8\u5e0c\u51b2\u7a81\u6bd4\u8f83\u4e25\u91cd\u65f6\uff0c\u624d\u6267\u884c\u6269\u5bb9\u64cd\u4f5c\u3002

    \u54c8\u5e0c\u8868\u7684\u7ed3\u6784\u6539\u826f\u65b9\u6cd5\u4e3b\u8981\u5305\u62ec\u201c\u94fe\u5f0f\u5730\u5740\u201d\u548c\u201c\u5f00\u653e\u5bfb\u5740\u201d\u3002

    "},{"location":"chapter_hashing/hash_collision/#621","title":"6.2.1 \u00a0 \u94fe\u5f0f\u5730\u5740","text":"

    \u5728\u539f\u59cb\u54c8\u5e0c\u8868\u4e2d\uff0c\u6bcf\u4e2a\u6876\u4ec5\u80fd\u5b58\u50a8\u4e00\u4e2a\u952e\u503c\u5bf9\u3002\u94fe\u5f0f\u5730\u5740\uff08separate chaining\uff09\u5c06\u5355\u4e2a\u5143\u7d20\u8f6c\u6362\u4e3a\u94fe\u8868\uff0c\u5c06\u952e\u503c\u5bf9\u4f5c\u4e3a\u94fe\u8868\u8282\u70b9\uff0c\u5c06\u6240\u6709\u53d1\u751f\u51b2\u7a81\u7684\u952e\u503c\u5bf9\u90fd\u5b58\u50a8\u5728\u540c\u4e00\u94fe\u8868\u4e2d\u3002\u56fe 6-5 \u5c55\u793a\u4e86\u4e00\u4e2a\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\u7684\u4f8b\u5b50\u3002

    \u56fe 6-5 \u00a0 \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868

    \u57fa\u4e8e\u94fe\u5f0f\u5730\u5740\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\u7684\u64cd\u4f5c\u65b9\u6cd5\u53d1\u751f\u4e86\u4ee5\u4e0b\u53d8\u5316\u3002

    • \u67e5\u8be2\u5143\u7d20\uff1a\u8f93\u5165 key \uff0c\u7ecf\u8fc7\u54c8\u5e0c\u51fd\u6570\u5f97\u5230\u6876\u7d22\u5f15\uff0c\u5373\u53ef\u8bbf\u95ee\u94fe\u8868\u5934\u8282\u70b9\uff0c\u7136\u540e\u904d\u5386\u94fe\u8868\u5e76\u5bf9\u6bd4 key \u4ee5\u67e5\u627e\u76ee\u6807\u952e\u503c\u5bf9\u3002
    • \u6dfb\u52a0\u5143\u7d20\uff1a\u9996\u5148\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u8bbf\u95ee\u94fe\u8868\u5934\u8282\u70b9\uff0c\u7136\u540e\u5c06\u8282\u70b9\uff08\u952e\u503c\u5bf9\uff09\u6dfb\u52a0\u5230\u94fe\u8868\u4e2d\u3002
    • \u5220\u9664\u5143\u7d20\uff1a\u6839\u636e\u54c8\u5e0c\u51fd\u6570\u7684\u7ed3\u679c\u8bbf\u95ee\u94fe\u8868\u5934\u90e8\uff0c\u63a5\u7740\u904d\u5386\u94fe\u8868\u4ee5\u67e5\u627e\u76ee\u6807\u8282\u70b9\u5e76\u5c06\u5176\u5220\u9664\u3002

    \u94fe\u5f0f\u5730\u5740\u5b58\u5728\u4ee5\u4e0b\u5c40\u9650\u6027\u3002

    • \u5360\u7528\u7a7a\u95f4\u589e\u5927\uff1a\u94fe\u8868\u5305\u542b\u8282\u70b9\u6307\u9488\uff0c\u5b83\u76f8\u6bd4\u6570\u7ec4\u66f4\u52a0\u8017\u8d39\u5185\u5b58\u7a7a\u95f4\u3002
    • \u67e5\u8be2\u6548\u7387\u964d\u4f4e\uff1a\u56e0\u4e3a\u9700\u8981\u7ebf\u6027\u904d\u5386\u94fe\u8868\u6765\u67e5\u627e\u5bf9\u5e94\u5143\u7d20\u3002

    \u4ee5\u4e0b\u4ee3\u7801\u7ed9\u51fa\u4e86\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\u7684\u7b80\u5355\u5b9e\u73b0\uff0c\u9700\u8981\u6ce8\u610f\u4e24\u70b9\u3002

    • \u4f7f\u7528\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\u4ee3\u66ff\u94fe\u8868\uff0c\u4ece\u800c\u7b80\u5316\u4ee3\u7801\u3002\u5728\u8fd9\u79cd\u8bbe\u5b9a\u4e0b\uff0c\u54c8\u5e0c\u8868\uff08\u6570\u7ec4\uff09\u5305\u542b\u591a\u4e2a\u6876\uff0c\u6bcf\u4e2a\u6876\u90fd\u662f\u4e00\u4e2a\u5217\u8868\u3002
    • \u4ee5\u4e0b\u5b9e\u73b0\u5305\u542b\u54c8\u5e0c\u8868\u6269\u5bb9\u65b9\u6cd5\u3002\u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7 \\(\\frac{2}{3}\\) \u65f6\uff0c\u6211\u4eec\u5c06\u54c8\u5e0c\u8868\u6269\u5bb9\u81f3\u539f\u5148\u7684 \\(2\\) \u500d\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_chaining.py
    class HashMapChaining:\n    \"\"\"\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets = [[] for _ in range(self.capacity)]  # \u6876\u6570\u7ec4\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def get(self, key: int) -> str | None:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket:\n            if pair.key == key:\n                return pair.val\n        # \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket:\n            if pair.key == key:\n                pair.val = val\n                return\n        # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        pair = Pair(key, val)\n        bucket.append(pair)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for pair in bucket:\n            if pair.key == key:\n                bucket.remove(pair)\n                self.size -= 1\n                break\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [[] for _ in range(self.capacity)]\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets:\n            for pair in bucket:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for bucket in self.buckets:\n            res = []\n            for pair in bucket:\n                res.append(str(pair.key) + \" -> \" + pair.val)\n            print(res)\n
    hash_map_chaining.cpp
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  private:\n    int size;                       // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;                   // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres;               // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;                // \u6269\u5bb9\u500d\u6570\n    vector<vector<Pair *>> buckets; // \u6876\u6570\u7ec4\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapChaining() : size(0), capacity(4), loadThres(2.0 / 3.0), extendRatio(2) {\n        buckets.resize(capacity);\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapChaining() {\n        for (auto &bucket : buckets) {\n            for (Pair *pair : bucket) {\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / (double)capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                return pair->val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                pair->val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].push_back(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        auto &bucket = buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (int i = 0; i < bucket.size(); i++) {\n            if (bucket[i]->key == key) {\n                Pair *tmp = bucket[i];\n                bucket.erase(bucket.begin() + i); // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n                delete tmp;                       // \u91ca\u653e\u5185\u5b58\n                size--;\n                return;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<vector<Pair *>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets.clear();\n        buckets.resize(capacity);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (auto &bucket : bucketsTmp) {\n            for (Pair *pair : bucket) {\n                put(pair->key, pair->val);\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (auto &bucket : buckets) {\n            cout << \"[\";\n            for (Pair *pair : bucket) {\n                cout << pair->key << \" -> \" << pair->val << \", \";\n            }\n            cout << \"]\\n\";\n        }\n    }\n};\n
    hash_map_chaining.java
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    String get(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        Pair pair = new Pair(key, val);\n        bucket.add(pair);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (List<Pair> bucket : bucketsTmp) {\n            for (Pair pair : bucket) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (List<Pair> bucket : buckets) {\n            List<String> res = new ArrayList<>();\n            for (Pair pair : bucket) {\n                res.add(pair.key + \" -> \" + pair.val);\n            }\n            System.out.println(res);\n        }\n    }\n}\n
    hash_map_chaining.cs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].Add(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        foreach (Pair pair in buckets[index].ToList()) {\n            if (pair.key == key) {\n                buckets[index].Remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (List<Pair> bucket in bucketsTmp) {\n            foreach (Pair pair in bucket) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (List<Pair> bucket in buckets) {\n            List<string> res = [];\n            foreach (Pair pair in bucket) {\n                res.Add(pair.key + \" -> \" + pair.val);\n            }\n            foreach (string kv in res) {\n                Console.WriteLine(kv);\n            }\n        }\n    }\n}\n
    hash_map_chaining.go
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntype hashMapChaining struct {\n    size        int      // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int      // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64  // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int      // \u6269\u5bb9\u500d\u6570\n    buckets     [][]pair // \u6876\u6570\u7ec4\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapChaining() *hashMapChaining {\n    buckets := make([][]pair, 4)\n    for i := 0; i < 4; i++ {\n        buckets[i] = make([]pair, 0)\n    }\n    return &hashMapChaining{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     buckets,\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (m *hashMapChaining) hashFunc(key int) int {\n    return key % m.capacity\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (m *hashMapChaining) loadFactor() float64 {\n    return float64(m.size) / float64(m.capacity)\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (m *hashMapChaining) get(key int) string {\n    idx := m.hashFunc(key)\n    bucket := m.buckets[idx]\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for _, p := range bucket {\n        if p.key == key {\n            return p.val\n        }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (m *hashMapChaining) put(key int, val string) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if m.loadFactor() > m.loadThres {\n        m.extend()\n    }\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for i := range m.buckets[idx] {\n        if m.buckets[idx][i].key == key {\n            m.buckets[idx][i].val = val\n            return\n        }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    p := pair{\n        key: key,\n        val: val,\n    }\n    m.buckets[idx] = append(m.buckets[idx], p)\n    m.size += 1\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (m *hashMapChaining) remove(key int) {\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for i, p := range m.buckets[idx] {\n        if p.key == key {\n            // \u5207\u7247\u5220\u9664\n            m.buckets[idx] = append(m.buckets[idx][:i], m.buckets[idx][i+1:]...)\n            m.size -= 1\n            break\n        }\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    tmpBuckets := make([][]pair, len(m.buckets))\n    for i := 0; i < len(m.buckets); i++ {\n        tmpBuckets[i] = make([]pair, len(m.buckets[i]))\n        copy(tmpBuckets[i], m.buckets[i])\n    }\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    m.capacity *= m.extendRatio\n    m.buckets = make([][]pair, m.capacity)\n    for i := 0; i < m.capacity; i++ {\n        m.buckets[i] = make([]pair, 0)\n    }\n    m.size = 0\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, bucket := range tmpBuckets {\n        for _, p := range bucket {\n            m.put(p.key, p.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) print() {\n    var builder strings.Builder\n\n    for _, bucket := range m.buckets {\n        builder.WriteString(\"[\")\n        for _, p := range bucket {\n            builder.WriteString(strconv.Itoa(p.key) + \" -> \" + p.val + \" \")\n        }\n        builder.WriteString(\"]\")\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    hash_map_chaining.swift
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [[Pair]] // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: [], count: capacity)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return pair.val\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de nil\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair(key: key, val: val)\n        buckets[index].append(pair)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pairIndex, pair) in bucket.enumerated() {\n            if pair.key == key {\n                buckets[index].remove(at: pairIndex)\n                size -= 1\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: [], count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in bucketsTmp {\n            for pair in bucket {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for bucket in buckets {\n            let res = bucket.map { \"\\($0.key) -> \\($0.val)\" }\n            Swift.print(res)\n        }\n    }\n}\n
    hash_map_chaining.js
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.ts
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    #buckets: Pair[][]; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key: number): number {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor(): number {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.dart
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  late int size; // \u952e\u503c\u5bf9\u6570\u91cf\n  late int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  late double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  late int extendRatio; // \u6269\u5bb9\u500d\u6570\n  late List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapChaining() {\n    size = 0;\n    capacity = 4;\n    loadThres = 2.0 / 3.0;\n    extendRatio = 2;\n    buckets = List.generate(capacity, (_) => []);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return size / capacity;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        return pair.val;\n      }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > loadThres) {\n      extend();\n    }\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        pair.val = val;\n        return;\n      }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    Pair pair = Pair(key, val);\n    bucket.add(pair);\n    size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        bucket.remove(pair);\n        size--;\n        break;\n      }\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<List<Pair>> bucketsTmp = buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    capacity *= extendRatio;\n    buckets = List.generate(capacity, (_) => []);\n    size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (List<Pair> bucket in bucketsTmp) {\n      for (Pair pair in bucket) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (List<Pair> bucket in buckets) {\n      List<String> res = [];\n      for (Pair pair in bucket) {\n        res.add(\"${pair.key} -> ${pair.val}\");\n      }\n      print(res);\n    }\n  }\n}\n
    hash_map_chaining.rs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapChaining {\n    size: i32,\n    capacity: i32,\n    load_thres: f32,\n    extend_ratio: i32,\n    buckets: Vec<Vec<Pair>>,\n}\n\nimpl HashMapChaining {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![vec![]; 4],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % self.capacity as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f32 {\n        self.size as f32 / self.capacity as f32\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) -> Option<String> {\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for i in 0..bucket.len() {\n            if bucket[i].key == key {\n                let pair = bucket.remove(i);\n                self.size -= 1;\n                return Some(pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = std::mem::replace(&mut self.buckets, vec![]);\n\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![Vec::new(); self.capacity as usize];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets_tmp {\n            for pair in bucket {\n                self.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for bucket in &self.buckets {\n            let mut res = Vec::new();\n            for pair in bucket {\n                res.push(format!(\"{} -> {}\", pair.key, pair.val));\n            }\n            println!(\"{:?}\", res);\n        }\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val;\n                return;\n            }\n        }\n        let bucket = &mut self.buckets[index];\n\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair { key, val };\n        bucket.push(pair);\n        self.size += 1;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&self, key: i32) -> Option<&str> {\n        let index = self.hash_func(key);\n        let bucket = &self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return Some(&pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n}\n
    hash_map_chaining.c
    /* \u94fe\u8868\u8282\u70b9 */\ntypedef struct Node {\n    Pair *pair;\n    struct Node *next;\n} Node;\n\n/* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Node **buckets;   // \u6876\u6570\u7ec4\n} HashMapChaining;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapChaining *newHashMapChaining() {\n    HashMapChaining *hashMap = (HashMapChaining *)malloc(sizeof(HashMapChaining));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapChaining(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        while (cur) {\n            Node *tmp = cur;\n            cur = cur->next;\n            free(tmp->pair);\n            free(tmp);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapChaining *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapChaining *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            return cur->pair->val;\n        }\n        cur = cur->next;\n    }\n    return \"\"; // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapChaining *hashMap, int key, const char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            strcpy(cur->pair->val, val); // \u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n            return;\n        }\n        cur = cur->next;\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n    Pair *newPair = (Pair *)malloc(sizeof(Pair));\n    newPair->key = key;\n    strcpy(newPair->val, val);\n    Node *newNode = (Node *)malloc(sizeof(Node));\n    newNode->pair = newPair;\n    newNode->next = hashMap->buckets[index];\n    hashMap->buckets[index] = newNode;\n    hashMap->size++;\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapChaining *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    int oldCapacity = hashMap->capacity;\n    Node **oldBuckets = hashMap->buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Node *cur = oldBuckets[i];\n        while (cur) {\n            put(hashMap, cur->pair->key, cur->pair->val);\n            Node *temp = cur;\n            cur = cur->next;\n            // \u91ca\u653e\u5185\u5b58\n            free(temp->pair);\n            free(temp);\n        }\n    }\n\n    free(oldBuckets);\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    Node *cur = hashMap->buckets[index];\n    Node *pre = NULL;\n    while (cur) {\n        if (cur->pair->key == key) {\n            // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n            if (pre) {\n                pre->next = cur->next;\n            } else {\n                hashMap->buckets[index] = cur->next;\n            }\n            // \u91ca\u653e\u5185\u5b58\n            free(cur->pair);\n            free(cur);\n            hashMap->size--;\n            return;\n        }\n        pre = cur;\n        cur = cur->next;\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        printf(\"[\");\n        while (cur) {\n            printf(\"%d -> %s, \", cur->pair->key, cur->pair->val);\n            cur = cur->next;\n        }\n        printf(\"]\\n\");\n    }\n}\n
    hash_map_chaining.kt
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    val loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    val extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: MutableList<MutableList<Pair>> // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (pair in bucket) {\n            if (pair.key == key) return pair._val\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (pair in bucket) {\n            if (pair.key == key) {\n                pair._val = _val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        val pair = Pair(key, _val)\n        bucket.add(pair)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pair in bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair)\n                size--\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        // mutablelist \u65e0\u56fa\u5b9a\u5927\u5c0f\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (bucket in bucketsTmp) {\n            for (pair in bucket) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (bucket in buckets) {\n            val res = mutableListOf<String>()\n            for (pair in bucket) {\n                val k = pair.key\n                val v = pair._val\n                res.add(\"$k -> $v\")\n            }\n            println(res)\n        }\n    }\n}\n
    hash_map_chaining.rb
    ### \u952e\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapChaining\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) { [] } # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for pair in bucket\n      return pair.val if pair.key == key\n    end\n    # \u82e5\u672a\u627e\u5230 key , \u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for pair in bucket\n      if pair.key == key\n        pair.val = val\n        return\n      end\n    end\n    # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    pair = Pair.new(key, val)\n    bucket << pair\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for pair in bucket\n      if pair.key == key\n        bucket.delete(pair)\n        @size -= 1\n        break\n      end\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u66ab\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity) { [] }\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for bucket in buckets\n      for pair in bucket\n        put(pair.key, pair.val)\n      end\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for bucket in @buckets\n      res = []\n      for pair in bucket\n        res << \"#{pair.key} -> #{pair.val}\"\n      end\n      pp res\n    end\n  end\nend\n
    hash_map_chaining.zig
    [class]{HashMapChaining}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u5f53\u94fe\u8868\u5f88\u957f\u65f6\uff0c\u67e5\u8be2\u6548\u7387 \\(O(n)\\) \u5f88\u5dee\u3002\u6b64\u65f6\u53ef\u4ee5\u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u201cAVL \u6811\u201d\u6216\u201c\u7ea2\u9ed1\u6811\u201d\uff0c\u4ece\u800c\u5c06\u67e5\u8be2\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(\\log n)\\) \u3002

    "},{"location":"chapter_hashing/hash_collision/#622","title":"6.2.2 \u00a0 \u5f00\u653e\u5bfb\u5740","text":"

    \u5f00\u653e\u5bfb\u5740\uff08open addressing\uff09\u4e0d\u5f15\u5165\u989d\u5916\u7684\u6570\u636e\u7ed3\u6784\uff0c\u800c\u662f\u901a\u8fc7\u201c\u591a\u6b21\u63a2\u6d4b\u201d\u6765\u5904\u7406\u54c8\u5e0c\u51b2\u7a81\uff0c\u63a2\u6d4b\u65b9\u5f0f\u4e3b\u8981\u5305\u62ec\u7ebf\u6027\u63a2\u6d4b\u3001\u5e73\u65b9\u63a2\u6d4b\u548c\u591a\u6b21\u54c8\u5e0c\u7b49\u3002

    \u4e0b\u9762\u4ee5\u7ebf\u6027\u63a2\u6d4b\u4e3a\u4f8b\uff0c\u4ecb\u7ecd\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\u7684\u5de5\u4f5c\u673a\u5236\u3002

    "},{"location":"chapter_hashing/hash_collision/#1","title":"1. \u00a0 \u7ebf\u6027\u63a2\u6d4b","text":"

    \u7ebf\u6027\u63a2\u6d4b\u91c7\u7528\u56fa\u5b9a\u6b65\u957f\u7684\u7ebf\u6027\u641c\u7d22\u6765\u8fdb\u884c\u63a2\u6d4b\uff0c\u5176\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u666e\u901a\u54c8\u5e0c\u8868\u6709\u6240\u4e0d\u540c\u3002

    • \u63d2\u5165\u5143\u7d20\uff1a\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u82e5\u53d1\u73b0\u6876\u5185\u5df2\u6709\u5143\u7d20\uff0c\u5219\u4ece\u51b2\u7a81\u4f4d\u7f6e\u5411\u540e\u7ebf\u6027\u904d\u5386\uff08\u6b65\u957f\u901a\u5e38\u4e3a \\(1\\) \uff09\uff0c\u76f4\u81f3\u627e\u5230\u7a7a\u6876\uff0c\u5c06\u5143\u7d20\u63d2\u5165\u5176\u4e2d\u3002
    • \u67e5\u627e\u5143\u7d20\uff1a\u82e5\u53d1\u73b0\u54c8\u5e0c\u51b2\u7a81\uff0c\u5219\u4f7f\u7528\u76f8\u540c\u6b65\u957f\u5411\u540e\u8fdb\u884c\u7ebf\u6027\u904d\u5386\uff0c\u76f4\u5230\u627e\u5230\u5bf9\u5e94\u5143\u7d20\uff0c\u8fd4\u56de value \u5373\u53ef\uff1b\u5982\u679c\u9047\u5230\u7a7a\u6876\uff0c\u8bf4\u660e\u76ee\u6807\u5143\u7d20\u4e0d\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u8fd4\u56de None \u3002

    \u56fe 6-6 \u5c55\u793a\u4e86\u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\uff09\u54c8\u5e0c\u8868\u7684\u952e\u503c\u5bf9\u5206\u5e03\u3002\u6839\u636e\u6b64\u54c8\u5e0c\u51fd\u6570\uff0c\u6700\u540e\u4e24\u4f4d\u76f8\u540c\u7684 key \u90fd\u4f1a\u88ab\u6620\u5c04\u5230\u76f8\u540c\u7684\u6876\u3002\u800c\u901a\u8fc7\u7ebf\u6027\u63a2\u6d4b\uff0c\u5b83\u4eec\u88ab\u4f9d\u6b21\u5b58\u50a8\u5728\u8be5\u6876\u4ee5\u53ca\u4e4b\u4e0b\u7684\u6876\u4e2d\u3002

    \u56fe 6-6 \u00a0 \u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\uff09\u54c8\u5e0c\u8868\u7684\u952e\u503c\u5bf9\u5206\u5e03

    \u7136\u800c\uff0c\u7ebf\u6027\u63a2\u6d4b\u5bb9\u6613\u4ea7\u751f\u201c\u805a\u96c6\u73b0\u8c61\u201d\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u6570\u7ec4\u4e2d\u8fde\u7eed\u88ab\u5360\u7528\u7684\u4f4d\u7f6e\u8d8a\u957f\uff0c\u8fd9\u4e9b\u8fde\u7eed\u4f4d\u7f6e\u53d1\u751f\u54c8\u5e0c\u51b2\u7a81\u7684\u53ef\u80fd\u6027\u8d8a\u5927\uff0c\u4ece\u800c\u8fdb\u4e00\u6b65\u4fc3\u4f7f\u8be5\u4f4d\u7f6e\u7684\u805a\u5806\u751f\u957f\uff0c\u5f62\u6210\u6076\u6027\u5faa\u73af\uff0c\u6700\u7ec8\u5bfc\u81f4\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u6548\u7387\u52a3\u5316\u3002

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6211\u4eec\u4e0d\u80fd\u5728\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\u4e2d\u76f4\u63a5\u5220\u9664\u5143\u7d20\u3002\u8fd9\u662f\u56e0\u4e3a\u5220\u9664\u5143\u7d20\u4f1a\u5728\u6570\u7ec4\u5185\u4ea7\u751f\u4e00\u4e2a\u7a7a\u6876 None \uff0c\u800c\u5f53\u67e5\u8be2\u5143\u7d20\u65f6\uff0c\u7ebf\u6027\u63a2\u6d4b\u5230\u8be5\u7a7a\u6876\u5c31\u4f1a\u8fd4\u56de\uff0c\u56e0\u6b64\u5728\u8be5\u7a7a\u6876\u4e4b\u4e0b\u7684\u5143\u7d20\u90fd\u65e0\u6cd5\u518d\u88ab\u8bbf\u95ee\u5230\uff0c\u7a0b\u5e8f\u53ef\u80fd\u8bef\u5224\u8fd9\u4e9b\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u5982\u56fe 6-7 \u6240\u793a\u3002

    \u56fe 6-7 \u00a0 \u5728\u5f00\u653e\u5bfb\u5740\u4e2d\u5220\u9664\u5143\u7d20\u5bfc\u81f4\u7684\u67e5\u8be2\u95ee\u9898

    \u4e3a\u4e86\u89e3\u51b3\u8be5\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u61d2\u5220\u9664\uff08lazy deletion\uff09\u673a\u5236\uff1a\u5b83\u4e0d\u76f4\u63a5\u4ece\u54c8\u5e0c\u8868\u4e2d\u79fb\u9664\u5143\u7d20\uff0c\u800c\u662f\u5229\u7528\u4e00\u4e2a\u5e38\u91cf TOMBSTONE \u6765\u6807\u8bb0\u8fd9\u4e2a\u6876\u3002\u5728\u8be5\u673a\u5236\u4e0b\uff0cNone \u548c TOMBSTONE \u90fd\u4ee3\u8868\u7a7a\u6876\uff0c\u90fd\u53ef\u4ee5\u653e\u7f6e\u952e\u503c\u5bf9\u3002\u4f46\u4e0d\u540c\u7684\u662f\uff0c\u7ebf\u6027\u63a2\u6d4b\u5230 TOMBSTONE \u65f6\u5e94\u8be5\u7ee7\u7eed\u904d\u5386\uff0c\u56e0\u4e3a\u5176\u4e4b\u4e0b\u53ef\u80fd\u8fd8\u5b58\u5728\u952e\u503c\u5bf9\u3002

    \u7136\u800c\uff0c\u61d2\u5220\u9664\u53ef\u80fd\u4f1a\u52a0\u901f\u54c8\u5e0c\u8868\u7684\u6027\u80fd\u9000\u5316\u3002\u8fd9\u662f\u56e0\u4e3a\u6bcf\u6b21\u5220\u9664\u64cd\u4f5c\u90fd\u4f1a\u4ea7\u751f\u4e00\u4e2a\u5220\u9664\u6807\u8bb0\uff0c\u968f\u7740 TOMBSTONE \u7684\u589e\u52a0\uff0c\u641c\u7d22\u65f6\u95f4\u4e5f\u4f1a\u589e\u52a0\uff0c\u56e0\u4e3a\u7ebf\u6027\u63a2\u6d4b\u53ef\u80fd\u9700\u8981\u8df3\u8fc7\u591a\u4e2a TOMBSTONE \u624d\u80fd\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002

    \u4e3a\u6b64\uff0c\u8003\u8651\u5728\u7ebf\u6027\u63a2\u6d4b\u4e2d\u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a TOMBSTONE \u7684\u7d22\u5f15\uff0c\u5e76\u5c06\u641c\u7d22\u5230\u7684\u76ee\u6807\u5143\u7d20\u4e0e\u8be5 TOMBSTONE \u4ea4\u6362\u4f4d\u7f6e\u3002\u8fd9\u6837\u505a\u7684\u597d\u5904\u662f\u5f53\u6bcf\u6b21\u67e5\u8be2\u6216\u6dfb\u52a0\u5143\u7d20\u65f6\uff0c\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u81f3\u8ddd\u79bb\u7406\u60f3\u4f4d\u7f6e\uff08\u63a2\u6d4b\u8d77\u59cb\u70b9\uff09\u66f4\u8fd1\u7684\u6876\uff0c\u4ece\u800c\u4f18\u5316\u67e5\u8be2\u6548\u7387\u3002

    \u4ee5\u4e0b\u4ee3\u7801\u5b9e\u73b0\u4e86\u4e00\u4e2a\u5305\u542b\u61d2\u5220\u9664\u7684\u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\uff09\u54c8\u5e0c\u8868\u3002\u4e3a\u4e86\u66f4\u52a0\u5145\u5206\u5730\u4f7f\u7528\u54c8\u5e0c\u8868\u7684\u7a7a\u95f4\uff0c\u6211\u4eec\u5c06\u54c8\u5e0c\u8868\u770b\u4f5c\u4e00\u4e2a\u201c\u73af\u5f62\u6570\u7ec4\u201d\uff0c\u5f53\u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u56de\u5230\u5934\u90e8\u7ee7\u7eed\u904d\u5386\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_open_addressing.py
    class HashMapOpenAddressing:\n    \"\"\"\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets: list[Pair | None] = [None] * self.capacity  # \u6876\u6570\u7ec4\n        self.TOMBSTONE = Pair(-1, \"-1\")  # \u5220\u9664\u6807\u8bb0\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def find_bucket(self, key: int) -> int:\n        \"\"\"\u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\"\"\"\n        index = self.hash_func(key)\n        first_tombstone = -1\n        # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index] is not None:\n            # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].key == key:\n                # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if first_tombstone != -1:\n                    self.buckets[first_tombstone] = self.buckets[index]\n                    self.buckets[index] = self.TOMBSTONE\n                    return first_tombstone  # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                return index  # \u8fd4\u56de\u6876\u7d22\u5f15\n            # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 and self.buckets[index] is self.TOMBSTONE:\n                first_tombstone = index\n            # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity\n        # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return index if first_tombstone == -1 else first_tombstone\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            return self.buckets[index].val\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index].val = val\n            return\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Pair(key, val)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index] = self.TOMBSTONE\n            self.size -= 1\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets_tmp = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [None] * self.capacity\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp:\n            if pair not in [None, self.TOMBSTONE]:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is None:\n                print(\"None\")\n            elif pair is self.TOMBSTONE:\n                print(\"TOMBSTONE\")\n            else:\n                print(pair.key, \"->\", pair.val)\n
    hash_map_open_addressing.cpp
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  private:\n    int size;                             // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4;                     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    const double loadThres = 2.0 / 3.0;     // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    const int extendRatio = 2;            // \u6269\u5bb9\u500d\u6570\n    vector<Pair *> buckets;               // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapOpenAddressing() : size(0), buckets(capacity, nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapOpenAddressing() {\n        for (Pair *pair : buckets) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                delete pair;\n            }\n        }\n        delete TOMBSTONE;\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != nullptr) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]->key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            return buckets[index]->val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            buckets[index]->val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            delete buckets[index];\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<Pair *> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = vector<Pair *>(capacity, nullptr);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair *pair : bucketsTmp) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                put(pair->key, pair->val);\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *pair : buckets) {\n            if (pair == nullptr) {\n                cout << \"nullptr\" << endl;\n            } else if (pair == TOMBSTONE) {\n                cout << \"TOMBSTONE\" << endl;\n            } else {\n                cout << pair->key << \" -> \" << pair->val << endl;\n            }\n        }\n    }\n};\n
    hash_map_open_addressing.java
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    private int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private final double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private final int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    private Pair[] buckets; // \u6876\u6570\u7ec4\n    private final Pair TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair pair : bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair pair : buckets) {\n            if (pair == null) {\n                System.out.println(\"null\");\n            } else if (pair == TOMBSTONE) {\n                System.out.println(\"TOMBSTONE\");\n            } else {\n                System.out.println(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.cs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    Pair[] buckets; // \u6876\u6570\u7ec4\n    Pair TOMBSTONE = new(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int FindBucket(int key) {\n        int index = HashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (Pair pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair pair in buckets) {\n            if (pair == null) {\n                Console.WriteLine(\"null\");\n            } else if (pair == TOMBSTONE) {\n                Console.WriteLine(\"TOMBSTONE\");\n            } else {\n                Console.WriteLine(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.go
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntype hashMapOpenAddressing struct {\n    size        int     // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64 // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int     // \u6269\u5bb9\u500d\u6570\n    buckets     []*pair // \u6876\u6570\u7ec4\n    TOMBSTONE   *pair   // \u5220\u9664\u6807\u8bb0\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapOpenAddressing() *hashMapOpenAddressing {\n    return &hashMapOpenAddressing{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     make([]*pair, 4),\n        TOMBSTONE:   &pair{-1, \"-1\"},\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (h *hashMapOpenAddressing) hashFunc(key int) int {\n    return key % h.capacity // \u6839\u636e\u952e\u8ba1\u7b97\u54c8\u5e0c\u503c\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (h *hashMapOpenAddressing) loadFactor() float64 {\n    return float64(h.size) / float64(h.capacity) // \u8ba1\u7b97\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nfunc (h *hashMapOpenAddressing) findBucket(key int) int {\n    index := h.hashFunc(key) // \u83b7\u53d6\u521d\u59cb\u7d22\u5f15\n    firstTombstone := -1     // \u8bb0\u5f55\u9047\u5230\u7684\u7b2c\u4e00\u4e2aTOMBSTONE\u7684\u4f4d\u7f6e\n    for h.buckets[index] != nil {\n        if h.buckets[index].key == key {\n            if firstTombstone != -1 {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                h.buckets[firstTombstone] = h.buckets[index]\n                h.buckets[index] = h.TOMBSTONE\n                return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index // \u8fd4\u56de\u627e\u5230\u7684\u7d22\u5f15\n        }\n        if firstTombstone == -1 && h.buckets[index] == h.TOMBSTONE {\n            firstTombstone = index // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\u7684\u4f4d\u7f6e\n        }\n        index = (index + 1) % h.capacity // \u7ebf\u6027\u63a2\u6d4b\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    if firstTombstone != -1 {\n        return firstTombstone\n    }\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) get(key int) string {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        return h.buckets[index].val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    }\n    return \"\" // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) put(key int, val string) {\n    if h.loadFactor() > h.loadThres {\n        h.extend() // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    }\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] == nil || h.buckets[index] == h.TOMBSTONE {\n        h.buckets[index] = &pair{key, val} // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        h.size++\n    } else {\n        h.buckets[index].val = val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val\n    }\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) remove(key int) {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        h.buckets[index] = h.TOMBSTONE // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        h.size--\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) extend() {\n    oldBuckets := h.buckets               // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    h.capacity *= h.extendRatio           // \u66f4\u65b0\u5bb9\u91cf\n    h.buckets = make([]*pair, h.capacity) // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    h.size = 0                            // \u91cd\u7f6e\u5927\u5c0f\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, pair := range oldBuckets {\n        if pair != nil && pair != h.TOMBSTONE {\n            h.put(pair.key, pair.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) print() {\n    for _, pair := range h.buckets {\n        if pair == nil {\n            fmt.Println(\"nil\")\n        } else if pair == h.TOMBSTONE {\n            fmt.Println(\"TOMBSTONE\")\n        } else {\n            fmt.Printf(\"%d -> %s\\n\", pair.key, pair.val)\n        }\n    }\n}\n
    hash_map_open_addressing.swift
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [Pair?] // \u6876\u6570\u7ec4\n    var TOMBSTONE: Pair // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: nil, count: capacity)\n        TOMBSTONE = Pair(key: -1, val: \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    func findBucket(key: Int) -> Int {\n        var index = hashFunc(key: key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while buckets[index] != nil {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if buckets[index]!.key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if firstTombstone != -1 {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if firstTombstone == -1 && buckets[index] == TOMBSTONE {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            return buckets[index]!.val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index]!.val = val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key: key, val: val)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index] = TOMBSTONE\n            size -= 1\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: nil, count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in bucketsTmp {\n            if let pair, pair != TOMBSTONE {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in buckets {\n            if pair == nil {\n                Swift.print(\"null\")\n            } else if pair == TOMBSTONE {\n                Swift.print(\"TOMBSTONE\")\n            } else {\n                Swift.print(\"\\(pair!.key) -> \\(pair!.val)\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.js
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n    #TOMBSTONE; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.#capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.#loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.#extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.#buckets = Array(this.#capacity).fill(null); // \u6876\u6570\u7ec4\n        this.#TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    #findBucket(key) {\n        let index = this.#hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.#buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.#buckets[index].key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.#buckets[firstTombstone] = this.#buckets[index];\n                    this.#buckets[index] = this.#TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.#buckets[index] === this.#TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.#capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            return this.#buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.#buckets[index] = new Pair(key, val);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index] = this.#TOMBSTONE;\n            this.#size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = Array(this.#capacity).fill(null);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.#TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const pair of this.#buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.#TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.ts
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    private capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    private buckets: Array<Pair | null>; // \u6876\u6570\u7ec4\n    private TOMBSTONE: Pair; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.buckets = Array(this.capacity).fill(null); // \u6876\u6570\u7ec4\n        this.TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % this.capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private loadFactor(): number {\n        return this.size / this.capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private findBucket(key: number): number {\n        let index = this.hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.buckets[index]!.key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.buckets[firstTombstone] = this.buckets[index];\n                    this.buckets[index] = this.TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.buckets[index] === this.TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            return this.buckets[index]!.val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.loadFactor() > this.loadThres) {\n            this.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index]!.val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.buckets[index] = new Pair(key, val);\n        this.size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index] = this.TOMBSTONE;\n            this.size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.capacity *= this.extendRatio;\n        this.buckets = Array(this.capacity).fill(null);\n        this.size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const pair of this.buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.dart
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  late int _size; // \u952e\u503c\u5bf9\u6570\u91cf\n  int _capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  double _loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  int _extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n  late List<Pair?> _buckets; // \u6876\u6570\u7ec4\n  Pair _TOMBSTONE = Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapOpenAddressing() {\n    _size = 0;\n    _buckets = List.generate(_capacity, (index) => null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % _capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return _size / _capacity;\n  }\n\n  /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n  int findBucket(int key) {\n    int index = hashFunc(key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (_buckets[index] != null) {\n      // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if (_buckets[index]!.key == key) {\n        // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if (firstTombstone != -1) {\n          _buckets[firstTombstone] = _buckets[index];\n          _buckets[index] = _TOMBSTONE;\n          return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        }\n        return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n      }\n      // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      if (firstTombstone == -1 && _buckets[index] == _TOMBSTONE) {\n        firstTombstone = index;\n      }\n      // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % _capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      return _buckets[index]!.val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > _loadThres) {\n      extend();\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index]!.val = val;\n      return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    _buckets[index] = new Pair(key, val);\n    _size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index] = _TOMBSTONE;\n      _size--;\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<Pair?> bucketsTmp = _buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    _capacity *= _extendRatio;\n    _buckets = List.generate(_capacity, (index) => null);\n    _size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (Pair? pair in bucketsTmp) {\n      if (pair != null && pair != _TOMBSTONE) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (Pair? pair in _buckets) {\n      if (pair == null) {\n        print(\"null\");\n      } else if (pair == _TOMBSTONE) {\n        print(\"TOMBSTONE\");\n      } else {\n        print(\"${pair.key} -> ${pair.val}\");\n      }\n    }\n  }\n}\n
    hash_map_open_addressing.rs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapOpenAddressing {\n    size: usize,                // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity: usize,            // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    load_thres: f64,            // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extend_ratio: usize,        // \u6269\u5bb9\u500d\u6570\n    buckets: Vec<Option<Pair>>, // \u6876\u6570\u7ec4\n    TOMBSTONE: Option<Pair>,    // \u5220\u9664\u6807\u8bb0\n}\n\nimpl HashMapOpenAddressing {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![None; 4],\n            TOMBSTONE: Some(Pair {\n                key: -1,\n                val: \"-1\".to_string(),\n            }),\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        (key % self.capacity as i32) as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f64 {\n        self.size as f64 / self.capacity as f64\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fn find_bucket(&mut self, key: i32) -> usize {\n        let mut index = self.hash_func(key);\n        let mut first_tombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index].is_some() {\n            // \u82e5\u9047\u5230 key\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].as_ref().unwrap().key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u5efa\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\n                if first_tombstone != -1 {\n                    self.buckets[first_tombstone as usize] = self.buckets[index].take();\n                    self.buckets[index] = self.TOMBSTONE.clone();\n                    return first_tombstone as usize; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 && self.buckets[index] == self.TOMBSTONE {\n                first_tombstone = index as i32;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        if first_tombstone == -1 {\n            index\n        } else {\n            first_tombstone as usize\n        }\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&mut self, key: i32) -> Option<&str> {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            return self.buckets[index].as_ref().map(|pair| &pair.val as &str);\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        None\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index].as_mut().unwrap().val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Some(Pair { key, val });\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index] = self.TOMBSTONE.clone();\n            self.size -= 1;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = self.buckets.clone();\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![None; self.capacity];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp {\n            if pair.is_none() || pair == self.TOMBSTONE {\n                continue;\n            }\n            let pair = pair.unwrap();\n\n            self.put(pair.key, pair.val);\n        }\n    }\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for pair in &self.buckets {\n            if pair.is_none() {\n                println!(\"null\");\n            } else if pair == &self.TOMBSTONE {\n                println!(\"TOMBSTONE\");\n            } else {\n                let pair = pair.as_ref().unwrap();\n                println!(\"{} -> {}\", pair.key, pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.c
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Pair **buckets;   // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE;  // \u5220\u9664\u6807\u8bb0\n} HashMapOpenAddressing;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapOpenAddressing *newHashMapOpenAddressing() {\n    HashMapOpenAddressing *hashMap = (HashMapOpenAddressing *)malloc(sizeof(HashMapOpenAddressing));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->TOMBSTONE = (Pair *)malloc(sizeof(Pair));\n    hashMap->TOMBSTONE->key = -1;\n    hashMap->TOMBSTONE->val = \"-1\";\n\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapOpenAddressing(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap->TOMBSTONE);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapOpenAddressing *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapOpenAddressing *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nint findBucket(HashMapOpenAddressing *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (hashMap->buckets[index] != NULL) {\n        // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        if (hashMap->buckets[index]->key == key) {\n            // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n            if (firstTombstone != -1) {\n                hashMap->buckets[firstTombstone] = hashMap->buckets[index];\n                hashMap->buckets[index] = hashMap->TOMBSTONE;\n                return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n        }\n        // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n        if (firstTombstone == -1 && hashMap->buckets[index] == hashMap->TOMBSTONE) {\n            firstTombstone = index;\n        }\n        // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n        index = (index + 1) % hashMap->capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        return hashMap->buckets[index]->val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\";\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapOpenAddressing *hashMap, int key, char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        free(hashMap->buckets[index]->val);\n        hashMap->buckets[index]->val = (char *)malloc(sizeof(strlen(val) + 1));\n        strcpy(hashMap->buckets[index]->val, val);\n        hashMap->buckets[index]->val[strlen(val)] = '\\0';\n        return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    Pair *pair = (Pair *)malloc(sizeof(Pair));\n    pair->key = key;\n    pair->val = (char *)malloc(sizeof(strlen(val) + 1));\n    strcpy(pair->val, val);\n    pair->val[strlen(val)] = '\\0';\n\n    hashMap->buckets[index] = pair;\n    hashMap->size++;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        Pair *pair = hashMap->buckets[index];\n        free(pair->val);\n        free(pair);\n        hashMap->buckets[index] = hashMap->TOMBSTONE;\n        hashMap->size--;\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapOpenAddressing *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    Pair **bucketsTmp = hashMap->buckets;\n    int oldCapacity = hashMap->capacity;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Pair *pair = bucketsTmp[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            put(hashMap, pair->key, pair->val);\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(bucketsTmp);\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair == NULL) {\n            printf(\"NULL\\n\");\n        } else if (pair == hashMap->TOMBSTONE) {\n            printf(\"TOMBSTONE\\n\");\n        } else {\n            printf(\"%d -> %s\\n\", pair->key, pair->val);\n        }\n    }\n}\n
    hash_map_open_addressing.kt
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private var size: Int               // \u952e\u503c\u5bf9\u6570\u91cf\n    private var capacity: Int           // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private val loadThres: Double       // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private val extendRatio: Int        // \u6269\u5bb9\u500d\u6570\n    private var buckets: Array<Pair?>   // \u6876\u6570\u7ec4\n    private val TOMBSTONE: Pair         // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = arrayOfNulls(capacity)\n        TOMBSTONE = Pair(-1, \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fun findBucket(key: Int): Int {\n        var index = hashFunc(key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]?.key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return if (firstTombstone == -1) index else firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index]?._val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index]!!._val = _val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key, _val)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE\n            size--\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = arrayOfNulls(capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (pair in buckets) {\n            if (pair == null) {\n                println(\"null\")\n            } else if (pair == TOMBSTONE) {\n                println(\"TOMESTOME\")\n            } else {\n                println(\"${pair.key} -> ${pair._val}\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.rb
    ### \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapOpenAddressing\n  TOMBSTONE = Pair.new(-1, '-1') # \u5220\u9664\u6807\u8bb0\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 ###\n  def find_bucket(key)\n    index = hash_func(key)\n    first_tombstone = -1\n    # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while !@buckets[index].nil?\n      # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if @buckets[index].key == key\n        # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if first_tombstone != -1\n          @buckets[first_tombstone] = @buckets[index]\n          @buckets[index] = TOMBSTONE\n          return first_tombstone # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        end\n        return index # \u8fd4\u56de\u6876\u7d22\u5f15\n      end\n      # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      first_tombstone = index if first_tombstone == -1 && @buckets[index] == TOMBSTONE\n      # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % @capacity\n    end\n    # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    first_tombstone == -1 ? index : first_tombstone\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    return @buckets[index].val unless [nil, TOMBSTONE].include?(@buckets[index])\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5f00\u8fd4\u56de\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index].val = val\n      return\n    end\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    @buckets[index] = Pair.new(key, val)\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index] = TOMBSTONE\n      @size -= 1\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets_tmp = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity)\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for pair in buckets_tmp\n      put(pair.key, pair.val) unless [nil, TOMBSTONE].include?(pair)\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for pair in @buckets\n      if pair.nil?\n        puts \"Nil\"\n      elsif pair == TOMBSTONE\n        puts \"TOMBSTONE\"\n      else\n        puts \"#{pair.key} -> #{pair.val}\"\n      end\n    end\n  end\nend\n
    hash_map_open_addressing.zig
    [class]{HashMapOpenAddressing}-[func]{}\n
    "},{"location":"chapter_hashing/hash_collision/#2","title":"2. \u00a0 \u5e73\u65b9\u63a2\u6d4b","text":"

    \u5e73\u65b9\u63a2\u6d4b\u4e0e\u7ebf\u6027\u63a2\u6d4b\u7c7b\u4f3c\uff0c\u90fd\u662f\u5f00\u653e\u5bfb\u5740\u7684\u5e38\u89c1\u7b56\u7565\u4e4b\u4e00\u3002\u5f53\u53d1\u751f\u51b2\u7a81\u65f6\uff0c\u5e73\u65b9\u63a2\u6d4b\u4e0d\u662f\u7b80\u5355\u5730\u8df3\u8fc7\u4e00\u4e2a\u56fa\u5b9a\u7684\u6b65\u6570\uff0c\u800c\u662f\u8df3\u8fc7\u201c\u63a2\u6d4b\u6b21\u6570\u7684\u5e73\u65b9\u201d\u7684\u6b65\u6570\uff0c\u5373 \\(1, 4, 9, \\dots\\) \u6b65\u3002

    \u5e73\u65b9\u63a2\u6d4b\u4e3b\u8981\u5177\u6709\u4ee5\u4e0b\u4f18\u52bf\u3002

    • \u5e73\u65b9\u63a2\u6d4b\u901a\u8fc7\u8df3\u8fc7\u63a2\u6d4b\u6b21\u6570\u5e73\u65b9\u7684\u8ddd\u79bb\uff0c\u8bd5\u56fe\u7f13\u89e3\u7ebf\u6027\u63a2\u6d4b\u7684\u805a\u96c6\u6548\u5e94\u3002
    • \u5e73\u65b9\u63a2\u6d4b\u4f1a\u8df3\u8fc7\u66f4\u5927\u7684\u8ddd\u79bb\u6765\u5bfb\u627e\u7a7a\u4f4d\u7f6e\uff0c\u6709\u52a9\u4e8e\u6570\u636e\u5206\u5e03\u5f97\u66f4\u52a0\u5747\u5300\u3002

    \u7136\u800c\uff0c\u5e73\u65b9\u63a2\u6d4b\u5e76\u4e0d\u662f\u5b8c\u7f8e\u7684\u3002

    • \u4ecd\u7136\u5b58\u5728\u805a\u96c6\u73b0\u8c61\uff0c\u5373\u67d0\u4e9b\u4f4d\u7f6e\u6bd4\u5176\u4ed6\u4f4d\u7f6e\u66f4\u5bb9\u6613\u88ab\u5360\u7528\u3002
    • \u7531\u4e8e\u5e73\u65b9\u7684\u589e\u957f\uff0c\u5e73\u65b9\u63a2\u6d4b\u53ef\u80fd\u4e0d\u4f1a\u63a2\u6d4b\u6574\u4e2a\u54c8\u5e0c\u8868\uff0c\u8fd9\u610f\u5473\u7740\u5373\u4f7f\u54c8\u5e0c\u8868\u4e2d\u6709\u7a7a\u6876\uff0c\u5e73\u65b9\u63a2\u6d4b\u4e5f\u53ef\u80fd\u65e0\u6cd5\u8bbf\u95ee\u5230\u5b83\u3002
    "},{"location":"chapter_hashing/hash_collision/#3","title":"3. \u00a0 \u591a\u6b21\u54c8\u5e0c","text":"

    \u987e\u540d\u601d\u4e49\uff0c\u591a\u6b21\u54c8\u5e0c\u65b9\u6cd5\u4f7f\u7528\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570 \\(f_1(x)\\)\u3001\\(f_2(x)\\)\u3001\\(f_3(x)\\)\u3001\\(\\dots\\) \u8fdb\u884c\u63a2\u6d4b\u3002

    • \u63d2\u5165\u5143\u7d20\uff1a\u82e5\u54c8\u5e0c\u51fd\u6570 \\(f_1(x)\\) \u51fa\u73b0\u51b2\u7a81\uff0c\u5219\u5c1d\u8bd5 \\(f_2(x)\\) \uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u5230\u627e\u5230\u7a7a\u4f4d\u540e\u63d2\u5165\u5143\u7d20\u3002
    • \u67e5\u627e\u5143\u7d20\uff1a\u5728\u76f8\u540c\u7684\u54c8\u5e0c\u51fd\u6570\u987a\u5e8f\u4e0b\u8fdb\u884c\u67e5\u627e\uff0c\u76f4\u5230\u627e\u5230\u76ee\u6807\u5143\u7d20\u65f6\u8fd4\u56de\uff1b\u82e5\u9047\u5230\u7a7a\u4f4d\u6216\u5df2\u5c1d\u8bd5\u6240\u6709\u54c8\u5e0c\u51fd\u6570\uff0c\u8bf4\u660e\u54c8\u5e0c\u8868\u4e2d\u4e0d\u5b58\u5728\u8be5\u5143\u7d20\uff0c\u5219\u8fd4\u56de None \u3002

    \u4e0e\u7ebf\u6027\u63a2\u6d4b\u76f8\u6bd4\uff0c\u591a\u6b21\u54c8\u5e0c\u65b9\u6cd5\u4e0d\u6613\u4ea7\u751f\u805a\u96c6\uff0c\u4f46\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570\u4f1a\u5e26\u6765\u989d\u5916\u7684\u8ba1\u7b97\u91cf\u3002

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\u3001\u5e73\u65b9\u63a2\u6d4b\u548c\u591a\u6b21\u54c8\u5e0c\uff09\u54c8\u5e0c\u8868\u90fd\u5b58\u5728\u201c\u4e0d\u80fd\u76f4\u63a5\u5220\u9664\u5143\u7d20\u201d\u7684\u95ee\u9898\u3002

    "},{"location":"chapter_hashing/hash_collision/#623","title":"6.2.3 \u00a0 \u7f16\u7a0b\u8bed\u8a00\u7684\u9009\u62e9","text":"

    \u5404\u79cd\u7f16\u7a0b\u8bed\u8a00\u91c7\u53d6\u4e86\u4e0d\u540c\u7684\u54c8\u5e0c\u8868\u5b9e\u73b0\u7b56\u7565\uff0c\u4e0b\u9762\u4e3e\u51e0\u4e2a\u4f8b\u5b50\u3002

    • Python \u91c7\u7528\u5f00\u653e\u5bfb\u5740\u3002\u5b57\u5178 dict \u4f7f\u7528\u4f2a\u968f\u673a\u6570\u8fdb\u884c\u63a2\u6d4b\u3002
    • Java \u91c7\u7528\u94fe\u5f0f\u5730\u5740\u3002\u81ea JDK 1.8 \u4ee5\u6765\uff0c\u5f53 HashMap \u5185\u6570\u7ec4\u957f\u5ea6\u8fbe\u5230 64 \u4e14\u94fe\u8868\u957f\u5ea6\u8fbe\u5230 8 \u65f6\uff0c\u94fe\u8868\u4f1a\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u4ee5\u63d0\u5347\u67e5\u627e\u6027\u80fd\u3002
    • Go \u91c7\u7528\u94fe\u5f0f\u5730\u5740\u3002Go \u89c4\u5b9a\u6bcf\u4e2a\u6876\u6700\u591a\u5b58\u50a8 8 \u4e2a\u952e\u503c\u5bf9\uff0c\u8d85\u51fa\u5bb9\u91cf\u5219\u8fde\u63a5\u4e00\u4e2a\u6ea2\u51fa\u6876\uff1b\u5f53\u6ea2\u51fa\u6876\u8fc7\u591a\u65f6\uff0c\u4f1a\u6267\u884c\u4e00\u6b21\u7279\u6b8a\u7684\u7b49\u91cf\u6269\u5bb9\u64cd\u4f5c\uff0c\u4ee5\u786e\u4fdd\u6027\u80fd\u3002
    "},{"location":"chapter_hashing/hash_map/","title":"6.1 \u00a0 \u54c8\u5e0c\u8868","text":"

    \u54c8\u5e0c\u8868\uff08hash table\uff09\uff0c\u53c8\u79f0\u6563\u5217\u8868\uff0c\u5b83\u901a\u8fc7\u5efa\u7acb\u952e key \u4e0e\u503c value \u4e4b\u95f4\u7684\u6620\u5c04\uff0c\u5b9e\u73b0\u9ad8\u6548\u7684\u5143\u7d20\u67e5\u8be2\u3002\u5177\u4f53\u800c\u8a00\uff0c\u6211\u4eec\u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u4e00\u4e2a\u952e key \uff0c\u5219\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u83b7\u53d6\u5bf9\u5e94\u7684\u503c value \u3002

    \u5982\u56fe 6-1 \u6240\u793a\uff0c\u7ed9\u5b9a \\(n\\) \u4e2a\u5b66\u751f\uff0c\u6bcf\u4e2a\u5b66\u751f\u90fd\u6709\u201c\u59d3\u540d\u201d\u548c\u201c\u5b66\u53f7\u201d\u4e24\u9879\u6570\u636e\u3002\u5047\u5982\u6211\u4eec\u5e0c\u671b\u5b9e\u73b0\u201c\u8f93\u5165\u4e00\u4e2a\u5b66\u53f7\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u59d3\u540d\u201d\u7684\u67e5\u8be2\u529f\u80fd\uff0c\u5219\u53ef\u4ee5\u91c7\u7528\u56fe 6-1 \u6240\u793a\u7684\u54c8\u5e0c\u8868\u6765\u5b9e\u73b0\u3002

    \u56fe 6-1 \u00a0 \u54c8\u5e0c\u8868\u7684\u62bd\u8c61\u8868\u793a

    \u9664\u54c8\u5e0c\u8868\u5916\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u67e5\u8be2\u529f\u80fd\uff0c\u5b83\u4eec\u7684\u6548\u7387\u5bf9\u6bd4\u5982\u8868 6-1 \u6240\u793a\u3002

    • \u6dfb\u52a0\u5143\u7d20\uff1a\u4ec5\u9700\u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u6570\u7ec4\uff08\u94fe\u8868\uff09\u7684\u5c3e\u90e8\u5373\u53ef\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002
    • \u67e5\u8be2\u5143\u7d20\uff1a\u7531\u4e8e\u6570\u7ec4\uff08\u94fe\u8868\uff09\u662f\u4e71\u5e8f\u7684\uff0c\u56e0\u6b64\u9700\u8981\u904d\u5386\u5176\u4e2d\u7684\u6240\u6709\u5143\u7d20\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002
    • \u5220\u9664\u5143\u7d20\uff1a\u9700\u8981\u5148\u67e5\u8be2\u5230\u5143\u7d20\uff0c\u518d\u4ece\u6570\u7ec4\uff08\u94fe\u8868\uff09\u4e2d\u5220\u9664\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002

    \u8868 6-1 \u00a0 \u5143\u7d20\u67e5\u8be2\u6548\u7387\u5bf9\u6bd4

    \u6570\u7ec4 \u94fe\u8868 \u54c8\u5e0c\u8868 \u67e5\u627e\u5143\u7d20 \\(O(n)\\) \\(O(n)\\) \\(O(1)\\) \u6dfb\u52a0\u5143\u7d20 \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(n)\\) \\(O(1)\\)

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u5728\u54c8\u5e0c\u8868\u4e2d\u8fdb\u884c\u589e\u5220\u67e5\u6539\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f \\(O(1)\\) \uff0c\u975e\u5e38\u9ad8\u6548\u3002

    "},{"location":"chapter_hashing/hash_map/#611","title":"6.1.1 \u00a0 \u54c8\u5e0c\u8868\u5e38\u7528\u64cd\u4f5c","text":"

    \u54c8\u5e0c\u8868\u7684\u5e38\u89c1\u64cd\u4f5c\u5305\u62ec\uff1a\u521d\u59cb\u5316\u3001\u67e5\u8be2\u64cd\u4f5c\u3001\u6dfb\u52a0\u952e\u503c\u5bf9\u548c\u5220\u9664\u952e\u503c\u5bf9\u7b49\uff0c\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map.py
    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\nhmap: dict = {}\n\n# \u6dfb\u52a0\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nhmap[12836] = \"\u5c0f\u54c8\"\nhmap[15937] = \"\u5c0f\u5570\"\nhmap[16750] = \"\u5c0f\u7b97\"\nhmap[13276] = \"\u5c0f\u6cd5\"\nhmap[10583] = \"\u5c0f\u9e2d\"\n\n# \u67e5\u8be2\u64cd\u4f5c\n# \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nname: str = hmap[15937]\n\n# \u5220\u9664\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nhmap.pop(10583)\n
    hash_map.cpp
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nunordered_map<int, string> map;\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\";\nmap[15937] = \"\u5c0f\u5570\";\nmap[16750] = \"\u5c0f\u7b97\";\nmap[13276] = \"\u5c0f\u6cd5\";\nmap[10583] = \"\u5c0f\u9e2d\";\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nstring name = map[15937];\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.erase(10583);\n
    hash_map.java
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nMap<Integer, String> map = new HashMap<>();\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.put(12836, \"\u5c0f\u54c8\");\nmap.put(15937, \"\u5c0f\u5570\");\nmap.put(16750, \"\u5c0f\u7b97\");\nmap.put(13276, \"\u5c0f\u6cd5\");\nmap.put(10583, \"\u5c0f\u9e2d\");\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nString name = map.get(15937);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.remove(10583);\n
    hash_map.cs
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nDictionary<int, string> map = new() {\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    // \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\n    { 12836, \"\u5c0f\u54c8\" },\n    { 15937, \"\u5c0f\u5570\" },\n    { 16750, \"\u5c0f\u7b97\" },\n    { 13276, \"\u5c0f\u6cd5\" },\n    { 10583, \"\u5c0f\u9e2d\" }\n};\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nstring name = map[15937];\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.Remove(10583);\n
    hash_map_test.go
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nhmap := make(map[int]string)\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nhmap[12836] = \"\u5c0f\u54c8\"\nhmap[15937] = \"\u5c0f\u5570\"\nhmap[16750] = \"\u5c0f\u7b97\"\nhmap[13276] = \"\u5c0f\u6cd5\"\nhmap[10583] = \"\u5c0f\u9e2d\"\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nname := hmap[15937]\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\ndelete(hmap, 10583)\n
    hash_map.swift
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nvar map: [Int: String] = [:]\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\"\nmap[15937] = \"\u5c0f\u5570\"\nmap[16750] = \"\u5c0f\u7b97\"\nmap[13276] = \"\u5c0f\u6cd5\"\nmap[10583] = \"\u5c0f\u9e2d\"\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet name = map[15937]!\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.removeValue(forKey: 10583)\n
    hash_map.js
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nconst map = new Map();\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.set(12836, '\u5c0f\u54c8');\nmap.set(15937, '\u5c0f\u5570');\nmap.set(16750, '\u5c0f\u7b97');\nmap.set(13276, '\u5c0f\u6cd5');\nmap.set(10583, '\u5c0f\u9e2d');\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet name = map.get(15937);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.delete(10583);\n
    hash_map.ts
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nconst map = new Map<number, string>();\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.set(12836, '\u5c0f\u54c8');\nmap.set(15937, '\u5c0f\u5570');\nmap.set(16750, '\u5c0f\u7b97');\nmap.set(13276, '\u5c0f\u6cd5');\nmap.set(10583, '\u5c0f\u9e2d');\nconsole.info('\\n\u6dfb\u52a0\u5b8c\u6210\u540e\uff0c\u54c8\u5e0c\u8868\u4e3a\\nKey -> Value');\nconsole.info(map);\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet name = map.get(15937);\nconsole.info('\\n\u8f93\u5165\u5b66\u53f7 15937 \uff0c\u67e5\u8be2\u5230\u59d3\u540d ' + name);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.delete(10583);\nconsole.info('\\n\u5220\u9664 10583 \u540e\uff0c\u54c8\u5e0c\u8868\u4e3a\\nKey -> Value');\nconsole.info(map);\n
    hash_map.dart
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nMap<int, String> map = {};\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\";\nmap[15937] = \"\u5c0f\u5570\";\nmap[16750] = \"\u5c0f\u7b97\";\nmap[13276] = \"\u5c0f\u6cd5\";\nmap[10583] = \"\u5c0f\u9e2d\";\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nString name = map[15937];\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.remove(10583);\n
    hash_map.rs
    use std::collections::HashMap;\n\n/* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nlet mut map: HashMap<i32, String> = HashMap::new();\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.insert(12836, \"\u5c0f\u54c8\".to_string());\nmap.insert(15937, \"\u5c0f\u5570\".to_string());\nmap.insert(16750, \"\u5c0f\u7b97\".to_string());\nmap.insert(13279, \"\u5c0f\u6cd5\".to_string());\nmap.insert(10583, \"\u5c0f\u9e2d\".to_string());\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet _name: Option<&String> = map.get(&15937);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nlet _removed_value: Option<String> = map.remove(&10583);\n
    hash_map.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u54c8\u5e0c\u8868\n
    hash_map.kt
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nval map = HashMap<Int,String>()\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\"\nmap[15937] = \"\u5c0f\u5570\"\nmap[16750] = \"\u5c0f\u7b97\"\nmap[13276] = \"\u5c0f\u6cd5\"\nmap[10583] = \"\u5c0f\u9e2d\"\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nval name = map[15937]\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.remove(10583)\n
    hash_map.rb
    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\nhmap = {}\n\n# \u6dfb\u52a0\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nhmap[12836] = \"\u5c0f\u54c8\"\nhmap[15937] = \"\u5c0f\u5570\"\nhmap[16750] = \"\u5c0f\u7b97\"\nhmap[13276] = \"\u5c0f\u6cd5\"\nhmap[10583] = \"\u5c0f\u9e2d\"\n\n# \u67e5\u8be2\u64cd\u4f5c\n# \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nname = hmap[15937]\n\n# \u5220\u9664\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nhmap.delete(10583)\n
    hash_map.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u54c8\u5e0c\u8868\u6709\u4e09\u79cd\u5e38\u7528\u7684\u904d\u5386\u65b9\u5f0f\uff1a\u904d\u5386\u952e\u503c\u5bf9\u3001\u904d\u5386\u952e\u548c\u904d\u5386\u503c\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map.py
    # \u904d\u5386\u54c8\u5e0c\u8868\n# \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor key, value in hmap.items():\n    print(key, \"->\", value)\n# \u5355\u72ec\u904d\u5386\u952e key\nfor key in hmap.keys():\n    print(key)\n# \u5355\u72ec\u904d\u5386\u503c value\nfor value in hmap.values():\n    print(value)\n
    hash_map.cpp
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor (auto kv: map) {\n    cout << kv.first << \" -> \" << kv.second << endl;\n}\n// \u4f7f\u7528\u8fed\u4ee3\u5668\u904d\u5386 key->value\nfor (auto iter = map.begin(); iter != map.end(); iter++) {\n    cout << iter->first << \"->\" << iter->second << endl;\n}\n
    hash_map.java
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor (Map.Entry <Integer, String> kv: map.entrySet()) {\n    System.out.println(kv.getKey() + \" -> \" + kv.getValue());\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nfor (int key: map.keySet()) {\n    System.out.println(key);\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nfor (String val: map.values()) {\n    System.out.println(val);\n}\n
    hash_map.cs
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nforeach (var kv in map) {\n    Console.WriteLine(kv.Key + \" -> \" + kv.Value);\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nforeach (int key in map.Keys) {\n    Console.WriteLine(key);\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nforeach (string val in map.Values) {\n    Console.WriteLine(val);\n}\n
    hash_map_test.go
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor key, value := range hmap {\n    fmt.Println(key, \"->\", value)\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nfor key := range hmap {\n    fmt.Println(key)\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nfor _, value := range hmap {\n    fmt.Println(value)\n}\n
    hash_map.swift
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nfor (key, value) in map {\n    print(\"\\(key) -> \\(value)\")\n}\n// \u5355\u72ec\u904d\u5386\u952e Key\nfor key in map.keys {\n    print(key)\n}\n// \u5355\u72ec\u904d\u5386\u503c Value\nfor value in map.values {\n    print(value)\n}\n
    hash_map.js
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\nconsole.info('\\n\u904d\u5386\u952e\u503c\u5bf9 Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u952e Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u503c Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.ts
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\nconsole.info('\\n\u904d\u5386\u952e\u503c\u5bf9 Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u952e Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u503c Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.dart
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nmap.forEach((key, value) {\n  print('$key -> $value');\n});\n\n// \u5355\u72ec\u904d\u5386\u952e Key\nmap.keys.forEach((key) {\n  print(key);\n});\n\n// \u5355\u72ec\u904d\u5386\u503c Value\nmap.values.forEach((value) {\n  print(value);\n});\n
    hash_map.rs
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nfor (key, value) in &map {\n    println!(\"{key} -> {value}\");\n}\n\n// \u5355\u72ec\u904d\u5386\u952e Key\nfor key in map.keys() {\n    println!(\"{key}\");\n}\n\n// \u5355\u72ec\u904d\u5386\u503c Value\nfor value in map.values() {\n    println!(\"{value}\");\n}\n
    hash_map.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u54c8\u5e0c\u8868\n
    hash_map.kt
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor ((key, value) in map) {\n    println(\"$key -> $value\")\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nfor (key in map.keys) {\n    println(key)\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nfor (_val in map.values) {\n    println(_val)\n}\n
    hash_map.rb
    # \u904d\u5386\u54c8\u5e0c\u8868\n# \u904d\u5386\u952e\u503c\u5bf9 key->value\nhmap.entries.each { |key, value| puts \"#{key} -> #{value}\" }\n\n# \u5355\u72ec\u904d\u5386\u952e key\nhmap.keys.each { |key| puts key }\n\n# \u5355\u72ec\u904d\u5386\u503c value\nhmap.values.each { |val| puts val }\n
    hash_map.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_hashing/hash_map/#612","title":"6.1.2 \u00a0 \u54c8\u5e0c\u8868\u7b80\u5355\u5b9e\u73b0","text":"

    \u6211\u4eec\u5148\u8003\u8651\u6700\u7b80\u5355\u7684\u60c5\u51b5\uff0c\u4ec5\u7528\u4e00\u4e2a\u6570\u7ec4\u6765\u5b9e\u73b0\u54c8\u5e0c\u8868\u3002\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u6211\u4eec\u5c06\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u7a7a\u4f4d\u79f0\u4e3a\u6876\uff08bucket\uff09\uff0c\u6bcf\u4e2a\u6876\u53ef\u5b58\u50a8\u4e00\u4e2a\u952e\u503c\u5bf9\u3002\u56e0\u6b64\uff0c\u67e5\u8be2\u64cd\u4f5c\u5c31\u662f\u627e\u5230 key \u5bf9\u5e94\u7684\u6876\uff0c\u5e76\u5728\u6876\u4e2d\u83b7\u53d6 value \u3002

    \u90a3\u4e48\uff0c\u5982\u4f55\u57fa\u4e8e key \u5b9a\u4f4d\u5bf9\u5e94\u7684\u6876\u5462\uff1f\u8fd9\u662f\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\uff08hash function\uff09\u5b9e\u73b0\u7684\u3002\u54c8\u5e0c\u51fd\u6570\u7684\u4f5c\u7528\u662f\u5c06\u4e00\u4e2a\u8f83\u5927\u7684\u8f93\u5165\u7a7a\u95f4\u6620\u5c04\u5230\u4e00\u4e2a\u8f83\u5c0f\u7684\u8f93\u51fa\u7a7a\u95f4\u3002\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u8f93\u5165\u7a7a\u95f4\u662f\u6240\u6709 key \uff0c\u8f93\u51fa\u7a7a\u95f4\u662f\u6240\u6709\u6876\uff08\u6570\u7ec4\u7d22\u5f15\uff09\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u8f93\u5165\u4e00\u4e2a key \uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u5f97\u5230\u8be5 key \u5bf9\u5e94\u7684\u952e\u503c\u5bf9\u5728\u6570\u7ec4\u4e2d\u7684\u5b58\u50a8\u4f4d\u7f6e\u3002

    \u8f93\u5165\u4e00\u4e2a key \uff0c\u54c8\u5e0c\u51fd\u6570\u7684\u8ba1\u7b97\u8fc7\u7a0b\u5206\u4e3a\u4ee5\u4e0b\u4e24\u6b65\u3002

    1. \u901a\u8fc7\u67d0\u79cd\u54c8\u5e0c\u7b97\u6cd5 hash() \u8ba1\u7b97\u5f97\u5230\u54c8\u5e0c\u503c\u3002
    2. \u5c06\u54c8\u5e0c\u503c\u5bf9\u6876\u6570\u91cf\uff08\u6570\u7ec4\u957f\u5ea6\uff09capacity \u53d6\u6a21\uff0c\u4ece\u800c\u83b7\u53d6\u8be5 key \u5bf9\u5e94\u7684\u6570\u7ec4\u7d22\u5f15 index \u3002
    index = hash(key) % capacity\n

    \u968f\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5229\u7528 index \u5728\u54c8\u5e0c\u8868\u4e2d\u8bbf\u95ee\u5bf9\u5e94\u7684\u6876\uff0c\u4ece\u800c\u83b7\u53d6 value \u3002

    \u8bbe\u6570\u7ec4\u957f\u5ea6 capacity = 100\u3001\u54c8\u5e0c\u7b97\u6cd5 hash(key) = key \uff0c\u6613\u5f97\u54c8\u5e0c\u51fd\u6570\u4e3a key % 100 \u3002\u56fe 6-2 \u4ee5 key \u5b66\u53f7\u548c value \u59d3\u540d\u4e3a\u4f8b\uff0c\u5c55\u793a\u4e86\u54c8\u5e0c\u51fd\u6570\u7684\u5de5\u4f5c\u539f\u7406\u3002

    \u56fe 6-2 \u00a0 \u54c8\u5e0c\u51fd\u6570\u5de5\u4f5c\u539f\u7406

    \u4ee5\u4e0b\u4ee3\u7801\u5b9e\u73b0\u4e86\u4e00\u4e2a\u7b80\u5355\u54c8\u5e0c\u8868\u3002\u5176\u4e2d\uff0c\u6211\u4eec\u5c06 key \u548c value \u5c01\u88c5\u6210\u4e00\u4e2a\u7c7b Pair \uff0c\u4ee5\u8868\u793a\u952e\u503c\u5bf9\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_hash_map.py
    class Pair:\n    \"\"\"\u952e\u503c\u5bf9\"\"\"\n\n    def __init__(self, key: int, val: str):\n        self.key = key\n        self.val = val\n\nclass ArrayHashMap:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        self.buckets: list[Pair | None] = [None] * 100\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        index = key % 100\n        return index\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        pair: Pair = self.buckets[index]\n        if pair is None:\n            return None\n        return pair.val\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        pair = Pair(key, val)\n        index: int = self.hash_func(key)\n        self.buckets[index] = pair\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        # \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None\n\n    def entry_set(self) -> list[Pair]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\"\"\"\n        result: list[Pair] = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair)\n        return result\n\n    def key_set(self) -> list[int]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.key)\n        return result\n\n    def value_set(self) -> list[str]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u503c\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.val)\n        return result\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is not None:\n                print(pair.key, \"->\", pair.val)\n
    array_hash_map.cpp
    /* \u952e\u503c\u5bf9 */\nstruct Pair {\n  public:\n    int key;\n    string val;\n    Pair(int key, string val) {\n        this->key = key;\n        this->val = val;\n    }\n};\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  private:\n    vector<Pair *> buckets;\n\n  public:\n    ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = vector<Pair *>(100);\n    }\n\n    ~ArrayHashMap() {\n        // \u91ca\u653e\u5185\u5b58\n        for (const auto &bucket : buckets) {\n            delete bucket;\n        }\n        buckets.clear();\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        Pair *pair = buckets[index];\n        if (pair == nullptr)\n            return \"\";\n        return pair->val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        Pair *pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        // \u91ca\u653e\u5185\u5b58\u5e76\u7f6e\u4e3a nullptr\n        delete buckets[index];\n        buckets[index] = nullptr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    vector<Pair *> pairSet() {\n        vector<Pair *> pairSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                pairSet.push_back(pair);\n            }\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    vector<int> keySet() {\n        vector<int> keySet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                keySet.push_back(pair->key);\n            }\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    vector<string> valueSet() {\n        vector<string> valueSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                valueSet.push_back(pair->val);\n            }\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *kv : pairSet()) {\n            cout << kv->key << \" -> \" << kv->val << endl;\n        }\n    }\n};\n
    array_hash_map.java
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n    public int key;\n    public String val;\n\n    public Pair(int key, String val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private List<Pair> buckets;\n\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = new ArrayList<>();\n        for (int i = 0; i < 100; i++) {\n            buckets.add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        int index = hashFunc(key);\n        Pair pair = buckets.get(index);\n        if (pair == null)\n            return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        Pair pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets.set(index, pair);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        int index = hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets.set(index, null);\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> pairSet() {\n        List<Pair> pairSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                pairSet.add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<Integer> keySet() {\n        List<Integer> keySet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                keySet.add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<String> valueSet() {\n        List<String> valueSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                valueSet.add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair kv : pairSet()) {\n            System.out.println(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.cs
    /* \u952e\u503c\u5bf9 int->string */\nclass Pair(int key, string val) {\n    public int key = key;\n    public string val = val;\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    List<Pair?> buckets;\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = [];\n        for (int i = 0; i < 100; i++) {\n            buckets.Add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        Pair? pair = buckets[index];\n        if (pair == null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        Pair pair = new(key, val);\n        int index = HashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> PairSet() {\n        List<Pair> pairSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                pairSet.Add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<int> KeySet() {\n        List<int> keySet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                keySet.Add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<string> ValueSet() {\n        List<string> valueSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                valueSet.Add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair kv in PairSet()) {\n            Console.WriteLine(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.go
    /* \u952e\u503c\u5bf9 */\ntype pair struct {\n    key int\n    val string\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntype arrayHashMap struct {\n    buckets []*pair\n}\n\n/* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nfunc newArrayHashMap() *arrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    buckets := make([]*pair, 100)\n    return &arrayHashMap{buckets: buckets}\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (a *arrayHashMap) hashFunc(key int) int {\n    index := key % 100\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (a *arrayHashMap) get(key int) string {\n    index := a.hashFunc(key)\n    pair := a.buckets[index]\n    if pair == nil {\n        return \"Not Found\"\n    }\n    return pair.val\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (a *arrayHashMap) put(key int, val string) {\n    pair := &pair{key: key, val: val}\n    index := a.hashFunc(key)\n    a.buckets[index] = pair\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (a *arrayHashMap) remove(key int) {\n    index := a.hashFunc(key)\n    // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    a.buckets[index] = nil\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u5bf9 */\nfunc (a *arrayHashMap) pairSet() []*pair {\n    var pairs []*pair\n    for _, pair := range a.buckets {\n        if pair != nil {\n            pairs = append(pairs, pair)\n        }\n    }\n    return pairs\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nfunc (a *arrayHashMap) keySet() []int {\n    var keys []int\n    for _, pair := range a.buckets {\n        if pair != nil {\n            keys = append(keys, pair.key)\n        }\n    }\n    return keys\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nfunc (a *arrayHashMap) valueSet() []string {\n    var values []string\n    for _, pair := range a.buckets {\n        if pair != nil {\n            values = append(values, pair.val)\n        }\n    }\n    return values\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (a *arrayHashMap) print() {\n    for _, pair := range a.buckets {\n        if pair != nil {\n            fmt.Println(pair.key, \"->\", pair.val)\n        }\n    }\n}\n
    array_hash_map.swift
    /* \u952e\u503c\u5bf9 */\nclass Pair: Equatable {\n    public var key: Int\n    public var val: String\n\n    public init(key: Int, val: String) {\n        self.key = key\n        self.val = val\n    }\n\n    public static func == (lhs: Pair, rhs: Pair) -> Bool {\n        lhs.key == rhs.key && lhs.val == rhs.val\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private var buckets: [Pair?]\n\n    init() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = Array(repeating: nil, count: 100)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private func hashFunc(key: Int) -> Int {\n        let index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let pair = buckets[index]\n        return pair?.val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        let pair = Pair(key: key, val: val)\n        let index = hashFunc(key: key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = nil\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    func pairSet() -> [Pair] {\n        buckets.compactMap { $0 }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    func keySet() -> [Int] {\n        buckets.compactMap { $0?.key }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    func valueSet() -> [String] {\n        buckets.compactMap { $0?.val }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in pairSet() {\n            Swift.print(\"\\(pair.key) -> \\(pair.val)\")\n        }\n    }\n}\n
    array_hash_map.js
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    constructor(key, val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    #buckets;\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.#buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        let index = this.#hashFunc(key);\n        let pair = this.#buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    set(key, val) {\n        let index = this.#hashFunc(key);\n        this.#buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    delete(key) {\n        let index = this.#hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.#buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    entries() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    keys() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    values() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.ts
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    public key: number;\n    public val: string;\n\n    constructor(key: number, val: string) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private readonly buckets: (Pair | null)[];\n\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public get(key: number): string | null {\n        let index = this.hashFunc(key);\n        let pair = this.buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public set(key: number, val: string) {\n        let index = this.hashFunc(key);\n        this.buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public delete(key: number) {\n        let index = this.hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public entries(): (Pair | null)[] {\n        let arr: (Pair | null)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public keys(): (number | undefined)[] {\n        let arr: (number | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public values(): (string | undefined)[] {\n        let arr: (string | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.dart
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n  int key;\n  String val;\n  Pair(this.key, this.val);\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  late List<Pair?> _buckets;\n\n  ArrayHashMap() {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    _buckets = List.filled(100, null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int _hashFunc(int key) {\n    final int index = key % 100;\n    return index;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    final int index = _hashFunc(key);\n    final Pair? pair = _buckets[index];\n    if (pair == null) {\n      return null;\n    }\n    return pair.val;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    final Pair pair = Pair(key, val);\n    final int index = _hashFunc(key);\n    _buckets[index] = pair;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    final int index = _hashFunc(key);\n    _buckets[index] = null;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n  List<Pair> pairSet() {\n    List<Pair> pairSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        pairSet.add(pair);\n      }\n    }\n    return pairSet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e */\n  List<int> keySet() {\n    List<int> keySet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        keySet.add(pair.key);\n      }\n    }\n    return keySet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u503c */\n  List<String> values() {\n    List<String> valueSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        valueSet.add(pair.val);\n      }\n    }\n    return valueSet;\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (final Pair kv in pairSet()) {\n      print(\"${kv.key} -> ${kv.val}\");\n    }\n  }\n}\n
    array_hash_map.rs
    /* \u952e\u503c\u5bf9 */\n#[derive(Debug, Clone, PartialEq)]\npub struct Pair {\n    pub key: i32,\n    pub val: String,\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\npub struct ArrayHashMap {\n    buckets: Vec<Option<Pair>>,\n}\n\nimpl ArrayHashMap {\n    pub fn new() -> ArrayHashMap {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        Self {\n            buckets: vec![None; 100],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % 100\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    pub fn get(&self, key: i32) -> Option<&String> {\n        let index = self.hash_func(key);\n        self.buckets[index].as_ref().map(|pair| &pair.val)\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    pub fn put(&mut self, key: i32, val: &str) {\n        let index = self.hash_func(key);\n        self.buckets[index] = Some(Pair {\n            key,\n            val: val.to_string(),\n        });\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    pub fn remove(&mut self, key: i32) {\n        let index = self.hash_func(key);\n        // \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    pub fn entry_set(&self) -> Vec<&Pair> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref())\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    pub fn key_set(&self) -> Vec<&i32> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.key))\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    pub fn value_set(&self) -> Vec<&String> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.val))\n            .collect()\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    pub fn print(&self) {\n        for pair in self.entry_set() {\n            println!(\"{} -> {}\", pair.key, pair.val);\n        }\n    }\n}\n
    array_hash_map.c
    /* \u952e\u503c\u5bf9 int->string */\ntypedef struct {\n    int key;\n    char *val;\n} Pair;\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntypedef struct {\n    Pair *buckets[MAX_SIZE];\n} ArrayHashMap;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayHashMap *newArrayHashMap() {\n    ArrayHashMap *hmap = malloc(sizeof(ArrayHashMap));\n    for (int i=0; i < MAX_SIZE; i++) {\n        hmap->buckets[i] = NULL;\n    }\n    return hmap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayHashMap(ArrayHashMap *hmap) {\n    for (int i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            free(hmap->buckets[i]->val);\n            free(hmap->buckets[i]);\n        }\n    }\n    free(hmap);\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(ArrayHashMap *hmap, const int key, const char *val) {\n    Pair *Pair = malloc(sizeof(Pair));\n    Pair->key = key;\n    Pair->val = malloc(strlen(val) + 1);\n    strcpy(Pair->val, val);\n\n    int index = hashFunc(key);\n    hmap->buckets[index] = Pair;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(ArrayHashMap *hmap, const int key) {\n    int index = hashFunc(key);\n    free(hmap->buckets[index]->val);\n    free(hmap->buckets[index]);\n    hmap->buckets[index] = NULL;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\nvoid pairSet(ArrayHashMap *hmap, MapSet *set) {\n    Pair *entries;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    entries = malloc(sizeof(Pair) * total);\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            entries[index].key = hmap->buckets[i]->key;\n            entries[index].val = malloc(strlen(hmap->buckets[i]->val) + 1);\n            strcpy(entries[index].val, hmap->buckets[i]->val);\n            index++;\n        }\n    }\n    set->set = entries;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nvoid keySet(ArrayHashMap *hmap, MapSet *set) {\n    int *keys;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    keys = malloc(total * sizeof(int));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            keys[index] = hmap->buckets[i]->key;\n            index++;\n        }\n    }\n    set->set = keys;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nvoid valueSet(ArrayHashMap *hmap, MapSet *set) {\n    char **vals;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    vals = malloc(total * sizeof(char *));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            vals[index] = hmap->buckets[i]->val;\n            index++;\n        }\n    }\n    set->set = vals;\n    set->len = total;\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(ArrayHashMap *hmap) {\n    int i;\n    MapSet set;\n    pairSet(hmap, &set);\n    Pair *entries = (Pair *)set.set;\n    for (i = 0; i < set.len; i++) {\n        printf(\"%d -> %s\\n\", entries[i].key, entries[i].val);\n    }\n    free(set.set);\n}\n
    array_hash_map.kt
    /* \u952e\u503c\u5bf9 */\nclass Pair(\n    var key: Int,\n    var _val: String\n)\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    private val buckets = arrayOfNulls<Pair>(100)\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        val index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val pair = buckets[index] ?: return null\n        return pair._val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        val pair = Pair(key, _val)\n        val index = hashFunc(key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    fun pairSet(): MutableList<Pair> {\n        val pairSet = mutableListOf<Pair>()\n        for (pair in buckets) {\n            if (pair != null)\n                pairSet.add(pair)\n        }\n        return pairSet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    fun keySet(): MutableList<Int> {\n        val keySet = mutableListOf<Int>()\n        for (pair in buckets) {\n            if (pair != null)\n                keySet.add(pair.key)\n        }\n        return keySet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    fun valueSet(): MutableList<String> {\n        val valueSet = mutableListOf<String>()\n        for (pair in buckets) {\n            if (pair != null)\n                valueSet.add(pair._val)\n        }\n        return valueSet\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (kv in pairSet()) {\n            val key = kv.key\n            val _val = kv._val\n            println(\"$key -> $_val\")\n        }\n    }\n}\n
    array_hash_map.rb
    ### \u952e\u503c\u5bf9 ###\nclass Pair\n  attr_accessor :key, :val\n\n  def initialize(key, val)\n    @key = key\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 ###\nclass ArrayHashMap\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    @buckets = Array.new(100)\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    index = key % 100\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    pair = @buckets[index]\n\n    return if pair.nil?\n    pair.val\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    pair = Pair.new(key, val)\n    index = hash_func(key)\n    @buckets[index] = pair\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    # \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    @buckets[index] = nil\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 ###\n  def entry_set\n    result = []\n    @buckets.each { |pair| result << pair unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e ###\n  def key_set\n    result = []\n    @buckets.each { |pair| result << pair.key unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u503c ###\n  def value_set\n    result = []\n    @buckets.each { |pair| result << pair.val unless pair.nil? }\n    result\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    @buckets.each { |pair| puts \"#{pair.key} -> #{pair.val}\" unless pair.nil? }\n  end\nend\n
    array_hash_map.zig
    // \u952e\u503c\u5bf9\nconst Pair = struct {\n    key: usize = undefined,\n    val: []const u8 = undefined,\n\n   pub fn init(key: usize, val: []const u8) Pair {\n        return Pair {\n            .key = key,\n            .val = val,\n        };\n    }\n};\n\n// \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\nfn ArrayHashMap(comptime T: type) type {\n    return struct {\n        bucket: ?std.ArrayList(?T) = null,\n        mem_allocator: std.mem.Allocator = undefined,\n\n        const Self = @This();\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            self.mem_allocator = allocator;\n            // \u521d\u59cb\u5316\u4e00\u4e2a\u957f\u5ea6\u4e3a 100 \u7684\u6876\uff08\u6570\u7ec4\uff09\n            self.bucket = std.ArrayList(?T).init(self.mem_allocator);\n            var i: i32 = 0;\n            while (i < 100) : (i += 1) {\n                try self.bucket.?.append(null);\n            }\n        }\n\n        // \u6790\u6784\u51fd\u6570\n        pub fn deinit(self: *Self) void {\n            if (self.bucket != null) self.bucket.?.deinit();\n        }\n\n        // \u54c8\u5e0c\u51fd\u6570\n        fn hashFunc(key: usize) usize {\n            var index = key % 100;\n            return index;\n        }\n\n        // \u67e5\u8be2\u64cd\u4f5c\n        pub fn get(self: *Self, key: usize) []const u8 {\n            var index = hashFunc(key);\n            var pair = self.bucket.?.items[index];\n            return pair.?.val;\n        }\n\n        // \u6dfb\u52a0\u64cd\u4f5c\n        pub fn put(self: *Self, key: usize, val: []const u8) !void {\n            var pair = Pair.init(key, val);\n            var index = hashFunc(key);\n            self.bucket.?.items[index] = pair;\n        }\n\n        // \u5220\u9664\u64cd\u4f5c\n        pub fn remove(self: *Self, key: usize) !void {\n            var index = hashFunc(key);\n            // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n            self.bucket.?.items[index] = null;\n        }       \n\n        // \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\n        pub fn pairSet(self: *Self) !std.ArrayList(T) {\n            var entry_set = std.ArrayList(T).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try entry_set.append(item.?);\n            }\n            return entry_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u952e\n        pub fn keySet(self: *Self) !std.ArrayList(usize) {\n            var key_set = std.ArrayList(usize).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try key_set.append(item.?.key);\n            }\n            return key_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u503c\n        pub fn valueSet(self: *Self) !std.ArrayList([]const u8) {\n            var value_set = std.ArrayList([]const u8).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try value_set.append(item.?.val);\n            }\n            return value_set;\n        }\n\n        // \u6253\u5370\u54c8\u5e0c\u8868\n        pub fn print(self: *Self) !void {\n            var entry_set = try self.pairSet();\n            defer entry_set.deinit();\n            for (entry_set.items) |item| {\n                std.debug.print(\"{} -> {s}\\n\", .{item.key, item.val});\n            }\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_hashing/hash_map/#613","title":"6.1.3 \u00a0 \u54c8\u5e0c\u51b2\u7a81\u4e0e\u6269\u5bb9","text":"

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u54c8\u5e0c\u51fd\u6570\u7684\u4f5c\u7528\u662f\u5c06\u6240\u6709 key \u6784\u6210\u7684\u8f93\u5165\u7a7a\u95f4\u6620\u5c04\u5230\u6570\u7ec4\u6240\u6709\u7d22\u5f15\u6784\u6210\u7684\u8f93\u51fa\u7a7a\u95f4\uff0c\u800c\u8f93\u5165\u7a7a\u95f4\u5f80\u5f80\u8fdc\u5927\u4e8e\u8f93\u51fa\u7a7a\u95f4\u3002\u56e0\u6b64\uff0c\u7406\u8bba\u4e0a\u4e00\u5b9a\u5b58\u5728\u201c\u591a\u4e2a\u8f93\u5165\u5bf9\u5e94\u76f8\u540c\u8f93\u51fa\u201d\u7684\u60c5\u51b5\u3002

    \u5bf9\u4e8e\u4e0a\u8ff0\u793a\u4f8b\u4e2d\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u5f53\u8f93\u5165\u7684 key \u540e\u4e24\u4f4d\u76f8\u540c\u65f6\uff0c\u54c8\u5e0c\u51fd\u6570\u7684\u8f93\u51fa\u7ed3\u679c\u4e5f\u76f8\u540c\u3002\u4f8b\u5982\uff0c\u67e5\u8be2\u5b66\u53f7\u4e3a 12836 \u548c 20336 \u7684\u4e24\u4e2a\u5b66\u751f\u65f6\uff0c\u6211\u4eec\u5f97\u5230\uff1a

    12836 % 100 = 36\n20336 % 100 = 36\n

    \u5982\u56fe 6-3 \u6240\u793a\uff0c\u4e24\u4e2a\u5b66\u53f7\u6307\u5411\u4e86\u540c\u4e00\u4e2a\u59d3\u540d\uff0c\u8fd9\u663e\u7136\u662f\u4e0d\u5bf9\u7684\u3002\u6211\u4eec\u5c06\u8fd9\u79cd\u591a\u4e2a\u8f93\u5165\u5bf9\u5e94\u540c\u4e00\u8f93\u51fa\u7684\u60c5\u51b5\u79f0\u4e3a\u54c8\u5e0c\u51b2\u7a81\uff08hash collision\uff09\u3002

    \u56fe 6-3 \u00a0 \u54c8\u5e0c\u51b2\u7a81\u793a\u4f8b

    \u5bb9\u6613\u60f3\u5230\uff0c\u54c8\u5e0c\u8868\u5bb9\u91cf \\(n\\) \u8d8a\u5927\uff0c\u591a\u4e2a key \u88ab\u5206\u914d\u5230\u540c\u4e00\u4e2a\u6876\u4e2d\u7684\u6982\u7387\u5c31\u8d8a\u4f4e\uff0c\u51b2\u7a81\u5c31\u8d8a\u5c11\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6269\u5bb9\u54c8\u5e0c\u8868\u6765\u51cf\u5c11\u54c8\u5e0c\u51b2\u7a81\u3002

    \u5982\u56fe 6-4 \u6240\u793a\uff0c\u6269\u5bb9\u524d\u952e\u503c\u5bf9 (136, A) \u548c (236, D) \u53d1\u751f\u51b2\u7a81\uff0c\u6269\u5bb9\u540e\u51b2\u7a81\u6d88\u5931\u3002

    \u56fe 6-4 \u00a0 \u54c8\u5e0c\u8868\u6269\u5bb9

    \u7c7b\u4f3c\u4e8e\u6570\u7ec4\u6269\u5bb9\uff0c\u54c8\u5e0c\u8868\u6269\u5bb9\u9700\u5c06\u6240\u6709\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u8fc1\u79fb\u81f3\u65b0\u54c8\u5e0c\u8868\uff0c\u975e\u5e38\u8017\u65f6\uff1b\u5e76\u4e14\u7531\u4e8e\u54c8\u5e0c\u8868\u5bb9\u91cf capacity \u6539\u53d8\uff0c\u6211\u4eec\u9700\u8981\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u6765\u91cd\u65b0\u8ba1\u7b97\u6240\u6709\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u4f4d\u7f6e\uff0c\u8fd9\u8fdb\u4e00\u6b65\u589e\u52a0\u4e86\u6269\u5bb9\u8fc7\u7a0b\u7684\u8ba1\u7b97\u5f00\u9500\u3002\u4e3a\u6b64\uff0c\u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u4f1a\u9884\u7559\u8db3\u591f\u5927\u7684\u54c8\u5e0c\u8868\u5bb9\u91cf\uff0c\u9632\u6b62\u9891\u7e41\u6269\u5bb9\u3002

    \u8d1f\u8f7d\u56e0\u5b50\uff08load factor\uff09\u662f\u54c8\u5e0c\u8868\u7684\u4e00\u4e2a\u91cd\u8981\u6982\u5ff5\uff0c\u5176\u5b9a\u4e49\u4e3a\u54c8\u5e0c\u8868\u7684\u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u6570\u91cf\uff0c\u7528\u4e8e\u8861\u91cf\u54c8\u5e0c\u51b2\u7a81\u7684\u4e25\u91cd\u7a0b\u5ea6\uff0c\u4e5f\u5e38\u4f5c\u4e3a\u54c8\u5e0c\u8868\u6269\u5bb9\u7684\u89e6\u53d1\u6761\u4ef6\u3002\u4f8b\u5982\u5728 Java \u4e2d\uff0c\u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7 \\(0.75\\) \u65f6\uff0c\u7cfb\u7edf\u4f1a\u5c06\u54c8\u5e0c\u8868\u6269\u5bb9\u81f3\u539f\u5148\u7684 \\(2\\) \u500d\u3002

    "},{"location":"chapter_hashing/summary/","title":"6.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_hashing/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u8f93\u5165 key \uff0c\u54c8\u5e0c\u8868\u80fd\u591f\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u67e5\u8be2\u5230 value \uff0c\u6548\u7387\u975e\u5e38\u9ad8\u3002
    • \u5e38\u89c1\u7684\u54c8\u5e0c\u8868\u64cd\u4f5c\u5305\u62ec\u67e5\u8be2\u3001\u6dfb\u52a0\u952e\u503c\u5bf9\u3001\u5220\u9664\u952e\u503c\u5bf9\u548c\u904d\u5386\u54c8\u5e0c\u8868\u7b49\u3002
    • \u54c8\u5e0c\u51fd\u6570\u5c06 key \u6620\u5c04\u4e3a\u6570\u7ec4\u7d22\u5f15\uff0c\u4ece\u800c\u8bbf\u95ee\u5bf9\u5e94\u6876\u5e76\u83b7\u53d6 value \u3002
    • \u4e24\u4e2a\u4e0d\u540c\u7684 key \u53ef\u80fd\u5728\u7ecf\u8fc7\u54c8\u5e0c\u51fd\u6570\u540e\u5f97\u5230\u76f8\u540c\u7684\u6570\u7ec4\u7d22\u5f15\uff0c\u5bfc\u81f4\u67e5\u8be2\u7ed3\u679c\u51fa\u9519\uff0c\u8fd9\u79cd\u73b0\u8c61\u88ab\u79f0\u4e3a\u54c8\u5e0c\u51b2\u7a81\u3002
    • \u54c8\u5e0c\u8868\u5bb9\u91cf\u8d8a\u5927\uff0c\u54c8\u5e0c\u51b2\u7a81\u7684\u6982\u7387\u5c31\u8d8a\u4f4e\u3002\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u6269\u5bb9\u54c8\u5e0c\u8868\u6765\u7f13\u89e3\u54c8\u5e0c\u51b2\u7a81\u3002\u4e0e\u6570\u7ec4\u6269\u5bb9\u7c7b\u4f3c\uff0c\u54c8\u5e0c\u8868\u6269\u5bb9\u64cd\u4f5c\u7684\u5f00\u9500\u5f88\u5927\u3002
    • \u8d1f\u8f7d\u56e0\u5b50\u5b9a\u4e49\u4e3a\u54c8\u5e0c\u8868\u4e2d\u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u6570\u91cf\uff0c\u53cd\u6620\u4e86\u54c8\u5e0c\u51b2\u7a81\u7684\u4e25\u91cd\u7a0b\u5ea6\uff0c\u5e38\u7528\u4f5c\u89e6\u53d1\u54c8\u5e0c\u8868\u6269\u5bb9\u7684\u6761\u4ef6\u3002
    • \u94fe\u5f0f\u5730\u5740\u901a\u8fc7\u5c06\u5355\u4e2a\u5143\u7d20\u8f6c\u5316\u4e3a\u94fe\u8868\uff0c\u5c06\u6240\u6709\u51b2\u7a81\u5143\u7d20\u5b58\u50a8\u5728\u540c\u4e00\u4e2a\u94fe\u8868\u4e2d\u3002\u7136\u800c\uff0c\u94fe\u8868\u8fc7\u957f\u4f1a\u964d\u4f4e\u67e5\u8be2\u6548\u7387\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fdb\u4e00\u6b65\u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u6765\u63d0\u9ad8\u6548\u7387\u3002
    • \u5f00\u653e\u5bfb\u5740\u901a\u8fc7\u591a\u6b21\u63a2\u6d4b\u6765\u5904\u7406\u54c8\u5e0c\u51b2\u7a81\u3002\u7ebf\u6027\u63a2\u6d4b\u4f7f\u7528\u56fa\u5b9a\u6b65\u957f\uff0c\u7f3a\u70b9\u662f\u4e0d\u80fd\u5220\u9664\u5143\u7d20\uff0c\u4e14\u5bb9\u6613\u4ea7\u751f\u805a\u96c6\u3002\u591a\u6b21\u54c8\u5e0c\u4f7f\u7528\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570\u8fdb\u884c\u63a2\u6d4b\uff0c\u76f8\u8f83\u7ebf\u6027\u63a2\u6d4b\u66f4\u4e0d\u6613\u4ea7\u751f\u805a\u96c6\uff0c\u4f46\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570\u589e\u52a0\u4e86\u8ba1\u7b97\u91cf\u3002
    • \u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u91c7\u53d6\u4e86\u4e0d\u540c\u7684\u54c8\u5e0c\u8868\u5b9e\u73b0\u3002\u4f8b\u5982\uff0cJava \u7684 HashMap \u4f7f\u7528\u94fe\u5f0f\u5730\u5740\uff0c\u800c Python \u7684 Dict \u91c7\u7528\u5f00\u653e\u5bfb\u5740\u3002
    • \u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u6211\u4eec\u5e0c\u671b\u54c8\u5e0c\u7b97\u6cd5\u5177\u6709\u786e\u5b9a\u6027\u3001\u9ad8\u6548\u7387\u548c\u5747\u5300\u5206\u5e03\u7684\u7279\u70b9\u3002\u5728\u5bc6\u7801\u5b66\u4e2d\uff0c\u54c8\u5e0c\u7b97\u6cd5\u8fd8\u5e94\u8be5\u5177\u5907\u6297\u78b0\u649e\u6027\u548c\u96ea\u5d29\u6548\u5e94\u3002
    • \u54c8\u5e0c\u7b97\u6cd5\u901a\u5e38\u91c7\u7528\u5927\u8d28\u6570\u4f5c\u4e3a\u6a21\u6570\uff0c\u4ee5\u6700\u5927\u5316\u5730\u4fdd\u8bc1\u54c8\u5e0c\u503c\u5747\u5300\u5206\u5e03\uff0c\u51cf\u5c11\u54c8\u5e0c\u51b2\u7a81\u3002
    • \u5e38\u89c1\u7684\u54c8\u5e0c\u7b97\u6cd5\u5305\u62ec MD5\u3001SHA-1\u3001SHA-2 \u548c SHA-3 \u7b49\u3002MD5 \u5e38\u7528\u4e8e\u6821\u9a8c\u6587\u4ef6\u5b8c\u6574\u6027\uff0cSHA-2 \u5e38\u7528\u4e8e\u5b89\u5168\u5e94\u7528\u4e0e\u534f\u8bae\u3002
    • \u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u4f1a\u4e3a\u6570\u636e\u7c7b\u578b\u63d0\u4f9b\u5185\u7f6e\u54c8\u5e0c\u7b97\u6cd5\uff0c\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u8868\u4e2d\u7684\u6876\u7d22\u5f15\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u53ea\u6709\u4e0d\u53ef\u53d8\u5bf9\u8c61\u662f\u53ef\u54c8\u5e0c\u7684\u3002
    "},{"location":"chapter_hashing/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u662f \\(O(n)\\) \uff1f

    \u5f53\u54c8\u5e0c\u51b2\u7a81\u6bd4\u8f83\u4e25\u91cd\u65f6\uff0c\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u9000\u5316\u81f3 \\(O(n)\\) \u3002\u5f53\u54c8\u5e0c\u51fd\u6570\u8bbe\u8ba1\u5f97\u6bd4\u8f83\u597d\u3001\u5bb9\u91cf\u8bbe\u7f6e\u6bd4\u8f83\u5408\u7406\u3001\u51b2\u7a81\u6bd4\u8f83\u5e73\u5747\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u3002\u6211\u4eec\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u5185\u7f6e\u7684\u54c8\u5e0c\u8868\u65f6\uff0c\u901a\u5e38\u8ba4\u4e3a\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u4e0d\u4f7f\u7528\u54c8\u5e0c\u51fd\u6570 \\(f(x) = x\\) \u5462\uff1f\u8fd9\u6837\u5c31\u4e0d\u4f1a\u6709\u51b2\u7a81\u4e86\u3002

    \u5728 \\(f(x) = x\\) \u54c8\u5e0c\u51fd\u6570\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u5bf9\u5e94\u552f\u4e00\u7684\u6876\u7d22\u5f15\uff0c\u8fd9\u4e0e\u6570\u7ec4\u7b49\u4ef7\u3002\u7136\u800c\uff0c\u8f93\u5165\u7a7a\u95f4\u901a\u5e38\u8fdc\u5927\u4e8e\u8f93\u51fa\u7a7a\u95f4\uff08\u6570\u7ec4\u957f\u5ea6\uff09\uff0c\u56e0\u6b64\u54c8\u5e0c\u51fd\u6570\u7684\u6700\u540e\u4e00\u6b65\u5f80\u5f80\u662f\u5bf9\u6570\u7ec4\u957f\u5ea6\u53d6\u6a21\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u54c8\u5e0c\u8868\u7684\u76ee\u6807\u662f\u5c06\u4e00\u4e2a\u8f83\u5927\u7684\u72b6\u6001\u7a7a\u95f4\u6620\u5c04\u5230\u4e00\u4e2a\u8f83\u5c0f\u7684\u7a7a\u95f4\uff0c\u5e76\u63d0\u4f9b \\(O(1)\\) \u7684\u67e5\u8be2\u6548\u7387\u3002

    Q\uff1a\u54c8\u5e0c\u8868\u5e95\u5c42\u5b9e\u73b0\u662f\u6570\u7ec4\u3001\u94fe\u8868\u3001\u4e8c\u53c9\u6811\uff0c\u4f46\u4e3a\u4ec0\u4e48\u6548\u7387\u53ef\u4ee5\u6bd4\u5b83\u4eec\u66f4\u9ad8\u5462\uff1f

    \u9996\u5148\uff0c\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u6548\u7387\u53d8\u9ad8\uff0c\u4f46\u7a7a\u95f4\u6548\u7387\u53d8\u4f4e\u4e86\u3002\u54c8\u5e0c\u8868\u6709\u76f8\u5f53\u4e00\u90e8\u5206\u5185\u5b58\u672a\u4f7f\u7528\u3002

    \u5176\u6b21\uff0c\u53ea\u662f\u5728\u7279\u5b9a\u4f7f\u7528\u573a\u666f\u4e0b\u65f6\u95f4\u6548\u7387\u53d8\u9ad8\u4e86\u3002\u5982\u679c\u4e00\u4e2a\u529f\u80fd\u80fd\u591f\u5728\u76f8\u540c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e0b\u4f7f\u7528\u6570\u7ec4\u6216\u94fe\u8868\u5b9e\u73b0\uff0c\u90a3\u4e48\u901a\u5e38\u6bd4\u54c8\u5e0c\u8868\u66f4\u5feb\u3002\u8fd9\u662f\u56e0\u4e3a\u54c8\u5e0c\u51fd\u6570\u8ba1\u7b97\u9700\u8981\u5f00\u9500\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u7684\u5e38\u6570\u9879\u66f4\u5927\u3002

    \u6700\u540e\uff0c\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u80fd\u53d1\u751f\u52a3\u5316\u3002\u4f8b\u5982\u5728\u94fe\u5f0f\u5730\u5740\u4e2d\uff0c\u6211\u4eec\u91c7\u53d6\u5728\u94fe\u8868\u6216\u7ea2\u9ed1\u6811\u4e2d\u6267\u884c\u67e5\u627e\u64cd\u4f5c\uff0c\u4ecd\u7136\u6709\u9000\u5316\u81f3 \\(O(n)\\) \u65f6\u95f4\u7684\u98ce\u9669\u3002

    Q\uff1a\u591a\u6b21\u54c8\u5e0c\u6709\u4e0d\u80fd\u76f4\u63a5\u5220\u9664\u5143\u7d20\u7684\u7f3a\u9677\u5417\uff1f\u6807\u8bb0\u4e3a\u5df2\u5220\u9664\u7684\u7a7a\u95f4\u8fd8\u80fd\u518d\u6b21\u4f7f\u7528\u5417\uff1f

    \u591a\u6b21\u54c8\u5e0c\u662f\u5f00\u653e\u5bfb\u5740\u7684\u4e00\u79cd\uff0c\u5f00\u653e\u5bfb\u5740\u6cd5\u90fd\u6709\u4e0d\u80fd\u76f4\u63a5\u5220\u9664\u5143\u7d20\u7684\u7f3a\u9677\uff0c\u9700\u8981\u901a\u8fc7\u6807\u8bb0\u5220\u9664\u3002\u6807\u8bb0\u4e3a\u5df2\u5220\u9664\u7684\u7a7a\u95f4\u53ef\u4ee5\u518d\u6b21\u4f7f\u7528\u3002\u5f53\u5c06\u65b0\u5143\u7d20\u63d2\u5165\u54c8\u5e0c\u8868\uff0c\u5e76\u4e14\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u627e\u5230\u6807\u8bb0\u4e3a\u5df2\u5220\u9664\u7684\u4f4d\u7f6e\u65f6\uff0c\u8be5\u4f4d\u7f6e\u53ef\u4ee5\u88ab\u65b0\u5143\u7d20\u4f7f\u7528\u3002\u8fd9\u6837\u505a\u65e2\u80fd\u4fdd\u6301\u54c8\u5e0c\u8868\u7684\u63a2\u6d4b\u5e8f\u5217\u4e0d\u53d8\uff0c\u53c8\u80fd\u4fdd\u8bc1\u54c8\u5e0c\u8868\u7684\u7a7a\u95f4\u4f7f\u7528\u7387\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u5728\u7ebf\u6027\u63a2\u6d4b\u4e2d\uff0c\u67e5\u627e\u5143\u7d20\u7684\u65f6\u5019\u4f1a\u51fa\u73b0\u54c8\u5e0c\u51b2\u7a81\u5462\uff1f

    \u67e5\u627e\u7684\u65f6\u5019\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u627e\u5230\u5bf9\u5e94\u7684\u6876\u548c\u952e\u503c\u5bf9\uff0c\u53d1\u73b0 key \u4e0d\u5339\u914d\uff0c\u8fd9\u5c31\u4ee3\u8868\u6709\u54c8\u5e0c\u51b2\u7a81\u3002\u56e0\u6b64\uff0c\u7ebf\u6027\u63a2\u6d4b\u6cd5\u4f1a\u6839\u636e\u9884\u5148\u8bbe\u5b9a\u7684\u6b65\u957f\u4f9d\u6b21\u5411\u4e0b\u67e5\u627e\uff0c\u76f4\u81f3\u627e\u5230\u6b63\u786e\u7684\u952e\u503c\u5bf9\u6216\u65e0\u6cd5\u627e\u5230\u8df3\u51fa\u4e3a\u6b62\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u54c8\u5e0c\u8868\u6269\u5bb9\u80fd\u591f\u7f13\u89e3\u54c8\u5e0c\u51b2\u7a81\uff1f

    \u54c8\u5e0c\u51fd\u6570\u7684\u6700\u540e\u4e00\u6b65\u5f80\u5f80\u662f\u5bf9\u6570\u7ec4\u957f\u5ea6 \\(n\\) \u53d6\u6a21\uff08\u53d6\u4f59\uff09\uff0c\u8ba9\u8f93\u51fa\u503c\u843d\u5728\u6570\u7ec4\u7d22\u5f15\u8303\u56f4\u5185\uff1b\u5728\u6269\u5bb9\u540e\uff0c\u6570\u7ec4\u957f\u5ea6 \\(n\\) \u53d1\u751f\u53d8\u5316\uff0c\u800c key \u5bf9\u5e94\u7684\u7d22\u5f15\u4e5f\u53ef\u80fd\u53d1\u751f\u53d8\u5316\u3002\u539f\u5148\u843d\u5728\u540c\u4e00\u4e2a\u6876\u7684\u591a\u4e2a key \uff0c\u5728\u6269\u5bb9\u540e\u53ef\u80fd\u4f1a\u88ab\u5206\u914d\u5230\u591a\u4e2a\u6876\u4e2d\uff0c\u4ece\u800c\u5b9e\u73b0\u54c8\u5e0c\u51b2\u7a81\u7684\u7f13\u89e3\u3002

    "},{"location":"chapter_heap/","title":"\u7b2c 8 \u7ae0 \u00a0 \u5806","text":"

    Abstract

    \u5806\u5c31\u50cf\u662f\u5c71\u5cb3\u5cf0\u5ce6\uff0c\u5c42\u53e0\u8d77\u4f0f\u3001\u5f62\u6001\u5404\u5f02\u3002

    \u5ea7\u5ea7\u5c71\u5cf0\u9ad8\u4f4e\u9519\u843d\uff0c\u800c\u6700\u9ad8\u7684\u5c71\u5cf0\u603b\u662f\u6700\u5148\u6620\u5165\u773c\u5e18\u3002

    "},{"location":"chapter_heap/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 8.1 \u00a0 \u5806
    • 8.2 \u00a0 \u5efa\u5806\u64cd\u4f5c
    • 8.3 \u00a0 Top-k \u95ee\u9898
    • 8.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_heap/build_heap/","title":"8.2 \u00a0 \u5efa\u5806\u64cd\u4f5c","text":"

    \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5e0c\u671b\u4f7f\u7528\u4e00\u4e2a\u5217\u8868\u7684\u6240\u6709\u5143\u7d20\u6765\u6784\u5efa\u4e00\u4e2a\u5806\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u88ab\u79f0\u4e3a\u201c\u5efa\u5806\u64cd\u4f5c\u201d\u3002

    "},{"location":"chapter_heap/build_heap/#821","title":"8.2.1 \u00a0 \u501f\u52a9\u5165\u5806\u64cd\u4f5c\u5b9e\u73b0","text":"

    \u6211\u4eec\u9996\u5148\u521b\u5efa\u4e00\u4e2a\u7a7a\u5806\uff0c\u7136\u540e\u904d\u5386\u5217\u8868\uff0c\u4f9d\u6b21\u5bf9\u6bcf\u4e2a\u5143\u7d20\u6267\u884c\u201c\u5165\u5806\u64cd\u4f5c\u201d\uff0c\u5373\u5148\u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u5806\u7684\u5c3e\u90e8\uff0c\u518d\u5bf9\u8be5\u5143\u7d20\u6267\u884c\u201c\u4ece\u5e95\u81f3\u9876\u201d\u5806\u5316\u3002

    \u6bcf\u5f53\u4e00\u4e2a\u5143\u7d20\u5165\u5806\uff0c\u5806\u7684\u957f\u5ea6\u5c31\u52a0\u4e00\u3002\u7531\u4e8e\u8282\u70b9\u662f\u4ece\u9876\u5230\u5e95\u4f9d\u6b21\u88ab\u6dfb\u52a0\u8fdb\u4e8c\u53c9\u6811\u7684\uff0c\u56e0\u6b64\u5806\u662f\u201c\u81ea\u4e0a\u800c\u4e0b\u201d\u6784\u5efa\u7684\u3002

    \u8bbe\u5143\u7d20\u6570\u91cf\u4e3a \\(n\\) \uff0c\u6bcf\u4e2a\u5143\u7d20\u7684\u5165\u5806\u64cd\u4f5c\u4f7f\u7528 \\(O(\\log{n})\\) \u65f6\u95f4\uff0c\u56e0\u6b64\u8be5\u5efa\u5806\u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    "},{"location":"chapter_heap/build_heap/#822","title":"8.2.2 \u00a0 \u901a\u8fc7\u904d\u5386\u5806\u5316\u5b9e\u73b0","text":"

    \u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9e\u73b0\u4e00\u79cd\u66f4\u4e3a\u9ad8\u6548\u7684\u5efa\u5806\u65b9\u6cd5\uff0c\u5171\u5206\u4e3a\u4e24\u6b65\u3002

    1. \u5c06\u5217\u8868\u6240\u6709\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u5730\u6dfb\u52a0\u5230\u5806\u4e2d\uff0c\u6b64\u65f6\u5806\u7684\u6027\u8d28\u5c1a\u672a\u5f97\u5230\u6ee1\u8db3\u3002
    2. \u5012\u5e8f\u904d\u5386\u5806\uff08\u5c42\u5e8f\u904d\u5386\u7684\u5012\u5e8f\uff09\uff0c\u4f9d\u6b21\u5bf9\u6bcf\u4e2a\u975e\u53f6\u8282\u70b9\u6267\u884c\u201c\u4ece\u9876\u81f3\u5e95\u5806\u5316\u201d\u3002

    \u6bcf\u5f53\u5806\u5316\u4e00\u4e2a\u8282\u70b9\u540e\uff0c\u4ee5\u8be5\u8282\u70b9\u4e3a\u6839\u8282\u70b9\u7684\u5b50\u6811\u5c31\u5f62\u6210\u4e00\u4e2a\u5408\u6cd5\u7684\u5b50\u5806\u3002\u800c\u7531\u4e8e\u662f\u5012\u5e8f\u904d\u5386\uff0c\u56e0\u6b64\u5806\u662f\u201c\u81ea\u4e0b\u800c\u4e0a\u201d\u6784\u5efa\u7684\u3002

    \u4e4b\u6240\u4ee5\u9009\u62e9\u5012\u5e8f\u904d\u5386\uff0c\u662f\u56e0\u4e3a\u8fd9\u6837\u80fd\u591f\u4fdd\u8bc1\u5f53\u524d\u8282\u70b9\u4e4b\u4e0b\u7684\u5b50\u6811\u5df2\u7ecf\u662f\u5408\u6cd5\u7684\u5b50\u5806\uff0c\u8fd9\u6837\u5806\u5316\u5f53\u524d\u8282\u70b9\u624d\u662f\u6709\u6548\u7684\u3002

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u7531\u4e8e\u53f6\u8282\u70b9\u6ca1\u6709\u5b50\u8282\u70b9\uff0c\u56e0\u6b64\u5b83\u4eec\u5929\u7136\u5c31\u662f\u5408\u6cd5\u7684\u5b50\u5806\uff0c\u65e0\u987b\u5806\u5316\u3002\u5982\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff0c\u6700\u540e\u4e00\u4e2a\u975e\u53f6\u8282\u70b9\u662f\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u7684\u7236\u8282\u70b9\uff0c\u6211\u4eec\u4ece\u5b83\u5f00\u59cb\u5012\u5e8f\u904d\u5386\u5e76\u6267\u884c\u5806\u5316\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def __init__(self, nums: list[int]):\n    \"\"\"\u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\"\"\"\n    # \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    self.max_heap = nums\n    # \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(self.parent(self.size() - 1), -1, -1):\n        self.sift_down(i)\n
    my_heap.cpp
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(vector<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums;\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.java
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<Integer> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new ArrayList<>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.cs
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(IEnumerable<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new List<int>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var size = Parent(this.Size() - 1);\n    for (int i = size; i >= 0; i--) {\n        SiftDown(i);\n    }\n}\n
    my_heap.go
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nfunc newMaxHeap(nums []any) *maxHeap {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    h := &maxHeap{data: nums}\n    for i := h.parent(len(h.data) - 1); i >= 0; i-- {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        h.siftDown(i)\n    }\n    return h\n}\n
    my_heap.swift
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\ninit(nums: [Int]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0 ... parent(i: size() - 1)).reversed() {\n        siftDown(i: i)\n    }\n}\n
    my_heap.js
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.#maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.#parent(this.size() - 1); i >= 0; i--) {\n        this.#siftDown(i);\n    }\n}\n
    my_heap.ts
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums?: number[]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.parent(this.size() - 1); i >= 0; i--) {\n        this.siftDown(i);\n    }\n}\n
    my_heap.dart
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<int> nums) {\n  // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n  _maxHeap = nums;\n  // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = _parent(size() - 1); i >= 0; i--) {\n    siftDown(i);\n  }\n}\n
    my_heap.rs
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nfn new(nums: Vec<i32>) -> Self {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    let mut heap = MaxHeap { max_heap: nums };\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=Self::parent(heap.size() - 1)).rev() {\n        heap.sift_down(i);\n    }\n    heap\n}\n
    my_heap.c
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nMaxHeap *newMaxHeap(int nums[], int size) {\n    // \u6240\u6709\u5143\u7d20\u5165\u5806\n    MaxHeap *maxHeap = (MaxHeap *)malloc(sizeof(MaxHeap));\n    maxHeap->size = size;\n    memcpy(maxHeap->data, nums, size * sizeof(int));\n    for (int i = parent(maxHeap, size - 1); i >= 0; i--) {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        siftDown(maxHeap, i);\n    }\n    return maxHeap;\n}\n
    my_heap.kt
    /* \u5927\u9876\u5806 */\nclass MaxHeap(nums: MutableList<Int>?) {\n    // \u4f7f\u7528\u5217\u8868\u800c\u975e\u6570\u7ec4\uff0c\u8fd9\u6837\u65e0\u987b\u8003\u8651\u6269\u5bb9\u95ee\u9898\n    private val maxHeap = mutableListOf<Int>()\n\n    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\n    init {\n        // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n        maxHeap.addAll(nums!!)\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        for (i in parent(size() - 1) downTo 0) {\n            siftDown(i)\n        }\n    }\n\n    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun parent(i: Int): Int {\n        return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u4ea4\u6362\u5143\u7d20 */\n    private fun swap(i: Int, j: Int) {\n        val temp = maxHeap[i]\n        maxHeap[i] = maxHeap[j]\n        maxHeap[j] = temp\n    }\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    fun size(): Int {\n        return maxHeap.size\n    }\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n        return size() == 0\n    }\n\n    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        return maxHeap[0]\n    }\n\n    /* \u5143\u7d20\u5165\u5806 */\n    fun push(_val: Int) {\n        // \u6dfb\u52a0\u8282\u70b9\n        maxHeap.add(_val)\n        // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n        siftUp(size() - 1)\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n    private fun siftUp(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n            val p = parent(i)\n            // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n            if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, p)\n            // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n            i = p\n        }\n    }\n\n    /* \u5143\u7d20\u51fa\u5806 */\n    fun pop(): Int {\n        // \u5224\u7a7a\u5904\u7406\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(0, size() - 1)\n        // \u5220\u9664\u8282\u70b9\n        val _val = maxHeap.removeAt(size() - 1)\n        // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n        siftDown(0)\n        // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n        return _val\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n    private fun siftDown(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n            val l = left(i)\n            val r = right(i)\n            var ma = i\n            if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n            if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n            // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n            if (ma == i) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, ma)\n            // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n            i = ma\n        }\n    }\n\n    /* \u6253\u5370\u5806\uff08\u4e8c\u53c9\u6811\uff09 */\n    fun print() {\n        val queue = PriorityQueue { a: Int, b: Int -> b - a }\n        queue.addAll(maxHeap)\n        printHeap(queue)\n    }\n}\n
    my_heap.rb
    [class]{MaxHeap}-[func]{__init__}\n
    my_heap.zig
    // \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\nfn init(self: *Self, allocator: std.mem.Allocator, nums: []const T) !void {\n    if (self.max_heap != null) return;\n    self.max_heap = std.ArrayList(T).init(allocator);\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    try self.max_heap.?.appendSlice(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var i: usize = parent(self.size() - 1) + 1;\n    while (i > 0) : (i -= 1) {\n        try self.siftDown(i - 1);\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/build_heap/#823","title":"8.2.3 \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    \u4e0b\u9762\uff0c\u6211\u4eec\u6765\u5c1d\u8bd5\u63a8\u7b97\u7b2c\u4e8c\u79cd\u5efa\u5806\u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    • \u5047\u8bbe\u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(n\\) \uff0c\u5219\u53f6\u8282\u70b9\u6570\u91cf\u4e3a \\((n + 1) / 2\\) \uff0c\u5176\u4e2d \\(/\\) \u4e3a\u5411\u4e0b\u6574\u9664\u3002\u56e0\u6b64\u9700\u8981\u5806\u5316\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\((n - 1) / 2\\) \u3002
    • \u5728\u4ece\u9876\u81f3\u5e95\u5806\u5316\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u4e2a\u8282\u70b9\u6700\u591a\u5806\u5316\u5230\u53f6\u8282\u70b9\uff0c\u56e0\u6b64\u6700\u5927\u8fed\u4ee3\u6b21\u6570\u4e3a\u4e8c\u53c9\u6811\u9ad8\u5ea6 \\(\\log n\\) \u3002

    \u5c06\u4e0a\u8ff0\u4e24\u8005\u76f8\u4e58\uff0c\u53ef\u5f97\u5230\u5efa\u5806\u8fc7\u7a0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002\u4f46\u8fd9\u4e2a\u4f30\u7b97\u7ed3\u679c\u5e76\u4e0d\u51c6\u786e\uff0c\u56e0\u4e3a\u6211\u4eec\u6ca1\u6709\u8003\u8651\u5230\u4e8c\u53c9\u6811\u5e95\u5c42\u8282\u70b9\u6570\u91cf\u8fdc\u591a\u4e8e\u9876\u5c42\u8282\u70b9\u7684\u6027\u8d28\u3002

    \u63a5\u4e0b\u6765\u6211\u4eec\u6765\u8fdb\u884c\u66f4\u4e3a\u51c6\u786e\u7684\u8ba1\u7b97\u3002\u4e3a\u4e86\u964d\u4f4e\u8ba1\u7b97\u96be\u5ea6\uff0c\u5047\u8bbe\u7ed9\u5b9a\u4e00\u4e2a\u8282\u70b9\u6570\u91cf\u4e3a \\(n\\) \u3001\u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u201c\u5b8c\u7f8e\u4e8c\u53c9\u6811\u201d\uff0c\u8be5\u5047\u8bbe\u4e0d\u4f1a\u5f71\u54cd\u8ba1\u7b97\u7ed3\u679c\u7684\u6b63\u786e\u6027\u3002

    \u56fe 8-5 \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811\u7684\u5404\u5c42\u8282\u70b9\u6570\u91cf

    \u5982\u56fe 8-5 \u6240\u793a\uff0c\u8282\u70b9\u201c\u4ece\u9876\u81f3\u5e95\u5806\u5316\u201d\u7684\u6700\u5927\u8fed\u4ee3\u6b21\u6570\u7b49\u4e8e\u8be5\u8282\u70b9\u5230\u53f6\u8282\u70b9\u7684\u8ddd\u79bb\uff0c\u800c\u8be5\u8ddd\u79bb\u6b63\u662f\u201c\u8282\u70b9\u9ad8\u5ea6\u201d\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u5404\u5c42\u7684\u201c\u8282\u70b9\u6570\u91cf \\(\\times\\) \u8282\u70b9\u9ad8\u5ea6\u201d\u6c42\u548c\uff0c\u5f97\u5230\u6240\u6709\u8282\u70b9\u7684\u5806\u5316\u8fed\u4ee3\u6b21\u6570\u7684\u603b\u548c\u3002

    \\[ T(h) = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{(h-1)}\\times1 \\]

    \u5316\u7b80\u4e0a\u5f0f\u9700\u8981\u501f\u52a9\u4e2d\u5b66\u7684\u6570\u5217\u77e5\u8bc6\uff0c\u5148\u5c06 \\(T(h)\\) \u4e58\u4ee5 \\(2\\) \uff0c\u5f97\u5230\uff1a

    \\[ \\begin{aligned} T(h) & = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{h-1}\\times1 \\newline 2 T(h) & = 2^1h + 2^2(h-1) + 2^3(h-2) + \\dots + 2^{h}\\times1 \\newline \\end{aligned} \\]

    \u4f7f\u7528\u9519\u4f4d\u76f8\u51cf\u6cd5\uff0c\u7528\u4e0b\u5f0f \\(2 T(h)\\) \u51cf\u53bb\u4e0a\u5f0f \\(T(h)\\) \uff0c\u53ef\u5f97\uff1a

    \\[ 2T(h) - T(h) = T(h) = -2^0h + 2^1 + 2^2 + \\dots + 2^{h-1} + 2^h \\]

    \u89c2\u5bdf\u4e0a\u5f0f\uff0c\u53d1\u73b0 \\(T(h)\\) \u662f\u4e00\u4e2a\u7b49\u6bd4\u6570\u5217\uff0c\u53ef\u76f4\u63a5\u4f7f\u7528\u6c42\u548c\u516c\u5f0f\uff0c\u5f97\u5230\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\uff1a

    \\[ \\begin{aligned} T(h) & = 2 \\frac{1 - 2^h}{1 - 2} - h \\newline & = 2^{h+1} - h - 2 \\newline & = O(2^h) \\end{aligned} \\]

    \u8fdb\u4e00\u6b65\uff0c\u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u5b8c\u7f8e\u4e8c\u53c9\u6811\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(n = 2^{h+1} - 1\\) \uff0c\u6613\u5f97\u590d\u6742\u5ea6\u4e3a \\(O(2^h) = O(n)\\) \u3002\u4ee5\u4e0a\u63a8\u7b97\u8868\u660e\uff0c\u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u975e\u5e38\u9ad8\u6548\u3002

    "},{"location":"chapter_heap/heap/","title":"8.1 \u00a0 \u5806","text":"

    \u5806\uff08heap\uff09\u662f\u4e00\u79cd\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u7684\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u4e3b\u8981\u53ef\u5206\u4e3a\u4e24\u79cd\u7c7b\u578b\uff0c\u5982\u56fe 8-1 \u6240\u793a\u3002

    • \u5c0f\u9876\u5806\uff08min heap\uff09\uff1a\u4efb\u610f\u8282\u70b9\u7684\u503c \\(\\leq\\) \u5176\u5b50\u8282\u70b9\u7684\u503c\u3002
    • \u5927\u9876\u5806\uff08max heap\uff09\uff1a\u4efb\u610f\u8282\u70b9\u7684\u503c \\(\\geq\\) \u5176\u5b50\u8282\u70b9\u7684\u503c\u3002

    \u56fe 8-1 \u00a0 \u5c0f\u9876\u5806\u4e0e\u5927\u9876\u5806

    \u5806\u4f5c\u4e3a\u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u4e00\u4e2a\u7279\u4f8b\uff0c\u5177\u6709\u4ee5\u4e0b\u7279\u6027\u3002

    • \u6700\u5e95\u5c42\u8282\u70b9\u9760\u5de6\u586b\u5145\uff0c\u5176\u4ed6\u5c42\u7684\u8282\u70b9\u90fd\u88ab\u586b\u6ee1\u3002
    • \u6211\u4eec\u5c06\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\u79f0\u4e3a\u201c\u5806\u9876\u201d\uff0c\u5c06\u5e95\u5c42\u6700\u9760\u53f3\u7684\u8282\u70b9\u79f0\u4e3a\u201c\u5806\u5e95\u201d\u3002
    • \u5bf9\u4e8e\u5927\u9876\u5806\uff08\u5c0f\u9876\u5806\uff09\uff0c\u5806\u9876\u5143\u7d20\uff08\u6839\u8282\u70b9\uff09\u7684\u503c\u662f\u6700\u5927\uff08\u6700\u5c0f\uff09\u7684\u3002
    "},{"location":"chapter_heap/heap/#811","title":"8.1.1 \u00a0 \u5806\u7684\u5e38\u7528\u64cd\u4f5c","text":"

    \u9700\u8981\u6307\u51fa\u7684\u662f\uff0c\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u7684\u662f\u4f18\u5148\u961f\u5217\uff08priority queue\uff09\uff0c\u8fd9\u662f\u4e00\u79cd\u62bd\u8c61\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5b9a\u4e49\u4e3a\u5177\u6709\u4f18\u5148\u7ea7\u6392\u5e8f\u7684\u961f\u5217\u3002

    \u5b9e\u9645\u4e0a\uff0c\u5806\u901a\u5e38\u7528\u4e8e\u5b9e\u73b0\u4f18\u5148\u961f\u5217\uff0c\u5927\u9876\u5806\u76f8\u5f53\u4e8e\u5143\u7d20\u6309\u4ece\u5927\u5230\u5c0f\u7684\u987a\u5e8f\u51fa\u961f\u7684\u4f18\u5148\u961f\u5217\u3002\u4ece\u4f7f\u7528\u89d2\u5ea6\u6765\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u201c\u4f18\u5148\u961f\u5217\u201d\u548c\u201c\u5806\u201d\u770b\u4f5c\u7b49\u4ef7\u7684\u6570\u636e\u7ed3\u6784\u3002\u56e0\u6b64\uff0c\u672c\u4e66\u5bf9\u4e24\u8005\u4e0d\u505a\u7279\u522b\u533a\u5206\uff0c\u7edf\u4e00\u79f0\u4f5c\u201c\u5806\u201d\u3002

    \u5806\u7684\u5e38\u7528\u64cd\u4f5c\u89c1\u8868 8-1 \uff0c\u65b9\u6cd5\u540d\u9700\u8981\u6839\u636e\u7f16\u7a0b\u8bed\u8a00\u6765\u786e\u5b9a\u3002

    \u8868 8-1 \u00a0 \u5806\u7684\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5\u540d \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push() \u5143\u7d20\u5165\u5806 \\(O(\\log n)\\) pop() \u5806\u9876\u5143\u7d20\u51fa\u5806 \\(O(\\log n)\\) peek() \u8bbf\u95ee\u5806\u9876\u5143\u7d20\uff08\u5bf9\u4e8e\u5927 / \u5c0f\u9876\u5806\u5206\u522b\u4e3a\u6700\u5927 / \u5c0f\u503c\uff09 \\(O(1)\\) size() \u83b7\u53d6\u5806\u7684\u5143\u7d20\u6570\u91cf \\(O(1)\\) isEmpty() \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a \\(O(1)\\)

    \u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u7684\u5806\u7c7b\uff08\u6216\u4f18\u5148\u961f\u5217\u7c7b\uff09\u3002

    \u7c7b\u4f3c\u4e8e\u6392\u5e8f\u7b97\u6cd5\u4e2d\u7684\u201c\u4ece\u5c0f\u5230\u5927\u6392\u5217\u201d\u548c\u201c\u4ece\u5927\u5230\u5c0f\u6392\u5217\u201d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e\u4e00\u4e2a flag \u6216\u4fee\u6539 Comparator \u5b9e\u73b0\u201c\u5c0f\u9876\u5806\u201d\u4e0e\u201c\u5927\u9876\u5806\u201d\u4e4b\u95f4\u7684\u8f6c\u6362\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap.py
    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\nmin_heap, flag = [], 1\n# \u521d\u59cb\u5316\u5927\u9876\u5806\nmax_heap, flag = [], -1\n\n# Python \u7684 heapq \u6a21\u5757\u9ed8\u8ba4\u5b9e\u73b0\u5c0f\u9876\u5806\n# \u8003\u8651\u5c06\u201c\u5143\u7d20\u53d6\u8d1f\u201d\u540e\u518d\u5165\u5806\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u5927\u5c0f\u5173\u7cfb\u98a0\u5012\uff0c\u4ece\u800c\u5b9e\u73b0\u5927\u9876\u5806\n# \u5728\u672c\u793a\u4f8b\u4e2d\uff0cflag = 1 \u65f6\u5bf9\u5e94\u5c0f\u9876\u5806\uff0cflag = -1 \u65f6\u5bf9\u5e94\u5927\u9876\u5806\n\n# \u5143\u7d20\u5165\u5806\nheapq.heappush(max_heap, flag * 1)\nheapq.heappush(max_heap, flag * 3)\nheapq.heappush(max_heap, flag * 2)\nheapq.heappush(max_heap, flag * 5)\nheapq.heappush(max_heap, flag * 4)\n\n# \u83b7\u53d6\u5806\u9876\u5143\u7d20\npeek: int = flag * max_heap[0] # 5\n\n# \u5806\u9876\u5143\u7d20\u51fa\u5806\n# \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nval = flag * heapq.heappop(max_heap) # 5\nval = flag * heapq.heappop(max_heap) # 4\nval = flag * heapq.heappop(max_heap) # 3\nval = flag * heapq.heappop(max_heap) # 2\nval = flag * heapq.heappop(max_heap) # 1\n\n# \u83b7\u53d6\u5806\u5927\u5c0f\nsize: int = len(max_heap)\n\n# \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = not max_heap\n\n# \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806\nmin_heap: list[int] = [1, 3, 2, 5, 4]\nheapq.heapify(min_heap)\n
    heap.cpp
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\npriority_queue<int, vector<int>, greater<int>> minHeap;\n// \u521d\u59cb\u5316\u5927\u9876\u5806\npriority_queue<int, vector<int>, less<int>> maxHeap;\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.push(1);\nmaxHeap.push(3);\nmaxHeap.push(2);\nmaxHeap.push(5);\nmaxHeap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.top(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nmaxHeap.pop(); // 5\nmaxHeap.pop(); // 4\nmaxHeap.pop(); // 3\nmaxHeap.pop(); // 2\nmaxHeap.pop(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nvector<int> input{1, 3, 2, 5, 4};\npriority_queue<int, vector<int>, greater<int>> minHeap(input.begin(), input.end());\n
    heap.java
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nQueue<Integer> minHeap = new PriorityQueue<>();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1);\nmaxHeap.offer(3);\nmaxHeap.offer(2);\nmaxHeap.offer(5);\nmaxHeap.offer(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.peek(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll(); // 5\npeek = maxHeap.poll(); // 4\npeek = maxHeap.poll(); // 3\npeek = maxHeap.poll(); // 2\npeek = maxHeap.poll(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = maxHeap.isEmpty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<>(Arrays.asList(1, 3, 2, 5, 4));\n
    heap.cs
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nPriorityQueue<int, int> minHeap = new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nPriorityQueue<int, int> maxHeap = new(Comparer<int>.Create((x, y) => y - x));\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.Enqueue(1, 1);\nmaxHeap.Enqueue(3, 3);\nmaxHeap.Enqueue(2, 2);\nmaxHeap.Enqueue(5, 5);\nmaxHeap.Enqueue(4, 4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.Peek();//5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.Dequeue();  // 5\npeek = maxHeap.Dequeue();  // 4\npeek = maxHeap.Dequeue();  // 3\npeek = maxHeap.Dequeue();  // 2\npeek = maxHeap.Dequeue();  // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.Count;\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.Count == 0;\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<int, int>([(1, 1), (3, 3), (2, 2), (5, 5), (4, 4)]);\n
    heap.go
    // Go \u8bed\u8a00\u4e2d\u53ef\u4ee5\u901a\u8fc7\u5b9e\u73b0 heap.Interface \u6765\u6784\u5efa\u6574\u6570\u5927\u9876\u5806\n// \u5b9e\u73b0 heap.Interface \u9700\u8981\u540c\u65f6\u5b9e\u73b0 sort.Interface\ntype intHeap []any\n\n// Push heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u63a8\u5165\u5143\u7d20\u5230\u5806\nfunc (h *intHeap) Push(x any) {\n    // Push \u548c Pop \u4f7f\u7528 pointer receiver \u4f5c\u4e3a\u53c2\u6570\n    // \u56e0\u4e3a\u5b83\u4eec\u4e0d\u4ec5\u4f1a\u5bf9\u5207\u7247\u7684\u5185\u5bb9\u8fdb\u884c\u8c03\u6574\uff0c\u8fd8\u4f1a\u4fee\u6539\u5207\u7247\u7684\u957f\u5ea6\u3002\n    *h = append(*h, x.(int))\n}\n\n// Pop heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u5f39\u51fa\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Pop() any {\n    // \u5f85\u51fa\u5806\u5143\u7d20\u5b58\u653e\u5728\u6700\u540e\n    last := (*h)[len(*h)-1]\n    *h = (*h)[:len(*h)-1]\n    return last\n}\n\n// Len sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Len() int {\n    return len(*h)\n}\n\n// Less sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Less(i, j int) bool {\n    // \u5982\u679c\u5b9e\u73b0\u5c0f\u9876\u5806\uff0c\u5219\u9700\u8981\u8c03\u6574\u4e3a\u5c0f\u4e8e\u53f7\n    return (*h)[i].(int) > (*h)[j].(int)\n}\n\n// Swap sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Swap(i, j int) {\n    (*h)[i], (*h)[j] = (*h)[j], (*h)[i]\n}\n\n// Top \u83b7\u53d6\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Top() any {\n    return (*h)[0]\n}\n\n/* Driver Code */\nfunc TestHeap(t *testing.T) {\n    /* \u521d\u59cb\u5316\u5806 */\n    // \u521d\u59cb\u5316\u5927\u9876\u5806\n    maxHeap := &intHeap{}\n    heap.Init(maxHeap)\n    /* \u5143\u7d20\u5165\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u6dfb\u52a0\u5143\u7d20\n    heap.Push(maxHeap, 1)\n    heap.Push(maxHeap, 3)\n    heap.Push(maxHeap, 2)\n    heap.Push(maxHeap, 4)\n    heap.Push(maxHeap, 5)\n\n    /* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\n    top := maxHeap.Top()\n    fmt.Printf(\"\u5806\u9876\u5143\u7d20\u4e3a %d\\n\", top)\n\n    /* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u79fb\u9664\u5143\u7d20\n    heap.Pop(maxHeap) // 5\n    heap.Pop(maxHeap) // 4\n    heap.Pop(maxHeap) // 3\n    heap.Pop(maxHeap) // 2\n    heap.Pop(maxHeap) // 1\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    size := len(*maxHeap)\n    fmt.Printf(\"\u5806\u5143\u7d20\u6570\u91cf\u4e3a %d\\n\", size)\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    isEmpty := len(*maxHeap) == 0\n    fmt.Printf(\"\u5806\u662f\u5426\u4e3a\u7a7a %t\\n\", isEmpty)\n}\n
    heap.swift
    /* \u521d\u59cb\u5316\u5806 */\n// Swift \u7684 Heap \u7c7b\u578b\u540c\u65f6\u652f\u6301\u6700\u5927\u5806\u548c\u6700\u5c0f\u5806\uff0c\u4e14\u9700\u8981\u5f15\u5165 swift-collections\nvar heap = Heap<Int>()\n\n/* \u5143\u7d20\u5165\u5806 */\nheap.insert(1)\nheap.insert(3)\nheap.insert(2)\nheap.insert(5)\nheap.insert(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = heap.max()!\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\npeek = heap.removeMax() // 5\npeek = heap.removeMax() // 4\npeek = heap.removeMax() // 3\npeek = heap.removeMax() // 2\npeek = heap.removeMax() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = heap.count\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = heap.isEmpty\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet heap2 = Heap([1, 3, 2, 5, 4])\n
    heap.js
    // JavaScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.ts
    // TypeScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.dart
    // Dart \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.rs
    use std::collections::BinaryHeap;\nuse std::cmp::Reverse;\n\n/* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nlet mut min_heap = BinaryHeap::<Reverse<i32>>::new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\nlet mut max_heap = BinaryHeap::new();\n\n/* \u5143\u7d20\u5165\u5806 */\nmax_heap.push(1);\nmax_heap.push(3);\nmax_heap.push(2);\nmax_heap.push(5);\nmax_heap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nlet peek = max_heap.peek().unwrap();  // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nlet peek = max_heap.pop().unwrap();   // 5\nlet peek = max_heap.pop().unwrap();   // 4\nlet peek = max_heap.pop().unwrap();   // 3\nlet peek = max_heap.pop().unwrap();   // 2\nlet peek = max_heap.pop().unwrap();   // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = max_heap.len();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = max_heap.is_empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet min_heap = BinaryHeap::from(vec![Reverse(1), Reverse(3), Reverse(2), Reverse(5), Reverse(4)]);\n
    heap.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.kt
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nvar minHeap = PriorityQueue<Int>()\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nval maxHeap = PriorityQueue { a: Int, b: Int -> b - a }\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1)\nmaxHeap.offer(3)\nmaxHeap.offer(2)\nmaxHeap.offer(5)\nmaxHeap.offer(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = maxHeap.peek() // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll() // 5\npeek = maxHeap.poll() // 4\npeek = maxHeap.poll() // 3\npeek = maxHeap.poll() // 2\npeek = maxHeap.poll() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nval size = maxHeap.size\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = maxHeap.isEmpty()\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = PriorityQueue(mutableListOf(1, 3, 2, 5, 4))\n
    heap.rb
    \n
    heap.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#812","title":"8.1.2 \u00a0 \u5806\u7684\u5b9e\u73b0","text":"

    \u4e0b\u6587\u5b9e\u73b0\u7684\u662f\u5927\u9876\u5806\u3002\u82e5\u8981\u5c06\u5176\u8f6c\u6362\u4e3a\u5c0f\u9876\u5806\uff0c\u53ea\u9700\u5c06\u6240\u6709\u5927\u5c0f\u903b\u8f91\u5224\u65ad\u8fdb\u884c\u9006\u8f6c\uff08\u4f8b\u5982\uff0c\u5c06 \\(\\geq\\) \u66ff\u6362\u4e3a \\(\\leq\\) \uff09\u3002\u611f\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u3002

    "},{"location":"chapter_heap/heap/#1","title":"1. \u00a0 \u5806\u7684\u5b58\u50a8\u4e0e\u8868\u793a","text":"

    \u201c\u4e8c\u53c9\u6811\u201d\u7ae0\u8282\u8bb2\u8fc7\uff0c\u5b8c\u5168\u4e8c\u53c9\u6811\u975e\u5e38\u9002\u5408\u7528\u6570\u7ec4\u6765\u8868\u793a\u3002\u7531\u4e8e\u5806\u6b63\u662f\u4e00\u79cd\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u56e0\u6b64\u6211\u4eec\u5c06\u91c7\u7528\u6570\u7ec4\u6765\u5b58\u50a8\u5806\u3002

    \u5f53\u4f7f\u7528\u6570\u7ec4\u8868\u793a\u4e8c\u53c9\u6811\u65f6\uff0c\u5143\u7d20\u4ee3\u8868\u8282\u70b9\u503c\uff0c\u7d22\u5f15\u4ee3\u8868\u8282\u70b9\u5728\u4e8c\u53c9\u6811\u4e2d\u7684\u4f4d\u7f6e\u3002\u8282\u70b9\u6307\u9488\u901a\u8fc7\u7d22\u5f15\u6620\u5c04\u516c\u5f0f\u6765\u5b9e\u73b0\u3002

    \u5982\u56fe 8-2 \u6240\u793a\uff0c\u7ed9\u5b9a\u7d22\u5f15 \\(i\\) \uff0c\u5176\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\(2i + 1\\) \uff0c\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\(2i + 2\\) \uff0c\u7236\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\((i - 1) / 2\\)\uff08\u5411\u4e0b\u6574\u9664\uff09\u3002\u5f53\u7d22\u5f15\u8d8a\u754c\u65f6\uff0c\u8868\u793a\u7a7a\u8282\u70b9\u6216\u8282\u70b9\u4e0d\u5b58\u5728\u3002

    \u56fe 8-2 \u00a0 \u5806\u7684\u8868\u793a\u4e0e\u5b58\u50a8

    \u6211\u4eec\u53ef\u4ee5\u5c06\u7d22\u5f15\u6620\u5c04\u516c\u5f0f\u5c01\u88c5\u6210\u51fd\u6570\uff0c\u65b9\u4fbf\u540e\u7eed\u4f7f\u7528\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def left(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 1\n\ndef right(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 2\n\ndef parent(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return (i - 1) // 2  # \u5411\u4e0b\u6574\u9664\n
    my_heap.cpp
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.java
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.cs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint Parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.go
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) parent(i int) int {\n    // \u5411\u4e0b\u6574\u9664\n    return (i - 1) / 2\n}\n
    my_heap.swift
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc left(i: Int) -> Int {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc right(i: Int) -> Int {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc parent(i: Int) -> Int {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.js
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#left(i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#right(i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n#parent(i) {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.ts
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nleft(i: number): number {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nright(i: number): number {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nparent(i: number): number {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.dart
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _left(int i) {\n  return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _right(int i) {\n  return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint _parent(int i) {\n  return (i - 1) ~/ 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn left(i: usize) -> usize {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn right(i: usize) -> usize {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfn parent(i: usize) -> usize {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.c
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(MaxHeap *maxHeap, int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(MaxHeap *maxHeap, int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(MaxHeap *maxHeap, int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u53d6\u6574\n}\n
    my_heap.kt
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun left(i: Int): Int {\n    return 2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun right(i: Int): Int {\n    return 2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfun parent(i: Int): Int {\n    return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rb
    ### \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef left(i)\n  2 * i + 1\nend\n\n### \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef right(i)\n  2 * i + 2\nend\n\n### \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef parent(i)\n  (i - 1) / 2     # \u5411\u4e0b\u6574\u9664\nend\n
    my_heap.zig
    // \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn left(i: usize) usize {\n    return 2 * i + 1;\n}\n\n// \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn right(i: usize) usize {\n    return 2 * i + 2;\n}\n\n// \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\nfn parent(i: usize) usize {\n    // return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n    return @divFloor(i - 1, 2);\n}\n
    "},{"location":"chapter_heap/heap/#2","title":"2. \u00a0 \u8bbf\u95ee\u5806\u9876\u5143\u7d20","text":"

    \u5806\u9876\u5143\u7d20\u5373\u4e3a\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\uff0c\u4e5f\u5c31\u662f\u5217\u8868\u7684\u9996\u4e2a\u5143\u7d20\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def peek(self) -> int:\n    \"\"\"\u8bbf\u95ee\u5806\u9876\u5143\u7d20\"\"\"\n    return self.max_heap[0]\n
    my_heap.cpp
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap[0];\n}\n
    my_heap.java
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap.get(0);\n}\n
    my_heap.cs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint Peek() {\n    return maxHeap[0];\n}\n
    my_heap.go
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc (h *maxHeap) peek() any {\n    return h.data[0]\n}\n
    my_heap.swift
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc peek() -> Int {\n    maxHeap[0]\n}\n
    my_heap.js
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek() {\n    return this.#maxHeap[0];\n}\n
    my_heap.ts
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek(): number {\n    return this.maxHeap[0];\n}\n
    my_heap.dart
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n  return _maxHeap[0];\n}\n
    my_heap.rs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfn peek(&self) -> Option<i32> {\n    self.max_heap.first().copied()\n}\n
    my_heap.c
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek(MaxHeap *maxHeap) {\n    return maxHeap->data[0];\n}\n
    my_heap.kt
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfun peek(): Int {\n    return maxHeap[0]\n}\n
    my_heap.rb
    ### \u8bbf\u95ee\u5806\u9876\u5143\u7d20 ###\ndef peek\n  @max_heap[0]\nend\n
    my_heap.zig
    // \u8bbf\u95ee\u5806\u9876\u5143\u7d20\nfn peek(self: *Self) T {\n    return self.max_heap.?.items[0];\n}  \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#3","title":"3. \u00a0 \u5143\u7d20\u5165\u5806","text":"

    \u7ed9\u5b9a\u5143\u7d20 val \uff0c\u6211\u4eec\u9996\u5148\u5c06\u5176\u6dfb\u52a0\u5230\u5806\u5e95\u3002\u6dfb\u52a0\u4e4b\u540e\uff0c\u7531\u4e8e val \u53ef\u80fd\u5927\u4e8e\u5806\u4e2d\u5176\u4ed6\u5143\u7d20\uff0c\u5806\u7684\u6210\u7acb\u6761\u4ef6\u53ef\u80fd\u5df2\u88ab\u7834\u574f\uff0c\u56e0\u6b64\u9700\u8981\u4fee\u590d\u4ece\u63d2\u5165\u8282\u70b9\u5230\u6839\u8282\u70b9\u7684\u8def\u5f84\u4e0a\u7684\u5404\u4e2a\u8282\u70b9\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u88ab\u79f0\u4e3a\u5806\u5316\uff08heapify\uff09\u3002

    \u8003\u8651\u4ece\u5165\u5806\u8282\u70b9\u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u6267\u884c\u5806\u5316\u3002\u5982\u56fe 8-3 \u6240\u793a\uff0c\u6211\u4eec\u6bd4\u8f83\u63d2\u5165\u8282\u70b9\u4e0e\u5176\u7236\u8282\u70b9\u7684\u503c\uff0c\u5982\u679c\u63d2\u5165\u8282\u70b9\u66f4\u5927\uff0c\u5219\u5c06\u5b83\u4eec\u4ea4\u6362\u3002\u7136\u540e\u7ee7\u7eed\u6267\u884c\u6b64\u64cd\u4f5c\uff0c\u4ece\u5e95\u81f3\u9876\u4fee\u590d\u5806\u4e2d\u7684\u5404\u4e2a\u8282\u70b9\uff0c\u76f4\u81f3\u8d8a\u8fc7\u6839\u8282\u70b9\u6216\u9047\u5230\u65e0\u987b\u4ea4\u6362\u7684\u8282\u70b9\u65f6\u7ed3\u675f\u3002

    <1><2><3><4><5><6><7><8><9>

    \u56fe 8-3 \u00a0 \u5143\u7d20\u5165\u5806\u6b65\u9aa4

    \u8bbe\u8282\u70b9\u603b\u6570\u4e3a \\(n\\) \uff0c\u5219\u6811\u7684\u9ad8\u5ea6\u4e3a \\(O(\\log n)\\) \u3002\u7531\u6b64\u53ef\u77e5\uff0c\u5806\u5316\u64cd\u4f5c\u7684\u5faa\u73af\u8f6e\u6570\u6700\u591a\u4e3a \\(O(\\log n)\\) \uff0c\u5143\u7d20\u5165\u5806\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def push(self, val: int):\n    \"\"\"\u5143\u7d20\u5165\u5806\"\"\"\n    # \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.append(val)\n    # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1)\n\ndef sift_up(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\"\"\"\n    while True:\n        # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p = self.parent(i)\n        # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 or self.max_heap[i] <= self.max_heap[p]:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p)\n        # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n
    my_heap.cpp
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.push_back(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap[i], maxHeap[p]);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap.get(i) <= maxHeap.get(p))\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u5165\u5806 */\nvoid Push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.Add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    SiftUp(Size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid SiftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = Parent(i);\n        // \u82e5\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u5165\u5806 */\nfunc (h *maxHeap) push(val any) {\n    // \u6dfb\u52a0\u8282\u70b9\n    h.data = append(h.data, val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    h.siftUp(len(h.data) - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc (h *maxHeap) siftUp(i int) {\n    for true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p := h.parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || h.data[i].(int) <= h.data[p].(int) {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u5165\u5806 */\nfunc push(val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.append(val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(i: size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc siftUp(i: Int) {\n    var i = i\n    while true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = parent(i: i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || maxHeap[i] <= maxHeap[p] {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u5165\u5806 */\npush(val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.#maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.#siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n#siftUp(i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.#parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.#maxHeap[i] <= this.#maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u5165\u5806 */\npush(val: number): void {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nsiftUp(i: number): void {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n  // \u6dfb\u52a0\u8282\u70b9\n  _maxHeap.add(val);\n  // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n  while (true) {\n    // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    int p = _parent(i);\n    // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    if (p < 0 || _maxHeap[i] <= _maxHeap[p]) {\n      break;\n    }\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, p);\n    // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u5165\u5806 */\nfn push(&mut self, val: i32) {\n    // \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfn sift_up(&mut self, mut i: usize) {\n    loop {\n        // \u8282\u70b9 i \u5df2\u7ecf\u662f\u5806\u9876\u8282\u70b9\u4e86\uff0c\u7ed3\u675f\u5806\u5316\n        if i == 0 {\n            break;\n        }\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = Self::parent(i);\n        // \u5f53\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if self.max_heap[i] <= self.max_heap[p] {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(MaxHeap *maxHeap, int val) {\n    // \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u4e0d\u5e94\u8be5\u6dfb\u52a0\u8fd9\u4e48\u591a\u8282\u70b9\n    if (maxHeap->size == MAX_SIZE) {\n        printf(\"heap is full!\");\n        return;\n    }\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap->data[maxHeap->size] = val;\n    maxHeap->size++;\n\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(maxHeap, maxHeap->size - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(maxHeap, i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap->data[i] <= maxHeap->data[p]) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u5165\u5806 */\nfun push(_val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(_val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfun siftUp(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        val p = parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u5165\u5806 ###\ndef push(val)\n  # \u6dfb\u52a0\u8282\u70b9\n  @max_heap << val\n  # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  sift_up(size - 1)\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 ###\ndef sift_up(i)\n  loop do\n    # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    p = parent(i)\n    # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    break if p < 0 || @max_heap[i] <= @max_heap[p]\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, p)\n    # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u5165\u5806\nfn push(self: *Self, val: T) !void {\n    // \u6dfb\u52a0\u8282\u70b9\n    try self.max_heap.?.append(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    try self.siftUp(self.size() - 1);\n}  \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\nfn siftUp(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        var p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 or self.max_heap.?.items[i] <= self.max_heap.?.items[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#4","title":"4. \u00a0 \u5806\u9876\u5143\u7d20\u51fa\u5806","text":"

    \u5806\u9876\u5143\u7d20\u662f\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\uff0c\u5373\u5217\u8868\u9996\u5143\u7d20\u3002\u5982\u679c\u6211\u4eec\u76f4\u63a5\u4ece\u5217\u8868\u4e2d\u5220\u9664\u9996\u5143\u7d20\uff0c\u90a3\u4e48\u4e8c\u53c9\u6811\u4e2d\u6240\u6709\u8282\u70b9\u7684\u7d22\u5f15\u90fd\u4f1a\u53d1\u751f\u53d8\u5316\uff0c\u8fd9\u5c06\u4f7f\u5f97\u540e\u7eed\u4f7f\u7528\u5806\u5316\u8fdb\u884c\u4fee\u590d\u53d8\u5f97\u56f0\u96be\u3002\u4e3a\u4e86\u5c3d\u91cf\u51cf\u5c11\u5143\u7d20\u7d22\u5f15\u7684\u53d8\u52a8\uff0c\u6211\u4eec\u91c7\u7528\u4ee5\u4e0b\u64cd\u4f5c\u6b65\u9aa4\u3002

    1. \u4ea4\u6362\u5806\u9876\u5143\u7d20\u4e0e\u5806\u5e95\u5143\u7d20\uff08\u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff09\u3002
    2. \u4ea4\u6362\u5b8c\u6210\u540e\uff0c\u5c06\u5806\u5e95\u4ece\u5217\u8868\u4e2d\u5220\u9664\uff08\u6ce8\u610f\uff0c\u7531\u4e8e\u5df2\u7ecf\u4ea4\u6362\uff0c\u56e0\u6b64\u5b9e\u9645\u4e0a\u5220\u9664\u7684\u662f\u539f\u6765\u7684\u5806\u9876\u5143\u7d20\uff09\u3002
    3. \u4ece\u6839\u8282\u70b9\u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u6267\u884c\u5806\u5316\u3002

    \u5982\u56fe 8-4 \u6240\u793a\uff0c\u201c\u4ece\u9876\u81f3\u5e95\u5806\u5316\u201d\u7684\u64cd\u4f5c\u65b9\u5411\u4e0e\u201c\u4ece\u5e95\u81f3\u9876\u5806\u5316\u201d\u76f8\u53cd\uff0c\u6211\u4eec\u5c06\u6839\u8282\u70b9\u7684\u503c\u4e0e\u5176\u4e24\u4e2a\u5b50\u8282\u70b9\u7684\u503c\u8fdb\u884c\u6bd4\u8f83\uff0c\u5c06\u6700\u5927\u7684\u5b50\u8282\u70b9\u4e0e\u6839\u8282\u70b9\u4ea4\u6362\u3002\u7136\u540e\u5faa\u73af\u6267\u884c\u6b64\u64cd\u4f5c\uff0c\u76f4\u5230\u8d8a\u8fc7\u53f6\u8282\u70b9\u6216\u9047\u5230\u65e0\u987b\u4ea4\u6362\u7684\u8282\u70b9\u65f6\u7ed3\u675f\u3002

    <1><2><3><4><5><6><7><8><9><10>

    \u56fe 8-4 \u00a0 \u5806\u9876\u5143\u7d20\u51fa\u5806\u6b65\u9aa4

    \u4e0e\u5143\u7d20\u5165\u5806\u64cd\u4f5c\u76f8\u4f3c\uff0c\u5806\u9876\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u4e3a \\(O(\\log n)\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def pop(self) -> int:\n    \"\"\"\u5143\u7d20\u51fa\u5806\"\"\"\n    # \u5224\u7a7a\u5904\u7406\n    if self.is_empty():\n        raise IndexError(\"\u5806\u4e3a\u7a7a\")\n    # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1)\n    # \u5220\u9664\u8282\u70b9\n    val = self.max_heap.pop()\n    # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0)\n    # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n\ndef sift_down(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l, r, ma = self.left(i), self.right(i), i\n        if l < self.size() and self.max_heap[l] > self.max_heap[ma]:\n            ma = l\n        if r < self.size() and self.max_heap[r] > self.max_heap[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma)\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n
    my_heap.cpp
    /* \u5143\u7d20\u51fa\u5806 */\nvoid pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) {\n        throw out_of_range(\"\u5806\u4e3a\u7a7a\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap[0], maxHeap[size() - 1]);\n    // \u5220\u9664\u8282\u70b9\n    maxHeap.pop_back();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        swap(maxHeap[i], maxHeap[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty())\n        throw new IndexOutOfBoundsException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.remove(size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap.get(l) > maxHeap.get(ma))\n            ma = l;\n        if (r < size() && maxHeap.get(r) > maxHeap.get(ma))\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u51fa\u5806 */\nint Pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (IsEmpty())\n        throw new IndexOutOfRangeException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    Swap(0, Size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.Last();\n    maxHeap.RemoveAt(Size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    SiftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = Left(i), r = Right(i), ma = i;\n        if (l < Size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < Size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u201c\u8282\u70b9 i \u6700\u5927\u201d\u6216\u201c\u8d8a\u8fc7\u53f6\u8282\u70b9\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u51fa\u5806 */\nfunc (h *maxHeap) pop() any {\n    // \u5224\u7a7a\u5904\u7406\n    if h.isEmpty() {\n        fmt.Println(\"error\")\n        return nil\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    h.swap(0, h.size()-1)\n    // \u5220\u9664\u8282\u70b9\n    val := h.data[len(h.data)-1]\n    h.data = h.data[:len(h.data)-1]\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    h.siftDown(0)\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc (h *maxHeap) siftDown(i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        l, r, max := h.left(i), h.right(i), i\n        if l < h.size() && h.data[l].(int) > h.data[max].(int) {\n            max = l\n        }\n        if r < h.size() && h.data[r].(int) > h.data[max].(int) {\n            max = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if max == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, max)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u51fa\u5806 */\nfunc pop() -> Int {\n    // \u5224\u7a7a\u5904\u7406\n    if isEmpty() {\n        fatalError(\"\u5806\u4e3a\u7a7a\")\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(i: 0, j: size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    let val = maxHeap.remove(at: size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(i: 0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = left(i: i)\n        let r = right(i: i)\n        var ma = i\n        if l < size(), maxHeap[l] > maxHeap[ma] {\n            ma = l\n        }\n        if r < size(), maxHeap[r] > maxHeap[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u51fa\u5806 */\npop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new Error('\u5806\u4e3a\u7a7a');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.#swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.#maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.#siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n#siftDown(i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.#left(i),\n            r = this.#right(i);\n        let ma = i;\n        if (l < this.size() && this.#maxHeap[l] > this.#maxHeap[ma]) ma = l;\n        if (r < this.size() && this.#maxHeap[r] > this.#maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u51fa\u5806 */\npop(): number {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new RangeError('Heap is empty.');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nsiftDown(i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.left(i),\n            r = this.right(i);\n        let ma = i;\n        if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;\n        if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n  // \u5224\u7a7a\u5904\u7406\n  if (isEmpty()) throw Exception('\u5806\u4e3a\u7a7a');\n  // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  _swap(0, size() - 1);\n  // \u5220\u9664\u8282\u70b9\n  int val = _maxHeap.removeLast();\n  // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  siftDown(0);\n  // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = _left(i);\n    int r = _right(i);\n    int ma = i;\n    if (l < size() && _maxHeap[l] > _maxHeap[ma]) ma = l;\n    if (r < size() && _maxHeap[r] > _maxHeap[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, ma);\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u51fa\u5806 */\nfn pop(&mut self) -> i32 {\n    // \u5224\u7a7a\u5904\u7406\n    if self.is_empty() {\n        panic!(\"index out of bounds\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    let val = self.max_heap.pop().unwrap();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(&mut self, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let (l, r, mut ma) = (Self::left(i), Self::right(i), i);\n        if l < self.size() && self.max_heap[l] > self.max_heap[ma] {\n            ma = l;\n        }\n        if r < self.size() && self.max_heap[r] > self.max_heap[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u51fa\u5806 */\nint pop(MaxHeap *maxHeap) {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty(maxHeap)) {\n        printf(\"heap is empty!\");\n        return INT_MAX;\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap, 0, size(maxHeap) - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap->data[maxHeap->size - 1];\n    maxHeap->size--;\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(maxHeap, 0);\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        int l = left(maxHeap, i);\n        int r = right(maxHeap, i);\n        int max = i;\n        if (l < size(maxHeap) && maxHeap->data[l] > maxHeap->data[max]) {\n            max = l;\n        }\n        if (r < size(maxHeap) && maxHeap->data[r] > maxHeap->data[max]) {\n            max = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (max == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, max);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u51fa\u5806 */\nfun pop(): Int {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) throw IndexOutOfBoundsException()\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    val _val = maxHeap.removeAt(size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return _val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = left(i)\n        val r = right(i)\n        var ma = i\n        if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n        if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u51fa\u5806 ###\ndef pop\n  # \u5224\u7a7a\u5904\u7406\n  raise IndexError, \"\u5806\u4e3a\u7a7a\" if is_empty?\n  # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  swap(0, size - 1)\n  # \u5220\u9664\u8282\u70b9\n  val = @max_heap.pop\n  # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  sift_down(0)\n  # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  val\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 ###\ndef sift_down(i)\n  loop do\n    # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    l, r, ma = left(i), right(i), i\n    ma = l if l < size && @max_heap[l] > @max_heap[ma]\n    ma = r if r < size && @max_heap[r] > @max_heap[ma]\n\n    # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    break if ma == i\n\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, ma)\n    # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u51fa\u5806\nfn pop(self: *Self) !T {\n    // \u5224\u65ad\u5904\u7406\n    if (self.isEmpty()) unreachable;\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    try self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    var val = self.max_heap.?.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    try self.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n} \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\nfn siftDown(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        var l = left(i);\n        var r = right(i);\n        var ma = i;\n        if (l < self.size() and self.max_heap.?.items[l] > self.max_heap.?.items[ma]) ma = l;\n        if (r < self.size() and self.max_heap.?.items[r] > self.max_heap.?.items[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#813","title":"8.1.3 \u00a0 \u5806\u7684\u5e38\u89c1\u5e94\u7528","text":"
    • \u4f18\u5148\u961f\u5217\uff1a\u5806\u901a\u5e38\u4f5c\u4e3a\u5b9e\u73b0\u4f18\u5148\u961f\u5217\u7684\u9996\u9009\u6570\u636e\u7ed3\u6784\uff0c\u5176\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(\\log n)\\) \uff0c\u800c\u5efa\u961f\u64cd\u4f5c\u4e3a \\(O(n)\\) \uff0c\u8fd9\u4e9b\u64cd\u4f5c\u90fd\u975e\u5e38\u9ad8\u6548\u3002
    • \u5806\u6392\u5e8f\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u6570\u636e\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u5b83\u4eec\u5efa\u7acb\u4e00\u4e2a\u5806\uff0c\u7136\u540e\u4e0d\u65ad\u5730\u6267\u884c\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\uff0c\u4ece\u800c\u5f97\u5230\u6709\u5e8f\u6570\u636e\u3002\u7136\u800c\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u4f7f\u7528\u4e00\u79cd\u66f4\u4f18\u96c5\u7684\u65b9\u5f0f\u5b9e\u73b0\u5806\u6392\u5e8f\uff0c\u8be6\u89c1\u201c\u5806\u6392\u5e8f\u201d\u7ae0\u8282\u3002
    • \u83b7\u53d6\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\uff1a\u8fd9\u662f\u4e00\u4e2a\u7ecf\u5178\u7684\u7b97\u6cd5\u95ee\u9898\uff0c\u540c\u65f6\u4e5f\u662f\u4e00\u79cd\u5178\u578b\u5e94\u7528\uff0c\u4f8b\u5982\u9009\u62e9\u70ed\u5ea6\u524d 10 \u7684\u65b0\u95fb\u4f5c\u4e3a\u5fae\u535a\u70ed\u641c\uff0c\u9009\u53d6\u9500\u91cf\u524d 10 \u7684\u5546\u54c1\u7b49\u3002
    "},{"location":"chapter_heap/summary/","title":"8.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_heap/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u5806\u662f\u4e00\u68f5\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u6839\u636e\u6210\u7acb\u6761\u4ef6\u53ef\u5206\u4e3a\u5927\u9876\u5806\u548c\u5c0f\u9876\u5806\u3002\u5927\uff08\u5c0f\uff09\u9876\u5806\u7684\u5806\u9876\u5143\u7d20\u662f\u6700\u5927\uff08\u5c0f\uff09\u7684\u3002
    • \u4f18\u5148\u961f\u5217\u7684\u5b9a\u4e49\u662f\u5177\u6709\u51fa\u961f\u4f18\u5148\u7ea7\u7684\u961f\u5217\uff0c\u901a\u5e38\u4f7f\u7528\u5806\u6765\u5b9e\u73b0\u3002
    • \u5806\u7684\u5e38\u7528\u64cd\u4f5c\u53ca\u5176\u5bf9\u5e94\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5305\u62ec\uff1a\u5143\u7d20\u5165\u5806 \\(O(\\log n)\\)\u3001\u5806\u9876\u5143\u7d20\u51fa\u5806 \\(O(\\log n)\\) \u548c\u8bbf\u95ee\u5806\u9876\u5143\u7d20 \\(O(1)\\) \u7b49\u3002
    • \u5b8c\u5168\u4e8c\u53c9\u6811\u975e\u5e38\u9002\u5408\u7528\u6570\u7ec4\u8868\u793a\uff0c\u56e0\u6b64\u6211\u4eec\u901a\u5e38\u4f7f\u7528\u6570\u7ec4\u6765\u5b58\u50a8\u5806\u3002
    • \u5806\u5316\u64cd\u4f5c\u7528\u4e8e\u7ef4\u62a4\u5806\u7684\u6027\u8d28\uff0c\u5728\u5165\u5806\u548c\u51fa\u5806\u64cd\u4f5c\u4e2d\u90fd\u4f1a\u7528\u5230\u3002
    • \u8f93\u5165 \\(n\\) \u4e2a\u5143\u7d20\u5e76\u5efa\u5806\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f18\u5316\u81f3 \\(O(n)\\) \uff0c\u975e\u5e38\u9ad8\u6548\u3002
    • Top-k \u662f\u4e00\u4e2a\u7ecf\u5178\u7b97\u6cd5\u95ee\u9898\uff0c\u53ef\u4ee5\u4f7f\u7528\u5806\u6570\u636e\u7ed3\u6784\u9ad8\u6548\u89e3\u51b3\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log k)\\) \u3002
    "},{"location":"chapter_heap/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6570\u636e\u7ed3\u6784\u7684\u201c\u5806\u201d\u4e0e\u5185\u5b58\u7ba1\u7406\u7684\u201c\u5806\u201d\u662f\u540c\u4e00\u4e2a\u6982\u5ff5\u5417\uff1f

    \u4e24\u8005\u4e0d\u662f\u540c\u4e00\u4e2a\u6982\u5ff5\uff0c\u53ea\u662f\u78b0\u5de7\u90fd\u53eb\u201c\u5806\u201d\u3002\u8ba1\u7b97\u673a\u7cfb\u7edf\u5185\u5b58\u4e2d\u7684\u5806\u662f\u52a8\u6001\u5185\u5b58\u5206\u914d\u7684\u4e00\u90e8\u5206\uff0c\u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u53ef\u4ee5\u4f7f\u7528\u5b83\u6765\u5b58\u50a8\u6570\u636e\u3002\u7a0b\u5e8f\u53ef\u4ee5\u8bf7\u6c42\u4e00\u5b9a\u91cf\u7684\u5806\u5185\u5b58\uff0c\u7528\u4e8e\u5b58\u50a8\u5982\u5bf9\u8c61\u548c\u6570\u7ec4\u7b49\u590d\u6742\u7ed3\u6784\u3002\u5f53\u8fd9\u4e9b\u6570\u636e\u4e0d\u518d\u9700\u8981\u65f6\uff0c\u7a0b\u5e8f\u9700\u8981\u91ca\u653e\u8fd9\u4e9b\u5185\u5b58\uff0c\u4ee5\u9632\u6b62\u5185\u5b58\u6cc4\u6f0f\u3002\u76f8\u8f83\u4e8e\u6808\u5185\u5b58\uff0c\u5806\u5185\u5b58\u7684\u7ba1\u7406\u548c\u4f7f\u7528\u9700\u8981\u66f4\u8c28\u614e\uff0c\u4f7f\u7528\u4e0d\u5f53\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u548c\u91ce\u6307\u9488\u7b49\u95ee\u9898\u3002

    "},{"location":"chapter_heap/top_k/","title":"8.3 \u00a0 Top-k \u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u65e0\u5e8f\u6570\u7ec4 nums \uff0c\u8bf7\u8fd4\u56de\u6570\u7ec4\u4e2d\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u3002

    \u5bf9\u4e8e\u8be5\u95ee\u9898\uff0c\u6211\u4eec\u5148\u4ecb\u7ecd\u4e24\u79cd\u601d\u8def\u6bd4\u8f83\u76f4\u63a5\u7684\u89e3\u6cd5\uff0c\u518d\u4ecb\u7ecd\u6548\u7387\u66f4\u9ad8\u7684\u5806\u89e3\u6cd5\u3002

    "},{"location":"chapter_heap/top_k/#831","title":"8.3.1 \u00a0 \u65b9\u6cd5\u4e00\uff1a\u904d\u5386\u9009\u62e9","text":"

    \u6211\u4eec\u53ef\u4ee5\u8fdb\u884c\u56fe 8-6 \u6240\u793a\u7684 \\(k\\) \u8f6e\u904d\u5386\uff0c\u5206\u522b\u5728\u6bcf\u8f6e\u4e2d\u63d0\u53d6\u7b2c \\(1\\)\u3001\\(2\\)\u3001\\(\\dots\\)\u3001\\(k\\) \u5927\u7684\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nk)\\) \u3002

    \u6b64\u65b9\u6cd5\u53ea\u9002\u7528\u4e8e \\(k \\ll n\\) \u7684\u60c5\u51b5\uff0c\u56e0\u4e3a\u5f53 \\(k\\) \u4e0e \\(n\\) \u6bd4\u8f83\u63a5\u8fd1\u65f6\uff0c\u5176\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u5411\u4e8e \\(O(n^2)\\) \uff0c\u975e\u5e38\u8017\u65f6\u3002

    \u56fe 8-6 \u00a0 \u904d\u5386\u5bfb\u627e\u6700\u5927\u7684 k \u4e2a\u5143\u7d20

    Tip

    \u5f53 \\(k = n\\) \u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5b8c\u6574\u7684\u6709\u5e8f\u5e8f\u5217\uff0c\u6b64\u65f6\u7b49\u4ef7\u4e8e\u201c\u9009\u62e9\u6392\u5e8f\u201d\u7b97\u6cd5\u3002

    "},{"location":"chapter_heap/top_k/#832","title":"8.3.2 \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u6392\u5e8f","text":"

    \u5982\u56fe 8-7 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u5bf9\u6570\u7ec4 nums \u8fdb\u884c\u6392\u5e8f\uff0c\u518d\u8fd4\u56de\u6700\u53f3\u8fb9\u7684 \\(k\\) \u4e2a\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    \u663e\u7136\uff0c\u8be5\u65b9\u6cd5\u201c\u8d85\u989d\u201d\u5b8c\u6210\u4efb\u52a1\u4e86\uff0c\u56e0\u4e3a\u6211\u4eec\u53ea\u9700\u627e\u51fa\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u5373\u53ef\uff0c\u800c\u4e0d\u9700\u8981\u6392\u5e8f\u5176\u4ed6\u5143\u7d20\u3002

    \u56fe 8-7 \u00a0 \u6392\u5e8f\u5bfb\u627e\u6700\u5927\u7684 k \u4e2a\u5143\u7d20

    "},{"location":"chapter_heap/top_k/#833","title":"8.3.3 \u00a0 \u65b9\u6cd5\u4e09\uff1a\u5806","text":"

    \u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u5806\u66f4\u52a0\u9ad8\u6548\u5730\u89e3\u51b3 Top-k \u95ee\u9898\uff0c\u6d41\u7a0b\u5982\u56fe 8-8 \u6240\u793a\u3002

    1. \u521d\u59cb\u5316\u4e00\u4e2a\u5c0f\u9876\u5806\uff0c\u5176\u5806\u9876\u5143\u7d20\u6700\u5c0f\u3002
    2. \u5148\u5c06\u6570\u7ec4\u7684\u524d \\(k\\) \u4e2a\u5143\u7d20\u4f9d\u6b21\u5165\u5806\u3002
    3. \u4ece\u7b2c \\(k + 1\\) \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\uff0c\u5e76\u5c06\u5f53\u524d\u5143\u7d20\u5165\u5806\u3002
    4. \u904d\u5386\u5b8c\u6210\u540e\uff0c\u5806\u4e2d\u4fdd\u5b58\u7684\u5c31\u662f\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u3002
    <1><2><3><4><5><6><7><8><9>

    \u56fe 8-8 \u00a0 \u57fa\u4e8e\u5806\u5bfb\u627e\u6700\u5927\u7684 k \u4e2a\u5143\u7d20

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig top_k.py
    def top_k_heap(nums: list[int], k: int) -> list[int]:\n    \"\"\"\u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\"\"\"\n    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    heap = []\n    # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i in range(k):\n        heapq.heappush(heap, nums[i])\n    # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in range(k, len(nums)):\n        # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap[0]:\n            heapq.heappop(heap)\n            heapq.heappush(heap, nums[i])\n    return heap\n
    top_k.cpp
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\npriority_queue<int, vector<int>, greater<int>> topKHeap(vector<int> &nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    priority_queue<int, vector<int>, greater<int>> heap;\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.push(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.size(); i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.top()) {\n            heap.pop();\n            heap.push(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.java
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nQueue<Integer> topKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    Queue<Integer> heap = new PriorityQueue<Integer>();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.offer(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll();\n            heap.offer(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.cs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nPriorityQueue<int, int> TopKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    PriorityQueue<int, int> heap = new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.Enqueue(nums[i], nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.Length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.Peek()) {\n            heap.Dequeue();\n            heap.Enqueue(nums[i], nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.go
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums []int, k int) *minHeap {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    h := &minHeap{}\n    heap.Init(h)\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i := 0; i < k; i++ {\n        heap.Push(h, nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i := k; i < len(nums); i++ {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > h.Top().(int) {\n            heap.Pop(h)\n            heap.Push(h, nums[i])\n        }\n    }\n    return h\n}\n
    top_k.swift
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums: [Int], k: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5c0f\u9876\u5806\uff0c\u5e76\u5c06\u524d k \u4e2a\u5143\u7d20\u5efa\u5806\n    var heap = Heap(nums.prefix(k))\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in nums.indices.dropFirst(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap.min()! {\n            _ = heap.removeMin()\n            heap.insert(nums[i])\n        }\n    }\n    return heap.unordered\n}\n
    top_k.js
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap, val) {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums, k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.ts
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap: MaxHeap, val: number): void {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap: MaxHeap): number[] {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num: number) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums: number[], k: number): number[] {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.dart
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nMinHeap topKHeap(List<int> nums, int k) {\n  // \u521d\u59cb\u5316\u5c0f\u9876\u5806\uff0c\u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  MinHeap heap = MinHeap(nums.sublist(0, k));\n  // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for (int i = k; i < nums.length; i++) {\n    // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if (nums[i] > heap.peek()) {\n      heap.pop();\n      heap.push(nums[i]);\n    }\n  }\n  return heap;\n}\n
    top_k.rs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfn top_k_heap(nums: Vec<i32>, k: usize) -> BinaryHeap<Reverse<i32>> {\n    // BinaryHeap \u662f\u5927\u9876\u5806\uff0c\u4f7f\u7528 Reverse \u5c06\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u5b9e\u73b0\u5c0f\u9876\u5806\n    let mut heap = BinaryHeap::<Reverse<i32>>::new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for &num in nums.iter().take(k) {\n        heap.push(Reverse(num));\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for &num in nums.iter().skip(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if num > heap.peek().unwrap().0 {\n            heap.pop();\n            heap.push(Reverse(num));\n        }\n    }\n    heap\n}\n
    top_k.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid pushMinHeap(MaxHeap *maxHeap, int val) {\n    // \u5143\u7d20\u53d6\u53cd\n    push(maxHeap, -val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nint popMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -pop(maxHeap);\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peekMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -peek(maxHeap);\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n// \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\u7684\u51fd\u6570\nint *topKHeap(int *nums, int sizeNums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    int *empty = (int *)malloc(0);\n    MaxHeap *maxHeap = newMaxHeap(empty, 0);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < sizeNums; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    int *res = getMinHeap(maxHeap);\n    // \u91ca\u653e\u5185\u5b58\n    delMaxHeap(maxHeap);\n    return res;\n}\n
    top_k.kt
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfun topKHeap(nums: IntArray, k: Int): Queue<Int> {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    val heap = PriorityQueue<Int>()\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (i in 0..<k) {\n        heap.offer(nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (i in k..<nums.size) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll()\n            heap.offer(nums[i])\n        }\n    }\n    return heap\n}\n
    top_k.rb
    ### \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 ###\ndef top_k_heap(nums, k)\n  # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n  # \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n  max_heap = MaxHeap.new([])\n\n  # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  for i in 0...k\n    push_min_heap(max_heap, nums[i])\n  end\n\n  # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for i in k...nums.length\n    # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if nums[i] > peek_min_heap(max_heap)\n      pop_min_heap(max_heap)\n      push_min_heap(max_heap, nums[i])\n    end\n  end\n\n  get_min_heap(max_heap)\nend\n
    top_k.zig
    [class]{}-[func]{topKHeap}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u603b\u5171\u6267\u884c\u4e86 \\(n\\) \u8f6e\u5165\u5806\u548c\u51fa\u5806\uff0c\u5806\u7684\u6700\u5927\u957f\u5ea6\u4e3a \\(k\\) \uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log k)\\) \u3002\u8be5\u65b9\u6cd5\u7684\u6548\u7387\u5f88\u9ad8\uff0c\u5f53 \\(k\\) \u8f83\u5c0f\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u5411 \\(O(n)\\) \uff1b\u5f53 \\(k\\) \u8f83\u5927\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u4f1a\u8d85\u8fc7 \\(O(n \\log n)\\) \u3002

    \u53e6\u5916\uff0c\u8be5\u65b9\u6cd5\u9002\u7528\u4e8e\u52a8\u6001\u6570\u636e\u6d41\u7684\u4f7f\u7528\u573a\u666f\u3002\u5728\u4e0d\u65ad\u52a0\u5165\u6570\u636e\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u6301\u7eed\u7ef4\u62a4\u5806\u5185\u7684\u5143\u7d20\uff0c\u4ece\u800c\u5b9e\u73b0\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u7684\u52a8\u6001\u66f4\u65b0\u3002

    "},{"location":"chapter_hello_algo/","title":"\u5e8f","text":"

    \u51e0\u5e74\u524d\uff0c\u6211\u5728\u529b\u6263\u4e0a\u5206\u4eab\u4e86\u201c\u5251\u6307 Offer\u201d\u7cfb\u5217\u9898\u89e3\uff0c\u53d7\u5230\u4e86\u8bb8\u591a\u8bfb\u8005\u7684\u9f13\u52b1\u548c\u652f\u6301\u3002\u5728\u4e0e\u8bfb\u8005\u4ea4\u6d41\u671f\u95f4\uff0c\u6211\u6700\u5e38\u88ab\u95ee\u7684\u4e00\u4e2a\u95ee\u9898\u662f\u201c\u5982\u4f55\u5165\u95e8\u7b97\u6cd5\u201d\u3002\u9010\u6e10\u5730\uff0c\u6211\u5bf9\u8fd9\u4e2a\u95ee\u9898\u4ea7\u751f\u4e86\u6d53\u539a\u7684\u5174\u8da3\u3002

    \u4e24\u773c\u4e00\u62b9\u9ed1\u5730\u5237\u9898\u4f3c\u4e4e\u662f\u6700\u53d7\u6b22\u8fce\u7684\u65b9\u6cd5\uff0c\u7b80\u5355\u3001\u76f4\u63a5\u4e14\u6709\u6548\u3002\u7136\u800c\u5237\u9898\u5c31\u5982\u540c\u73a9\u201c\u626b\u96f7\u201d\u6e38\u620f\uff0c\u81ea\u5b66\u80fd\u529b\u5f3a\u7684\u4eba\u80fd\u591f\u987a\u5229\u5c06\u5730\u96f7\u9010\u4e2a\u6392\u6389\uff0c\u800c\u57fa\u7840\u4e0d\u8db3\u7684\u4eba\u5f88\u53ef\u80fd\u88ab\u70b8\u5f97\u6ee1\u5934\u662f\u5305\uff0c\u5e76\u5728\u632b\u6298\u4e2d\u6b65\u6b65\u9000\u7f29\u3002\u901a\u8bfb\u6559\u6750\u4e5f\u662f\u4e00\u79cd\u5e38\u89c1\u505a\u6cd5\uff0c\u4f46\u5bf9\u4e8e\u9762\u5411\u6c42\u804c\u7684\u4eba\u6765\u8bf4\uff0c\u6bd5\u4e1a\u8bba\u6587\u3001\u6295\u9012\u7b80\u5386\u3001\u51c6\u5907\u7b14\u8bd5\u548c\u9762\u8bd5\u5df2\u7ecf\u6d88\u8017\u4e86\u5927\u90e8\u5206\u7cbe\u529b\uff0c\u5543\u539a\u91cd\u7684\u4e66\u5f80\u5f80\u53d8\u6210\u4e86\u4e00\u9879\u8270\u5de8\u7684\u6311\u6218\u3002

    \u5982\u679c\u4f60\u4e5f\u9762\u4e34\u7c7b\u4f3c\u7684\u56f0\u6270\uff0c\u90a3\u4e48\u5f88\u5e78\u8fd0\u8fd9\u672c\u4e66\u201c\u627e\u201d\u5230\u4e86\u4f60\u3002\u672c\u4e66\u662f\u6211\u5bf9\u8fd9\u4e2a\u95ee\u9898\u7ed9\u51fa\u7684\u7b54\u6848\uff0c\u5373\u4f7f\u4e0d\u662f\u6700\u4f18\u89e3\uff0c\u4e5f\u81f3\u5c11\u662f\u4e00\u6b21\u79ef\u6781\u7684\u5c1d\u8bd5\u3002\u672c\u4e66\u867d\u7136\u4e0d\u8db3\u4ee5\u8ba9\u4f60\u76f4\u63a5\u62ff\u5230 Offer\uff0c\u4f46\u4f1a\u5f15\u5bfc\u4f60\u63a2\u7d22\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u201c\u77e5\u8bc6\u5730\u56fe\u201d\uff0c\u5e26\u4f60\u4e86\u89e3\u4e0d\u540c\u201c\u5730\u96f7\u201d\u7684\u5f62\u72b6\u3001\u5927\u5c0f\u548c\u5206\u5e03\u4f4d\u7f6e\uff0c\u8ba9\u4f60\u638c\u63e1\u5404\u79cd\u201c\u6392\u96f7\u65b9\u6cd5\u201d\u3002\u6709\u4e86\u8fd9\u4e9b\u672c\u9886\uff0c\u76f8\u4fe1\u4f60\u53ef\u4ee5\u66f4\u52a0\u81ea\u5982\u5730\u5237\u9898\u548c\u9605\u8bfb\u6587\u732e\uff0c\u9010\u6b65\u6784\u5efa\u8d77\u5b8c\u6574\u7684\u77e5\u8bc6\u4f53\u7cfb\u3002

    \u6211\u6df1\u6df1\u8d5e\u540c\u8d39\u66fc\u6559\u6388\u6240\u8a00\uff1a\u201cKnowledge isn't free. You have to pay attention.\u201d\u4ece\u8fd9\u4e2a\u610f\u4e49\u4e0a\u770b\uff0c\u8fd9\u672c\u4e66\u5e76\u975e\u5b8c\u5168\u201c\u514d\u8d39\u201d\u3002\u4e3a\u4e86\u4e0d\u8f9c\u8d1f\u4f60\u4e3a\u672c\u4e66\u6240\u4ed8\u51fa\u7684\u5b9d\u8d35\u201c\u6ce8\u610f\u529b\u201d\uff0c\u6211\u4f1a\u7aed\u5c3d\u6240\u80fd\uff0c\u6295\u5165\u6700\u5927\u7684\u201c\u6ce8\u610f\u529b\u201d\u6765\u5b8c\u6210\u672c\u4e66\u7684\u521b\u4f5c\u3002

    \u672c\u4eba\u81ea\u77e5\u5b66\u758f\u624d\u6d45\uff0c\u4e66\u4e2d\u5185\u5bb9\u867d\u7136\u5df2\u7ecf\u8fc7\u4e00\u6bb5\u65f6\u95f4\u7684\u6253\u78e8\uff0c\u4f46\u4e00\u5b9a\u4ecd\u6709\u8bb8\u591a\u9519\u8bef\uff0c\u6073\u8bf7\u5404\u4f4d\u8001\u5e08\u548c\u540c\u5b66\u6279\u8bc4\u6307\u6b63\u3002

    Hello\uff0c\u7b97\u6cd5\uff01

    \u8ba1\u7b97\u673a\u7684\u51fa\u73b0\u7ed9\u4e16\u754c\u5e26\u6765\u4e86\u5de8\u5927\u53d8\u9769\uff0c\u5b83\u51ed\u501f\u9ad8\u901f\u7684\u8ba1\u7b97\u80fd\u529b\u548c\u51fa\u8272\u7684\u53ef\u7f16\u7a0b\u6027\uff0c\u6210\u4e3a\u4e86\u6267\u884c\u7b97\u6cd5\u4e0e\u5904\u7406\u6570\u636e\u7684\u7406\u60f3\u5a92\u4ecb\u3002\u65e0\u8bba\u662f\u7535\u5b50\u6e38\u620f\u7684\u903c\u771f\u753b\u9762\u3001\u81ea\u52a8\u9a7e\u9a76\u7684\u667a\u80fd\u51b3\u7b56\uff0c\u8fd8\u662f AlphaGo \u7684\u7cbe\u5f69\u68cb\u5c40\u3001ChatGPT \u7684\u81ea\u7136\u4ea4\u4e92\uff0c\u8fd9\u4e9b\u5e94\u7528\u90fd\u662f\u7b97\u6cd5\u5728\u8ba1\u7b97\u673a\u4e0a\u7684\u7cbe\u5999\u6f14\u7ece\u3002

    \u4e8b\u5b9e\u4e0a\uff0c\u5728\u8ba1\u7b97\u673a\u95ee\u4e16\u4e4b\u524d\uff0c\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u5c31\u5df2\u7ecf\u5b58\u5728\u4e8e\u4e16\u754c\u7684\u5404\u4e2a\u89d2\u843d\u3002\u65e9\u671f\u7684\u7b97\u6cd5\u76f8\u5bf9\u7b80\u5355\uff0c\u4f8b\u5982\u53e4\u4ee3\u7684\u8ba1\u6570\u65b9\u6cd5\u548c\u5de5\u5177\u5236\u4f5c\u6b65\u9aa4\u7b49\u3002\u968f\u7740\u6587\u660e\u7684\u8fdb\u6b65\uff0c\u7b97\u6cd5\u9010\u6e10\u53d8\u5f97\u66f4\u52a0\u7cbe\u7ec6\u548c\u590d\u6742\u3002\u4ece\u5de7\u593a\u5929\u5de5\u7684\u5320\u4eba\u6280\u827a\u3001\u5230\u89e3\u653e\u751f\u4ea7\u529b\u7684\u5de5\u4e1a\u4ea7\u54c1\u3001\u518d\u5230\u5b87\u5b99\u8fd0\u884c\u7684\u79d1\u5b66\u89c4\u5f8b\uff0c\u51e0\u4e4e\u6bcf\u4e00\u4ef6\u5e73\u51e1\u6216\u4ee4\u4eba\u60ca\u53f9\u7684\u4e8b\u7269\u80cc\u540e\uff0c\u90fd\u9690\u85cf\u7740\u7cbe\u5999\u7684\u7b97\u6cd5\u601d\u60f3\u3002

    \u540c\u6837\uff0c\u6570\u636e\u7ed3\u6784\u65e0\u5904\u4e0d\u5728\uff1a\u5927\u5230\u793e\u4f1a\u7f51\u7edc\uff0c\u5c0f\u5230\u5730\u94c1\u7ebf\u8def\uff0c\u8bb8\u591a\u7cfb\u7edf\u90fd\u53ef\u4ee5\u5efa\u6a21\u4e3a\u201c\u56fe\u201d\uff1b\u5927\u5230\u4e00\u4e2a\u56fd\u5bb6\uff0c\u5c0f\u5230\u4e00\u4e2a\u5bb6\u5ead\uff0c\u793e\u4f1a\u7684\u4e3b\u8981\u7ec4\u7ec7\u5f62\u5f0f\u5448\u73b0\u51fa\u201c\u6811\u201d\u7684\u7279\u5f81\uff1b\u51ac\u5929\u7684\u8863\u670d\u5c31\u50cf\u201c\u6808\u201d\uff0c\u6700\u5148\u7a7f\u4e0a\u7684\u6700\u540e\u624d\u80fd\u8131\u4e0b\uff1b\u7fbd\u6bdb\u7403\u7b52\u5219\u5982\u540c\u201c\u961f\u5217\u201d\uff0c\u4e00\u7aef\u653e\u5165\u3001\u53e6\u4e00\u7aef\u53d6\u51fa\uff1b\u5b57\u5178\u5c31\u50cf\u4e00\u4e2a\u201c\u54c8\u5e0c\u8868\u201d\uff0c\u80fd\u591f\u5feb\u901f\u67e5\u627e\u76ee\u6807\u8bcd\u6761\u3002

    \u672c\u4e66\u65e8\u5728\u901a\u8fc7\u6e05\u6670\u6613\u61c2\u7684\u52a8\u753b\u56fe\u89e3\u548c\u53ef\u8fd0\u884c\u7684\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u7406\u89e3\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u80fd\u591f\u901a\u8fc7\u7f16\u7a0b\u6765\u5b9e\u73b0\u5b83\u4eec\u3002\u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u672c\u4e66\u81f4\u529b\u4e8e\u63ed\u793a\u7b97\u6cd5\u5728\u590d\u6742\u4e16\u754c\u4e2d\u7684\u751f\u52a8\u4f53\u73b0\uff0c\u5c55\u73b0\u7b97\u6cd5\u4e4b\u7f8e\u3002\u5e0c\u671b\u672c\u4e66\u80fd\u591f\u5e2e\u52a9\u5230\u4f60\uff01

    "},{"location":"chapter_introduction/","title":"\u7b2c 1 \u7ae0 \u00a0 \u521d\u8bc6\u7b97\u6cd5","text":"

    Abstract

    \u4e00\u4f4d\u5c11\u5973\u7fe9\u7fe9\u8d77\u821e\uff0c\u4e0e\u6570\u636e\u4ea4\u7ec7\u5728\u4e00\u8d77\uff0c\u88d9\u6446\u4e0a\u98d8\u626c\u7740\u7b97\u6cd5\u7684\u65cb\u5f8b\u3002

    \u5979\u9080\u8bf7\u4f60\u5171\u821e\uff0c\u8bf7\u7d27\u8ddf\u5979\u7684\u6b65\u4f10\uff0c\u8e0f\u5165\u5145\u6ee1\u903b\u8f91\u4e0e\u7f8e\u611f\u7684\u7b97\u6cd5\u4e16\u754c\u3002

    "},{"location":"chapter_introduction/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 1.1 \u00a0 \u7b97\u6cd5\u65e0\u5904\u4e0d\u5728
    • 1.2 \u00a0 \u7b97\u6cd5\u662f\u4ec0\u4e48
    • 1.3 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_introduction/algorithms_are_everywhere/","title":"1.1 \u00a0 \u7b97\u6cd5\u65e0\u5904\u4e0d\u5728","text":"

    \u5f53\u6211\u4eec\u542c\u5230\u201c\u7b97\u6cd5\u201d\u8fd9\u4e2a\u8bcd\u65f6\uff0c\u5f88\u81ea\u7136\u5730\u4f1a\u60f3\u5230\u6570\u5b66\u3002\u7136\u800c\u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u7b97\u6cd5\u5e76\u4e0d\u6d89\u53ca\u590d\u6742\u6570\u5b66\uff0c\u800c\u662f\u66f4\u591a\u5730\u4f9d\u8d56\u57fa\u672c\u903b\u8f91\uff0c\u8fd9\u4e9b\u903b\u8f91\u5728\u6211\u4eec\u7684\u65e5\u5e38\u751f\u6d3b\u4e2d\u5904\u5904\u53ef\u89c1\u3002

    \u5728\u6b63\u5f0f\u63a2\u8ba8\u7b97\u6cd5\u4e4b\u524d\uff0c\u6709\u4e00\u4e2a\u6709\u8da3\u7684\u4e8b\u5b9e\u503c\u5f97\u5206\u4eab\uff1a\u4f60\u5df2\u7ecf\u5728\u4e0d\u77e5\u4e0d\u89c9\u4e2d\u5b66\u4f1a\u4e86\u8bb8\u591a\u7b97\u6cd5\uff0c\u5e76\u4e60\u60ef\u5c06\u5b83\u4eec\u5e94\u7528\u5230\u65e5\u5e38\u751f\u6d3b\u4e2d\u4e86\u3002\u4e0b\u9762\u6211\u5c06\u4e3e\u51e0\u4e2a\u5177\u4f53\u7684\u4f8b\u5b50\u6765\u8bc1\u5b9e\u8fd9\u4e00\u70b9\u3002

    \u4f8b\u4e00\uff1a\u67e5\u5b57\u5178\u3002\u5728\u5b57\u5178\u91cc\uff0c\u6bcf\u4e2a\u6c49\u5b57\u90fd\u5bf9\u5e94\u4e00\u4e2a\u62fc\u97f3\uff0c\u800c\u5b57\u5178\u662f\u6309\u7167\u62fc\u97f3\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\u7684\u3002\u5047\u8bbe\u6211\u4eec\u9700\u8981\u67e5\u627e\u4e00\u4e2a\u62fc\u97f3\u9996\u5b57\u6bcd\u4e3a \\(r\\) \u7684\u5b57\uff0c\u901a\u5e38\u4f1a\u6309\u7167\u56fe 1-1 \u6240\u793a\u7684\u65b9\u5f0f\u5b9e\u73b0\u3002

    1. \u7ffb\u5f00\u5b57\u5178\u7ea6\u4e00\u534a\u7684\u9875\u6570\uff0c\u67e5\u770b\u8be5\u9875\u7684\u9996\u5b57\u6bcd\u662f\u4ec0\u4e48\uff0c\u5047\u8bbe\u9996\u5b57\u6bcd\u4e3a \\(m\\) \u3002
    2. \u7531\u4e8e\u5728\u62fc\u97f3\u5b57\u6bcd\u8868\u4e2d \\(r\\) \u4f4d\u4e8e \\(m\\) \u4e4b\u540e\uff0c\u6240\u4ee5\u6392\u9664\u5b57\u5178\u524d\u534a\u90e8\u5206\uff0c\u67e5\u627e\u8303\u56f4\u7f29\u5c0f\u5230\u540e\u534a\u90e8\u5206\u3002
    3. \u4e0d\u65ad\u91cd\u590d\u6b65\u9aa4 1. \u548c \u6b65\u9aa4 2. \uff0c\u76f4\u81f3\u627e\u5230\u62fc\u97f3\u9996\u5b57\u6bcd\u4e3a \\(r\\) \u7684\u9875\u7801\u4e3a\u6b62\u3002
    <1><2><3><4><5>

    \u56fe 1-1 \u00a0 \u67e5\u5b57\u5178\u6b65\u9aa4

    \u67e5\u5b57\u5178\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5fc5\u5907\u6280\u80fd\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u8457\u540d\u7684\u201c\u4e8c\u5206\u67e5\u627e\u201d\u7b97\u6cd5\u3002\u4ece\u6570\u636e\u7ed3\u6784\u7684\u89d2\u5ea6\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u5b57\u5178\u89c6\u4e3a\u4e00\u4e2a\u5df2\u6392\u5e8f\u7684\u201c\u6570\u7ec4\u201d\uff1b\u4ece\u7b97\u6cd5\u7684\u89d2\u5ea6\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u4e0a\u8ff0\u67e5\u5b57\u5178\u7684\u4e00\u7cfb\u5217\u64cd\u4f5c\u770b\u4f5c\u201c\u4e8c\u5206\u67e5\u627e\u201d\u3002

    \u4f8b\u4e8c\uff1a\u6574\u7406\u6251\u514b\u3002\u6211\u4eec\u5728\u6253\u724c\u65f6\uff0c\u6bcf\u5c40\u90fd\u9700\u8981\u6574\u7406\u624b\u4e2d\u7684\u6251\u514b\u724c\uff0c\u4f7f\u5176\u4ece\u5c0f\u5230\u5927\u6392\u5217\uff0c\u5b9e\u73b0\u6d41\u7a0b\u5982\u56fe 1-2 \u6240\u793a\u3002

    1. \u5c06\u6251\u514b\u724c\u5212\u5206\u4e3a\u201c\u6709\u5e8f\u201d\u548c\u201c\u65e0\u5e8f\u201d\u4e24\u90e8\u5206\uff0c\u5e76\u5047\u8bbe\u521d\u59cb\u72b6\u6001\u4e0b\u6700\u5de6 1 \u5f20\u6251\u514b\u724c\u5df2\u7ecf\u6709\u5e8f\u3002
    2. \u5728\u65e0\u5e8f\u90e8\u5206\u62bd\u51fa\u4e00\u5f20\u6251\u514b\u724c\uff0c\u63d2\u5165\u81f3\u6709\u5e8f\u90e8\u5206\u7684\u6b63\u786e\u4f4d\u7f6e\uff1b\u5b8c\u6210\u540e\u6700\u5de6 2 \u5f20\u6251\u514b\u5df2\u7ecf\u6709\u5e8f\u3002
    3. \u4e0d\u65ad\u5faa\u73af\u6b65\u9aa4 2. \uff0c\u6bcf\u4e00\u8f6e\u5c06\u4e00\u5f20\u6251\u514b\u724c\u4ece\u65e0\u5e8f\u90e8\u5206\u63d2\u5165\u81f3\u6709\u5e8f\u90e8\u5206\uff0c\u76f4\u81f3\u6240\u6709\u6251\u514b\u724c\u90fd\u6709\u5e8f\u3002

    \u56fe 1-2 \u00a0 \u6251\u514b\u6392\u5e8f\u6b65\u9aa4

    \u4e0a\u8ff0\u6574\u7406\u6251\u514b\u724c\u7684\u65b9\u6cd5\u672c\u8d28\u4e0a\u662f\u201c\u63d2\u5165\u6392\u5e8f\u201d\u7b97\u6cd5\uff0c\u5b83\u5728\u5904\u7406\u5c0f\u578b\u6570\u636e\u96c6\u65f6\u975e\u5e38\u9ad8\u6548\u3002\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u6392\u5e8f\u5e93\u51fd\u6570\u4e2d\u90fd\u6709\u63d2\u5165\u6392\u5e8f\u7684\u8eab\u5f71\u3002

    \u4f8b\u4e09\uff1a\u8d27\u5e01\u627e\u96f6\u3002\u5047\u8bbe\u6211\u4eec\u5728\u8d85\u5e02\u8d2d\u4e70\u4e86 \\(69\\) \u5143\u7684\u5546\u54c1\uff0c\u7ed9\u4e86\u6536\u94f6\u5458 \\(100\\) \u5143\uff0c\u5219\u6536\u94f6\u5458\u9700\u8981\u627e\u6211\u4eec \\(31\\) \u5143\u3002\u4ed6\u4f1a\u5f88\u81ea\u7136\u5730\u5b8c\u6210\u5982\u56fe 1-3 \u6240\u793a\u7684\u601d\u8003\u3002

    1. \u53ef\u9009\u9879\u662f\u6bd4 \\(31\\) \u5143\u9762\u503c\u66f4\u5c0f\u7684\u8d27\u5e01\uff0c\u5305\u62ec \\(1\\) \u5143\u3001\\(5\\) \u5143\u3001\\(10\\) \u5143\u3001\\(20\\) \u5143\u3002
    2. \u4ece\u53ef\u9009\u9879\u4e2d\u62ff\u51fa\u6700\u5927\u7684 \\(20\\) \u5143\uff0c\u5269\u4f59 \\(31 - 20 = 11\\) \u5143\u3002
    3. \u4ece\u5269\u4f59\u53ef\u9009\u9879\u4e2d\u62ff\u51fa\u6700\u5927\u7684 \\(10\\) \u5143\uff0c\u5269\u4f59 \\(11 - 10 = 1\\) \u5143\u3002
    4. \u4ece\u5269\u4f59\u53ef\u9009\u9879\u4e2d\u62ff\u51fa\u6700\u5927\u7684 \\(1\\) \u5143\uff0c\u5269\u4f59 \\(1 - 1 = 0\\) \u5143\u3002
    5. \u5b8c\u6210\u627e\u96f6\uff0c\u65b9\u6848\u4e3a \\(20 + 10 + 1 = 31\\) \u5143\u3002

    \u56fe 1-3 \u00a0 \u8d27\u5e01\u627e\u96f6\u8fc7\u7a0b

    \u5728\u4ee5\u4e0a\u6b65\u9aa4\u4e2d\uff0c\u6211\u4eec\u6bcf\u4e00\u6b65\u90fd\u91c7\u53d6\u5f53\u524d\u770b\u6765\u6700\u597d\u7684\u9009\u62e9\uff08\u5c3d\u53ef\u80fd\u7528\u5927\u9762\u989d\u7684\u8d27\u5e01\uff09\uff0c\u6700\u7ec8\u5f97\u5230\u4e86\u53ef\u884c\u7684\u627e\u96f6\u65b9\u6848\u3002\u4ece\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u89d2\u5ea6\u770b\uff0c\u8fd9\u79cd\u65b9\u6cd5\u672c\u8d28\u4e0a\u662f\u201c\u8d2a\u5fc3\u201d\u7b97\u6cd5\u3002

    \u5c0f\u5230\u70f9\u996a\u4e00\u9053\u83dc\uff0c\u5927\u5230\u661f\u9645\u822a\u884c\uff0c\u51e0\u4e4e\u6240\u6709\u95ee\u9898\u7684\u89e3\u51b3\u90fd\u79bb\u4e0d\u5f00\u7b97\u6cd5\u3002\u8ba1\u7b97\u673a\u7684\u51fa\u73b0\u4f7f\u5f97\u6211\u4eec\u80fd\u591f\u901a\u8fc7\u7f16\u7a0b\u5c06\u6570\u636e\u7ed3\u6784\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\uff0c\u540c\u65f6\u7f16\u5199\u4ee3\u7801\u8c03\u7528 CPU \u548c GPU \u6267\u884c\u7b97\u6cd5\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u6211\u4eec\u5c31\u80fd\u628a\u751f\u6d3b\u4e2d\u7684\u95ee\u9898\u8f6c\u79fb\u5230\u8ba1\u7b97\u673a\u4e0a\uff0c\u4ee5\u66f4\u9ad8\u6548\u7684\u65b9\u5f0f\u89e3\u51b3\u5404\u79cd\u590d\u6742\u95ee\u9898\u3002

    Tip

    \u5982\u679c\u4f60\u5bf9\u6570\u636e\u7ed3\u6784\u3001\u7b97\u6cd5\u3001\u6570\u7ec4\u548c\u4e8c\u5206\u67e5\u627e\u7b49\u6982\u5ff5\u4ecd\u611f\u5230\u4e00\u77e5\u534a\u89e3\uff0c\u8bf7\u7ee7\u7eed\u5f80\u4e0b\u9605\u8bfb\uff0c\u672c\u4e66\u5c06\u5f15\u5bfc\u4f60\u8fc8\u5165\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u77e5\u8bc6\u6bbf\u5802\u3002

    "},{"location":"chapter_introduction/summary/","title":"1.3 \u00a0 \u5c0f\u7ed3","text":"
    • \u7b97\u6cd5\u5728\u65e5\u5e38\u751f\u6d3b\u4e2d\u65e0\u5904\u4e0d\u5728\uff0c\u5e76\u4e0d\u662f\u9065\u4e0d\u53ef\u53ca\u7684\u9ad8\u6df1\u77e5\u8bc6\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u5df2\u7ecf\u5728\u4e0d\u77e5\u4e0d\u89c9\u4e2d\u5b66\u4f1a\u4e86\u8bb8\u591a\u7b97\u6cd5\uff0c\u7528\u4ee5\u89e3\u51b3\u751f\u6d3b\u4e2d\u7684\u5927\u5c0f\u95ee\u9898\u3002
    • \u67e5\u5b57\u5178\u7684\u539f\u7406\u4e0e\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u76f8\u4e00\u81f4\u3002\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u4f53\u73b0\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u91cd\u8981\u7b97\u6cd5\u601d\u60f3\u3002
    • \u6574\u7406\u6251\u514b\u7684\u8fc7\u7a0b\u4e0e\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\u975e\u5e38\u7c7b\u4f3c\u3002\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\u9002\u5408\u6392\u5e8f\u5c0f\u578b\u6570\u636e\u96c6\u3002
    • \u8d27\u5e01\u627e\u96f6\u7684\u6b65\u9aa4\u672c\u8d28\u4e0a\u662f\u8d2a\u5fc3\u7b97\u6cd5\uff0c\u6bcf\u4e00\u6b65\u90fd\u91c7\u53d6\u5f53\u524d\u770b\u6765\u6700\u597d\u7684\u9009\u62e9\u3002
    • \u7b97\u6cd5\u662f\u5728\u6709\u9650\u65f6\u95f4\u5185\u89e3\u51b3\u7279\u5b9a\u95ee\u9898\u7684\u4e00\u7ec4\u6307\u4ee4\u6216\u64cd\u4f5c\u6b65\u9aa4\uff0c\u800c\u6570\u636e\u7ed3\u6784\u662f\u8ba1\u7b97\u673a\u4e2d\u7ec4\u7ec7\u548c\u5b58\u50a8\u6570\u636e\u7684\u65b9\u5f0f\u3002
    • \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7d27\u5bc6\u76f8\u8fde\u3002\u6570\u636e\u7ed3\u6784\u662f\u7b97\u6cd5\u7684\u57fa\u77f3\uff0c\u800c\u7b97\u6cd5\u662f\u6570\u636e\u7ed3\u6784\u53d1\u6325\u4f5c\u7528\u7684\u821e\u53f0\u3002
    • \u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7c7b\u6bd4\u4e3a\u62fc\u88c5\u79ef\u6728\uff0c\u79ef\u6728\u4ee3\u8868\u6570\u636e\uff0c\u79ef\u6728\u7684\u5f62\u72b6\u548c\u8fde\u63a5\u65b9\u5f0f\u7b49\u4ee3\u8868\u6570\u636e\u7ed3\u6784\uff0c\u62fc\u88c5\u79ef\u6728\u7684\u6b65\u9aa4\u5219\u5bf9\u5e94\u7b97\u6cd5\u3002
    "},{"location":"chapter_introduction/summary/#1-q-a","title":"1. \u00a0 Q & A","text":"

    Q\uff1a\u4f5c\u4e3a\u4e00\u540d\u7a0b\u5e8f\u5458\uff0c\u6211\u5728\u65e5\u5e38\u5de5\u4f5c\u4e2d\u4ece\u672a\u7528\u7b97\u6cd5\u89e3\u51b3\u8fc7\u95ee\u9898\uff0c\u5e38\u7528\u7b97\u6cd5\u90fd\u88ab\u7f16\u7a0b\u8bed\u8a00\u5c01\u88c5\u597d\u4e86\uff0c\u76f4\u63a5\u7528\u5c31\u53ef\u4ee5\u4e86\uff1b\u8fd9\u662f\u5426\u610f\u5473\u7740\u6211\u4eec\u5de5\u4f5c\u4e2d\u7684\u95ee\u9898\u8fd8\u6ca1\u6709\u5230\u8fbe\u9700\u8981\u7b97\u6cd5\u7684\u7a0b\u5ea6\uff1f

    \u5982\u679c\u628a\u5177\u4f53\u7684\u5de5\u4f5c\u6280\u80fd\u6bd4\u4f5c\u662f\u6b66\u529f\u7684\u201c\u62db\u5f0f\u201d\u7684\u8bdd\uff0c\u90a3\u4e48\u57fa\u7840\u79d1\u76ee\u5e94\u8be5\u66f4\u50cf\u662f\u201c\u5185\u529f\u201d\u3002

    \u6211\u8ba4\u4e3a\u5b66\u7b97\u6cd5\uff08\u4ee5\u53ca\u5176\u4ed6\u57fa\u7840\u79d1\u76ee\uff09\u7684\u610f\u4e49\u4e0d\u662f\u5728\u4e8e\u5728\u5de5\u4f5c\u4e2d\u4ece\u96f6\u5b9e\u73b0\u5b83\uff0c\u800c\u662f\u57fa\u4e8e\u5b66\u5230\u7684\u77e5\u8bc6\uff0c\u5728\u89e3\u51b3\u95ee\u9898\u65f6\u80fd\u591f\u4f5c\u51fa\u4e13\u4e1a\u7684\u53cd\u5e94\u548c\u5224\u65ad\uff0c\u4ece\u800c\u63d0\u5347\u5de5\u4f5c\u7684\u6574\u4f53\u8d28\u91cf\u3002\u4e3e\u4e00\u4e2a\u7b80\u5355\u4f8b\u5b50\uff0c\u6bcf\u79cd\u7f16\u7a0b\u8bed\u8a00\u90fd\u5185\u7f6e\u4e86\u6392\u5e8f\u51fd\u6570\uff1a

    • \u5982\u679c\u6211\u4eec\u6ca1\u6709\u5b66\u8fc7\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\uff0c\u90a3\u4e48\u7ed9\u5b9a\u4efb\u4f55\u6570\u636e\uff0c\u6211\u4eec\u53ef\u80fd\u90fd\u585e\u7ed9\u8fd9\u4e2a\u6392\u5e8f\u51fd\u6570\u53bb\u505a\u4e86\u3002\u8fd0\u884c\u987a\u7545\u3001\u6027\u80fd\u4e0d\u9519\uff0c\u770b\u4e0a\u53bb\u5e76\u6ca1\u6709\u4ec0\u4e48\u95ee\u9898\u3002
    • \u4f46\u5982\u679c\u5b66\u8fc7\u7b97\u6cd5\uff0c\u6211\u4eec\u5c31\u4f1a\u77e5\u9053\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(n \\log n)\\) \uff1b\u800c\u5982\u679c\u7ed9\u5b9a\u7684\u6570\u636e\u662f\u56fa\u5b9a\u4f4d\u6570\u7684\u6574\u6570\uff08\u4f8b\u5982\u5b66\u53f7\uff09\uff0c\u90a3\u4e48\u6211\u4eec\u5c31\u53ef\u4ee5\u7528\u6548\u7387\u66f4\u9ad8\u7684\u201c\u57fa\u6570\u6392\u5e8f\u201d\u6765\u505a\uff0c\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u964d\u4e3a \\(O(nk)\\) \uff0c\u5176\u4e2d \\(k\\) \u4e3a\u4f4d\u6570\u3002\u5f53\u6570\u636e\u4f53\u91cf\u5f88\u5927\u65f6\uff0c\u8282\u7701\u51fa\u6765\u7684\u8fd0\u884c\u65f6\u95f4\u5c31\u80fd\u521b\u9020\u8f83\u5927\u4ef7\u503c\uff08\u6210\u672c\u964d\u4f4e\u3001\u4f53\u9a8c\u53d8\u597d\u7b49\uff09\u3002

    \u5728\u5de5\u7a0b\u9886\u57df\u4e2d\uff0c\u5927\u91cf\u95ee\u9898\u662f\u96be\u4ee5\u8fbe\u5230\u6700\u4f18\u89e3\u7684\uff0c\u8bb8\u591a\u95ee\u9898\u53ea\u662f\u88ab\u201c\u5dee\u4e0d\u591a\u201d\u5730\u89e3\u51b3\u4e86\u3002\u95ee\u9898\u7684\u96be\u6613\u7a0b\u5ea6\u4e00\u65b9\u9762\u53d6\u51b3\u4e8e\u95ee\u9898\u672c\u8eab\u7684\u6027\u8d28\uff0c\u53e6\u4e00\u65b9\u9762\u4e5f\u53d6\u51b3\u4e8e\u89c2\u6d4b\u95ee\u9898\u7684\u4eba\u7684\u77e5\u8bc6\u50a8\u5907\u3002\u4eba\u7684\u77e5\u8bc6\u8d8a\u5b8c\u5907\u3001\u7ecf\u9a8c\u8d8a\u591a\uff0c\u5206\u6790\u95ee\u9898\u5c31\u4f1a\u8d8a\u6df1\u5165\uff0c\u95ee\u9898\u5c31\u80fd\u88ab\u89e3\u51b3\u5f97\u66f4\u4f18\u96c5\u3002

    "},{"location":"chapter_introduction/what_is_dsa/","title":"1.2 \u00a0 \u7b97\u6cd5\u662f\u4ec0\u4e48","text":""},{"location":"chapter_introduction/what_is_dsa/#121","title":"1.2.1 \u00a0 \u7b97\u6cd5\u5b9a\u4e49","text":"

    \u7b97\u6cd5\uff08algorithm\uff09\u662f\u5728\u6709\u9650\u65f6\u95f4\u5185\u89e3\u51b3\u7279\u5b9a\u95ee\u9898\u7684\u4e00\u7ec4\u6307\u4ee4\u6216\u64cd\u4f5c\u6b65\u9aa4\uff0c\u5b83\u5177\u6709\u4ee5\u4e0b\u7279\u6027\u3002

    • \u95ee\u9898\u662f\u660e\u786e\u7684\uff0c\u5305\u542b\u6e05\u6670\u7684\u8f93\u5165\u548c\u8f93\u51fa\u5b9a\u4e49\u3002
    • \u5177\u6709\u53ef\u884c\u6027\uff0c\u80fd\u591f\u5728\u6709\u9650\u6b65\u9aa4\u3001\u65f6\u95f4\u548c\u5185\u5b58\u7a7a\u95f4\u4e0b\u5b8c\u6210\u3002
    • \u5404\u6b65\u9aa4\u90fd\u6709\u786e\u5b9a\u7684\u542b\u4e49\uff0c\u5728\u76f8\u540c\u7684\u8f93\u5165\u548c\u8fd0\u884c\u6761\u4ef6\u4e0b\uff0c\u8f93\u51fa\u59cb\u7ec8\u76f8\u540c\u3002
    "},{"location":"chapter_introduction/what_is_dsa/#122","title":"1.2.2 \u00a0 \u6570\u636e\u7ed3\u6784\u5b9a\u4e49","text":"

    \u6570\u636e\u7ed3\u6784\uff08data structure\uff09\u662f\u8ba1\u7b97\u673a\u4e2d\u7ec4\u7ec7\u548c\u5b58\u50a8\u6570\u636e\u7684\u65b9\u5f0f\uff0c\u5177\u6709\u4ee5\u4e0b\u8bbe\u8ba1\u76ee\u6807\u3002

    • \u7a7a\u95f4\u5360\u7528\u5c3d\u91cf\u5c11\uff0c\u4ee5\u8282\u7701\u8ba1\u7b97\u673a\u5185\u5b58\u3002
    • \u6570\u636e\u64cd\u4f5c\u5c3d\u53ef\u80fd\u5feb\u901f\uff0c\u6db5\u76d6\u6570\u636e\u8bbf\u95ee\u3001\u6dfb\u52a0\u3001\u5220\u9664\u3001\u66f4\u65b0\u7b49\u3002
    • \u63d0\u4f9b\u7b80\u6d01\u7684\u6570\u636e\u8868\u793a\u548c\u903b\u8f91\u4fe1\u606f\uff0c\u4ee5\u4fbf\u7b97\u6cd5\u9ad8\u6548\u8fd0\u884c\u3002

    \u6570\u636e\u7ed3\u6784\u8bbe\u8ba1\u662f\u4e00\u4e2a\u5145\u6ee1\u6743\u8861\u7684\u8fc7\u7a0b\u3002\u5982\u679c\u60f3\u5728\u67d0\u65b9\u9762\u53d6\u5f97\u63d0\u5347\uff0c\u5f80\u5f80\u9700\u8981\u5728\u53e6\u4e00\u65b9\u9762\u4f5c\u51fa\u59a5\u534f\u3002\u4e0b\u9762\u4e3e\u4e24\u4e2a\u4f8b\u5b50\u3002

    • \u94fe\u8868\u76f8\u8f83\u4e8e\u6570\u7ec4\uff0c\u5728\u6570\u636e\u6dfb\u52a0\u548c\u5220\u9664\u64cd\u4f5c\u4e0a\u66f4\u52a0\u4fbf\u6377\uff0c\u4f46\u727a\u7272\u4e86\u6570\u636e\u8bbf\u95ee\u901f\u5ea6\u3002
    • \u56fe\u76f8\u8f83\u4e8e\u94fe\u8868\uff0c\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u903b\u8f91\u4fe1\u606f\uff0c\u4f46\u9700\u8981\u5360\u7528\u66f4\u5927\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    "},{"location":"chapter_introduction/what_is_dsa/#123","title":"1.2.3 \u00a0 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u5173\u7cfb","text":"

    \u5982\u56fe 1-4 \u6240\u793a\uff0c\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u9ad8\u5ea6\u76f8\u5173\u3001\u7d27\u5bc6\u7ed3\u5408\uff0c\u5177\u4f53\u8868\u73b0\u5728\u4ee5\u4e0b\u4e09\u4e2a\u65b9\u9762\u3002

    • \u6570\u636e\u7ed3\u6784\u662f\u7b97\u6cd5\u7684\u57fa\u77f3\u3002\u6570\u636e\u7ed3\u6784\u4e3a\u7b97\u6cd5\u63d0\u4f9b\u4e86\u7ed3\u6784\u5316\u5b58\u50a8\u7684\u6570\u636e\uff0c\u4ee5\u53ca\u64cd\u4f5c\u6570\u636e\u7684\u65b9\u6cd5\u3002
    • \u7b97\u6cd5\u662f\u6570\u636e\u7ed3\u6784\u53d1\u6325\u4f5c\u7528\u7684\u821e\u53f0\u3002\u6570\u636e\u7ed3\u6784\u672c\u8eab\u4ec5\u5b58\u50a8\u6570\u636e\u4fe1\u606f\uff0c\u7ed3\u5408\u7b97\u6cd5\u624d\u80fd\u89e3\u51b3\u7279\u5b9a\u95ee\u9898\u3002
    • \u7b97\u6cd5\u901a\u5e38\u53ef\u4ee5\u57fa\u4e8e\u4e0d\u540c\u7684\u6570\u636e\u7ed3\u6784\u5b9e\u73b0\uff0c\u4f46\u6267\u884c\u6548\u7387\u53ef\u80fd\u76f8\u5dee\u5f88\u5927\uff0c\u9009\u62e9\u5408\u9002\u7684\u6570\u636e\u7ed3\u6784\u662f\u5173\u952e\u3002

    \u56fe 1-4 \u00a0 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u5173\u7cfb

    \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u72b9\u5982\u56fe 1-5 \u6240\u793a\u7684\u62fc\u88c5\u79ef\u6728\u3002\u4e00\u5957\u79ef\u6728\uff0c\u9664\u4e86\u5305\u542b\u8bb8\u591a\u96f6\u4ef6\u4e4b\u5916\uff0c\u8fd8\u9644\u6709\u8be6\u7ec6\u7684\u7ec4\u88c5\u8bf4\u660e\u4e66\u3002\u6211\u4eec\u6309\u7167\u8bf4\u660e\u4e66\u4e00\u6b65\u6b65\u64cd\u4f5c\uff0c\u5c31\u80fd\u7ec4\u88c5\u51fa\u7cbe\u7f8e\u7684\u79ef\u6728\u6a21\u578b\u3002

    \u56fe 1-5 \u00a0 \u62fc\u88c5\u79ef\u6728

    \u4e24\u8005\u7684\u8be6\u7ec6\u5bf9\u5e94\u5173\u7cfb\u5982\u8868 1-1 \u6240\u793a\u3002

    \u8868 1-1 \u00a0 \u5c06\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7c7b\u6bd4\u4e3a\u62fc\u88c5\u79ef\u6728

    \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 \u62fc\u88c5\u79ef\u6728 \u8f93\u5165\u6570\u636e \u672a\u62fc\u88c5\u7684\u79ef\u6728 \u6570\u636e\u7ed3\u6784 \u79ef\u6728\u7ec4\u7ec7\u5f62\u5f0f\uff0c\u5305\u62ec\u5f62\u72b6\u3001\u5927\u5c0f\u3001\u8fde\u63a5\u65b9\u5f0f\u7b49 \u7b97\u6cd5 \u628a\u79ef\u6728\u62fc\u6210\u76ee\u6807\u5f62\u6001\u7684\u4e00\u7cfb\u5217\u64cd\u4f5c\u6b65\u9aa4 \u8f93\u51fa\u6570\u636e \u79ef\u6728\u6a21\u578b

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u662f\u72ec\u7acb\u4e8e\u7f16\u7a0b\u8bed\u8a00\u7684\u3002\u6b63\u56e0\u5982\u6b64\uff0c\u672c\u4e66\u5f97\u4ee5\u63d0\u4f9b\u57fa\u4e8e\u591a\u79cd\u7f16\u7a0b\u8bed\u8a00\u7684\u5b9e\u73b0\u3002

    \u7ea6\u5b9a\u4fd7\u6210\u7684\u7b80\u79f0

    \u5728\u5b9e\u9645\u8ba8\u8bba\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5c06\u201c\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u201d\u7b80\u79f0\u4e3a\u201c\u7b97\u6cd5\u201d\u3002\u6bd4\u5982\u4f17\u6240\u5468\u77e5\u7684 LeetCode \u7b97\u6cd5\u9898\u76ee\uff0c\u5b9e\u9645\u4e0a\u540c\u65f6\u8003\u67e5\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u4e24\u65b9\u9762\u7684\u77e5\u8bc6\u3002

    "},{"location":"chapter_paperbook/","title":"\u7eb8\u8d28\u4e66","text":"

    \u7ecf\u8fc7\u957f\u65f6\u95f4\u7684\u6253\u78e8\uff0c\u300aHello \u7b97\u6cd5\u300b\u7eb8\u8d28\u4e66\u7ec8\u4e8e\u53d1\u5e03\u4e86\uff01\u6b64\u65f6\u7684\u5fc3\u60c5\u53ef\u4ee5\u7528\u4e00\u53e5\u8bd7\u6765\u5f62\u5bb9\uff1a

    \u8ffd\u98ce\u8d76\u6708\u83ab\u505c\u7559\uff0c\u5e73\u829c\u5c3d\u5904\u662f\u6625\u5c71\u3002

    \u4ee5\u4e0b\u89c6\u9891\u5c55\u793a\u4e86\u7eb8\u8d28\u4e66\uff0c\u5e76\u4e14\u5305\u542b\u6211\u7684\u4e00\u4e9b\u601d\u8003\uff1a

    • \u5b66\u4e60\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u91cd\u8981\u6027\u3002
    • \u4e3a\u4ec0\u4e48\u5728\u7eb8\u8d28\u4e66\u4e2d\u9009\u62e9 Python\u3002
    • \u5bf9\u77e5\u8bc6\u5206\u4eab\u7684\u7406\u89e3\u3002

    \u65b0\u4eba UP \u4e3b\uff0c\u8bf7\u591a\u591a\u5173\u7167\u3001\u4e00\u952e\u4e09\u8fde\uff5e\u8c22\u8c22\uff01

    \u9644\u7eb8\u8d28\u4e66\u5feb\u7167\uff1a

    "},{"location":"chapter_paperbook/#_2","title":"\u4f18\u52bf\u4e0e\u4e0d\u8db3","text":"

    \u603b\u7ed3\u4e00\u4e0b\u7eb8\u8d28\u4e66\u53ef\u80fd\u4f1a\u7ed9\u5927\u5bb6\u5e26\u6765\u60ca\u559c\u7684\u5730\u65b9\uff1a

    • \u91c7\u7528\u5168\u5f69\u5370\u5237\uff0c\u80fd\u591f\u539f\u6c41\u539f\u5473\u5730\u53d1\u6325\u51fa\u672c\u4e66\u201c\u52a8\u753b\u56fe\u89e3\u201d\u7684\u4f18\u52bf\u3002
    • \u8003\u7a76\u7eb8\u5f20\u6750\u8d28\uff0c\u65e2\u4fdd\u8bc1\u8272\u5f69\u9ad8\u5ea6\u8fd8\u539f\uff0c\u4e5f\u4fdd\u7559\u7eb8\u8d28\u4e66\u7279\u6709\u7684\u8d28\u611f\u3002
    • \u7eb8\u8d28\u7248\u6bd4\u7f51\u9875\u7248\u7684\u683c\u5f0f\u66f4\u52a0\u89c4\u8303\uff0c\u4f8b\u5982\u56fe\u4e2d\u7684\u516c\u5f0f\u4f7f\u7528\u659c\u4f53\u3002
    • \u5728\u4e0d\u63d0\u5347\u5b9a\u4ef7\u7684\u524d\u63d0\u4e0b\uff0c\u9644\u8d60\u601d\u7ef4\u5bfc\u56fe\u6298\u9875\u3001\u4e66\u7b7e\u3002
    • \u7eb8\u8d28\u4e66\u3001\u7f51\u9875\u7248\u3001PDF \u7248\u5185\u5bb9\u540c\u6b65\uff0c\u968f\u610f\u5207\u6362\u9605\u8bfb\u3002

    Tip

    \u7531\u4e8e\u7eb8\u8d28\u4e66\u548c\u7f51\u9875\u7248\u7684\u540c\u6b65\u96be\u5ea6\u8f83\u5927\uff0c\u56e0\u6b64\u53ef\u80fd\u4f1a\u6709\u4e00\u4e9b\u7ec6\u8282\u4e0a\u7684\u4e0d\u540c\uff0c\u8bf7\u60a8\u89c1\u8c05\uff01

    \u5f53\u7136\uff0c\u7eb8\u8d28\u4e66\u4e5f\u6709\u4e00\u4e9b\u503c\u5f97\u5927\u5bb6\u5165\u624b\u524d\u8003\u8651\u7684\u5730\u65b9\uff1a

    • \u4f7f\u7528 Python \u8bed\u8a00\uff0c\u53ef\u80fd\u4e0d\u5339\u914d\u4f60\u7684\u4e3b\u8bed\u8a00\uff08\u53ef\u4ee5\u628a Python \u770b\u4f5c\u4f2a\u4ee3\u7801\uff0c\u91cd\u5728\u7406\u89e3\u601d\u8def\uff09\u3002
    • \u5168\u5f69\u5370\u5237\u867d\u7136\u5927\u5e45\u63d0\u5347\u4e86\u56fe\u89e3\u548c\u4ee3\u7801\u7684\u9605\u8bfb\u4f53\u9a8c\uff0c\u4f46\u4ef7\u683c\u4f1a\u6bd4\u9ed1\u767d\u5370\u5237\u9ad8\u4e00\u4e9b\u3002

    Tip

    \u201c\u5370\u5237\u8d28\u91cf\u201d\u548c\u201c\u4ef7\u683c\u201d\u5c31\u50cf\u7b97\u6cd5\u4e2d\u7684\u201c\u65f6\u95f4\u6548\u7387\u201d\u548c\u201c\u7a7a\u95f4\u6548\u7387\u201d\uff0c\u96be\u4ee5\u4e24\u5168\u3002\u800c\u6211\u8ba4\u4e3a\uff0c\u201c\u5370\u5237\u8d28\u91cf\u201d\u5bf9\u5e94\u7684\u662f\u201c\u65f6\u95f4\u6548\u7387\u201d\uff0c\u66f4\u5e94\u8be5\u88ab\u6ce8\u91cd\u3002

    "},{"location":"chapter_paperbook/#_3","title":"\u8d2d\u4e70\u94fe\u63a5","text":"

    \u5982\u679c\u4f60\u5bf9\u7eb8\u8d28\u4e66\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u8003\u8651\u5165\u624b\u4e00\u672c\u3002\u6211\u4eec\u4e3a\u5927\u5bb6\u4e89\u53d6\u5230\u4e86\u65b0\u4e66 5 \u6298\u4f18\u60e0\uff0c\u8bf7\u89c1\u6b64\u94fe\u63a5\u6216\u626b\u63cf\u4ee5\u4e0b\u4e8c\u7ef4\u7801\uff1a

    "},{"location":"chapter_paperbook/#_4","title":"\u5c3e\u8bb0","text":"

    \u8d77\u521d\uff0c\u6211\u4f4e\u4f30\u4e86\u7eb8\u8d28\u4e66\u51fa\u7248\u7684\u5de5\u4f5c\u91cf\uff0c\u4ee5\u4e3a\u53ea\u8981\u7ef4\u62a4\u597d\u4e86\u5f00\u6e90\u9879\u76ee\uff0c\u7eb8\u8d28\u7248\u5c31\u53ef\u4ee5\u901a\u8fc7\u67d0\u4e9b\u81ea\u52a8\u5316\u624b\u6bb5\u751f\u6210\u51fa\u6765\u3002\u5b9e\u8df5\u8bc1\u660e\uff0c\u7eb8\u8d28\u4e66\u7684\u751f\u4ea7\u6d41\u7a0b\u4e0e\u5f00\u6e90\u9879\u76ee\u7684\u66f4\u65b0\u673a\u5236\u5b58\u5728\u5f88\u5927\u7684\u4e0d\u540c\uff0c\u4e24\u8005\u4e4b\u95f4\u7684\u8f6c\u5316\u9700\u8981\u505a\u8bb8\u591a\u989d\u5916\u5de5\u4f5c\u3002

    \u4e00\u672c\u4e66\u7684\u521d\u7a3f\u4e0e\u8fbe\u5230\u51fa\u7248\u6807\u51c6\u7684\u5b9a\u7a3f\u4e4b\u95f4\u4ecd\u6709\u8f83\u957f\u8ddd\u79bb\uff0c\u9700\u8981\u51fa\u7248\u793e\uff08\u7b56\u5212\u3001\u7f16\u8f91\u3001\u8bbe\u8ba1\u3001\u5e02\u573a\u7b49\uff09\u4e0e\u4f5c\u8005\u7684\u901a\u529b\u5408\u4f5c\u3001\u957f\u671f\u96d5\u7422\u3002\u5728\u6b64\u611f\u8c22\u56fe\u7075\u7b56\u5212\u7f16\u8f91\u738b\u519b\u82b1\u3001\u4ee5\u53ca\u4eba\u6c11\u90ae\u7535\u51fa\u7248\u793e\u548c\u56fe\u7075\u793e\u533a\u6bcf\u4f4d\u53c2\u4e0e\u672c\u4e66\u51fa\u7248\u6d41\u7a0b\u7684\u5de5\u4f5c\u4eba\u5458\uff01

    \u5e0c\u671b\u8fd9\u672c\u4e66\u80fd\u591f\u5e2e\u52a9\u5230\u4f60\uff01

    "},{"location":"chapter_preface/","title":"\u7b2c 0 \u7ae0 \u00a0 \u524d\u8a00","text":"

    Abstract

    \u7b97\u6cd5\u72b9\u5982\u7f8e\u5999\u7684\u4ea4\u54cd\u4e50\uff0c\u6bcf\u4e00\u884c\u4ee3\u7801\u90fd\u50cf\u97f5\u5f8b\u822c\u6d41\u6dcc\u3002

    \u613f\u8fd9\u672c\u4e66\u5728\u4f60\u7684\u8111\u6d77\u4e2d\u8f7b\u8f7b\u54cd\u8d77\uff0c\u7559\u4e0b\u72ec\u7279\u800c\u6df1\u523b\u7684\u65cb\u5f8b\u3002

    "},{"location":"chapter_preface/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 0.1 \u00a0 \u5173\u4e8e\u672c\u4e66
    • 0.2 \u00a0 \u5982\u4f55\u4f7f\u7528\u672c\u4e66
    • 0.3 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_preface/about_the_book/","title":"0.1 \u00a0 \u5173\u4e8e\u672c\u4e66","text":"

    \u672c\u9879\u76ee\u65e8\u5728\u521b\u5efa\u4e00\u672c\u5f00\u6e90\u3001\u514d\u8d39\u3001\u5bf9\u65b0\u624b\u53cb\u597d\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5165\u95e8\u6559\u7a0b\u3002

    • \u5168\u4e66\u91c7\u7528\u52a8\u753b\u56fe\u89e3\uff0c\u7ed3\u6784\u5316\u5730\u8bb2\u89e3\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u77e5\u8bc6\uff0c\u5185\u5bb9\u6e05\u6670\u6613\u61c2\uff0c\u5b66\u4e60\u66f2\u7ebf\u5e73\u6ed1\u3002
    • \u7b97\u6cd5\u6e90\u4ee3\u7801\u7686\u53ef\u4e00\u952e\u8fd0\u884c\uff0c\u652f\u6301 Python\u3001C++\u3001Java\u3001C#\u3001Go\u3001Swift\u3001JavaScript\u3001TypeScript\u3001Dart\u3001Rust\u3001C \u548c Zig \u7b49\u8bed\u8a00\u3002
    • \u9f13\u52b1\u8bfb\u8005\u5728\u7ebf\u4e0a\u7ae0\u8282\u8bc4\u8bba\u533a\u4e92\u5e2e\u4e92\u52a9\u3001\u5171\u540c\u8fdb\u6b65\uff0c\u63d0\u95ee\u4e0e\u8bc4\u8bba\u901a\u5e38\u53ef\u5728\u4e24\u65e5\u5185\u5f97\u5230\u56de\u590d\u3002
    "},{"location":"chapter_preface/about_the_book/#011","title":"0.1.1 \u00a0 \u8bfb\u8005\u5bf9\u8c61","text":"

    \u82e5\u4f60\u662f\u7b97\u6cd5\u521d\u5b66\u8005\uff0c\u4ece\u672a\u63a5\u89e6\u8fc7\u7b97\u6cd5\uff0c\u6216\u8005\u5df2\u7ecf\u6709\u4e00\u4e9b\u5237\u9898\u7ecf\u9a8c\uff0c\u5bf9\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u6709\u6a21\u7cca\u7684\u8ba4\u8bc6\uff0c\u5728\u4f1a\u4e0e\u4e0d\u4f1a\u4e4b\u95f4\u53cd\u590d\u6a2a\u8df3\uff0c\u90a3\u4e48\u672c\u4e66\u6b63\u662f\u4e3a\u4f60\u91cf\u8eab\u5b9a\u5236\u7684\uff01

    \u5982\u679c\u4f60\u5df2\u7ecf\u79ef\u7d2f\u4e00\u5b9a\u7684\u5237\u9898\u91cf\uff0c\u719f\u6089\u5927\u90e8\u5206\u9898\u578b\uff0c\u90a3\u4e48\u672c\u4e66\u53ef\u52a9\u4f60\u56de\u987e\u4e0e\u68b3\u7406\u7b97\u6cd5\u77e5\u8bc6\u4f53\u7cfb\uff0c\u4ed3\u5e93\u6e90\u4ee3\u7801\u53ef\u4ee5\u5f53\u4f5c\u201c\u5237\u9898\u5de5\u5177\u5e93\u201d\u6216\u201c\u7b97\u6cd5\u5b57\u5178\u201d\u6765\u4f7f\u7528\u3002

    \u82e5\u4f60\u662f\u7b97\u6cd5\u201c\u5927\u795e\u201d\uff0c\u6211\u4eec\u671f\u5f85\u6536\u5230\u4f60\u7684\u5b9d\u8d35\u5efa\u8bae\uff0c\u6216\u8005\u4e00\u8d77\u53c2\u4e0e\u521b\u4f5c\u3002

    \u524d\u7f6e\u6761\u4ef6

    \u4f60\u9700\u8981\u81f3\u5c11\u5177\u5907\u4efb\u4e00\u8bed\u8a00\u7684\u7f16\u7a0b\u57fa\u7840\uff0c\u80fd\u591f\u9605\u8bfb\u548c\u7f16\u5199\u7b80\u5355\u4ee3\u7801\u3002

    "},{"location":"chapter_preface/about_the_book/#012","title":"0.1.2 \u00a0 \u5185\u5bb9\u7ed3\u6784","text":"

    \u672c\u4e66\u7684\u4e3b\u8981\u5185\u5bb9\u5982\u56fe 0-1 \u6240\u793a\u3002

    • \u590d\u6742\u5ea6\u5206\u6790\uff1a\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u7684\u8bc4\u4ef7\u7ef4\u5ea6\u4e0e\u65b9\u6cd5\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u63a8\u7b97\u65b9\u6cd5\u3001\u5e38\u89c1\u7c7b\u578b\u3001\u793a\u4f8b\u7b49\u3002
    • \u6570\u636e\u7ed3\u6784\uff1a\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u6570\u636e\u7ed3\u6784\u7684\u5206\u7c7b\u65b9\u6cd5\u3002\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\u7b49\u6570\u636e\u7ed3\u6784\u7684\u5b9a\u4e49\u3001\u4f18\u7f3a\u70b9\u3001\u5e38\u7528\u64cd\u4f5c\u3001\u5e38\u89c1\u7c7b\u578b\u3001\u5178\u578b\u5e94\u7528\u3001\u5b9e\u73b0\u65b9\u6cd5\u7b49\u3002
    • \u7b97\u6cd5\uff1a\u641c\u7d22\u3001\u6392\u5e8f\u3001\u5206\u6cbb\u3001\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\u3001\u8d2a\u5fc3\u7b49\u7b97\u6cd5\u7684\u5b9a\u4e49\u3001\u4f18\u7f3a\u70b9\u3001\u6548\u7387\u3001\u5e94\u7528\u573a\u666f\u3001\u89e3\u9898\u6b65\u9aa4\u548c\u793a\u4f8b\u95ee\u9898\u7b49\u3002

    \u56fe 0-1 \u00a0 \u672c\u4e66\u4e3b\u8981\u5185\u5bb9

    "},{"location":"chapter_preface/about_the_book/#013","title":"0.1.3 \u00a0 \u81f4\u8c22","text":"

    \u672c\u4e66\u5728\u5f00\u6e90\u793e\u533a\u4f17\u591a\u8d21\u732e\u8005\u7684\u5171\u540c\u52aa\u529b\u4e0b\u4e0d\u65ad\u5b8c\u5584\u3002\u611f\u8c22\u6bcf\u4e00\u4f4d\u6295\u5165\u65f6\u95f4\u4e0e\u7cbe\u529b\u7684\u64b0\u7a3f\u4eba\uff0c\u4ed6\u4eec\u662f\uff08\u6309\u7167 GitHub \u81ea\u52a8\u751f\u6210\u7684\u987a\u5e8f\uff09\uff1akrahets\u3001Gonglja\u3001nuomi1\u3001codingonion\u3001Reanon\u3001justin-tse\u3001hpstory\u3001danielsss\u3001curtishd\u3001night-cruise\u3001S-N-O-R-L-A-X\u3001msk397\u3001gvenusleo\u3001RiverTwilight\u3001gyt95\u3001zhuoqinyue\u3001Zuoxun\u3001mingXta\u3001hello-ikun\u3001khoaxuantu\u3001FangYuan33\u3001GN-Yu\u3001longsizhuo\u3001mgisr\u3001Cathay-Chen\u3001guowei-gong\u3001xBLACKICEx\u3001K3v123\u3001IsChristina\u3001JoseHung\u3001qualifier1024\u3001pengchzn\u3001Guanngxu\u3001QiLOL\u3001L-Super\u3001WSL0809\u3001Slone123c\u3001lhxsm\u3001yuan0221\u3001what-is-me\u3001rongyi\u3001JeffersonHuang\u3001longranger2\u3001theNefelibatas\u3001yuelinxin\u3001xiongsp\u3001nanlei\u3001a16su\u3001cy-by-side\u3001gaofer\u3001malone6\u3001Wonderdch\u3001hongyun-robot\u3001XiaChuerwu\u3001yd-j\u3001bluebean-cloud\u3001iron-irax\u3001he-weilai\u3001Nigh\u3001MolDuM\u3001Phoenix0415\u3001XC-Zero\u3001SamJin98\u3001reeswell\u3001NI-SW\u3001Horbin-Magician\u3001xjr7670\u3001YangXuanyi\u3001DullSword\u3001iStig\u3001qq909244296\u3001jiaxianhua\u3001wenjianmin\u3001keshida\u3001kilikilikid\u3001lclc6\u3001lwbaptx\u3001luluxia\u3001boloboloda\u3001hts0000\u3001gledfish\u3001fbigm\u3001echo1937\u3001szu17dmy\u3001dshlstarr\u3001coderlef\u3001czruby\u3001beintentional\u3001KeiichiKasai\u3001xb534\u3001ElaBosak233\u3001baagod\u3001zhouLion\u3001yishangzhang\u3001yi427\u3001yabo083\u3001weibk\u3001wangwang105\u3001th1nk3r-ing\u3001tao363\u30014yDX3906\u3001syd168\u3001siqyka\u3001selear\u3001sdshaoda\u3001noobcodemaker\u3001chadyi\u3001lyl625760\u3001lucaswangdev\u3001liuxjerry\u30010130w\u3001shanghai-Jerry\u3001JackYang-hellobobo\u3001Javesun99\u3001lipusheng\u3001ShiMaRing\u3001FreddieLi\u3001FloranceYeh\u3001Transmigration-zhou\u3001fanchenggang\u3001gltianwen\u3001Dr-XYZ\u3001curly210102\u3001CuB3y0nd\u3001youshaoXG\u3001bubble9um\u3001fanenr\u300152coder\u3001foursevenlove\u3001KorsChen\u3001ZongYangL\u3001hezhizhen\u3001linzeyan\u3001ZJKung\u3001GaochaoZhu\u3001yang-le\u3001Evilrabbit520\u3001Turing-1024-Lee\u3001Suremotoo\u3001Allen-Scai\u3001Richard-Zhang1019\u3001qingpeng9802\u3001primexiao\u3001nidhoggfgg\u30011ch0\u3001MwumLi\u3001ZnYang2018\u3001hugtyftg\u3001logan-qiu\u3001psychelzh \u548c Keynman \u3002

    \u672c\u4e66\u7684\u4ee3\u7801\u5ba1\u9605\u5de5\u4f5c\u7531 codingonion\u3001curtishd\u3001Gonglja\u3001gvenusleo\u3001hpstory\u3001justin-tse\u3001krahets\u3001night-cruise\u3001nuomi1 \u548c Reanon \u5b8c\u6210\uff08\u6309\u7167\u9996\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\uff09\u3002\u611f\u8c22\u4ed6\u4eec\u4ed8\u51fa\u7684\u65f6\u95f4\u4e0e\u7cbe\u529b\uff0c\u6b63\u662f\u4ed6\u4eec\u786e\u4fdd\u4e86\u5404\u8bed\u8a00\u4ee3\u7801\u7684\u89c4\u8303\u4e0e\u7edf\u4e00\u3002

    \u5728\u672c\u4e66\u7684\u521b\u4f5c\u8fc7\u7a0b\u4e2d\uff0c\u6211\u5f97\u5230\u4e86\u8bb8\u591a\u4eba\u7684\u5e2e\u52a9\u3002

    • \u611f\u8c22\u6211\u5728\u516c\u53f8\u7684\u5bfc\u5e08\u674e\u6c50\u535a\u58eb\uff0c\u5728\u4e00\u6b21\u7545\u8c08\u4e2d\u4f60\u9f13\u52b1\u6211\u201c\u5feb\u884c\u52a8\u8d77\u6765\u201d\uff0c\u575a\u5b9a\u4e86\u6211\u5199\u8fd9\u672c\u4e66\u7684\u51b3\u5fc3\uff1b
    • \u611f\u8c22\u6211\u7684\u5973\u670b\u53cb\u6ce1\u6ce1\u4f5c\u4e3a\u672c\u4e66\u7684\u9996\u4f4d\u8bfb\u8005\uff0c\u4ece\u7b97\u6cd5\u5c0f\u767d\u7684\u89d2\u5ea6\u63d0\u51fa\u8bb8\u591a\u5b9d\u8d35\u5efa\u8bae\uff0c\u4f7f\u5f97\u672c\u4e66\u66f4\u9002\u5408\u65b0\u624b\u9605\u8bfb\uff1b
    • \u611f\u8c22\u817e\u5b9d\u3001\u7426\u5b9d\u3001\u98de\u5b9d\u4e3a\u672c\u4e66\u8d77\u4e86\u4e00\u4e2a\u5bcc\u6709\u521b\u610f\u7684\u540d\u5b57\uff0c\u5524\u8d77\u5927\u5bb6\u5199\u4e0b\u7b2c\u4e00\u884c\u4ee3\u7801\u201cHello World!\u201d\u7684\u7f8e\u597d\u56de\u5fc6\uff1b
    • \u611f\u8c22\u6821\u94e8\u5728\u77e5\u8bc6\u4ea7\u6743\u65b9\u9762\u63d0\u4f9b\u7684\u4e13\u4e1a\u5e2e\u52a9\uff0c\u8fd9\u5bf9\u672c\u5f00\u6e90\u4e66\u7684\u5b8c\u5584\u8d77\u5230\u4e86\u91cd\u8981\u4f5c\u7528\uff1b
    • \u611f\u8c22\u82cf\u6f7c\u4e3a\u672c\u4e66\u8bbe\u8ba1\u4e86\u7cbe\u7f8e\u7684\u5c01\u9762\u548c logo \uff0c\u5e76\u5728\u6211\u7684\u5f3a\u8feb\u75c7\u7684\u9a71\u4f7f\u4e0b\u591a\u6b21\u8010\u5fc3\u4fee\u6539\uff1b
    • \u611f\u8c22 @squidfunk \u63d0\u4f9b\u7684\u6392\u7248\u5efa\u8bae\uff0c\u4ee5\u53ca\u4ed6\u5f00\u53d1\u7684\u5f00\u6e90\u6587\u6863\u4e3b\u9898 Material-for-MkDocs \u3002

    \u5728\u5199\u4f5c\u8fc7\u7a0b\u4e2d\uff0c\u6211\u9605\u8bfb\u4e86\u8bb8\u591a\u5173\u4e8e\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u6559\u6750\u548c\u6587\u7ae0\u3002\u8fd9\u4e9b\u4f5c\u54c1\u4e3a\u672c\u4e66\u63d0\u4f9b\u4e86\u4f18\u79c0\u7684\u8303\u672c\uff0c\u786e\u4fdd\u4e86\u672c\u4e66\u5185\u5bb9\u7684\u51c6\u786e\u6027\u4e0e\u54c1\u8d28\u3002\u5728\u6b64\u611f\u8c22\u6240\u6709\u8001\u5e08\u548c\u524d\u8f88\u7684\u6770\u51fa\u8d21\u732e\uff01

    \u672c\u4e66\u5021\u5bfc\u624b\u8111\u5e76\u7528\u7684\u5b66\u4e60\u65b9\u5f0f\uff0c\u5728\u8fd9\u4e00\u70b9\u4e0a\u6211\u6df1\u53d7\u300a\u52a8\u624b\u5b66\u6df1\u5ea6\u5b66\u4e60\u300b\u7684\u542f\u53d1\u3002\u5728\u6b64\u5411\u5404\u4f4d\u8bfb\u8005\u5f3a\u70c8\u63a8\u8350\u8fd9\u672c\u4f18\u79c0\u7684\u8457\u4f5c\u3002

    \u8877\u5fc3\u611f\u8c22\u6211\u7684\u7236\u6bcd\uff0c\u6b63\u662f\u4f60\u4eec\u4e00\u76f4\u4ee5\u6765\u7684\u652f\u6301\u4e0e\u9f13\u52b1\uff0c\u8ba9\u6211\u6709\u673a\u4f1a\u505a\u8fd9\u4ef6\u5bcc\u6709\u8da3\u5473\u7684\u4e8b\u3002

    "},{"location":"chapter_preface/suggestions/","title":"0.2 \u00a0 \u5982\u4f55\u4f7f\u7528\u672c\u4e66","text":"

    Tip

    \u4e3a\u4e86\u83b7\u5f97\u6700\u4f73\u7684\u9605\u8bfb\u4f53\u9a8c\uff0c\u5efa\u8bae\u4f60\u901a\u8bfb\u672c\u8282\u5185\u5bb9\u3002

    "},{"location":"chapter_preface/suggestions/#021","title":"0.2.1 \u00a0 \u884c\u6587\u98ce\u683c\u7ea6\u5b9a","text":"
    • \u6807\u9898\u540e\u6807\u6ce8 * \u7684\u662f\u9009\u8bfb\u7ae0\u8282\uff0c\u5185\u5bb9\u76f8\u5bf9\u56f0\u96be\u3002\u5982\u679c\u4f60\u7684\u65f6\u95f4\u6709\u9650\uff0c\u53ef\u4ee5\u5148\u8df3\u8fc7\u3002
    • \u4e13\u4e1a\u672f\u8bed\u4f1a\u4f7f\u7528\u9ed1\u4f53\uff08\u7eb8\u8d28\u7248\u548c PDF \u7248\uff09\u6216\u6dfb\u52a0\u4e0b\u5212\u7ebf\uff08\u7f51\u9875\u7248\uff09\uff0c\u4f8b\u5982\u6570\u7ec4\uff08array\uff09\u3002\u5efa\u8bae\u8bb0\u4f4f\u5b83\u4eec\uff0c\u4ee5\u4fbf\u9605\u8bfb\u6587\u732e\u3002
    • \u91cd\u70b9\u5185\u5bb9\u548c\u603b\u7ed3\u6027\u8bed\u53e5\u4f1a \u52a0\u7c97\uff0c\u8fd9\u7c7b\u6587\u5b57\u503c\u5f97\u7279\u522b\u5173\u6ce8\u3002
    • \u6709\u7279\u6307\u542b\u4e49\u7684\u8bcd\u53e5\u4f1a\u4f7f\u7528\u201c\u5f15\u53f7\u201d\u6807\u6ce8\uff0c\u4ee5\u907f\u514d\u6b67\u4e49\u3002
    • \u5f53\u6d89\u53ca\u7f16\u7a0b\u8bed\u8a00\u4e4b\u95f4\u4e0d\u4e00\u81f4\u7684\u540d\u8bcd\u65f6\uff0c\u672c\u4e66\u5747\u4ee5 Python \u4e3a\u51c6\uff0c\u4f8b\u5982\u4f7f\u7528 None \u6765\u8868\u793a\u201c\u7a7a\u201d\u3002
    • \u672c\u4e66\u90e8\u5206\u653e\u5f03\u4e86\u7f16\u7a0b\u8bed\u8a00\u7684\u6ce8\u91ca\u89c4\u8303\uff0c\u4ee5\u6362\u53d6\u66f4\u52a0\u7d27\u51d1\u7684\u5185\u5bb9\u6392\u7248\u3002\u6ce8\u91ca\u4e3b\u8981\u5206\u4e3a\u4e09\u79cd\u7c7b\u578b\uff1a\u6807\u9898\u6ce8\u91ca\u3001\u5185\u5bb9\u6ce8\u91ca\u3001\u591a\u884c\u6ce8\u91ca\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    \"\"\"\u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49\"\"\"\n\n# \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n\"\"\"\n\u591a\u884c\n\u6ce8\u91ca\n\"\"\"\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    ### \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 ###\n\n# \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n# \u591a\u884c\n# \u6ce8\u91ca\n
    // \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n// \u591a\u884c\n// \u6ce8\u91ca\n
    "},{"location":"chapter_preface/suggestions/#022","title":"0.2.2 \u00a0 \u5728\u52a8\u753b\u56fe\u89e3\u4e2d\u9ad8\u6548\u5b66\u4e60","text":"

    \u76f8\u8f83\u4e8e\u6587\u5b57\uff0c\u89c6\u9891\u548c\u56fe\u7247\u5177\u6709\u66f4\u9ad8\u7684\u4fe1\u606f\u5bc6\u5ea6\u548c\u7ed3\u6784\u5316\u7a0b\u5ea6\uff0c\u66f4\u6613\u4e8e\u7406\u89e3\u3002\u5728\u672c\u4e66\u4e2d\uff0c\u91cd\u70b9\u548c\u96be\u70b9\u77e5\u8bc6\u5c06\u4e3b\u8981\u901a\u8fc7\u52a8\u753b\u4ee5\u56fe\u89e3\u5f62\u5f0f\u5c55\u793a\uff0c\u800c\u6587\u5b57\u5219\u4f5c\u4e3a\u89e3\u91ca\u4e0e\u8865\u5145\u3002

    \u5982\u679c\u4f60\u5728\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u53d1\u73b0\u67d0\u6bb5\u5185\u5bb9\u63d0\u4f9b\u4e86\u5982\u56fe 0-2 \u6240\u793a\u7684\u52a8\u753b\u56fe\u89e3\uff0c\u8bf7\u4ee5\u56fe\u4e3a\u4e3b\u3001\u4ee5\u6587\u5b57\u4e3a\u8f85\uff0c\u7efc\u5408\u4e24\u8005\u6765\u7406\u89e3\u5185\u5bb9\u3002

    \u56fe 0-2 \u00a0 \u52a8\u753b\u56fe\u89e3\u793a\u4f8b

    "},{"location":"chapter_preface/suggestions/#023","title":"0.2.3 \u00a0 \u5728\u4ee3\u7801\u5b9e\u8df5\u4e2d\u52a0\u6df1\u7406\u89e3","text":"

    \u672c\u4e66\u7684\u914d\u5957\u4ee3\u7801\u6258\u7ba1\u5728 GitHub \u4ed3\u5e93\u3002\u5982\u56fe 0-3 \u6240\u793a\uff0c\u6e90\u4ee3\u7801\u9644\u6709\u6d4b\u8bd5\u6837\u4f8b\uff0c\u53ef\u4e00\u952e\u8fd0\u884c\u3002

    \u5982\u679c\u65f6\u95f4\u5141\u8bb8\uff0c\u5efa\u8bae\u4f60\u53c2\u7167\u4ee3\u7801\u81ea\u884c\u6572\u4e00\u904d\u3002\u5982\u679c\u5b66\u4e60\u65f6\u95f4\u6709\u9650\uff0c\u8bf7\u81f3\u5c11\u901a\u8bfb\u5e76\u8fd0\u884c\u6240\u6709\u4ee3\u7801\u3002

    \u4e0e\u9605\u8bfb\u4ee3\u7801\u76f8\u6bd4\uff0c\u7f16\u5199\u4ee3\u7801\u7684\u8fc7\u7a0b\u5f80\u5f80\u80fd\u5e26\u6765\u66f4\u591a\u6536\u83b7\u3002\u52a8\u624b\u5b66\uff0c\u624d\u662f\u771f\u7684\u5b66\u3002

    \u56fe 0-3 \u00a0 \u8fd0\u884c\u4ee3\u7801\u793a\u4f8b

    \u8fd0\u884c\u4ee3\u7801\u7684\u524d\u7f6e\u5de5\u4f5c\u4e3b\u8981\u5206\u4e3a\u4e09\u6b65\u3002

    \u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5\u672c\u5730\u7f16\u7a0b\u73af\u5883\u3002\u8bf7\u53c2\u7167\u9644\u5f55\u6240\u793a\u7684\u6559\u7a0b\u8fdb\u884c\u5b89\u88c5\uff0c\u5982\u679c\u5df2\u5b89\u88c5\uff0c\u5219\u53ef\u8df3\u8fc7\u6b64\u6b65\u9aa4\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u514b\u9686\u6216\u4e0b\u8f7d\u4ee3\u7801\u4ed3\u5e93\u3002\u524d\u5f80 GitHub \u4ed3\u5e93\u3002\u5982\u679c\u5df2\u7ecf\u5b89\u88c5 Git \uff0c\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u547d\u4ee4\u514b\u9686\u672c\u4ed3\u5e93\uff1a

    git clone https://github.com/krahets/hello-algo.git\n

    \u5f53\u7136\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5728\u56fe 0-4 \u6240\u793a\u7684\u4f4d\u7f6e\uff0c\u70b9\u51fb\u201cDownload ZIP\u201d\u6309\u94ae\u76f4\u63a5\u4e0b\u8f7d\u4ee3\u7801\u538b\u7f29\u5305\uff0c\u7136\u540e\u5728\u672c\u5730\u89e3\u538b\u5373\u53ef\u3002

    \u56fe 0-4 \u00a0 \u514b\u9686\u4ed3\u5e93\u4e0e\u4e0b\u8f7d\u4ee3\u7801

    \u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6e90\u4ee3\u7801\u3002\u5982\u56fe 0-5 \u6240\u793a\uff0c\u5bf9\u4e8e\u9876\u90e8\u6807\u6709\u6587\u4ef6\u540d\u79f0\u7684\u4ee3\u7801\u5757\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u4ed3\u5e93\u7684 codes \u6587\u4ef6\u5939\u5185\u627e\u5230\u5bf9\u5e94\u7684\u6e90\u4ee3\u7801\u6587\u4ef6\u3002\u6e90\u4ee3\u7801\u6587\u4ef6\u53ef\u4e00\u952e\u8fd0\u884c\uff0c\u5c06\u5e2e\u52a9\u4f60\u8282\u7701\u4e0d\u5fc5\u8981\u7684\u8c03\u8bd5\u65f6\u95f4\uff0c\u8ba9\u4f60\u80fd\u591f\u4e13\u6ce8\u4e8e\u5b66\u4e60\u5185\u5bb9\u3002

    \u56fe 0-5 \u00a0 \u4ee3\u7801\u5757\u4e0e\u5bf9\u5e94\u7684\u6e90\u4ee3\u7801\u6587\u4ef6

    \u9664\u4e86\u672c\u5730\u8fd0\u884c\u4ee3\u7801\uff0c\u7f51\u9875\u7248\u8fd8\u652f\u6301 Python \u4ee3\u7801\u7684\u53ef\u89c6\u5316\u8fd0\u884c\uff08\u57fa\u4e8e pythontutor \u5b9e\u73b0\uff09\u3002\u5982\u56fe 0-6 \u6240\u793a\uff0c\u4f60\u53ef\u4ee5\u70b9\u51fb\u4ee3\u7801\u5757\u4e0b\u65b9\u7684\u201c\u53ef\u89c6\u5316\u8fd0\u884c\u201d\u6765\u5c55\u5f00\u89c6\u56fe\uff0c\u89c2\u5bdf\u7b97\u6cd5\u4ee3\u7801\u7684\u6267\u884c\u8fc7\u7a0b\uff1b\u4e5f\u53ef\u4ee5\u70b9\u51fb\u201c\u5168\u5c4f\u89c2\u770b\u201d\uff0c\u4ee5\u83b7\u5f97\u66f4\u597d\u7684\u9605\u89c8\u4f53\u9a8c\u3002

    \u56fe 0-6 \u00a0 Python \u4ee3\u7801\u7684\u53ef\u89c6\u5316\u8fd0\u884c

    "},{"location":"chapter_preface/suggestions/#024","title":"0.2.4 \u00a0 \u5728\u63d0\u95ee\u8ba8\u8bba\u4e2d\u5171\u540c\u6210\u957f","text":"

    \u5728\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u8bf7\u4e0d\u8981\u8f7b\u6613\u8df3\u8fc7\u90a3\u4e9b\u6ca1\u5b66\u660e\u767d\u7684\u77e5\u8bc6\u70b9\u3002\u6b22\u8fce\u5728\u8bc4\u8bba\u533a\u63d0\u51fa\u4f60\u7684\u95ee\u9898\uff0c\u6211\u548c\u5c0f\u4f19\u4f34\u4eec\u5c06\u7aed\u8bda\u4e3a\u4f60\u89e3\u7b54\uff0c\u4e00\u822c\u60c5\u51b5\u4e0b\u53ef\u5728\u4e24\u5929\u5185\u56de\u590d\u3002

    \u5982\u56fe 0-7 \u6240\u793a\uff0c\u7f51\u9875\u7248\u6bcf\u4e2a\u7ae0\u8282\u7684\u5e95\u90e8\u90fd\u914d\u6709\u8bc4\u8bba\u533a\u3002\u5e0c\u671b\u4f60\u80fd\u591a\u5173\u6ce8\u8bc4\u8bba\u533a\u7684\u5185\u5bb9\u3002\u4e00\u65b9\u9762\uff0c\u4f60\u53ef\u4ee5\u4e86\u89e3\u5927\u5bb6\u9047\u5230\u7684\u95ee\u9898\uff0c\u4ece\u800c\u67e5\u6f0f\u8865\u7f3a\uff0c\u6fc0\u53d1\u66f4\u6df1\u5165\u7684\u601d\u8003\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u671f\u5f85\u4f60\u80fd\u6177\u6168\u5730\u56de\u7b54\u5176\u4ed6\u5c0f\u4f19\u4f34\u7684\u95ee\u9898\uff0c\u5206\u4eab\u4f60\u7684\u89c1\u89e3\uff0c\u5e2e\u52a9\u4ed6\u4eba\u8fdb\u6b65\u3002

    \u56fe 0-7 \u00a0 \u8bc4\u8bba\u533a\u793a\u4f8b

    "},{"location":"chapter_preface/suggestions/#025","title":"0.2.5 \u00a0 \u7b97\u6cd5\u5b66\u4e60\u8def\u7ebf","text":"

    \u4ece\u603b\u4f53\u4e0a\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u8fc7\u7a0b\u5212\u5206\u4e3a\u4e09\u4e2a\u9636\u6bb5\u3002

    1. \u9636\u6bb5\u4e00\uff1a\u7b97\u6cd5\u5165\u95e8\u3002\u6211\u4eec\u9700\u8981\u719f\u6089\u5404\u79cd\u6570\u636e\u7ed3\u6784\u7684\u7279\u70b9\u548c\u7528\u6cd5\uff0c\u5b66\u4e60\u4e0d\u540c\u7b97\u6cd5\u7684\u539f\u7406\u3001\u6d41\u7a0b\u3001\u7528\u9014\u548c\u6548\u7387\u7b49\u65b9\u9762\u7684\u5185\u5bb9\u3002
    2. \u9636\u6bb5\u4e8c\uff1a\u5237\u7b97\u6cd5\u9898\u3002\u5efa\u8bae\u4ece\u70ed\u95e8\u9898\u76ee\u5f00\u5237\uff0c\u5148\u79ef\u7d2f\u81f3\u5c11 100 \u9053\u9898\u76ee\uff0c\u719f\u6089\u4e3b\u6d41\u7684\u7b97\u6cd5\u95ee\u9898\u3002\u521d\u6b21\u5237\u9898\u65f6\uff0c\u201c\u77e5\u8bc6\u9057\u5fd8\u201d\u53ef\u80fd\u662f\u4e00\u4e2a\u6311\u6218\uff0c\u4f46\u8bf7\u653e\u5fc3\uff0c\u8fd9\u662f\u5f88\u6b63\u5e38\u7684\u3002\u6211\u4eec\u53ef\u4ee5\u6309\u7167\u201c\u827e\u5bbe\u6d69\u65af\u9057\u5fd8\u66f2\u7ebf\u201d\u6765\u590d\u4e60\u9898\u76ee\uff0c\u901a\u5e38\u5728\u8fdb\u884c 3\uff5e5 \u8f6e\u7684\u91cd\u590d\u540e\uff0c\u5c31\u80fd\u5c06\u5176\u7262\u8bb0\u5728\u5fc3\u3002\u63a8\u8350\u7684\u9898\u5355\u548c\u5237\u9898\u8ba1\u5212\u8bf7\u89c1\u6b64 GitHub \u4ed3\u5e93\u3002
    3. \u9636\u6bb5\u4e09\uff1a\u642d\u5efa\u77e5\u8bc6\u4f53\u7cfb\u3002\u5728\u5b66\u4e60\u65b9\u9762\uff0c\u6211\u4eec\u53ef\u4ee5\u9605\u8bfb\u7b97\u6cd5\u4e13\u680f\u6587\u7ae0\u3001\u89e3\u9898\u6846\u67b6\u548c\u7b97\u6cd5\u6559\u6750\uff0c\u4ee5\u4e0d\u65ad\u4e30\u5bcc\u77e5\u8bc6\u4f53\u7cfb\u3002\u5728\u5237\u9898\u65b9\u9762\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u91c7\u7528\u8fdb\u9636\u5237\u9898\u7b56\u7565\uff0c\u5982\u6309\u4e13\u9898\u5206\u7c7b\u3001\u4e00\u9898\u591a\u89e3\u3001\u4e00\u89e3\u591a\u9898\u7b49\uff0c\u76f8\u5173\u7684\u5237\u9898\u5fc3\u5f97\u53ef\u4ee5\u5728\u5404\u4e2a\u793e\u533a\u627e\u5230\u3002

    \u5982\u56fe 0-8 \u6240\u793a\uff0c\u672c\u4e66\u5185\u5bb9\u4e3b\u8981\u6db5\u76d6\u201c\u9636\u6bb5\u4e00\u201d\uff0c\u65e8\u5728\u5e2e\u52a9\u4f60\u66f4\u9ad8\u6548\u5730\u5c55\u5f00\u9636\u6bb5\u4e8c\u548c\u9636\u6bb5\u4e09\u7684\u5b66\u4e60\u3002

    \u56fe 0-8 \u00a0 \u7b97\u6cd5\u5b66\u4e60\u8def\u7ebf

    "},{"location":"chapter_preface/summary/","title":"0.3 \u00a0 \u5c0f\u7ed3","text":"
    • \u672c\u4e66\u7684\u4e3b\u8981\u53d7\u4f17\u662f\u7b97\u6cd5\u521d\u5b66\u8005\u3002\u5982\u679c\u4f60\u5df2\u6709\u4e00\u5b9a\u57fa\u7840\uff0c\u672c\u4e66\u80fd\u5e2e\u52a9\u4f60\u7cfb\u7edf\u56de\u987e\u7b97\u6cd5\u77e5\u8bc6\uff0c\u4e66\u4e2d\u6e90\u4ee3\u7801\u4e5f\u53ef\u4f5c\u4e3a\u201c\u5237\u9898\u5de5\u5177\u5e93\u201d\u4f7f\u7528\u3002
    • \u4e66\u4e2d\u5185\u5bb9\u4e3b\u8981\u5305\u62ec\u590d\u6742\u5ea6\u5206\u6790\u3001\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u4e09\u90e8\u5206\uff0c\u6db5\u76d6\u4e86\u8be5\u9886\u57df\u7684\u5927\u90e8\u5206\u4e3b\u9898\u3002
    • \u5bf9\u4e8e\u7b97\u6cd5\u65b0\u624b\uff0c\u5728\u521d\u5b66\u9636\u6bb5\u9605\u8bfb\u4e00\u672c\u5165\u95e8\u4e66\u81f3\u5173\u91cd\u8981\uff0c\u53ef\u4ee5\u5c11\u8d70\u8bb8\u591a\u5f2f\u8def\u3002
    • \u4e66\u4e2d\u7684\u52a8\u753b\u56fe\u89e3\u901a\u5e38\u7528\u4e8e\u4ecb\u7ecd\u91cd\u70b9\u548c\u96be\u70b9\u77e5\u8bc6\u3002\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u5e94\u7ed9\u4e88\u8fd9\u4e9b\u5185\u5bb9\u66f4\u591a\u5173\u6ce8\u3002
    • \u5b9e\u8df5\u4e43\u5b66\u4e60\u7f16\u7a0b\u4e4b\u6700\u4f73\u9014\u5f84\u3002\u5f3a\u70c8\u5efa\u8bae\u8fd0\u884c\u6e90\u4ee3\u7801\u5e76\u4eb2\u81ea\u6572\u4ee3\u7801\u3002
    • \u672c\u4e66\u7f51\u9875\u7248\u7684\u6bcf\u4e2a\u7ae0\u8282\u90fd\u8bbe\u6709\u8bc4\u8bba\u533a\uff0c\u6b22\u8fce\u968f\u65f6\u5206\u4eab\u4f60\u7684\u7591\u60d1\u4e0e\u89c1\u89e3\u3002
    "},{"location":"chapter_reference/","title":"\u53c2\u8003\u6587\u732e","text":"

    [1] Thomas H. Cormen, et al. Introduction to Algorithms (3rd Edition).

    [2] Aditya Bhargava. Grokking Algorithms: An Illustrated Guide for Programmers and Other Curious People (1st Edition).

    [3] Robert Sedgewick, et al. Algorithms (4th Edition).

    [4] \u4e25\u851a\u654f. \u6570\u636e\u7ed3\u6784\uff08C \u8bed\u8a00\u7248\uff09.

    [5] \u9093\u4fca\u8f89. \u6570\u636e\u7ed3\u6784\uff08C++ \u8bed\u8a00\u7248\uff0c\u7b2c\u4e09\u7248\uff09.

    [6] \u9a6c\u514b \u827e\u4f26 \u7ef4\u65af\u8457\uff0c\u9648\u8d8a\u8bd1. \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5206\u6790\uff1aJava\u8bed\u8a00\u63cf\u8ff0\uff08\u7b2c\u4e09\u7248\uff09.

    [7] \u7a0b\u6770. \u5927\u8bdd\u6570\u636e\u7ed3\u6784.

    [8] \u738b\u4e89. \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u4e4b\u7f8e.

    [9] Gayle Laakmann McDowell. Cracking the Coding Interview: 189 Programming Questions and Solutions (6th Edition).

    [10] Aston Zhang, et al. Dive into Deep Learning.

    "},{"location":"chapter_searching/","title":"\u7b2c 10 \u7ae0 \u00a0 \u641c\u7d22","text":"

    Abstract

    \u641c\u7d22\u662f\u4e00\u573a\u672a\u77e5\u7684\u5192\u9669\uff0c\u6211\u4eec\u6216\u8bb8\u9700\u8981\u8d70\u904d\u795e\u79d8\u7a7a\u95f4\u7684\u6bcf\u4e2a\u89d2\u843d\uff0c\u53c8\u6216\u8bb8\u53ef\u4ee5\u5feb\u901f\u9501\u5b9a\u76ee\u6807\u3002

    \u5728\u8fd9\u573a\u5bfb\u89c5\u4e4b\u65c5\u4e2d\uff0c\u6bcf\u4e00\u6b21\u63a2\u7d22\u90fd\u53ef\u80fd\u5f97\u5230\u4e00\u4e2a\u672a\u66fe\u6599\u60f3\u7684\u7b54\u6848\u3002

    "},{"location":"chapter_searching/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 10.1 \u00a0 \u4e8c\u5206\u67e5\u627e
    • 10.2 \u00a0 \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9
    • 10.3 \u00a0 \u4e8c\u5206\u67e5\u627e\u8fb9\u754c
    • 10.4 \u00a0 \u54c8\u5e0c\u4f18\u5316\u7b56\u7565
    • 10.5 \u00a0 \u91cd\u8bc6\u641c\u7d22\u7b97\u6cd5
    • 10.6 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_searching/binary_search/","title":"10.1 \u00a0 \u4e8c\u5206\u67e5\u627e","text":"

    \u4e8c\u5206\u67e5\u627e\uff08binary search\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u9ad8\u6548\u641c\u7d22\u7b97\u6cd5\u3002\u5b83\u5229\u7528\u6570\u636e\u7684\u6709\u5e8f\u6027\uff0c\u6bcf\u8f6e\u7f29\u5c0f\u4e00\u534a\u641c\u7d22\u8303\u56f4\uff0c\u76f4\u81f3\u627e\u5230\u76ee\u6807\u5143\u7d20\u6216\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u4e3a\u6b62\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4 nums \uff0c\u5143\u7d20\u6309\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u4e14\u4e0d\u91cd\u590d\u3002\u8bf7\u67e5\u627e\u5e76\u8fd4\u56de\u5143\u7d20 target \u5728\u8be5\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15\u3002\u82e5\u6570\u7ec4\u4e0d\u5305\u542b\u8be5\u5143\u7d20\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002\u793a\u4f8b\u5982\u56fe 10-1 \u6240\u793a\u3002

    \u56fe 10-1 \u00a0 \u4e8c\u5206\u67e5\u627e\u793a\u4f8b\u6570\u636e

    \u5982\u56fe 10-2 \u6240\u793a\uff0c\u6211\u4eec\u5148\u521d\u59cb\u5316\u6307\u9488 \\(i = 0\\) \u548c \\(j = n - 1\\) \uff0c\u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u548c\u5c3e\u5143\u7d20\uff0c\u4ee3\u8868\u641c\u7d22\u533a\u95f4 \\([0, n - 1]\\) \u3002\u8bf7\u6ce8\u610f\uff0c\u4e2d\u62ec\u53f7\u8868\u793a\u95ed\u533a\u95f4\uff0c\u5176\u5305\u542b\u8fb9\u754c\u503c\u672c\u8eab\u3002

    \u63a5\u4e0b\u6765\uff0c\u5faa\u73af\u6267\u884c\u4ee5\u4e0b\u4e24\u6b65\u3002

    1. \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 \\(m = \\lfloor {(i + j) / 2} \\rfloor\\) \uff0c\u5176\u4e2d \\(\\lfloor \\: \\rfloor\\) \u8868\u793a\u5411\u4e0b\u53d6\u6574\u64cd\u4f5c\u3002
    2. \u5224\u65ad nums[m] \u548c target \u7684\u5927\u5c0f\u5173\u7cfb\uff0c\u5206\u4e3a\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\u3002
      1. \u5f53 nums[m] < target \u65f6\uff0c\u8bf4\u660e target \u5728\u533a\u95f4 \\([m + 1, j]\\) \u4e2d\uff0c\u56e0\u6b64\u6267\u884c \\(i = m + 1\\) \u3002
      2. \u5f53 nums[m] > target \u65f6\uff0c\u8bf4\u660e target \u5728\u533a\u95f4 \\([i, m - 1]\\) \u4e2d\uff0c\u56e0\u6b64\u6267\u884c \\(j = m - 1\\) \u3002
      3. \u5f53 nums[m] = target \u65f6\uff0c\u8bf4\u660e\u627e\u5230 target \uff0c\u56e0\u6b64\u8fd4\u56de\u7d22\u5f15 \\(m\\) \u3002

    \u82e5\u6570\u7ec4\u4e0d\u5305\u542b\u76ee\u6807\u5143\u7d20\uff0c\u641c\u7d22\u533a\u95f4\u6700\u7ec8\u4f1a\u7f29\u5c0f\u4e3a\u7a7a\u3002\u6b64\u65f6\u8fd4\u56de \\(-1\\) \u3002

    <1><2><3><4><5><6><7>

    \u56fe 10-2 \u00a0 \u4e8c\u5206\u67e5\u627e\u6d41\u7a0b

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u7531\u4e8e \\(i\\) \u548c \\(j\\) \u90fd\u662f int \u7c7b\u578b\uff0c\u56e0\u6b64 \\(i + j\\) \u53ef\u80fd\u4f1a\u8d85\u51fa int \u7c7b\u578b\u7684\u53d6\u503c\u8303\u56f4\u3002\u4e3a\u4e86\u907f\u514d\u5927\u6570\u8d8a\u754c\uff0c\u6211\u4eec\u901a\u5e38\u91c7\u7528\u516c\u5f0f \\(m = \\lfloor {i + (j - i) / 2} \\rfloor\\) \u6765\u8ba1\u7b97\u4e2d\u70b9\u3002

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search.py
    def binary_search(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09\"\"\"\n    # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    i, j = 0, len(nums) - 1\n    # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j:\n        # \u7406\u8bba\u4e0a Python \u7684\u6570\u5b57\u53ef\u4ee5\u65e0\u9650\u5927\uff08\u53d6\u51b3\u4e8e\u5185\u5b58\u5927\u5c0f\uff09\uff0c\u65e0\u987b\u8003\u8651\u5927\u6570\u8d8a\u754c\u95ee\u9898\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n
    binary_search.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(vector<int> &nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.size() - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.java
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.cs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint BinarySearch(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.Length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2;   // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else                       // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.go
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunc binarySearch(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    i, j := 0, len(nums)-1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    for i <= j {\n        m := i + (j-i)/2      // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.swift
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunc binarySearch(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.js
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunction binarySearch(nums, target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let i = 0,\n        j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m \uff0c\u4f7f\u7528 parseInt() \u5411\u4e0b\u53d6\u6574\n        const m = parseInt(i + (j - i) / 2);\n        if (nums[m] < target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else return m; // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.ts
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunction binarySearch(nums: number[], target: number): number {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let i = 0,\n        j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        const m = Math.floor(i + (j - i) / 2);\n        if (nums[m] < target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if (nums[m] > target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    return -1; // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n}\n
    binary_search.dart
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(List<int> nums, int target) {\n  // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n  int i = 0, j = nums.length - 1;\n  // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n      i = m + 1;\n    } else if (nums[m] > target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n      j = m - 1;\n    } else {\n      // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n      return m;\n    }\n  }\n  // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n  return -1;\n}\n
    binary_search.rs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfn binary_search(nums: &[i32], target: i32) -> i32 {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let mut i = 0;\n    let mut j = nums.len() as i32 - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if nums[m as usize] > target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.c
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(int *nums, int len, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = len - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.kt
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfun binarySearch(nums: IntArray, target: Int): Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i = 0\n    var j = nums.size - 1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        else  // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.rb
    ### \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 ###\ndef binary_search(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n  i, j = 0, nums.length - 1\n\n  # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n  while i <= j\n    # \u7406\u8bba\u4e0a Ruby \u7684\u6570\u5b57\u53ef\u4ee5\u65e0\u9650\u5927\uff08\u53d6\u51b3\u4e8e\u5185\u5b58\u5927\u5c0f\uff09\uff0c\u65e0\u987b\u8003\u8651\u5927\u6570\u8d8a\u754c\u95ee\u9898\n    m = (i + j) / 2   # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n\n    if nums[m] < target\n      i = m + 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    end\n  end\n\n  -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\nend\n
    binary_search.zig
    // \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09\nfn binarySearch(comptime T: type, nums: std.ArrayList(T), target: T) T {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i: usize = 0;\n    var j: usize = nums.items.len - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        var m = i + (j - i) / 2;                // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums.items[m] < target) {           // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if (nums.items[m] > target) {    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {                                // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return @intCast(m);\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \uff1a\u5728\u4e8c\u5206\u5faa\u73af\u4e2d\uff0c\u533a\u95f4\u6bcf\u8f6e\u7f29\u5c0f\u4e00\u534a\uff0c\u56e0\u6b64\u5faa\u73af\u6b21\u6570\u4e3a \\(\\log_2 n\\) \u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7a7a\u95f4\u3002

    "},{"location":"chapter_searching/binary_search/#1011","title":"10.1.1 \u00a0 \u533a\u95f4\u8868\u793a\u65b9\u6cd5","text":"

    \u9664\u4e86\u4e0a\u8ff0\u53cc\u95ed\u533a\u95f4\u5916\uff0c\u5e38\u89c1\u7684\u533a\u95f4\u8868\u793a\u8fd8\u6709\u201c\u5de6\u95ed\u53f3\u5f00\u201d\u533a\u95f4\uff0c\u5b9a\u4e49\u4e3a \\([0, n)\\) \uff0c\u5373\u5de6\u8fb9\u754c\u5305\u542b\u81ea\u8eab\uff0c\u53f3\u8fb9\u754c\u4e0d\u5305\u542b\u81ea\u8eab\u3002\u5728\u8be5\u8868\u793a\u4e0b\uff0c\u533a\u95f4 \\([i, j)\\) \u5728 \\(i = j\\) \u65f6\u4e3a\u7a7a\u3002

    \u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u8be5\u8868\u793a\u5b9e\u73b0\u5177\u6709\u76f8\u540c\u529f\u80fd\u7684\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search.py
    def binary_search_lcro(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09\"\"\"\n    # \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    i, j = 0, len(nums)\n    # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n        elif nums[m] > target:\n            j = m  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n        else:\n            return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n
    binary_search.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(vector<int> &nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.size();\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.java
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.cs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint BinarySearchLCRO(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.Length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2;   // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else                       // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.go
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunc binarySearchLCRO(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    i, j := 0, len(nums)\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    for i < j {\n        m := i + (j-i)/2      // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.swift
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunc binarySearchLCRO(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i = nums.startIndex\n    var j = nums.endIndex\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.js
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunction binarySearchLCRO(nums, target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let i = 0,\n        j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m \uff0c\u4f7f\u7528 parseInt() \u5411\u4e0b\u53d6\u6574\n        const m = parseInt(i + (j - i) / 2);\n        if (nums[m] < target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        else return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.ts
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunction binarySearchLCRO(nums: number[], target: number): number {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let i = 0,\n        j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        const m = Math.floor(i + (j - i) / 2);\n        if (nums[m] < target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if (nums[m] > target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    return -1; // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n}\n
    binary_search.dart
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(List<int> nums, int target) {\n  // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n  int i = 0, j = nums.length;\n  // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n  while (i < j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n      i = m + 1;\n    } else if (nums[m] > target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n      j = m;\n    } else {\n      // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n      return m;\n    }\n  }\n  // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n  return -1;\n}\n
    binary_search.rs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfn binary_search_lcro(nums: &[i32], target: i32) -> i32 {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let mut i = 0;\n    let mut j = nums.len() as i32;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if nums[m as usize] > target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.c
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(int *nums, int len, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = len;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.kt
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfun binarySearchLCRO(nums: IntArray, target: Int): Int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i = 0\n    var j = nums.size\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        else  // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.rb
    ### \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 ###\ndef binary_search_lcro(nums, target)\n  # \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n  i, j = 0, nums.length\n\n  # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n  while i < j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n    else\n      return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    end\n  end\n\n  -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\nend\n
    binary_search.zig
    // \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09\nfn binarySearchLCRO(comptime T: type, nums: std.ArrayList(T), target: T) T {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i: usize = 0;\n    var j: usize = nums.items.len;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        var m = i + (j - i) / 2;                // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums.items[m] < target) {           // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if (nums.items[m] > target) {    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {                                // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return @intCast(m);\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 10-3 \u6240\u793a\uff0c\u5728\u4e24\u79cd\u533a\u95f4\u8868\u793a\u4e0b\uff0c\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u7684\u521d\u59cb\u5316\u3001\u5faa\u73af\u6761\u4ef6\u548c\u7f29\u5c0f\u533a\u95f4\u64cd\u4f5c\u7686\u6709\u6240\u4e0d\u540c\u3002

    \u7531\u4e8e\u201c\u53cc\u95ed\u533a\u95f4\u201d\u8868\u793a\u4e2d\u7684\u5de6\u53f3\u8fb9\u754c\u90fd\u88ab\u5b9a\u4e49\u4e3a\u95ed\u533a\u95f4\uff0c\u56e0\u6b64\u901a\u8fc7\u6307\u9488 \\(i\\) \u548c\u6307\u9488 \\(j\\) \u7f29\u5c0f\u533a\u95f4\u7684\u64cd\u4f5c\u4e5f\u662f\u5bf9\u79f0\u7684\u3002\u8fd9\u6837\u66f4\u4e0d\u5bb9\u6613\u51fa\u9519\uff0c\u56e0\u6b64\u4e00\u822c\u5efa\u8bae\u91c7\u7528\u201c\u53cc\u95ed\u533a\u95f4\u201d\u7684\u5199\u6cd5\u3002

    \u56fe 10-3 \u00a0 \u4e24\u79cd\u533a\u95f4\u5b9a\u4e49

    "},{"location":"chapter_searching/binary_search/#1012","title":"10.1.2 \u00a0 \u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u4e8c\u5206\u67e5\u627e\u5728\u65f6\u95f4\u548c\u7a7a\u95f4\u65b9\u9762\u90fd\u6709\u8f83\u597d\u7684\u6027\u80fd\u3002

    • \u4e8c\u5206\u67e5\u627e\u7684\u65f6\u95f4\u6548\u7387\u9ad8\u3002\u5728\u5927\u6570\u636e\u91cf\u4e0b\uff0c\u5bf9\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5177\u6709\u663e\u8457\u4f18\u52bf\u3002\u4f8b\u5982\uff0c\u5f53\u6570\u636e\u5927\u5c0f \\(n = 2^{20}\\) \u65f6\uff0c\u7ebf\u6027\u67e5\u627e\u9700\u8981 \\(2^{20} = 1048576\\) \u8f6e\u5faa\u73af\uff0c\u800c\u4e8c\u5206\u67e5\u627e\u4ec5\u9700 \\(\\log_2 2^{20} = 20\\) \u8f6e\u5faa\u73af\u3002
    • \u4e8c\u5206\u67e5\u627e\u65e0\u987b\u989d\u5916\u7a7a\u95f4\u3002\u76f8\u8f83\u4e8e\u9700\u8981\u501f\u52a9\u989d\u5916\u7a7a\u95f4\u7684\u641c\u7d22\u7b97\u6cd5\uff08\u4f8b\u5982\u54c8\u5e0c\u67e5\u627e\uff09\uff0c\u4e8c\u5206\u67e5\u627e\u66f4\u52a0\u8282\u7701\u7a7a\u95f4\u3002

    \u7136\u800c\uff0c\u4e8c\u5206\u67e5\u627e\u5e76\u975e\u9002\u7528\u4e8e\u6240\u6709\u60c5\u51b5\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u4e8c\u5206\u67e5\u627e\u4ec5\u9002\u7528\u4e8e\u6709\u5e8f\u6570\u636e\u3002\u82e5\u8f93\u5165\u6570\u636e\u65e0\u5e8f\uff0c\u4e3a\u4e86\u4f7f\u7528\u4e8c\u5206\u67e5\u627e\u800c\u4e13\u95e8\u8fdb\u884c\u6392\u5e8f\uff0c\u5f97\u4e0d\u507f\u5931\u3002\u56e0\u4e3a\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u4e3a \\(O(n \\log n)\\) \uff0c\u6bd4\u7ebf\u6027\u67e5\u627e\u548c\u4e8c\u5206\u67e5\u627e\u90fd\u66f4\u9ad8\u3002\u5bf9\u4e8e\u9891\u7e41\u63d2\u5165\u5143\u7d20\u7684\u573a\u666f\uff0c\u4e3a\u4fdd\u6301\u6570\u7ec4\u6709\u5e8f\u6027\uff0c\u9700\u8981\u5c06\u5143\u7d20\u63d2\u5165\u5230\u7279\u5b9a\u4f4d\u7f6e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u4e5f\u662f\u975e\u5e38\u6602\u8d35\u7684\u3002
    • \u4e8c\u5206\u67e5\u627e\u4ec5\u9002\u7528\u4e8e\u6570\u7ec4\u3002\u4e8c\u5206\u67e5\u627e\u9700\u8981\u8df3\u8dc3\u5f0f\uff08\u975e\u8fde\u7eed\u5730\uff09\u8bbf\u95ee\u5143\u7d20\uff0c\u800c\u5728\u94fe\u8868\u4e2d\u6267\u884c\u8df3\u8dc3\u5f0f\u8bbf\u95ee\u7684\u6548\u7387\u8f83\u4f4e\uff0c\u56e0\u6b64\u4e0d\u9002\u5408\u5e94\u7528\u5728\u94fe\u8868\u6216\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002
    • \u5c0f\u6570\u636e\u91cf\u4e0b\uff0c\u7ebf\u6027\u67e5\u627e\u6027\u80fd\u66f4\u4f73\u3002\u5728\u7ebf\u6027\u67e5\u627e\u4e2d\uff0c\u6bcf\u8f6e\u53ea\u9700 1 \u6b21\u5224\u65ad\u64cd\u4f5c\uff1b\u800c\u5728\u4e8c\u5206\u67e5\u627e\u4e2d\uff0c\u9700\u8981 1 \u6b21\u52a0\u6cd5\u30011 \u6b21\u9664\u6cd5\u30011 ~ 3 \u6b21\u5224\u65ad\u64cd\u4f5c\u30011 \u6b21\u52a0\u6cd5\uff08\u51cf\u6cd5\uff09\uff0c\u5171 4 ~ 6 \u4e2a\u5355\u5143\u64cd\u4f5c\uff1b\u56e0\u6b64\uff0c\u5f53\u6570\u636e\u91cf \\(n\\) \u8f83\u5c0f\u65f6\uff0c\u7ebf\u6027\u67e5\u627e\u53cd\u800c\u6bd4\u4e8c\u5206\u67e5\u627e\u66f4\u5feb\u3002
    "},{"location":"chapter_searching/binary_search_edge/","title":"10.3 \u00a0 \u4e8c\u5206\u67e5\u627e\u8fb9\u754c","text":""},{"location":"chapter_searching/binary_search_edge/#1031","title":"10.3.1 \u00a0 \u67e5\u627e\u5de6\u8fb9\u754c","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6709\u5e8f\u6570\u7ec4 nums \uff0c\u5176\u4e2d\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\u3002\u8bf7\u8fd4\u56de\u6570\u7ec4\u4e2d\u6700\u5de6\u4e00\u4e2a\u5143\u7d20 target \u7684\u7d22\u5f15\u3002\u82e5\u6570\u7ec4\u4e2d\u4e0d\u5305\u542b\u8be5\u5143\u7d20\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002

    \u56de\u5fc6\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\u7684\u65b9\u6cd5\uff0c\u641c\u7d22\u5b8c\u6210\u540e \\(i\\) \u6307\u5411\u6700\u5de6\u4e00\u4e2a target \uff0c\u56e0\u6b64\u67e5\u627e\u63d2\u5165\u70b9\u672c\u8d28\u4e0a\u662f\u5728\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target \u7684\u7d22\u5f15\u3002

    \u8003\u8651\u901a\u8fc7\u67e5\u627e\u63d2\u5165\u70b9\u7684\u51fd\u6570\u5b9e\u73b0\u67e5\u627e\u5de6\u8fb9\u754c\u3002\u8bf7\u6ce8\u610f\uff0c\u6570\u7ec4\u4e2d\u53ef\u80fd\u4e0d\u5305\u542b target \uff0c\u8fd9\u79cd\u60c5\u51b5\u53ef\u80fd\u5bfc\u81f4\u4ee5\u4e0b\u4e24\u79cd\u7ed3\u679c\u3002

    • \u63d2\u5165\u70b9\u7684\u7d22\u5f15 \\(i\\) \u8d8a\u754c\u3002
    • \u5143\u7d20 nums[i] \u4e0e target \u4e0d\u76f8\u7b49\u3002

    \u5f53\u9047\u5230\u4ee5\u4e0a\u4e24\u79cd\u60c5\u51b5\u65f6\uff0c\u76f4\u63a5\u8fd4\u56de \\(-1\\) \u5373\u53ef\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_edge.py
    def binary_search_left_edge(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target\"\"\"\n    # \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    i = binary_search_insertion(nums, target)\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == len(nums) or nums[i] != target:\n        return -1\n    # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n
    binary_search_edge.cpp
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(vector<int> &nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.size() || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.java
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(int[] nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binary_search_insertion.binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.length || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.cs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint BinarySearchLeftEdge(int[] nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binary_search_insertion.BinarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.Length || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.go
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunc binarySearchLeftEdge(nums []int, target int) int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    i := binarySearchInsertion(nums, target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == len(nums) || nums[i] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.swift
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunc binarySearchLeftEdge(nums: [Int], target: Int) -> Int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    let i = binarySearchInsertion(nums: nums, target: target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == nums.endIndex || nums[i] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.js
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunction binarySearchLeftEdge(nums, target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    const i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i === nums.length || nums[i] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.ts
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunction binarySearchLeftEdge(nums: Array<number>, target: number): number {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    const i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i === nums.length || nums[i] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.dart
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(List<int> nums, int target) {\n  // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n  int i = binarySearchInsertion(nums, target);\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  if (i == nums.length || nums[i] != target) {\n    return -1;\n  }\n  // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n  return i;\n}\n
    binary_search_edge.rs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfn binary_search_left_edge(nums: &[i32], target: i32) -> i32 {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    let i = binary_search_insertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == nums.len() as i32 || nums[i as usize] != target {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    i\n}\n
    binary_search_edge.c
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(int *nums, int numSize, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binarySearchInsertion(nums, numSize, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == numSize || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.kt
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfun binarySearchLeftEdge(nums: IntArray, target: Int): Int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    val i = binarySearchInsertion(nums, target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.size || nums[i] != target) {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.rb
    ### \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target ###\ndef binary_search_left_edge(nums, target)\n  # \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n  i = binary_search_insertion(nums, target)\n\n  # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  return -1 if i == nums.length || nums[i] != target\n\n  i # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\nend\n
    binary_search_edge.zig
    [class]{}-[func]{binarySearchLeftEdge}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_searching/binary_search_edge/#1032","title":"10.3.2 \u00a0 \u67e5\u627e\u53f3\u8fb9\u754c","text":"

    \u90a3\u4e48\u5982\u4f55\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target \u5462\uff1f\u6700\u76f4\u63a5\u7684\u65b9\u5f0f\u662f\u4fee\u6539\u4ee3\u7801\uff0c\u66ff\u6362\u5728 nums[m] == target \u60c5\u51b5\u4e0b\u7684\u6307\u9488\u6536\u7f29\u64cd\u4f5c\u3002\u4ee3\u7801\u5728\u6b64\u7701\u7565\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u3002

    \u4e0b\u9762\u6211\u4eec\u4ecb\u7ecd\u4e24\u79cd\u66f4\u52a0\u53d6\u5de7\u7684\u65b9\u6cd5\u3002

    "},{"location":"chapter_searching/binary_search_edge/#1","title":"1. \u00a0 \u590d\u7528\u67e5\u627e\u5de6\u8fb9\u754c","text":"

    \u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u67e5\u627e\u6700\u5de6\u5143\u7d20\u7684\u51fd\u6570\u6765\u67e5\u627e\u6700\u53f3\u5143\u7d20\uff0c\u5177\u4f53\u65b9\u6cd5\u4e3a\uff1a\u5c06\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\u3002

    \u5982\u56fe 10-7 \u6240\u793a\uff0c\u67e5\u627e\u5b8c\u6210\u540e\uff0c\u6307\u9488 \\(i\\) \u6307\u5411\u6700\u5de6\u4e00\u4e2a target + 1\uff08\u5982\u679c\u5b58\u5728\uff09\uff0c\u800c \\(j\\) \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0c\u56e0\u6b64\u8fd4\u56de \\(j\\) \u5373\u53ef\u3002

    \u56fe 10-7 \u00a0 \u5c06\u67e5\u627e\u53f3\u8fb9\u754c\u8f6c\u5316\u4e3a\u67e5\u627e\u5de6\u8fb9\u754c

    \u8bf7\u6ce8\u610f\uff0c\u8fd4\u56de\u7684\u63d2\u5165\u70b9\u662f \\(i\\) \uff0c\u56e0\u6b64\u9700\u8981\u5c06\u5176\u51cf \\(1\\) \uff0c\u4ece\u800c\u83b7\u5f97 \\(j\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_edge.py
    def binary_search_right_edge(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target\"\"\"\n    # \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    i = binary_search_insertion(nums, target + 1)\n    # j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    j = i - 1\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 or nums[j] != target:\n        return -1\n    # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n
    binary_search_edge.cpp
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(vector<int> &nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.java
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(int[] nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binary_search_insertion.binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.cs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint BinarySearchRightEdge(int[] nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binary_search_insertion.BinarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.go
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunc binarySearchRightEdge(nums []int, target int) int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    i := binarySearchInsertion(nums, target+1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    j := i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.swift
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunc binarySearchRightEdge(nums: [Int], target: Int) -> Int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    let i = binarySearchInsertion(nums: nums, target: target + 1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    let j = i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.js
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunction binarySearchRightEdge(nums, target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    const i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    const j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j === -1 || nums[j] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.ts
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunction binarySearchRightEdge(nums: Array<number>, target: number): number {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    const i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    const j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j === -1 || nums[j] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.dart
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(List<int> nums, int target) {\n  // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n  int i = binarySearchInsertion(nums, target + 1);\n  // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n  int j = i - 1;\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  if (j == -1 || nums[j] != target) {\n    return -1;\n  }\n  // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n  return j;\n}\n
    binary_search_edge.rs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfn binary_search_right_edge(nums: &[i32], target: i32) -> i32 {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    let i = binary_search_insertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    let j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j as usize] != target {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    j\n}\n
    binary_search_edge.c
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(int *nums, int numSize, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binarySearchInsertion(nums, numSize, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.kt
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfun binarySearchRightEdge(nums: IntArray, target: Int): Int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    val i = binarySearchInsertion(nums, target + 1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    val j = i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.rb
    ### \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target ###\ndef binary_search_right_edge(nums, target)\n  # \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n  i = binary_search_insertion(nums, target + 1)\n\n  # j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n  j = i - 1\n\n  # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  return -1 if j == -1 || nums[j] != target\n\n  j # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\nend\n
    binary_search_edge.zig
    [class]{}-[func]{binarySearchRightEdge}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_searching/binary_search_edge/#2","title":"2. \u00a0 \u8f6c\u5316\u4e3a\u67e5\u627e\u5143\u7d20","text":"

    \u6211\u4eec\u77e5\u9053\uff0c\u5f53\u6570\u7ec4\u4e0d\u5305\u542b target \u65f6\uff0c\u6700\u7ec8 \\(i\\) \u548c \\(j\\) \u4f1a\u5206\u522b\u6307\u5411\u9996\u4e2a\u5927\u4e8e\u3001\u5c0f\u4e8e target \u7684\u5143\u7d20\u3002

    \u56e0\u6b64\uff0c\u5982\u56fe 10-8 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u9020\u4e00\u4e2a\u6570\u7ec4\u4e2d\u4e0d\u5b58\u5728\u7684\u5143\u7d20\uff0c\u7528\u4e8e\u67e5\u627e\u5de6\u53f3\u8fb9\u754c\u3002

    • \u67e5\u627e\u6700\u5de6\u4e00\u4e2a target \uff1a\u53ef\u4ee5\u8f6c\u5316\u4e3a\u67e5\u627e target - 0.5 \uff0c\u5e76\u8fd4\u56de\u6307\u9488 \\(i\\) \u3002
    • \u67e5\u627e\u6700\u53f3\u4e00\u4e2a target \uff1a\u53ef\u4ee5\u8f6c\u5316\u4e3a\u67e5\u627e target + 0.5 \uff0c\u5e76\u8fd4\u56de\u6307\u9488 \\(j\\) \u3002

    \u56fe 10-8 \u00a0 \u5c06\u67e5\u627e\u8fb9\u754c\u8f6c\u5316\u4e3a\u67e5\u627e\u5143\u7d20

    \u4ee3\u7801\u5728\u6b64\u7701\u7565\uff0c\u4ee5\u4e0b\u4e24\u70b9\u503c\u5f97\u6ce8\u610f\u3002

    • \u7ed9\u5b9a\u6570\u7ec4\u4e0d\u5305\u542b\u5c0f\u6570\uff0c\u8fd9\u610f\u5473\u7740\u6211\u4eec\u65e0\u987b\u5173\u5fc3\u5982\u4f55\u5904\u7406\u76f8\u7b49\u7684\u60c5\u51b5\u3002
    • \u56e0\u4e3a\u8be5\u65b9\u6cd5\u5f15\u5165\u4e86\u5c0f\u6570\uff0c\u6240\u4ee5\u9700\u8981\u5c06\u51fd\u6570\u4e2d\u7684\u53d8\u91cf target \u6539\u4e3a\u6d6e\u70b9\u6570\u7c7b\u578b\uff08Python \u65e0\u987b\u6539\u52a8\uff09\u3002
    "},{"location":"chapter_searching/binary_search_insertion/","title":"10.2 \u00a0 \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9","text":"

    \u4e8c\u5206\u67e5\u627e\u4e0d\u4ec5\u53ef\u7528\u4e8e\u641c\u7d22\u76ee\u6807\u5143\u7d20\uff0c\u8fd8\u53ef\u7528\u4e8e\u89e3\u51b3\u8bb8\u591a\u53d8\u79cd\u95ee\u9898\uff0c\u6bd4\u5982\u641c\u7d22\u76ee\u6807\u5143\u7d20\u7684\u63d2\u5165\u4f4d\u7f6e\u3002

    "},{"location":"chapter_searching/binary_search_insertion/#1021","title":"10.2.1 \u00a0 \u65e0\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6709\u5e8f\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u5143\u7d20 target \uff0c\u6570\u7ec4\u4e0d\u5b58\u5728\u91cd\u590d\u5143\u7d20\u3002\u73b0\u5c06 target \u63d2\u5165\u6570\u7ec4 nums \u4e2d\uff0c\u5e76\u4fdd\u6301\u5176\u6709\u5e8f\u6027\u3002\u82e5\u6570\u7ec4\u4e2d\u5df2\u5b58\u5728\u5143\u7d20 target \uff0c\u5219\u63d2\u5165\u5230\u5176\u5de6\u65b9\u3002\u8bf7\u8fd4\u56de\u63d2\u5165\u540e target \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15\u3002\u793a\u4f8b\u5982\u56fe 10-4 \u6240\u793a\u3002

    \u56fe 10-4 \u00a0 \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\u793a\u4f8b\u6570\u636e

    \u5982\u679c\u60f3\u590d\u7528\u4e0a\u4e00\u8282\u7684\u4e8c\u5206\u67e5\u627e\u4ee3\u7801\uff0c\u5219\u9700\u8981\u56de\u7b54\u4ee5\u4e0b\u4e24\u4e2a\u95ee\u9898\u3002

    \u95ee\u9898\u4e00\uff1a\u5f53\u6570\u7ec4\u4e2d\u5305\u542b target \u65f6\uff0c\u63d2\u5165\u70b9\u7684\u7d22\u5f15\u662f\u5426\u662f\u8be5\u5143\u7d20\u7684\u7d22\u5f15\uff1f

    \u9898\u76ee\u8981\u6c42\u5c06 target \u63d2\u5165\u5230\u76f8\u7b49\u5143\u7d20\u7684\u5de6\u8fb9\uff0c\u8fd9\u610f\u5473\u7740\u65b0\u63d2\u5165\u7684 target \u66ff\u6362\u4e86\u539f\u6765 target \u7684\u4f4d\u7f6e\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u6570\u7ec4\u5305\u542b target \u65f6\uff0c\u63d2\u5165\u70b9\u7684\u7d22\u5f15\u5c31\u662f\u8be5 target \u7684\u7d22\u5f15\u3002

    \u95ee\u9898\u4e8c\uff1a\u5f53\u6570\u7ec4\u4e2d\u4e0d\u5b58\u5728 target \u65f6\uff0c\u63d2\u5165\u70b9\u662f\u54ea\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\uff1f

    \u8fdb\u4e00\u6b65\u601d\u8003\u4e8c\u5206\u67e5\u627e\u8fc7\u7a0b\uff1a\u5f53 nums[m] < target \u65f6 \\(i\\) \u79fb\u52a8\uff0c\u8fd9\u610f\u5473\u7740\u6307\u9488 \\(i\\) \u5728\u5411\u5927\u4e8e\u7b49\u4e8e target \u7684\u5143\u7d20\u9760\u8fd1\u3002\u540c\u7406\uff0c\u6307\u9488 \\(j\\) \u59cb\u7ec8\u5728\u5411\u5c0f\u4e8e\u7b49\u4e8e target \u7684\u5143\u7d20\u9760\u8fd1\u3002

    \u56e0\u6b64\u4e8c\u5206\u7ed3\u675f\u65f6\u4e00\u5b9a\u6709\uff1a\\(i\\) \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\uff0c\\(j\\) \u6307\u5411\u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u3002\u6613\u5f97\u5f53\u6570\u7ec4\u4e0d\u5305\u542b target \u65f6\uff0c\u63d2\u5165\u7d22\u5f15\u4e3a \\(i\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_insertion.py
    def binary_search_insertion_simple(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09\"\"\"\n    i, j = 0, len(nums) - 1  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            return m  # \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n
    binary_search_insertion.cpp
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(vector<int> &nums, int target) {\n    int i = 0, j = nums.size() - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.java
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(int[] nums, int target) {\n    int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.cs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint BinarySearchInsertionSimple(int[] nums, int target) {\n    int i = 0, j = nums.Length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.go
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertionSimple(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    i, j := 0, len(nums)-1\n    for i <= j {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        m := i + (j-i)/2\n        if nums[m] < target {\n            // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target {\n            // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else {\n            // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n            return m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.swift
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertionSimple(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m] > target {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.js
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertionSimple(nums, target) {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.ts
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertionSimple(\n    nums: Array<number>,\n    target: number\n): number {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.dart
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(List<int> nums, int target) {\n  int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    } else if (nums[m] > target) {\n      j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    } else {\n      return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    }\n  }\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n  return i;\n}\n
    binary_search_insertion.rs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfn binary_search_insertion_simple(nums: &[i32], target: i32) -> i32 {\n    let (mut i, mut j) = (0, nums.len() as i32 - 1); // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m as usize] > target {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    i\n}\n
    binary_search_insertion.c
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(int *nums, int numSize, int target) {\n    int i = 0, j = numSize - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.kt
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfun binarySearchInsertionSimple(nums: IntArray, target: Int): Int {\n    var i = 0\n    var j = nums.size - 1 // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.rb
    ### \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 ###\ndef binary_search_insertion_simple(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  i, j = 0, nums.length - 1\n\n  while i <= j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      return m  # \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    end\n  end\n\n  i # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\nend\n
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertionSimple}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_searching/binary_search_insertion/#1022","title":"10.2.2 \u00a0 \u5b58\u5728\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u5728\u4e0a\u4e00\u9898\u7684\u57fa\u7840\u4e0a\uff0c\u89c4\u5b9a\u6570\u7ec4\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u5176\u4f59\u4e0d\u53d8\u3002

    \u5047\u8bbe\u6570\u7ec4\u4e2d\u5b58\u5728\u591a\u4e2a target \uff0c\u5219\u666e\u901a\u4e8c\u5206\u67e5\u627e\u53ea\u80fd\u8fd4\u56de\u5176\u4e2d\u4e00\u4e2a target \u7684\u7d22\u5f15\uff0c\u800c\u65e0\u6cd5\u786e\u5b9a\u8be5\u5143\u7d20\u7684\u5de6\u8fb9\u548c\u53f3\u8fb9\u8fd8\u6709\u591a\u5c11 target\u3002

    \u9898\u76ee\u8981\u6c42\u5c06\u76ee\u6807\u5143\u7d20\u63d2\u5165\u5230\u6700\u5de6\u8fb9\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5de6\u4e00\u4e2a target \u7684\u7d22\u5f15\u3002\u521d\u6b65\u8003\u8651\u901a\u8fc7\u56fe 10-5 \u6240\u793a\u7684\u6b65\u9aa4\u5b9e\u73b0\u3002

    1. \u6267\u884c\u4e8c\u5206\u67e5\u627e\uff0c\u5f97\u5230\u4efb\u610f\u4e00\u4e2a target \u7684\u7d22\u5f15\uff0c\u8bb0\u4e3a \\(k\\) \u3002
    2. \u4ece\u7d22\u5f15 \\(k\\) \u5f00\u59cb\uff0c\u5411\u5de6\u8fdb\u884c\u7ebf\u6027\u904d\u5386\uff0c\u5f53\u627e\u5230\u6700\u5de6\u8fb9\u7684 target \u65f6\u8fd4\u56de\u3002

    \u56fe 10-5 \u00a0 \u7ebf\u6027\u67e5\u627e\u91cd\u590d\u5143\u7d20\u7684\u63d2\u5165\u70b9

    \u6b64\u65b9\u6cd5\u867d\u7136\u53ef\u7528\uff0c\u4f46\u5176\u5305\u542b\u7ebf\u6027\u67e5\u627e\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002\u5f53\u6570\u7ec4\u4e2d\u5b58\u5728\u5f88\u591a\u91cd\u590d\u7684 target \u65f6\uff0c\u8be5\u65b9\u6cd5\u6548\u7387\u5f88\u4f4e\u3002

    \u73b0\u8003\u8651\u62d3\u5c55\u4e8c\u5206\u67e5\u627e\u4ee3\u7801\u3002\u5982\u56fe 10-6 \u6240\u793a\uff0c\u6574\u4f53\u6d41\u7a0b\u4fdd\u6301\u4e0d\u53d8\uff0c\u6bcf\u8f6e\u5148\u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 \\(m\\) \uff0c\u518d\u5224\u65ad target \u548c nums[m] \u7684\u5927\u5c0f\u5173\u7cfb\uff0c\u5206\u4e3a\u4ee5\u4e0b\u51e0\u79cd\u60c5\u51b5\u3002

    • \u5f53 nums[m] < target \u6216 nums[m] > target \u65f6\uff0c\u8bf4\u660e\u8fd8\u6ca1\u6709\u627e\u5230 target \uff0c\u56e0\u6b64\u91c7\u7528\u666e\u901a\u4e8c\u5206\u67e5\u627e\u7684\u7f29\u5c0f\u533a\u95f4\u64cd\u4f5c\uff0c\u4ece\u800c\u4f7f\u6307\u9488 \\(i\\) \u548c \\(j\\) \u5411 target \u9760\u8fd1\u3002
    • \u5f53 nums[m] == target \u65f6\uff0c\u8bf4\u660e\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 \\([i, m - 1]\\) \u4e2d\uff0c\u56e0\u6b64\u91c7\u7528 \\(j = m - 1\\) \u6765\u7f29\u5c0f\u533a\u95f4\uff0c\u4ece\u800c\u4f7f\u6307\u9488 \\(j\\) \u5411\u5c0f\u4e8e target \u7684\u5143\u7d20\u9760\u8fd1\u3002

    \u5faa\u73af\u5b8c\u6210\u540e\uff0c\\(i\\) \u6307\u5411\u6700\u5de6\u8fb9\u7684 target \uff0c\\(j\\) \u6307\u5411\u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\uff0c\u56e0\u6b64\u7d22\u5f15 \\(i\\) \u5c31\u662f\u63d2\u5165\u70b9\u3002

    <1><2><3><4><5><6><7><8>

    \u56fe 10-6 \u00a0 \u4e8c\u5206\u67e5\u627e\u91cd\u590d\u5143\u7d20\u7684\u63d2\u5165\u70b9\u7684\u6b65\u9aa4

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u5224\u65ad\u5206\u652f nums[m] > target \u548c nums[m] == target \u7684\u64cd\u4f5c\u76f8\u540c\uff0c\u56e0\u6b64\u4e24\u8005\u53ef\u4ee5\u5408\u5e76\u3002

    \u5373\u4fbf\u5982\u6b64\uff0c\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u5c06\u5224\u65ad\u6761\u4ef6\u4fdd\u6301\u5c55\u5f00\uff0c\u56e0\u4e3a\u5176\u903b\u8f91\u66f4\u52a0\u6e05\u6670\u3001\u53ef\u8bfb\u6027\u66f4\u597d\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_insertion.py
    def binary_search_insertion(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09\"\"\"\n    i, j = 0, len(nums) - 1  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            j = m - 1  # \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    # \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n
    binary_search_insertion.cpp
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(vector<int> &nums, int target) {\n    int i = 0, j = nums.size() - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.java
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(int[] nums, int target) {\n    int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.cs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint BinarySearchInsertion(int[] nums, int target) {\n    int i = 0, j = nums.Length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.go
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertion(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    i, j := 0, len(nums)-1\n    for i <= j {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        m := i + (j-i)/2\n        if nums[m] < target {\n            // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target {\n            // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else {\n            // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.swift
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertion(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m] > target {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1 // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.js
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertion(nums, target) {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.ts
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertion(nums: Array<number>, target: number): number {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.dart
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(List<int> nums, int target) {\n  int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    } else if (nums[m] > target) {\n      j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    } else {\n      j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    }\n  }\n  // \u8fd4\u56de\u63d2\u5165\u70b9 i\n  return i;\n}\n
    binary_search_insertion.rs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\npub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 {\n    let (mut i, mut j) = (0, nums.len() as i32 - 1); // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m as usize] > target {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    i\n}\n
    binary_search_insertion.c
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(int *nums, int numSize, int target) {\n    int i = 0, j = numSize - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.kt
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfun binarySearchInsertion(nums: IntArray, target: Int): Int {\n    var i = 0\n    var j = nums.size - 1 // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1 // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.rb
    ### \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 ###\ndef binary_search_insertion(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  i, j = 0, nums.length - 1\n\n  while i <= j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      j = m - 1 # \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    end\n  end\n\n  i # \u8fd4\u56de\u63d2\u5165\u70b9 i\nend\n
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertion}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    Tip

    \u672c\u8282\u7684\u4ee3\u7801\u90fd\u662f\u201c\u53cc\u95ed\u533a\u95f4\u201d\u5199\u6cd5\u3002\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u201c\u5de6\u95ed\u53f3\u5f00\u201d\u5199\u6cd5\u3002

    \u603b\u7684\u6765\u770b\uff0c\u4e8c\u5206\u67e5\u627e\u65e0\u975e\u5c31\u662f\u7ed9\u6307\u9488 \\(i\\) \u548c \\(j\\) \u5206\u522b\u8bbe\u5b9a\u641c\u7d22\u76ee\u6807\uff0c\u76ee\u6807\u53ef\u80fd\u662f\u4e00\u4e2a\u5177\u4f53\u7684\u5143\u7d20\uff08\u4f8b\u5982 target \uff09\uff0c\u4e5f\u53ef\u80fd\u662f\u4e00\u4e2a\u5143\u7d20\u8303\u56f4\uff08\u4f8b\u5982\u5c0f\u4e8e target \u7684\u5143\u7d20\uff09\u3002

    \u5728\u4e0d\u65ad\u7684\u5faa\u73af\u4e8c\u5206\u4e2d\uff0c\u6307\u9488 \\(i\\) \u548c \\(j\\) \u90fd\u9010\u6e10\u903c\u8fd1\u9884\u5148\u8bbe\u5b9a\u7684\u76ee\u6807\u3002\u6700\u7ec8\uff0c\u5b83\u4eec\u6216\u662f\u6210\u529f\u627e\u5230\u7b54\u6848\uff0c\u6216\u662f\u8d8a\u8fc7\u8fb9\u754c\u540e\u505c\u6b62\u3002

    "},{"location":"chapter_searching/replace_linear_by_hashing/","title":"10.4 \u00a0 \u54c8\u5e0c\u4f18\u5316\u7b56\u7565","text":"

    \u5728\u7b97\u6cd5\u9898\u4e2d\uff0c\u6211\u4eec\u5e38\u901a\u8fc7\u5c06\u7ebf\u6027\u67e5\u627e\u66ff\u6362\u4e3a\u54c8\u5e0c\u67e5\u627e\u6765\u964d\u4f4e\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6211\u4eec\u501f\u52a9\u4e00\u4e2a\u7b97\u6cd5\u9898\u6765\u52a0\u6df1\u7406\u89e3\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6574\u6570\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u76ee\u6807\u5143\u7d20 target \uff0c\u8bf7\u5728\u6570\u7ec4\u4e2d\u641c\u7d22\u201c\u548c\u201d\u4e3a target \u7684\u4e24\u4e2a\u5143\u7d20\uff0c\u5e76\u8fd4\u56de\u5b83\u4eec\u7684\u6570\u7ec4\u7d22\u5f15\u3002\u8fd4\u56de\u4efb\u610f\u4e00\u4e2a\u89e3\u5373\u53ef\u3002

    "},{"location":"chapter_searching/replace_linear_by_hashing/#1041","title":"10.4.1 \u00a0 \u7ebf\u6027\u67e5\u627e\uff1a\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4","text":"

    \u8003\u8651\u76f4\u63a5\u904d\u5386\u6240\u6709\u53ef\u80fd\u7684\u7ec4\u5408\u3002\u5982\u56fe 10-9 \u6240\u793a\uff0c\u6211\u4eec\u5f00\u542f\u4e00\u4e2a\u4e24\u5c42\u5faa\u73af\uff0c\u5728\u6bcf\u8f6e\u4e2d\u5224\u65ad\u4e24\u4e2a\u6574\u6570\u7684\u548c\u662f\u5426\u4e3a target \uff0c\u82e5\u662f\uff0c\u5219\u8fd4\u56de\u5b83\u4eec\u7684\u7d22\u5f15\u3002

    \u56fe 10-9 \u00a0 \u7ebf\u6027\u67e5\u627e\u6c42\u89e3\u4e24\u6570\u4e4b\u548c

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig two_sum.py
    def two_sum_brute_force(nums: list[int], target: int) -> list[int]:\n    \"\"\"\u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e\"\"\"\n    # \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in range(len(nums) - 1):\n        for j in range(i + 1, len(nums)):\n            if nums[i] + nums[j] == target:\n                return [i, j]\n    return []\n
    two_sum.cpp
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nvector<int> twoSumBruteForce(vector<int> &nums, int target) {\n    int size = nums.size();\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return {i, j};\n        }\n    }\n    return {};\n}\n
    two_sum.java
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint[] twoSumBruteForce(int[] nums, int target) {\n    int size = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return new int[] { i, j };\n        }\n    }\n    return new int[0];\n}\n
    two_sum.cs
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint[] TwoSumBruteForce(int[] nums, int target) {\n    int size = nums.Length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return [i, j];\n        }\n    }\n    return [];\n}\n
    two_sum.go
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunc twoSumBruteForce(nums []int, target int) []int {\n    size := len(nums)\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i := 0; i < size-1; i++ {\n        for j := i + 1; j < size; j++ {\n            if nums[i]+nums[j] == target {\n                return []int{i, j}\n            }\n        }\n    }\n    return nil\n}\n
    two_sum.swift
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunc twoSumBruteForce(nums: [Int], target: Int) -> [Int] {\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in nums.indices.dropLast() {\n        for j in nums.indices.dropFirst(i + 1) {\n            if nums[i] + nums[j] == target {\n                return [i, j]\n            }\n        }\n    }\n    return [0]\n}\n
    two_sum.js
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunction twoSumBruteForce(nums, target) {\n    const n = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (let i = 0; i < n; i++) {\n        for (let j = i + 1; j < n; j++) {\n            if (nums[i] + nums[j] === target) {\n                return [i, j];\n            }\n        }\n    }\n    return [];\n}\n
    two_sum.ts
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunction twoSumBruteForce(nums: number[], target: number): number[] {\n    const n = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (let i = 0; i < n; i++) {\n        for (let j = i + 1; j < n; j++) {\n            if (nums[i] + nums[j] === target) {\n                return [i, j];\n            }\n        }\n    }\n    return [];\n}\n
    two_sum.dart
    /* \u65b9\u6cd5\u4e00\uff1a \u66b4\u529b\u679a\u4e3e */\nList<int> twoSumBruteForce(List<int> nums, int target) {\n  int size = nums.length;\n  // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n  for (var i = 0; i < size - 1; i++) {\n    for (var j = i + 1; j < size; j++) {\n      if (nums[i] + nums[j] == target) return [i, j];\n    }\n  }\n  return [0];\n}\n
    two_sum.rs
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\npub fn two_sum_brute_force(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {\n    let size = nums.len();\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in 0..size - 1 {\n        for j in i + 1..size {\n            if nums[i] + nums[j] == target {\n                return Some(vec![i as i32, j as i32]);\n            }\n        }\n    }\n    None\n}\n
    two_sum.c
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint *twoSumBruteForce(int *nums, int numsSize, int target, int *returnSize) {\n    for (int i = 0; i < numsSize; ++i) {\n        for (int j = i + 1; j < numsSize; ++j) {\n            if (nums[i] + nums[j] == target) {\n                int *res = malloc(sizeof(int) * 2);\n                res[0] = i, res[1] = j;\n                *returnSize = 2;\n                return res;\n            }\n        }\n    }\n    *returnSize = 0;\n    return NULL;\n}\n
    two_sum.kt
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfun twoSumBruteForce(nums: IntArray, target: Int): IntArray {\n    val size = nums.size\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (i in 0..<size - 1) {\n        for (j in i + 1..<size) {\n            if (nums[i] + nums[j] == target) return intArrayOf(i, j)\n        }\n    }\n    return IntArray(0)\n}\n
    two_sum.rb
    ### \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e ###\ndef two_sum_brute_force(nums, target)\n  # \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n  for i in 0...(nums.length - 1)\n    for j in (i + 1)...nums.length\n      return [i, j] if nums[i] + nums[j] == target\n    end\n  end\n\n  []\nend\n
    two_sum.zig
    // \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e\nfn twoSumBruteForce(nums: []i32, target: i32) ?[2]i32 {\n    var size: usize = nums.len;\n    var i: usize = 0;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    while (i < size - 1) : (i += 1) {\n        var j = i + 1;\n        while (j < size) : (j += 1) {\n            if (nums[i] + nums[j] == target) {\n                return [_]i32{@intCast(i), @intCast(j)};\n            }\n        }\n    }\n    return null;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6b64\u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff0c\u5728\u5927\u6570\u636e\u91cf\u4e0b\u975e\u5e38\u8017\u65f6\u3002

    "},{"location":"chapter_searching/replace_linear_by_hashing/#1042","title":"10.4.2 \u00a0 \u54c8\u5e0c\u67e5\u627e\uff1a\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4","text":"

    \u8003\u8651\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u8868\uff0c\u952e\u503c\u5bf9\u5206\u522b\u4e3a\u6570\u7ec4\u5143\u7d20\u548c\u5143\u7d20\u7d22\u5f15\u3002\u5faa\u73af\u904d\u5386\u6570\u7ec4\uff0c\u6bcf\u8f6e\u6267\u884c\u56fe 10-10 \u6240\u793a\u7684\u6b65\u9aa4\u3002

    1. \u5224\u65ad\u6570\u5b57 target - nums[i] \u662f\u5426\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u82e5\u662f\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u8fd9\u4e24\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u3002
    2. \u5c06\u952e\u503c\u5bf9 nums[i] \u548c\u7d22\u5f15 i \u6dfb\u52a0\u8fdb\u54c8\u5e0c\u8868\u3002
    <1><2><3>

    \u56fe 10-10 \u00a0 \u8f85\u52a9\u54c8\u5e0c\u8868\u6c42\u89e3\u4e24\u6570\u4e4b\u548c

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff0c\u4ec5\u9700\u5355\u5c42\u5faa\u73af\u5373\u53ef\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig two_sum.py
    def two_sum_hash_table(nums: list[int], target: int) -> list[int]:\n    \"\"\"\u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868\"\"\"\n    # \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    dic = {}\n    # \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for i in range(len(nums)):\n        if target - nums[i] in dic:\n            return [dic[target - nums[i]], i]\n        dic[nums[i]] = i\n    return []\n
    two_sum.cpp
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nvector<int> twoSumHashTable(vector<int> &nums, int target) {\n    int size = nums.size();\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    unordered_map<int, int> dic;\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.find(target - nums[i]) != dic.end()) {\n            return {dic[target - nums[i]], i};\n        }\n        dic.emplace(nums[i], i);\n    }\n    return {};\n}\n
    two_sum.java
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint[] twoSumHashTable(int[] nums, int target) {\n    int size = nums.length;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    Map<Integer, Integer> dic = new HashMap<>();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.containsKey(target - nums[i])) {\n            return new int[] { dic.get(target - nums[i]), i };\n        }\n        dic.put(nums[i], i);\n    }\n    return new int[0];\n}\n
    two_sum.cs
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint[] TwoSumHashTable(int[] nums, int target) {\n    int size = nums.Length;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    Dictionary<int, int> dic = [];\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.ContainsKey(target - nums[i])) {\n            return [dic[target - nums[i]], i];\n        }\n        dic.Add(nums[i], i);\n    }\n    return [];\n}\n
    two_sum.go
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunc twoSumHashTable(nums []int, target int) []int {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    hashTable := map[int]int{}\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for idx, val := range nums {\n        if preIdx, ok := hashTable[target-val]; ok {\n            return []int{preIdx, idx}\n        }\n        hashTable[val] = idx\n    }\n    return nil\n}\n
    two_sum.swift
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunc twoSumHashTable(nums: [Int], target: Int) -> [Int] {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    var dic: [Int: Int] = [:]\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for i in nums.indices {\n        if let j = dic[target - nums[i]] {\n            return [j, i]\n        }\n        dic[nums[i]] = i\n    }\n    return [0]\n}\n
    two_sum.js
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunction twoSumHashTable(nums, target) {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let m = {};\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (let i = 0; i < nums.length; i++) {\n        if (m[target - nums[i]] !== undefined) {\n            return [m[target - nums[i]], i];\n        } else {\n            m[nums[i]] = i;\n        }\n    }\n    return [];\n}\n
    two_sum.ts
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunction twoSumHashTable(nums: number[], target: number): number[] {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let m: Map<number, number> = new Map();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (let i = 0; i < nums.length; i++) {\n        let index = m.get(target - nums[i]);\n        if (index !== undefined) {\n            return [index, i];\n        } else {\n            m.set(nums[i], i);\n        }\n    }\n    return [];\n}\n
    two_sum.dart
    /* \u65b9\u6cd5\u4e8c\uff1a \u8f85\u52a9\u54c8\u5e0c\u8868 */\nList<int> twoSumHashTable(List<int> nums, int target) {\n  int size = nums.length;\n  // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  Map<int, int> dic = HashMap();\n  // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  for (var i = 0; i < size; i++) {\n    if (dic.containsKey(target - nums[i])) {\n      return [dic[target - nums[i]]!, i];\n    }\n    dic.putIfAbsent(nums[i], () => i);\n  }\n  return [0];\n}\n
    two_sum.rs
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\npub fn two_sum_hash_table(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let mut dic = HashMap::new();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (i, num) in nums.iter().enumerate() {\n        match dic.get(&(target - num)) {\n            Some(v) => return Some(vec![*v as i32, i as i32]),\n            None => dic.insert(num, i as i32),\n        };\n    }\n    None\n}\n
    two_sum.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u54c8\u5e0c\u8868\u67e5\u8be2 */\nHashTable *find(HashTable *h, int key) {\n    HashTable *tmp;\n    HASH_FIND_INT(h, &key, tmp);\n    return tmp;\n}\n\n/* \u54c8\u5e0c\u8868\u5143\u7d20\u63d2\u5165 */\nvoid insert(HashTable *h, int key, int val) {\n    HashTable *t = find(h, key);\n    if (t == NULL) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = key, tmp->val = val;\n        HASH_ADD_INT(h, key, tmp);\n    } else {\n        t->val = val;\n    }\n}\n\n/* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint *twoSumHashTable(int *nums, int numsSize, int target, int *returnSize) {\n    HashTable *hashtable = NULL;\n    for (int i = 0; i < numsSize; i++) {\n        HashTable *t = find(hashtable, target - nums[i]);\n        if (t != NULL) {\n            int *res = malloc(sizeof(int) * 2);\n            res[0] = t->val, res[1] = i;\n            *returnSize = 2;\n            return res;\n        }\n        insert(hashtable, nums[i], i);\n    }\n    *returnSize = 0;\n    return NULL;\n}\n
    two_sum.kt
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfun twoSumHashTable(nums: IntArray, target: Int): IntArray {\n    val size = nums.size\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    val dic = HashMap<Int, Int>()\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (i in 0..<size) {\n        if (dic.containsKey(target - nums[i])) {\n            return intArrayOf(dic[target - nums[i]]!!, i)\n        }\n        dic[nums[i]] = i\n    }\n    return IntArray(0)\n}\n
    two_sum.rb
    ### \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 ###\ndef two_sum_hash_table(nums, target)\n  # \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  dic = {}\n  # \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  for i in 0...nums.length\n    return [dic[target - nums[i]], i] if dic.has_key?(target - nums[i])\n\n    dic[nums[i]] = i\n  end\n\n  []\nend\n
    two_sum.zig
    // \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868\nfn twoSumHashTable(nums: []i32, target: i32) !?[2]i32 {\n    var size: usize = nums.len;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    var dic = std.AutoHashMap(i32, i32).init(std.heap.page_allocator);\n    defer dic.deinit();\n    var i: usize = 0;\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    while (i < size) : (i += 1) {\n        if (dic.contains(target - nums[i])) {\n            return [_]i32{dic.get(target - nums[i]).?, @intCast(i)};\n        }\n        try dic.put(nums[i], @intCast(i));\n    }\n    return null;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6b64\u65b9\u6cd5\u901a\u8fc7\u54c8\u5e0c\u67e5\u627e\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n^2)\\) \u964d\u81f3 \\(O(n)\\) \uff0c\u5927\u5e45\u63d0\u5347\u8fd0\u884c\u6548\u7387\u3002

    \u7531\u4e8e\u9700\u8981\u7ef4\u62a4\u4e00\u4e2a\u989d\u5916\u7684\u54c8\u5e0c\u8868\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002\u5c3d\u7ba1\u5982\u6b64\uff0c\u8be5\u65b9\u6cd5\u7684\u6574\u4f53\u65f6\u7a7a\u6548\u7387\u66f4\u4e3a\u5747\u8861\uff0c\u56e0\u6b64\u5b83\u662f\u672c\u9898\u7684\u6700\u4f18\u89e3\u6cd5\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/","title":"10.5 \u00a0 \u91cd\u8bc6\u641c\u7d22\u7b97\u6cd5","text":"

    \u641c\u7d22\u7b97\u6cd5\uff08searching algorithm\uff09\u7528\u4e8e\u5728\u6570\u636e\u7ed3\u6784\uff08\u4f8b\u5982\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6811\u6216\u56fe\uff09\u4e2d\u641c\u7d22\u4e00\u4e2a\u6216\u4e00\u7ec4\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u7684\u5143\u7d20\u3002

    \u641c\u7d22\u7b97\u6cd5\u53ef\u6839\u636e\u5b9e\u73b0\u601d\u8def\u5206\u4e3a\u4ee5\u4e0b\u4e24\u7c7b\u3002

    • \u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u6765\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\uff0c\u4f8b\u5982\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6811\u548c\u56fe\u7684\u904d\u5386\u7b49\u3002
    • \u5229\u7528\u6570\u636e\u7ec4\u7ec7\u7ed3\u6784\u6216\u6570\u636e\u5305\u542b\u7684\u5148\u9a8c\u4fe1\u606f\uff0c\u5b9e\u73b0\u9ad8\u6548\u5143\u7d20\u67e5\u627e\uff0c\u4f8b\u5982\u4e8c\u5206\u67e5\u627e\u3001\u54c8\u5e0c\u67e5\u627e\u548c\u4e8c\u53c9\u641c\u7d22\u6811\u67e5\u627e\u7b49\u3002

    \u4e0d\u96be\u53d1\u73b0\uff0c\u8fd9\u4e9b\u77e5\u8bc6\u70b9\u90fd\u5df2\u5728\u524d\u9762\u7684\u7ae0\u8282\u4e2d\u4ecb\u7ecd\u8fc7\uff0c\u56e0\u6b64\u641c\u7d22\u7b97\u6cd5\u5bf9\u4e8e\u6211\u4eec\u6765\u8bf4\u5e76\u4e0d\u964c\u751f\u3002\u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5c06\u4ece\u66f4\u52a0\u7cfb\u7edf\u7684\u89c6\u89d2\u5207\u5165\uff0c\u91cd\u65b0\u5ba1\u89c6\u641c\u7d22\u7b97\u6cd5\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1051","title":"10.5.1 \u00a0 \u66b4\u529b\u641c\u7d22","text":"

    \u66b4\u529b\u641c\u7d22\u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u7684\u6bcf\u4e2a\u5143\u7d20\u6765\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002

    • \u201c\u7ebf\u6027\u641c\u7d22\u201d\u9002\u7528\u4e8e\u6570\u7ec4\u548c\u94fe\u8868\u7b49\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002\u5b83\u4ece\u6570\u636e\u7ed3\u6784\u7684\u4e00\u7aef\u5f00\u59cb\uff0c\u9010\u4e2a\u8bbf\u95ee\u5143\u7d20\uff0c\u76f4\u5230\u627e\u5230\u76ee\u6807\u5143\u7d20\u6216\u5230\u8fbe\u53e6\u4e00\u7aef\u4ecd\u6ca1\u6709\u627e\u5230\u76ee\u6807\u5143\u7d20\u4e3a\u6b62\u3002
    • \u201c\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u201d\u548c\u201c\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u201d\u662f\u56fe\u548c\u6811\u7684\u4e24\u79cd\u904d\u5386\u7b56\u7565\u3002\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u4ece\u521d\u59cb\u8282\u70b9\u5f00\u59cb\u9010\u5c42\u641c\u7d22\uff0c\u7531\u8fd1\u53ca\u8fdc\u5730\u8bbf\u95ee\u5404\u4e2a\u8282\u70b9\u3002\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u4ece\u521d\u59cb\u8282\u70b9\u5f00\u59cb\uff0c\u6cbf\u7740\u4e00\u6761\u8def\u5f84\u8d70\u5230\u5934\uff0c\u518d\u56de\u6eaf\u5e76\u5c1d\u8bd5\u5176\u4ed6\u8def\u5f84\uff0c\u76f4\u5230\u904d\u5386\u5b8c\u6574\u4e2a\u6570\u636e\u7ed3\u6784\u3002

    \u66b4\u529b\u641c\u7d22\u7684\u4f18\u70b9\u662f\u7b80\u5355\u4e14\u901a\u7528\u6027\u597d\uff0c\u65e0\u987b\u5bf9\u6570\u636e\u505a\u9884\u5904\u7406\u548c\u501f\u52a9\u989d\u5916\u7684\u6570\u636e\u7ed3\u6784\u3002

    \u7136\u800c\uff0c\u6b64\u7c7b\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u5143\u7d20\u6570\u91cf\uff0c\u56e0\u6b64\u5728\u6570\u636e\u91cf\u8f83\u5927\u7684\u60c5\u51b5\u4e0b\u6027\u80fd\u8f83\u5dee\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1052","title":"10.5.2 \u00a0 \u81ea\u9002\u5e94\u641c\u7d22","text":"

    \u81ea\u9002\u5e94\u641c\u7d22\u5229\u7528\u6570\u636e\u7684\u7279\u6709\u5c5e\u6027\uff08\u4f8b\u5982\u6709\u5e8f\u6027\uff09\u6765\u4f18\u5316\u641c\u7d22\u8fc7\u7a0b\uff0c\u4ece\u800c\u66f4\u9ad8\u6548\u5730\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002

    • \u201c\u4e8c\u5206\u67e5\u627e\u201d\u5229\u7528\u6570\u636e\u7684\u6709\u5e8f\u6027\u5b9e\u73b0\u9ad8\u6548\u67e5\u627e\uff0c\u4ec5\u9002\u7528\u4e8e\u6570\u7ec4\u3002
    • \u201c\u54c8\u5e0c\u67e5\u627e\u201d\u5229\u7528\u54c8\u5e0c\u8868\u5c06\u641c\u7d22\u6570\u636e\u548c\u76ee\u6807\u6570\u636e\u5efa\u7acb\u4e3a\u952e\u503c\u5bf9\u6620\u5c04\uff0c\u4ece\u800c\u5b9e\u73b0\u67e5\u8be2\u64cd\u4f5c\u3002
    • \u201c\u6811\u67e5\u627e\u201d\u5728\u7279\u5b9a\u7684\u6811\u7ed3\u6784\uff08\u4f8b\u5982\u4e8c\u53c9\u641c\u7d22\u6811\uff09\u4e2d\uff0c\u57fa\u4e8e\u6bd4\u8f83\u8282\u70b9\u503c\u6765\u5feb\u901f\u6392\u9664\u8282\u70b9\uff0c\u4ece\u800c\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002

    \u6b64\u7c7b\u7b97\u6cd5\u7684\u4f18\u70b9\u662f\u6548\u7387\u9ad8\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe\u5230 \\(O(\\log n)\\) \u751a\u81f3 \\(O(1)\\) \u3002

    \u7136\u800c\uff0c\u4f7f\u7528\u8fd9\u4e9b\u7b97\u6cd5\u5f80\u5f80\u9700\u8981\u5bf9\u6570\u636e\u8fdb\u884c\u9884\u5904\u7406\u3002\u4f8b\u5982\uff0c\u4e8c\u5206\u67e5\u627e\u9700\u8981\u9884\u5148\u5bf9\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\uff0c\u54c8\u5e0c\u67e5\u627e\u548c\u6811\u67e5\u627e\u90fd\u9700\u8981\u501f\u52a9\u989d\u5916\u7684\u6570\u636e\u7ed3\u6784\uff0c\u7ef4\u62a4\u8fd9\u4e9b\u6570\u636e\u7ed3\u6784\u4e5f\u9700\u8981\u989d\u5916\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u5f00\u9500\u3002

    Tip

    \u81ea\u9002\u5e94\u641c\u7d22\u7b97\u6cd5\u5e38\u88ab\u79f0\u4e3a\u67e5\u627e\u7b97\u6cd5\uff0c\u4e3b\u8981\u7528\u4e8e\u5728\u7279\u5b9a\u6570\u636e\u7ed3\u6784\u4e2d\u5feb\u901f\u68c0\u7d22\u76ee\u6807\u5143\u7d20\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1053","title":"10.5.3 \u00a0 \u641c\u7d22\u65b9\u6cd5\u9009\u53d6","text":"

    \u7ed9\u5b9a\u5927\u5c0f\u4e3a \\(n\\) \u7684\u4e00\u7ec4\u6570\u636e\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7ebf\u6027\u641c\u7d22\u3001\u4e8c\u5206\u67e5\u627e\u3001\u6811\u67e5\u627e\u3001\u54c8\u5e0c\u67e5\u627e\u7b49\u591a\u79cd\u65b9\u6cd5\u4ece\u4e2d\u641c\u7d22\u76ee\u6807\u5143\u7d20\u3002\u5404\u4e2a\u65b9\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u5982\u56fe 10-11 \u6240\u793a\u3002

    \u56fe 10-11 \u00a0 \u591a\u79cd\u641c\u7d22\u7b56\u7565

    \u4e0a\u8ff0\u51e0\u79cd\u65b9\u6cd5\u7684\u64cd\u4f5c\u6548\u7387\u4e0e\u7279\u6027\u5982\u8868 10-1 \u6240\u793a\u3002

    \u8868 10-1 \u00a0 \u67e5\u627e\u7b97\u6cd5\u6548\u7387\u5bf9\u6bd4

    \u7ebf\u6027\u641c\u7d22 \u4e8c\u5206\u67e5\u627e \u6811\u67e5\u627e \u54c8\u5e0c\u67e5\u627e \u67e5\u627e\u5143\u7d20 \\(O(n)\\) \\(O(\\log n)\\) \\(O(\\log n)\\) \\(O(1)\\) \u63d2\u5165\u5143\u7d20 \\(O(1)\\) \\(O(n)\\) \\(O(\\log n)\\) \\(O(1)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(n)\\) \\(O(\\log n)\\) \\(O(1)\\) \u989d\u5916\u7a7a\u95f4 \\(O(1)\\) \\(O(1)\\) \\(O(n)\\) \\(O(n)\\) \u6570\u636e\u9884\u5904\u7406 / \u6392\u5e8f \\(O(n \\log n)\\) \u5efa\u6811 \\(O(n \\log n)\\) \u5efa\u54c8\u5e0c\u8868 \\(O(n)\\) \u6570\u636e\u662f\u5426\u6709\u5e8f \u65e0\u5e8f \u6709\u5e8f \u6709\u5e8f \u65e0\u5e8f

    \u641c\u7d22\u7b97\u6cd5\u7684\u9009\u62e9\u8fd8\u53d6\u51b3\u4e8e\u6570\u636e\u4f53\u91cf\u3001\u641c\u7d22\u6027\u80fd\u8981\u6c42\u3001\u6570\u636e\u67e5\u8be2\u4e0e\u66f4\u65b0\u9891\u7387\u7b49\u3002

    \u7ebf\u6027\u641c\u7d22

    • \u901a\u7528\u6027\u8f83\u597d\uff0c\u65e0\u987b\u4efb\u4f55\u6570\u636e\u9884\u5904\u7406\u64cd\u4f5c\u3002\u5047\u5982\u6211\u4eec\u4ec5\u9700\u67e5\u8be2\u4e00\u6b21\u6570\u636e\uff0c\u90a3\u4e48\u5176\u4ed6\u4e09\u79cd\u65b9\u6cd5\u7684\u6570\u636e\u9884\u5904\u7406\u7684\u65f6\u95f4\u6bd4\u7ebf\u6027\u641c\u7d22\u7684\u65f6\u95f4\u8fd8\u8981\u66f4\u957f\u3002
    • \u9002\u7528\u4e8e\u4f53\u91cf\u8f83\u5c0f\u7684\u6570\u636e\uff0c\u6b64\u60c5\u51b5\u4e0b\u65f6\u95f4\u590d\u6742\u5ea6\u5bf9\u6548\u7387\u5f71\u54cd\u8f83\u5c0f\u3002
    • \u9002\u7528\u4e8e\u6570\u636e\u66f4\u65b0\u9891\u7387\u8f83\u9ad8\u7684\u573a\u666f\uff0c\u56e0\u4e3a\u8be5\u65b9\u6cd5\u4e0d\u9700\u8981\u5bf9\u6570\u636e\u8fdb\u884c\u4efb\u4f55\u989d\u5916\u7ef4\u62a4\u3002

    \u4e8c\u5206\u67e5\u627e

    • \u9002\u7528\u4e8e\u5927\u6570\u636e\u91cf\u7684\u60c5\u51b5\uff0c\u6548\u7387\u8868\u73b0\u7a33\u5b9a\uff0c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u3002
    • \u6570\u636e\u91cf\u4e0d\u80fd\u8fc7\u5927\uff0c\u56e0\u4e3a\u5b58\u50a8\u6570\u7ec4\u9700\u8981\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    • \u4e0d\u9002\u7528\u4e8e\u9ad8\u9891\u589e\u5220\u6570\u636e\u7684\u573a\u666f\uff0c\u56e0\u4e3a\u7ef4\u62a4\u6709\u5e8f\u6570\u7ec4\u7684\u5f00\u9500\u8f83\u5927\u3002

    \u54c8\u5e0c\u67e5\u627e

    • \u9002\u5408\u5bf9\u67e5\u8be2\u6027\u80fd\u8981\u6c42\u5f88\u9ad8\u7684\u573a\u666f\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002
    • \u4e0d\u9002\u5408\u9700\u8981\u6709\u5e8f\u6570\u636e\u6216\u8303\u56f4\u67e5\u627e\u7684\u573a\u666f\uff0c\u56e0\u4e3a\u54c8\u5e0c\u8868\u65e0\u6cd5\u7ef4\u62a4\u6570\u636e\u7684\u6709\u5e8f\u6027\u3002
    • \u5bf9\u54c8\u5e0c\u51fd\u6570\u548c\u54c8\u5e0c\u51b2\u7a81\u5904\u7406\u7b56\u7565\u7684\u4f9d\u8d56\u6027\u8f83\u9ad8\uff0c\u5177\u6709\u8f83\u5927\u7684\u6027\u80fd\u52a3\u5316\u98ce\u9669\u3002
    • \u4e0d\u9002\u5408\u6570\u636e\u91cf\u8fc7\u5927\u7684\u60c5\u51b5\uff0c\u56e0\u4e3a\u54c8\u5e0c\u8868\u9700\u8981\u989d\u5916\u7a7a\u95f4\u6765\u6700\u5927\u7a0b\u5ea6\u5730\u51cf\u5c11\u51b2\u7a81\uff0c\u4ece\u800c\u63d0\u4f9b\u826f\u597d\u7684\u67e5\u8be2\u6027\u80fd\u3002

    \u6811\u67e5\u627e

    • \u9002\u7528\u4e8e\u6d77\u91cf\u6570\u636e\uff0c\u56e0\u4e3a\u6811\u8282\u70b9\u5728\u5185\u5b58\u4e2d\u662f\u5206\u6563\u5b58\u50a8\u7684\u3002
    • \u9002\u5408\u9700\u8981\u7ef4\u62a4\u6709\u5e8f\u6570\u636e\u6216\u8303\u56f4\u67e5\u627e\u7684\u573a\u666f\u3002
    • \u5728\u6301\u7eed\u589e\u5220\u8282\u70b9\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u53ef\u80fd\u4ea7\u751f\u503e\u659c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u52a3\u5316\u81f3 \\(O(n)\\) \u3002
    • \u82e5\u4f7f\u7528 AVL \u6811\u6216\u7ea2\u9ed1\u6811\uff0c\u5219\u5404\u9879\u64cd\u4f5c\u53ef\u5728 \\(O(\\log n)\\) \u6548\u7387\u4e0b\u7a33\u5b9a\u8fd0\u884c\uff0c\u4f46\u7ef4\u62a4\u6811\u5e73\u8861\u7684\u64cd\u4f5c\u4f1a\u589e\u52a0\u989d\u5916\u7684\u5f00\u9500\u3002
    "},{"location":"chapter_searching/summary/","title":"10.6 \u00a0 \u5c0f\u7ed3","text":"
    • \u4e8c\u5206\u67e5\u627e\u4f9d\u8d56\u6570\u636e\u7684\u6709\u5e8f\u6027\uff0c\u901a\u8fc7\u5faa\u73af\u9010\u6b65\u7f29\u51cf\u4e00\u534a\u641c\u7d22\u533a\u95f4\u6765\u8fdb\u884c\u67e5\u627e\u3002\u5b83\u8981\u6c42\u8f93\u5165\u6570\u636e\u6709\u5e8f\uff0c\u4e14\u4ec5\u9002\u7528\u4e8e\u6570\u7ec4\u6216\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002
    • \u66b4\u529b\u641c\u7d22\u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u6765\u5b9a\u4f4d\u6570\u636e\u3002\u7ebf\u6027\u641c\u7d22\u9002\u7528\u4e8e\u6570\u7ec4\u548c\u94fe\u8868\uff0c\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u548c\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u9002\u7528\u4e8e\u56fe\u548c\u6811\u3002\u6b64\u7c7b\u7b97\u6cd5\u901a\u7528\u6027\u597d\uff0c\u65e0\u987b\u5bf9\u6570\u636e\u8fdb\u884c\u9884\u5904\u7406\uff0c\u4f46\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u8f83\u9ad8\u3002
    • \u54c8\u5e0c\u67e5\u627e\u3001\u6811\u67e5\u627e\u548c\u4e8c\u5206\u67e5\u627e\u5c5e\u4e8e\u9ad8\u6548\u641c\u7d22\u65b9\u6cd5\uff0c\u53ef\u5728\u7279\u5b9a\u6570\u636e\u7ed3\u6784\u4e2d\u5feb\u901f\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002\u6b64\u7c7b\u7b97\u6cd5\u6548\u7387\u9ad8\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe \\(O(\\log n)\\) \u751a\u81f3 \\(O(1)\\) \uff0c\u4f46\u901a\u5e38\u9700\u8981\u501f\u52a9\u989d\u5916\u6570\u636e\u7ed3\u6784\u3002
    • \u5b9e\u9645\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u5bf9\u6570\u636e\u4f53\u91cf\u3001\u641c\u7d22\u6027\u80fd\u8981\u6c42\u3001\u6570\u636e\u67e5\u8be2\u548c\u66f4\u65b0\u9891\u7387\u7b49\u56e0\u7d20\u8fdb\u884c\u5177\u4f53\u5206\u6790\uff0c\u4ece\u800c\u9009\u62e9\u5408\u9002\u7684\u641c\u7d22\u65b9\u6cd5\u3002
    • \u7ebf\u6027\u641c\u7d22\u9002\u7528\u4e8e\u5c0f\u578b\u6216\u9891\u7e41\u66f4\u65b0\u7684\u6570\u636e\uff1b\u4e8c\u5206\u67e5\u627e\u9002\u7528\u4e8e\u5927\u578b\u3001\u6392\u5e8f\u7684\u6570\u636e\uff1b\u54c8\u5e0c\u67e5\u627e\u9002\u7528\u4e8e\u5bf9\u67e5\u8be2\u6548\u7387\u8981\u6c42\u8f83\u9ad8\u4e14\u65e0\u987b\u8303\u56f4\u67e5\u8be2\u7684\u6570\u636e\uff1b\u6811\u67e5\u627e\u9002\u7528\u4e8e\u9700\u8981\u7ef4\u62a4\u987a\u5e8f\u548c\u652f\u6301\u8303\u56f4\u67e5\u8be2\u7684\u5927\u578b\u52a8\u6001\u6570\u636e\u3002
    • \u7528\u54c8\u5e0c\u67e5\u627e\u66ff\u6362\u7ebf\u6027\u67e5\u627e\u662f\u4e00\u79cd\u5e38\u7528\u7684\u4f18\u5316\u8fd0\u884c\u65f6\u95f4\u7684\u7b56\u7565\uff0c\u53ef\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n)\\) \u964d\u81f3 \\(O(1)\\) \u3002
    "},{"location":"chapter_sorting/","title":"\u7b2c 11 \u7ae0 \u00a0 \u6392\u5e8f","text":"

    Abstract

    \u6392\u5e8f\u72b9\u5982\u4e00\u628a\u5c06\u6df7\u4e71\u53d8\u4e3a\u79e9\u5e8f\u7684\u9b54\u6cd5\u94a5\u5319\uff0c\u4f7f\u6211\u4eec\u80fd\u4ee5\u66f4\u9ad8\u6548\u7684\u65b9\u5f0f\u7406\u89e3\u4e0e\u5904\u7406\u6570\u636e\u3002

    \u65e0\u8bba\u662f\u7b80\u5355\u7684\u5347\u5e8f\uff0c\u8fd8\u662f\u590d\u6742\u7684\u5206\u7c7b\u6392\u5217\uff0c\u6392\u5e8f\u90fd\u5411\u6211\u4eec\u5c55\u793a\u4e86\u6570\u636e\u7684\u548c\u8c10\u7f8e\u611f\u3002

    "},{"location":"chapter_sorting/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 11.1 \u00a0 \u6392\u5e8f\u7b97\u6cd5
    • 11.2 \u00a0 \u9009\u62e9\u6392\u5e8f
    • 11.3 \u00a0 \u5192\u6ce1\u6392\u5e8f
    • 11.4 \u00a0 \u63d2\u5165\u6392\u5e8f
    • 11.5 \u00a0 \u5feb\u901f\u6392\u5e8f
    • 11.6 \u00a0 \u5f52\u5e76\u6392\u5e8f
    • 11.7 \u00a0 \u5806\u6392\u5e8f
    • 11.8 \u00a0 \u6876\u6392\u5e8f
    • 11.9 \u00a0 \u8ba1\u6570\u6392\u5e8f
    • 11.10 \u00a0 \u57fa\u6570\u6392\u5e8f
    • 11.11 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_sorting/bubble_sort/","title":"11.3 \u00a0 \u5192\u6ce1\u6392\u5e8f","text":"

    \u5192\u6ce1\u6392\u5e8f\uff08bubble sort\uff09\u901a\u8fc7\u8fde\u7eed\u5730\u6bd4\u8f83\u4e0e\u4ea4\u6362\u76f8\u90bb\u5143\u7d20\u5b9e\u73b0\u6392\u5e8f\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5c31\u50cf\u6c14\u6ce1\u4ece\u5e95\u90e8\u5347\u5230\u9876\u90e8\u4e00\u6837\uff0c\u56e0\u6b64\u5f97\u540d\u5192\u6ce1\u6392\u5e8f\u3002

    \u5982\u56fe 11-4 \u6240\u793a\uff0c\u5192\u6ce1\u8fc7\u7a0b\u53ef\u4ee5\u5229\u7528\u5143\u7d20\u4ea4\u6362\u64cd\u4f5c\u6765\u6a21\u62df\uff1a\u4ece\u6570\u7ec4\u6700\u5de6\u7aef\u5f00\u59cb\u5411\u53f3\u904d\u5386\uff0c\u4f9d\u6b21\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u5927\u5c0f\uff0c\u5982\u679c\u201c\u5de6\u5143\u7d20 > \u53f3\u5143\u7d20\u201d\u5c31\u4ea4\u6362\u4e8c\u8005\u3002\u904d\u5386\u5b8c\u6210\u540e\uff0c\u6700\u5927\u7684\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u6570\u7ec4\u7684\u6700\u53f3\u7aef\u3002

    <1><2><3><4><5><6><7>

    \u56fe 11-4 \u00a0 \u5229\u7528\u5143\u7d20\u4ea4\u6362\u64cd\u4f5c\u6a21\u62df\u5192\u6ce1

    "},{"location":"chapter_sorting/bubble_sort/#1131","title":"11.3.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u8bbe\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6b65\u9aa4\u5982\u56fe 11-5 \u6240\u793a\u3002

    1. \u9996\u5148\uff0c\u5bf9 \\(n\\) \u4e2a\u5143\u7d20\u6267\u884c\u201c\u5192\u6ce1\u201d\uff0c\u5c06\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u6b63\u786e\u4f4d\u7f6e\u3002
    2. \u63a5\u4e0b\u6765\uff0c\u5bf9\u5269\u4f59 \\(n - 1\\) \u4e2a\u5143\u7d20\u6267\u884c\u201c\u5192\u6ce1\u201d\uff0c\u5c06\u7b2c\u4e8c\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u6b63\u786e\u4f4d\u7f6e\u3002
    3. \u4ee5\u6b64\u7c7b\u63a8\uff0c\u7ecf\u8fc7 \\(n - 1\\) \u8f6e\u201c\u5192\u6ce1\u201d\u540e\uff0c\u524d \\(n - 1\\) \u5927\u7684\u5143\u7d20\u90fd\u88ab\u4ea4\u6362\u81f3\u6b63\u786e\u4f4d\u7f6e\u3002
    4. \u4ec5\u5269\u7684\u4e00\u4e2a\u5143\u7d20\u5fc5\u5b9a\u662f\u6700\u5c0f\u5143\u7d20\uff0c\u65e0\u987b\u6392\u5e8f\uff0c\u56e0\u6b64\u6570\u7ec4\u6392\u5e8f\u5b8c\u6210\u3002

    \u56fe 11-5 \u00a0 \u5192\u6ce1\u6392\u5e8f\u6d41\u7a0b

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bubble_sort.py
    def bubble_sort(nums: list[int]):\n    \"\"\"\u5192\u6ce1\u6392\u5e8f\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(n - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j + 1] = nums[j + 1], nums[j]\n
    bubble_sort.cpp
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                // \u8fd9\u91cc\u4f7f\u7528\u4e86 std::swap() \u51fd\u6570\n                swap(nums[j], nums[j + 1]);\n            }\n        }\n    }\n}\n
    bubble_sort.java
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.cs
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid BubbleSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n            }\n        }\n    }\n}\n
    bubble_sort.go
    /* \u5192\u6ce1\u6392\u5e8f */\nfunc bubbleSort(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j+1] = nums[j+1], nums[j]\n            }\n        }\n    }\n}\n
    bubble_sort.swift
    /* \u5192\u6ce1\u6392\u5e8f */\nfunc bubbleSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums.swapAt(j, j + 1)\n            }\n        }\n    }\n}\n
    bubble_sort.js
    /* \u5192\u6ce1\u6392\u5e8f */\nfunction bubbleSort(nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.ts
    /* \u5192\u6ce1\u6392\u5e8f */\nfunction bubbleSort(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.dart
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (int i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (int j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n      }\n    }\n  }\n}\n
    bubble_sort.rs
    /* \u5192\u6ce1\u6392\u5e8f */\nfn bubble_sort(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.c
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = size - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                int temp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = temp;\n            }\n        }\n    }\n}\n
    bubble_sort.kt
    /* \u5192\u6ce1\u6392\u5e8f */\nfun bubbleSort(nums: IntArray) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n            }\n        }\n    }\n}\n
    bubble_sort.rb
    [class]{}-[func]{bubble_sort}\n
    bubble_sort.zig
    // \u5192\u6ce1\u6392\u5e8f\nfn bubbleSort(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: usize = nums.len - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/bubble_sort/#1132","title":"11.3.2 \u00a0 \u6548\u7387\u4f18\u5316","text":"

    \u6211\u4eec\u53d1\u73b0\uff0c\u5982\u679c\u67d0\u8f6e\u201c\u5192\u6ce1\u201d\u4e2d\u6ca1\u6709\u6267\u884c\u4efb\u4f55\u4ea4\u6362\u64cd\u4f5c\uff0c\u8bf4\u660e\u6570\u7ec4\u5df2\u7ecf\u5b8c\u6210\u6392\u5e8f\uff0c\u53ef\u76f4\u63a5\u8fd4\u56de\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u589e\u52a0\u4e00\u4e2a\u6807\u5fd7\u4f4d flag \u6765\u76d1\u6d4b\u8fd9\u79cd\u60c5\u51b5\uff0c\u4e00\u65e6\u51fa\u73b0\u5c31\u7acb\u5373\u8fd4\u56de\u3002

    \u7ecf\u8fc7\u4f18\u5316\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(n^2)\\) \uff1b\u4f46\u5f53\u8f93\u5165\u6570\u7ec4\u5b8c\u5168\u6709\u5e8f\u65f6\uff0c\u53ef\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bubble_sort.py
    def bubble_sort_with_flag(nums: list[int]):\n    \"\"\"\u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(n - 1, 0, -1):\n        flag = False  # \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j + 1] = nums[j + 1], nums[j]\n                flag = True  # \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n        if not flag:\n            break  # \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n
    bubble_sort.cpp
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                // \u8fd9\u91cc\u4f7f\u7528\u4e86 std::swap() \u51fd\u6570\n                swap(nums[j], nums[j + 1]);\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag)\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.java
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nvoid bubbleSortWithFlag(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        boolean flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag)\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.cs
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid BubbleSortWithFlag(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                flag = true;  // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break;     // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.go
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunc bubbleSortWithFlag(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        flag := false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j+1] = nums[j+1], nums[j]\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if flag == false { // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n            break\n        }\n    }\n}\n
    bubble_sort.swift
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunc bubbleSortWithFlag(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        var flag = false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums.swapAt(j, j + 1)\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if !flag { // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n            break\n        }\n    }\n}\n
    bubble_sort.js
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunction bubbleSortWithFlag(nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        let flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.ts
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunction bubbleSortWithFlag(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        let flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.dart
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (int i = nums.length - 1; i > 0; i--) {\n    bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (int j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n      }\n    }\n    if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n  }\n}\n
    bubble_sort.rs
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nfn bubble_sort_with_flag(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        let mut flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if !flag {\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n        };\n    }\n}\n
    bubble_sort.c
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = size - 1; i > 0; i--) {\n        bool flag = false;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                int temp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = temp;\n                flag = true;\n            }\n        }\n        if (!flag)\n            break;\n    }\n}\n
    bubble_sort.kt
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nfun bubbleSortWithFlag(nums: IntArray) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        var flag = false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.rb
    [class]{}-[func]{bubble_sort_with_flag}\n
    bubble_sort.zig
    // \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09\nfn bubbleSortWithFlag(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: usize = nums.len - 1;\n    while (i > 0) : (i -= 1) {\n        var flag = false;   // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true;\n            }\n        }\n        if (!flag) break;   // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/bubble_sort/#1133","title":"11.3.3 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\u3001\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5404\u8f6e\u201c\u5192\u6ce1\u201d\u904d\u5386\u7684\u6570\u7ec4\u957f\u5ea6\u4f9d\u6b21\u4e3a \\(n - 1\\)\u3001\\(n - 2\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \uff0c\u603b\u548c\u4e3a \\((n - 1) n / 2\\) \u3002\u5728\u5f15\u5165 flag \u4f18\u5316\u540e\uff0c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe\u5230 \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u7531\u4e8e\u5728\u201c\u5192\u6ce1\u201d\u4e2d\u9047\u5230\u76f8\u7b49\u5143\u7d20\u4e0d\u4ea4\u6362\u3002
    "},{"location":"chapter_sorting/bucket_sort/","title":"11.8 \u00a0 \u6876\u6392\u5e8f","text":"

    \u524d\u8ff0\u51e0\u79cd\u6392\u5e8f\u7b97\u6cd5\u90fd\u5c5e\u4e8e\u201c\u57fa\u4e8e\u6bd4\u8f83\u7684\u6392\u5e8f\u7b97\u6cd5\u201d\uff0c\u5b83\u4eec\u901a\u8fc7\u6bd4\u8f83\u5143\u7d20\u95f4\u7684\u5927\u5c0f\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u6b64\u7c7b\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u65e0\u6cd5\u8d85\u8d8a \\(O(n \\log n)\\) \u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u63a2\u8ba8\u51e0\u79cd\u201c\u975e\u6bd4\u8f83\u6392\u5e8f\u7b97\u6cd5\u201d\uff0c\u5b83\u4eec\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u7ebf\u6027\u9636\u3002

    \u6876\u6392\u5e8f\uff08bucket sort\uff09\u662f\u5206\u6cbb\u7b56\u7565\u7684\u4e00\u4e2a\u5178\u578b\u5e94\u7528\u3002\u5b83\u901a\u8fc7\u8bbe\u7f6e\u4e00\u4e9b\u5177\u6709\u5927\u5c0f\u987a\u5e8f\u7684\u6876\uff0c\u6bcf\u4e2a\u6876\u5bf9\u5e94\u4e00\u4e2a\u6570\u636e\u8303\u56f4\uff0c\u5c06\u6570\u636e\u5e73\u5747\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\uff1b\u7136\u540e\uff0c\u5728\u6bcf\u4e2a\u6876\u5185\u90e8\u5206\u522b\u6267\u884c\u6392\u5e8f\uff1b\u6700\u7ec8\u6309\u7167\u6876\u7684\u987a\u5e8f\u5c06\u6240\u6709\u6570\u636e\u5408\u5e76\u3002

    "},{"location":"chapter_sorting/bucket_sort/#1181","title":"11.8.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u8003\u8651\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\uff0c\u5176\u5143\u7d20\u662f\u8303\u56f4 \\([0, 1)\\) \u5185\u7684\u6d6e\u70b9\u6570\u3002\u6876\u6392\u5e8f\u7684\u6d41\u7a0b\u5982\u56fe 11-13 \u6240\u793a\u3002

    1. \u521d\u59cb\u5316 \\(k\\) \u4e2a\u6876\uff0c\u5c06 \\(n\\) \u4e2a\u5143\u7d20\u5206\u914d\u5230 \\(k\\) \u4e2a\u6876\u4e2d\u3002
    2. \u5bf9\u6bcf\u4e2a\u6876\u5206\u522b\u6267\u884c\u6392\u5e8f\uff08\u8fd9\u91cc\u91c7\u7528\u7f16\u7a0b\u8bed\u8a00\u7684\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff09\u3002
    3. \u6309\u7167\u6876\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u5408\u5e76\u7ed3\u679c\u3002

    \u56fe 11-13 \u00a0 \u6876\u6392\u5e8f\u7b97\u6cd5\u6d41\u7a0b

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bucket_sort.py
    def bucket_sort(nums: list[float]):\n    \"\"\"\u6876\u6392\u5e8f\"\"\"\n    # \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    k = len(nums) // 2\n    buckets = [[] for _ in range(k)]\n    # 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for num in nums:\n        # \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        i = int(num * k)\n        # \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].append(num)\n    # 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for bucket in buckets:\n        # \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort()\n    # 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    i = 0\n    for bucket in buckets:\n        for num in bucket:\n            nums[i] = num\n            i += 1\n
    bucket_sort.cpp
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(vector<float> &nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.size() / 2;\n    vector<vector<float>> buckets(k);\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (float num : nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = num * k;\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 bucket_idx\n        buckets[i].push_back(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (vector<float> &bucket : buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        sort(bucket.begin(), bucket.end());\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int i = 0;\n    for (vector<float> &bucket : buckets) {\n        for (float num : bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.java
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(float[] nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.length / 2;\n    List<List<Float>> buckets = new ArrayList<>();\n    for (int i = 0; i < k; i++) {\n        buckets.add(new ArrayList<>());\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (float num : nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = (int) (num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets.get(i).add(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (List<Float> bucket : buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        Collections.sort(bucket);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int i = 0;\n    for (List<Float> bucket : buckets) {\n        for (float num : bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.cs
    /* \u6876\u6392\u5e8f */\nvoid BucketSort(float[] nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.Length / 2;\n    List<List<float>> buckets = [];\n    for (int i = 0; i < k; i++) {\n        buckets.Add([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    foreach (float num in nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = (int)(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].Add(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    foreach (List<float> bucket in buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.Sort();\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int j = 0;\n    foreach (List<float> bucket in buckets) {\n        foreach (float num in bucket) {\n            nums[j++] = num;\n        }\n    }\n}\n
    bucket_sort.go
    /* \u6876\u6392\u5e8f */\nfunc bucketSort(nums []float64) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    k := len(nums) / 2\n    buckets := make([][]float64, k)\n    for i := 0; i < k; i++ {\n        buckets[i] = make([]float64, 0)\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for _, num := range nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        i := int(num * float64(k))\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i] = append(buckets[i], num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for i := 0; i < k; i++ {\n        // \u4f7f\u7528\u5185\u7f6e\u5207\u7247\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        sort.Float64s(buckets[i])\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    i := 0\n    for _, bucket := range buckets {\n        for _, num := range bucket {\n            nums[i] = num\n            i++\n        }\n    }\n}\n
    bucket_sort.swift
    /* \u6876\u6392\u5e8f */\nfunc bucketSort(nums: inout [Double]) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    let k = nums.count / 2\n    var buckets = (0 ..< k).map { _ in [Double]() }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for num in nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        let i = Int(num * Double(k))\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].append(num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for i in buckets.indices {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        buckets[i].sort()\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    var i = nums.startIndex\n    for bucket in buckets {\n        for num in bucket {\n            nums[i] = num\n            i += 1\n        }\n    }\n}\n
    bucket_sort.js
    /* \u6876\u6392\u5e8f */\nfunction bucketSort(nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    const k = nums.length / 2;\n    const buckets = [];\n    for (let i = 0; i < k; i++) {\n        buckets.push([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (const num of nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        const i = Math.floor(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (const bucket of buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort((a, b) => a - b);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let i = 0;\n    for (const bucket of buckets) {\n        for (const num of bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.ts
    /* \u6876\u6392\u5e8f */\nfunction bucketSort(nums: number[]): void {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    const k = nums.length / 2;\n    const buckets: number[][] = [];\n    for (let i = 0; i < k; i++) {\n        buckets.push([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (const num of nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        const i = Math.floor(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (const bucket of buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort((a, b) => a - b);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let i = 0;\n    for (const bucket of buckets) {\n        for (const num of bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.dart
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(List<double> nums) {\n  // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n  int k = nums.length ~/ 2;\n  List<List<double>> buckets = List.generate(k, (index) => []);\n\n  // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n  for (double _num in nums) {\n    // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 _num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n    int i = (_num * k).toInt();\n    // \u5c06 _num \u6dfb\u52a0\u8fdb\u6876 bucket_idx\n    buckets[i].add(_num);\n  }\n  // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n  for (List<double> bucket in buckets) {\n    bucket.sort();\n  }\n  // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n  int i = 0;\n  for (List<double> bucket in buckets) {\n    for (double _num in bucket) {\n      nums[i++] = _num;\n    }\n  }\n}\n
    bucket_sort.rs
    /* \u6876\u6392\u5e8f */\nfn bucket_sort(nums: &mut [f64]) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    let k = nums.len() / 2;\n    let mut buckets = vec![vec![]; k];\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for &mut num in &mut *nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        let i = (num * k as f64) as usize;\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for bucket in &mut buckets {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort_by(|a, b| a.partial_cmp(b).unwrap());\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let mut i = 0;\n    for bucket in &mut buckets {\n        for &mut num in bucket {\n            nums[i] = num;\n            i += 1;\n        }\n    }\n}\n
    bucket_sort.c
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(float nums[], int n) {\n    int k = n / 2;                                 // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\n    int *sizes = malloc(k * sizeof(int));          // \u8bb0\u5f55\u6bcf\u4e2a\u6876\u7684\u5927\u5c0f\n    float **buckets = malloc(k * sizeof(float *)); // \u52a8\u6001\u6570\u7ec4\u7684\u6570\u7ec4\uff08\u6876\uff09\n    // \u4e3a\u6bcf\u4e2a\u6876\u9884\u5206\u914d\u8db3\u591f\u7684\u7a7a\u95f4\n    for (int i = 0; i < k; ++i) {\n        buckets[i] = (float *)malloc(n * sizeof(float));\n        sizes[i] = 0;\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (int i = 0; i < n; ++i) {\n        int idx = (int)(nums[i] * k);\n        buckets[idx][sizes[idx]++] = nums[i];\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (int i = 0; i < k; ++i) {\n        qsort(buckets[i], sizes[i], sizeof(float), compare);\n    }\n    // 3. \u5408\u5e76\u6392\u5e8f\u540e\u7684\u6876\n    int idx = 0;\n    for (int i = 0; i < k; ++i) {\n        for (int j = 0; j < sizes[i]; ++j) {\n            nums[idx++] = buckets[i][j];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(buckets[i]);\n    }\n}\n
    bucket_sort.kt
    /* \u6876\u6392\u5e8f */\nfun bucketSort(nums: FloatArray) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    val k = nums.size / 2\n    val buckets = mutableListOf<MutableList<Float>>()\n    for (i in 0..<k) {\n        buckets.add(mutableListOf())\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (num in nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        val i = (num * k).toInt()\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].add(num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (bucket in buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort()\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    var i = 0\n    for (bucket in buckets) {\n        for (num in bucket) {\n            nums[i++] = num\n        }\n    }\n}\n
    bucket_sort.rb
    [class]{}-[func]{bucket_sort}\n
    bucket_sort.zig
    [class]{}-[func]{bucketSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/bucket_sort/#1182","title":"11.8.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"

    \u6876\u6392\u5e8f\u9002\u7528\u4e8e\u5904\u7406\u4f53\u91cf\u5f88\u5927\u7684\u6570\u636e\u3002\u4f8b\u5982\uff0c\u8f93\u5165\u6570\u636e\u5305\u542b 100 \u4e07\u4e2a\u5143\u7d20\uff0c\u7531\u4e8e\u7a7a\u95f4\u9650\u5236\uff0c\u7cfb\u7edf\u5185\u5b58\u65e0\u6cd5\u4e00\u6b21\u6027\u52a0\u8f7d\u6240\u6709\u6570\u636e\u3002\u6b64\u65f6\uff0c\u53ef\u4ee5\u5c06\u6570\u636e\u5206\u6210 1000 \u4e2a\u6876\uff0c\u7136\u540e\u5206\u522b\u5bf9\u6bcf\u4e2a\u6876\u8fdb\u884c\u6392\u5e8f\uff0c\u6700\u540e\u5c06\u7ed3\u679c\u5408\u5e76\u3002

    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + k)\\) \uff1a\u5047\u8bbe\u5143\u7d20\u5728\u5404\u4e2a\u6876\u5185\u5e73\u5747\u5206\u5e03\uff0c\u90a3\u4e48\u6bcf\u4e2a\u6876\u5185\u7684\u5143\u7d20\u6570\u91cf\u4e3a \\(\\frac{n}{k}\\) \u3002\u5047\u8bbe\u6392\u5e8f\u5355\u4e2a\u6876\u4f7f\u7528 \\(O(\\frac{n}{k} \\log\\frac{n}{k})\\) \u65f6\u95f4\uff0c\u5219\u6392\u5e8f\u6240\u6709\u6876\u4f7f\u7528 \\(O(n \\log\\frac{n}{k})\\) \u65f6\u95f4\u3002\u5f53\u6876\u6570\u91cf \\(k\\) \u6bd4\u8f83\u5927\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5219\u8d8b\u5411\u4e8e \\(O(n)\\) \u3002\u5408\u5e76\u7ed3\u679c\u65f6\u9700\u8981\u904d\u5386\u6240\u6709\u6876\u548c\u5143\u7d20\uff0c\u82b1\u8d39 \\(O(n + k)\\) \u65f6\u95f4\u3002
    • \u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u6570\u636e\u88ab\u5206\u914d\u5230\u4e00\u4e2a\u6876\u4e2d\uff0c\u4e14\u6392\u5e8f\u8be5\u6876\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + k)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u9700\u8981\u501f\u52a9 \\(k\\) \u4e2a\u6876\u548c\u603b\u5171 \\(n\\) \u4e2a\u5143\u7d20\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u6876\u6392\u5e8f\u662f\u5426\u7a33\u5b9a\u53d6\u51b3\u4e8e\u6392\u5e8f\u6876\u5185\u5143\u7d20\u7684\u7b97\u6cd5\u662f\u5426\u7a33\u5b9a\u3002
    "},{"location":"chapter_sorting/bucket_sort/#1183","title":"11.8.3 \u00a0 \u5982\u4f55\u5b9e\u73b0\u5e73\u5747\u5206\u914d","text":"

    \u6876\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7406\u8bba\u4e0a\u53ef\u4ee5\u8fbe\u5230 \\(O(n)\\) \uff0c\u5173\u952e\u5728\u4e8e\u5c06\u5143\u7d20\u5747\u5300\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\uff0c\u56e0\u4e3a\u5b9e\u9645\u6570\u636e\u5f80\u5f80\u4e0d\u662f\u5747\u5300\u5206\u5e03\u7684\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u60f3\u8981\u5c06\u6dd8\u5b9d\u4e0a\u7684\u6240\u6709\u5546\u54c1\u6309\u4ef7\u683c\u8303\u56f4\u5e73\u5747\u5206\u914d\u5230 10 \u4e2a\u6876\u4e2d\uff0c\u4f46\u5546\u54c1\u4ef7\u683c\u5206\u5e03\u4e0d\u5747\uff0c\u4f4e\u4e8e 100 \u5143\u7684\u975e\u5e38\u591a\uff0c\u9ad8\u4e8e 1000 \u5143\u7684\u975e\u5e38\u5c11\u3002\u82e5\u5c06\u4ef7\u683c\u533a\u95f4\u5e73\u5747\u5212\u5206\u4e3a 10 \u4e2a\uff0c\u5404\u4e2a\u6876\u4e2d\u7684\u5546\u54c1\u6570\u91cf\u5dee\u8ddd\u4f1a\u975e\u5e38\u5927\u3002

    \u4e3a\u5b9e\u73b0\u5e73\u5747\u5206\u914d\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u8bbe\u5b9a\u4e00\u6761\u5927\u81f4\u7684\u5206\u754c\u7ebf\uff0c\u5c06\u6570\u636e\u7c97\u7565\u5730\u5206\u5230 3 \u4e2a\u6876\u4e2d\u3002\u5206\u914d\u5b8c\u6bd5\u540e\uff0c\u518d\u5c06\u5546\u54c1\u8f83\u591a\u7684\u6876\u7ee7\u7eed\u5212\u5206\u4e3a 3 \u4e2a\u6876\uff0c\u76f4\u81f3\u6240\u6709\u6876\u4e2d\u7684\u5143\u7d20\u6570\u91cf\u5927\u81f4\u76f8\u7b49\u3002

    \u5982\u56fe 11-14 \u6240\u793a\uff0c\u8fd9\u79cd\u65b9\u6cd5\u672c\u8d28\u4e0a\u662f\u521b\u5efa\u4e00\u68f5\u9012\u5f52\u6811\uff0c\u76ee\u6807\u662f\u8ba9\u53f6\u8282\u70b9\u7684\u503c\u5c3d\u53ef\u80fd\u5e73\u5747\u3002\u5f53\u7136\uff0c\u4e0d\u4e00\u5b9a\u8981\u6bcf\u8f6e\u5c06\u6570\u636e\u5212\u5206\u4e3a 3 \u4e2a\u6876\uff0c\u5177\u4f53\u5212\u5206\u65b9\u5f0f\u53ef\u6839\u636e\u6570\u636e\u7279\u70b9\u7075\u6d3b\u9009\u62e9\u3002

    \u56fe 11-14 \u00a0 \u9012\u5f52\u5212\u5206\u6876

    \u5982\u679c\u6211\u4eec\u63d0\u524d\u77e5\u9053\u5546\u54c1\u4ef7\u683c\u7684\u6982\u7387\u5206\u5e03\uff0c\u5219\u53ef\u4ee5\u6839\u636e\u6570\u636e\u6982\u7387\u5206\u5e03\u8bbe\u7f6e\u6bcf\u4e2a\u6876\u7684\u4ef7\u683c\u5206\u754c\u7ebf\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6570\u636e\u5206\u5e03\u5e76\u4e0d\u4e00\u5b9a\u9700\u8981\u7279\u610f\u7edf\u8ba1\uff0c\u4e5f\u53ef\u4ee5\u6839\u636e\u6570\u636e\u7279\u70b9\u91c7\u7528\u67d0\u79cd\u6982\u7387\u6a21\u578b\u8fdb\u884c\u8fd1\u4f3c\u3002

    \u5982\u56fe 11-15 \u6240\u793a\uff0c\u6211\u4eec\u5047\u8bbe\u5546\u54c1\u4ef7\u683c\u670d\u4ece\u6b63\u6001\u5206\u5e03\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5408\u7406\u5730\u8bbe\u5b9a\u4ef7\u683c\u533a\u95f4\uff0c\u4ece\u800c\u5c06\u5546\u54c1\u5e73\u5747\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\u3002

    \u56fe 11-15 \u00a0 \u6839\u636e\u6982\u7387\u5206\u5e03\u5212\u5206\u6876

    "},{"location":"chapter_sorting/counting_sort/","title":"11.9 \u00a0 \u8ba1\u6570\u6392\u5e8f","text":"

    \u8ba1\u6570\u6392\u5e8f\uff08counting sort\uff09\u901a\u8fc7\u7edf\u8ba1\u5143\u7d20\u6570\u91cf\u6765\u5b9e\u73b0\u6392\u5e8f\uff0c\u901a\u5e38\u5e94\u7528\u4e8e\u6574\u6570\u6570\u7ec4\u3002

    "},{"location":"chapter_sorting/counting_sort/#1191","title":"11.9.1 \u00a0 \u7b80\u5355\u5b9e\u73b0","text":"

    \u5148\u6765\u770b\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\u3002\u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4 nums \uff0c\u5176\u4e2d\u7684\u5143\u7d20\u90fd\u662f\u201c\u975e\u8d1f\u6574\u6570\u201d\uff0c\u8ba1\u6570\u6392\u5e8f\u7684\u6574\u4f53\u6d41\u7a0b\u5982\u56fe 11-16 \u6240\u793a\u3002

    1. \u904d\u5386\u6570\u7ec4\uff0c\u627e\u51fa\u5176\u4e2d\u7684\u6700\u5927\u6570\u5b57\uff0c\u8bb0\u4e3a \\(m\\) \uff0c\u7136\u540e\u521b\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(m + 1\\) \u7684\u8f85\u52a9\u6570\u7ec4 counter \u3002
    2. \u501f\u52a9 counter \u7edf\u8ba1 nums \u4e2d\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\uff0c\u5176\u4e2d counter[num] \u5bf9\u5e94\u6570\u5b57 num \u7684\u51fa\u73b0\u6b21\u6570\u3002\u7edf\u8ba1\u65b9\u6cd5\u5f88\u7b80\u5355\uff0c\u53ea\u9700\u904d\u5386 nums\uff08\u8bbe\u5f53\u524d\u6570\u5b57\u4e3a num\uff09\uff0c\u6bcf\u8f6e\u5c06 counter[num] \u589e\u52a0 \\(1\\) \u5373\u53ef\u3002
    3. \u7531\u4e8e counter \u7684\u5404\u4e2a\u7d22\u5f15\u5929\u7136\u6709\u5e8f\uff0c\u56e0\u6b64\u76f8\u5f53\u4e8e\u6240\u6709\u6570\u5b57\u5df2\u7ecf\u6392\u5e8f\u597d\u4e86\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u904d\u5386 counter \uff0c\u6839\u636e\u5404\u6570\u5b57\u51fa\u73b0\u6b21\u6570\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u586b\u5165 nums \u5373\u53ef\u3002

    \u56fe 11-16 \u00a0 \u8ba1\u6570\u6392\u5e8f\u6d41\u7a0b

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig counting_sort.py
    def counting_sort_naive(nums: list[int]):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\"\"\"\n    # \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\n    # 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m = 0\n    for num in nums:\n        m = max(m, num)\n    # 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    # counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter = [0] * (m + 1)\n    for num in nums:\n        counter[num] += 1\n    # 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    i = 0\n    for num in range(m + 1):\n        for _ in range(counter[num]):\n            nums[i] = num\n            i += 1\n
    counting_sort.cpp
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(vector<int> &nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    vector<int> counter(m + 1, 0);\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.java
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.cs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid CountingSortNaive(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    foreach (int num in nums) {\n        m = Math.Max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    foreach (int num in nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.go
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunc countingSortNaive(nums []int) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m := 0\n    for _, num := range nums {\n        if num > m {\n            m = num\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter := make([]int, m+1)\n    for _, num := range nums {\n        counter[num]++\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    for i, num := 0, 0; num < m+1; num++ {\n        for j := 0; j < counter[num]; j++ {\n            nums[i] = num\n            i++\n        }\n    }\n}\n
    counting_sort.swift
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunc countingSortNaive(nums: inout [Int]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = nums.max()!\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    var counter = Array(repeating: 0, count: m + 1)\n    for num in nums {\n        counter[num] += 1\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    var i = 0\n    for num in 0 ..< m + 1 {\n        for _ in 0 ..< counter[num] {\n            nums[i] = num\n            i += 1\n        }\n    }\n}\n
    counting_sort.js
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunction countingSortNaive(nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter = new Array(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let i = 0;\n    for (let num = 0; num < m + 1; num++) {\n        for (let j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.ts
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunction countingSortNaive(nums: number[]): void {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter: number[] = new Array<number>(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let i = 0;\n    for (let num = 0; num < m + 1; num++) {\n        for (let j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.dart
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(List<int> nums) {\n  // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n  int m = 0;\n  for (int _num in nums) {\n    m = max(m, _num);\n  }\n  // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  // counter[_num] \u4ee3\u8868 _num \u7684\u51fa\u73b0\u6b21\u6570\n  List<int> counter = List.filled(m + 1, 0);\n  for (int _num in nums) {\n    counter[_num]++;\n  }\n  // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n  int i = 0;\n  for (int _num = 0; _num < m + 1; _num++) {\n    for (int j = 0; j < counter[_num]; j++, i++) {\n      nums[i] = _num;\n    }\n  }\n}\n
    counting_sort.rs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfn counting_sort_naive(nums: &mut [i32]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = *nums.into_iter().max().unwrap();\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    let mut counter = vec![0; m as usize + 1];\n    for &num in &*nums {\n        counter[num as usize] += 1;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let mut i = 0;\n    for num in 0..m + 1 {\n        for _ in 0..counter[num as usize] {\n            nums[i] = num;\n            i += 1;\n        }\n    }\n}\n
    counting_sort.c
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(int nums[], int size) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int i = 0; i < size; i++) {\n        if (nums[i] > m) {\n            m = nums[i];\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int *counter = calloc(m + 1, sizeof(int));\n    for (int i = 0; i < size; i++) {\n        counter[nums[i]]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n    // 4. \u91ca\u653e\u5185\u5b58\n    free(counter);\n}\n
    counting_sort.kt
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfun countingSortNaive(nums: IntArray) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    var m = 0\n    for (num in nums) {\n        m = max(m, num)\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    val counter = IntArray(m + 1)\n    for (num in nums) {\n        counter[num]++\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    var i = 0\n    for (num in 0..<m + 1) {\n        var j = 0\n        while (j < counter[num]) {\n            nums[i] = num\n            j++\n            i++\n        }\n    }\n}\n
    counting_sort.rb
    [class]{}-[func]{counting_sort_naive}\n
    counting_sort.zig
    [class]{}-[func]{countingSortNaive}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u8ba1\u6570\u6392\u5e8f\u4e0e\u6876\u6392\u5e8f\u7684\u8054\u7cfb

    \u4ece\u6876\u6392\u5e8f\u7684\u89d2\u5ea6\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u8ba1\u6570\u6392\u5e8f\u4e2d\u7684\u8ba1\u6570\u6570\u7ec4 counter \u7684\u6bcf\u4e2a\u7d22\u5f15\u89c6\u4e3a\u4e00\u4e2a\u6876\uff0c\u5c06\u7edf\u8ba1\u6570\u91cf\u7684\u8fc7\u7a0b\u770b\u4f5c\u5c06\u5404\u4e2a\u5143\u7d20\u5206\u914d\u5230\u5bf9\u5e94\u7684\u6876\u4e2d\u3002\u672c\u8d28\u4e0a\uff0c\u8ba1\u6570\u6392\u5e8f\u662f\u6876\u6392\u5e8f\u5728\u6574\u578b\u6570\u636e\u4e0b\u7684\u4e00\u4e2a\u7279\u4f8b\u3002

    "},{"location":"chapter_sorting/counting_sort/#1192","title":"11.9.2 \u00a0 \u5b8c\u6574\u5b9e\u73b0","text":"

    \u7ec6\u5fc3\u7684\u8bfb\u8005\u53ef\u80fd\u53d1\u73b0\u4e86\uff0c\u5982\u679c\u8f93\u5165\u6570\u636e\u662f\u5bf9\u8c61\uff0c\u4e0a\u8ff0\u6b65\u9aa4 3. \u5c31\u5931\u6548\u4e86\u3002\u5047\u8bbe\u8f93\u5165\u6570\u636e\u662f\u5546\u54c1\u5bf9\u8c61\uff0c\u6211\u4eec\u60f3\u6309\u7167\u5546\u54c1\u4ef7\u683c\uff08\u7c7b\u7684\u6210\u5458\u53d8\u91cf\uff09\u5bf9\u5546\u54c1\u8fdb\u884c\u6392\u5e8f\uff0c\u800c\u4e0a\u8ff0\u7b97\u6cd5\u53ea\u80fd\u7ed9\u51fa\u4ef7\u683c\u7684\u6392\u5e8f\u7ed3\u679c\u3002

    \u90a3\u4e48\u5982\u4f55\u624d\u80fd\u5f97\u5230\u539f\u6570\u636e\u7684\u6392\u5e8f\u7ed3\u679c\u5462\uff1f\u6211\u4eec\u9996\u5148\u8ba1\u7b97 counter \u7684\u201c\u524d\u7f00\u548c\u201d\u3002\u987e\u540d\u601d\u4e49\uff0c\u7d22\u5f15 i \u5904\u7684\u524d\u7f00\u548c prefix[i] \u7b49\u4e8e\u6570\u7ec4\u524d i \u4e2a\u5143\u7d20\u4e4b\u548c\uff1a

    \\[ \\text{prefix}[i] = \\sum_{j=0}^i \\text{counter[j]} \\]

    \u524d\u7f00\u548c\u5177\u6709\u660e\u786e\u7684\u610f\u4e49\uff0cprefix[num] - 1 \u4ee3\u8868\u5143\u7d20 num \u5728\u7ed3\u679c\u6570\u7ec4 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\u3002\u8fd9\u4e2a\u4fe1\u606f\u975e\u5e38\u5173\u952e\uff0c\u56e0\u4e3a\u5b83\u544a\u8bc9\u6211\u4eec\u5404\u4e2a\u5143\u7d20\u5e94\u8be5\u51fa\u73b0\u5728\u7ed3\u679c\u6570\u7ec4\u7684\u54ea\u4e2a\u4f4d\u7f6e\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5012\u5e8f\u904d\u5386\u539f\u6570\u7ec4 nums \u7684\u6bcf\u4e2a\u5143\u7d20 num \uff0c\u5728\u6bcf\u8f6e\u8fed\u4ee3\u4e2d\u6267\u884c\u4ee5\u4e0b\u4e24\u6b65\u3002

    1. \u5c06 num \u586b\u5165\u6570\u7ec4 res \u7684\u7d22\u5f15 prefix[num] - 1 \u5904\u3002
    2. \u4ee4\u524d\u7f00\u548c prefix[num] \u51cf\u5c0f \\(1\\) \uff0c\u4ece\u800c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\u3002

    \u904d\u5386\u5b8c\u6210\u540e\uff0c\u6570\u7ec4 res \u4e2d\u5c31\u662f\u6392\u5e8f\u597d\u7684\u7ed3\u679c\uff0c\u6700\u540e\u4f7f\u7528 res \u8986\u76d6\u539f\u6570\u7ec4 nums \u5373\u53ef\u3002\u56fe 11-17 \u5c55\u793a\u4e86\u5b8c\u6574\u7684\u8ba1\u6570\u6392\u5e8f\u6d41\u7a0b\u3002

    <1><2><3><4><5><6><7><8>

    \u56fe 11-17 \u00a0 \u8ba1\u6570\u6392\u5e8f\u6b65\u9aa4

    \u8ba1\u6570\u6392\u5e8f\u7684\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig counting_sort.py
    def counting_sort(nums: list[int]):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\"\"\"\n    # \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\n    # 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m = max(nums)\n    # 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    # counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter = [0] * (m + 1)\n    for num in nums:\n        counter[num] += 1\n    # 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    # \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in range(m):\n        counter[i + 1] += counter[i]\n    # 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    # \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    n = len(nums)\n    res = [0] * n\n    for i in range(n - 1, -1, -1):\n        num = nums[i]\n        res[counter[num] - 1] = num  # \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num] -= 1  # \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    # \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in range(n):\n        nums[i] = res[i]\n
    counting_sort.cpp
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(vector<int> &nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    vector<int> counter(m + 1, 0);\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.size();\n    vector<int> res(n);\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--;              // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    nums = res;\n}\n
    counting_sort.java
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.length;\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.cs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid CountingSort(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    foreach (int num in nums) {\n        m = Math.Max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    foreach (int num in nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.Length;\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.go
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunc countingSort(nums []int) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m := 0\n    for _, num := range nums {\n        if num > m {\n            m = num\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter := make([]int, m+1)\n    for _, num := range nums {\n        counter[num]++\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i := 0; i < m; i++ {\n        counter[i+1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    n := len(nums)\n    res := make([]int, n)\n    for i := n - 1; i >= 0; i-- {\n        num := nums[i]\n        // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        res[counter[num]-1] = num\n        // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n        counter[num]--\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    copy(nums, res)\n}\n
    counting_sort.swift
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunc countingSort(nums: inout [Int]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = nums.max()!\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    var counter = Array(repeating: 0, count: m + 1)\n    for num in nums {\n        counter[num] += 1\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in 0 ..< m {\n        counter[i + 1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    var res = Array(repeating: 0, count: nums.count)\n    for i in nums.indices.reversed() {\n        let num = nums[i]\n        res[counter[num] - 1] = num // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num] -= 1 // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in nums.indices {\n        nums[i] = res[i]\n    }\n}\n
    counting_sort.js
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunction countingSort(nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter = new Array(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (let i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    const n = nums.length;\n    const res = new Array(n);\n    for (let i = n - 1; i >= 0; i--) {\n        const num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.ts
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunction countingSort(nums: number[]): void {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter: number[] = new Array<number>(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (let i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    const n = nums.length;\n    const res: number[] = new Array<number>(n);\n    for (let i = n - 1; i >= 0; i--) {\n        const num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.dart
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(List<int> nums) {\n  // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n  int m = 0;\n  for (int _num in nums) {\n    m = max(m, _num);\n  }\n  // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  // counter[_num] \u4ee3\u8868 _num \u7684\u51fa\u73b0\u6b21\u6570\n  List<int> counter = List.filled(m + 1, 0);\n  for (int _num in nums) {\n    counter[_num]++;\n  }\n  // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n  // \u5373 counter[_num]-1 \u662f _num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n  for (int i = 0; i < m; i++) {\n    counter[i + 1] += counter[i];\n  }\n  // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n  // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n  int n = nums.length;\n  List<int> res = List.filled(n, 0);\n  for (int i = n - 1; i >= 0; i--) {\n    int _num = nums[i];\n    res[counter[_num] - 1] = _num; // \u5c06 _num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n    counter[_num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e _num \u7684\u7d22\u5f15\n  }\n  // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n  nums.setAll(0, res);\n}\n
    counting_sort.rs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfn counting_sort(nums: &mut [i32]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = *nums.into_iter().max().unwrap();\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    let mut counter = vec![0; m as usize + 1];\n    for &num in &*nums {\n        counter[num as usize] += 1;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in 0..m as usize {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    let n = nums.len();\n    let mut res = vec![0; n];\n    for i in (0..n).rev() {\n        let num = nums[i];\n        res[counter[num as usize] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num as usize] -= 1; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in 0..n {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.c
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(int nums[], int size) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int i = 0; i < size; i++) {\n        if (nums[i] > m) {\n            m = nums[i];\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int *counter = calloc(m, sizeof(int));\n    for (int i = 0; i < size; i++) {\n        counter[nums[i]]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int *res = malloc(sizeof(int) * size);\n    for (int i = size - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--;              // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    memcpy(nums, res, size * sizeof(int));\n    // 5. \u91ca\u653e\u5185\u5b58\n    free(counter);\n}\n
    counting_sort.kt
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfun countingSort(nums: IntArray) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    var m = 0\n    for (num in nums) {\n        m = max(m, num)\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    val counter = IntArray(m + 1)\n    for (num in nums) {\n        counter[num]++\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (i in 0..<m) {\n        counter[i + 1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    val n = nums.size\n    val res = IntArray(n)\n    for (i in n - 1 downTo 0) {\n        val num = nums[i]\n        res[counter[num] - 1] = num // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]-- // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (i in 0..<n) {\n        nums[i] = res[i]\n    }\n}\n
    counting_sort.rb
    [class]{}-[func]{counting_sort}\n
    counting_sort.zig
    [class]{}-[func]{countingSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/counting_sort/#1193","title":"11.9.3 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + m)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f \uff1a\u6d89\u53ca\u904d\u5386 nums \u548c\u904d\u5386 counter \uff0c\u90fd\u4f7f\u7528\u7ebf\u6027\u65f6\u95f4\u3002\u4e00\u822c\u60c5\u51b5\u4e0b \\(n \\gg m\\) \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u4e8e \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + m)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u501f\u52a9\u4e86\u957f\u5ea6\u5206\u522b\u4e3a \\(n\\) \u548c \\(m\\) \u7684\u6570\u7ec4 res \u548c counter \u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u7531\u4e8e\u5411 res \u4e2d\u586b\u5145\u5143\u7d20\u7684\u987a\u5e8f\u662f\u201c\u4ece\u53f3\u5411\u5de6\u201d\u7684\uff0c\u56e0\u6b64\u5012\u5e8f\u904d\u5386 nums \u53ef\u4ee5\u907f\u514d\u6539\u53d8\u76f8\u7b49\u5143\u7d20\u4e4b\u95f4\u7684\u76f8\u5bf9\u4f4d\u7f6e\uff0c\u4ece\u800c\u5b9e\u73b0\u7a33\u5b9a\u6392\u5e8f\u3002\u5b9e\u9645\u4e0a\uff0c\u6b63\u5e8f\u904d\u5386 nums \u4e5f\u53ef\u4ee5\u5f97\u5230\u6b63\u786e\u7684\u6392\u5e8f\u7ed3\u679c\uff0c\u4f46\u7ed3\u679c\u662f\u975e\u7a33\u5b9a\u7684\u3002
    "},{"location":"chapter_sorting/counting_sort/#1194","title":"11.9.4 \u00a0 \u5c40\u9650\u6027","text":"

    \u770b\u5230\u8fd9\u91cc\uff0c\u4f60\u4e5f\u8bb8\u4f1a\u89c9\u5f97\u8ba1\u6570\u6392\u5e8f\u975e\u5e38\u5de7\u5999\uff0c\u4ec5\u901a\u8fc7\u7edf\u8ba1\u6570\u91cf\u5c31\u53ef\u4ee5\u5b9e\u73b0\u9ad8\u6548\u7684\u6392\u5e8f\u3002\u7136\u800c\uff0c\u4f7f\u7528\u8ba1\u6570\u6392\u5e8f\u7684\u524d\u7f6e\u6761\u4ef6\u76f8\u5bf9\u8f83\u4e3a\u4e25\u683c\u3002

    \u8ba1\u6570\u6392\u5e8f\u53ea\u9002\u7528\u4e8e\u975e\u8d1f\u6574\u6570\u3002\u82e5\u60f3\u5c06\u5176\u7528\u4e8e\u5176\u4ed6\u7c7b\u578b\u7684\u6570\u636e\uff0c\u9700\u8981\u786e\u4fdd\u8fd9\u4e9b\u6570\u636e\u53ef\u4ee5\u8f6c\u6362\u4e3a\u975e\u8d1f\u6574\u6570\uff0c\u5e76\u4e14\u5728\u8f6c\u6362\u8fc7\u7a0b\u4e2d\u4e0d\u80fd\u6539\u53d8\u5404\u4e2a\u5143\u7d20\u4e4b\u95f4\u7684\u76f8\u5bf9\u5927\u5c0f\u5173\u7cfb\u3002\u4f8b\u5982\uff0c\u5bf9\u4e8e\u5305\u542b\u8d1f\u6570\u7684\u6574\u6570\u6570\u7ec4\uff0c\u53ef\u4ee5\u5148\u7ed9\u6240\u6709\u6570\u5b57\u52a0\u4e0a\u4e00\u4e2a\u5e38\u6570\uff0c\u5c06\u5168\u90e8\u6570\u5b57\u8f6c\u5316\u4e3a\u6b63\u6570\uff0c\u6392\u5e8f\u5b8c\u6210\u540e\u518d\u8f6c\u6362\u56de\u53bb\u3002

    \u8ba1\u6570\u6392\u5e8f\u9002\u7528\u4e8e\u6570\u636e\u91cf\u5927\u4f46\u6570\u636e\u8303\u56f4\u8f83\u5c0f\u7684\u60c5\u51b5\u3002\u6bd4\u5982\uff0c\u5728\u4e0a\u8ff0\u793a\u4f8b\u4e2d \\(m\\) \u4e0d\u80fd\u592a\u5927\uff0c\u5426\u5219\u4f1a\u5360\u7528\u8fc7\u591a\u7a7a\u95f4\u3002\u800c\u5f53 \\(n \\ll m\\) \u65f6\uff0c\u8ba1\u6570\u6392\u5e8f\u4f7f\u7528 \\(O(m)\\) \u65f6\u95f4\uff0c\u53ef\u80fd\u6bd4 \\(O(n \\log n)\\) \u7684\u6392\u5e8f\u7b97\u6cd5\u8fd8\u8981\u6162\u3002

    "},{"location":"chapter_sorting/heap_sort/","title":"11.7 \u00a0 \u5806\u6392\u5e8f","text":"

    Tip

    \u9605\u8bfb\u672c\u8282\u524d\uff0c\u8bf7\u786e\u4fdd\u5df2\u5b66\u5b8c\u201c\u5806\u201c\u7ae0\u8282\u3002

    \u5806\u6392\u5e8f\uff08heap sort\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5806\u6570\u636e\u7ed3\u6784\u5b9e\u73b0\u7684\u9ad8\u6548\u6392\u5e8f\u7b97\u6cd5\u3002\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u5df2\u7ecf\u5b66\u8fc7\u7684\u201c\u5efa\u5806\u64cd\u4f5c\u201d\u548c\u201c\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\u201d\u5b9e\u73b0\u5806\u6392\u5e8f\u3002

    1. \u8f93\u5165\u6570\u7ec4\u5e76\u5efa\u7acb\u5c0f\u9876\u5806\uff0c\u6b64\u65f6\u6700\u5c0f\u5143\u7d20\u4f4d\u4e8e\u5806\u9876\u3002
    2. \u4e0d\u65ad\u6267\u884c\u51fa\u5806\u64cd\u4f5c\uff0c\u4f9d\u6b21\u8bb0\u5f55\u51fa\u5806\u5143\u7d20\uff0c\u5373\u53ef\u5f97\u5230\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u7684\u5e8f\u5217\u3002

    \u4ee5\u4e0a\u65b9\u6cd5\u867d\u7136\u53ef\u884c\uff0c\u4f46\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u989d\u5916\u6570\u7ec4\u6765\u4fdd\u5b58\u5f39\u51fa\u7684\u5143\u7d20\uff0c\u6bd4\u8f83\u6d6a\u8d39\u7a7a\u95f4\u3002\u5728\u5b9e\u9645\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f7f\u7528\u4e00\u79cd\u66f4\u52a0\u4f18\u96c5\u7684\u5b9e\u73b0\u65b9\u5f0f\u3002

    "},{"location":"chapter_sorting/heap_sort/#1171","title":"11.7.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u8bbe\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u5806\u6392\u5e8f\u7684\u6d41\u7a0b\u5982\u56fe 11-12 \u6240\u793a\u3002

    1. \u8f93\u5165\u6570\u7ec4\u5e76\u5efa\u7acb\u5927\u9876\u5806\u3002\u5b8c\u6210\u540e\uff0c\u6700\u5927\u5143\u7d20\u4f4d\u4e8e\u5806\u9876\u3002
    2. \u5c06\u5806\u9876\u5143\u7d20\uff08\u7b2c\u4e00\u4e2a\u5143\u7d20\uff09\u4e0e\u5806\u5e95\u5143\u7d20\uff08\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\u4ea4\u6362\u3002\u5b8c\u6210\u4ea4\u6362\u540e\uff0c\u5806\u7684\u957f\u5ea6\u51cf \\(1\\) \uff0c\u5df2\u6392\u5e8f\u5143\u7d20\u6570\u91cf\u52a0 \\(1\\) \u3002
    3. \u4ece\u5806\u9876\u5143\u7d20\u5f00\u59cb\uff0c\u4ece\u9876\u5230\u5e95\u6267\u884c\u5806\u5316\u64cd\u4f5c\uff08sift down\uff09\u3002\u5b8c\u6210\u5806\u5316\u540e\uff0c\u5806\u7684\u6027\u8d28\u5f97\u5230\u4fee\u590d\u3002
    4. \u5faa\u73af\u6267\u884c\u7b2c 2. \u6b65\u548c\u7b2c 3. \u6b65\u3002\u5faa\u73af \\(n - 1\\) \u8f6e\u540e\uff0c\u5373\u53ef\u5b8c\u6210\u6570\u7ec4\u6392\u5e8f\u3002

    Tip

    \u5b9e\u9645\u4e0a\uff0c\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\u4e2d\u4e5f\u5305\u542b\u7b2c 2. \u6b65\u548c\u7b2c 3. \u6b65\uff0c\u53ea\u662f\u591a\u4e86\u4e00\u4e2a\u5f39\u51fa\u5143\u7d20\u7684\u6b65\u9aa4\u3002

    <1><2><3><4><5><6><7><8><9><10><11><12>

    \u56fe 11-12 \u00a0 \u5806\u6392\u5e8f\u6b65\u9aa4

    \u5728\u4ee3\u7801\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86\u4e0e\u201c\u5806\u201d\u7ae0\u8282\u76f8\u540c\u7684\u4ece\u9876\u81f3\u5e95\u5806\u5316 sift_down() \u51fd\u6570\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u7531\u4e8e\u5806\u7684\u957f\u5ea6\u4f1a\u968f\u7740\u63d0\u53d6\u6700\u5927\u5143\u7d20\u800c\u51cf\u5c0f\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u7ed9 sift_down() \u51fd\u6570\u6dfb\u52a0\u4e00\u4e2a\u957f\u5ea6\u53c2\u6570 \\(n\\) \uff0c\u7528\u4e8e\u6307\u5b9a\u5806\u7684\u5f53\u524d\u6709\u6548\u957f\u5ea6\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap_sort.py
    def sift_down(nums: list[int], n: int, i: int):\n    \"\"\"\u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l = 2 * i + 1\n        r = 2 * i + 2\n        ma = i\n        if l < n and nums[l] > nums[ma]:\n            ma = l\n        if r < n and nums[r] > nums[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        nums[i], nums[ma] = nums[ma], nums[i]\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n\ndef heap_sort(nums: list[int]):\n    \"\"\"\u5806\u6392\u5e8f\"\"\"\n    # \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(len(nums) // 2 - 1, -1, -1):\n        sift_down(nums, len(nums), i)\n    # \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in range(len(nums) - 1, 0, -1):\n        # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        nums[0], nums[i] = nums[i], nums[0]\n        # \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        sift_down(nums, i, 0)\n
    heap_sort.cpp
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(vector<int> &nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(nums[i], nums[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(vector<int> &nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.size() / 2 - 1; i >= 0; --i) {\n        siftDown(nums, nums.size(), i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.size() - 1; i > 0; --i) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(nums[0], nums[i]);\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.java
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int[] nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        int temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(int[] nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.length / 2 - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        int tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.cs
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int[] nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        (nums[ma], nums[i]) = (nums[i], nums[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid HeapSort(int[] nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.Length / 2 - 1; i >= 0; i--) {\n        SiftDown(nums, nums.Length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        (nums[i], nums[0]) = (nums[0], nums[i]);\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        SiftDown(nums, i, 0);\n    }\n}\n
    heap_sort.go
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(nums *[]int, n, i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l := 2*i + 1\n        r := 2*i + 2\n        ma := i\n        if l < n && (*nums)[l] > (*nums)[ma] {\n            ma = l\n        }\n        if r < n && (*nums)[r] > (*nums)[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        (*nums)[i], (*nums)[ma] = (*nums)[ma], (*nums)[i]\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunc heapSort(nums *[]int) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i := len(*nums)/2 - 1; i >= 0; i-- {\n        siftDown(nums, len(*nums), i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i := len(*nums) - 1; i > 0; i-- {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        (*nums)[0], (*nums)[i] = (*nums)[i], (*nums)[0]\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0)\n    }\n}\n
    heap_sort.swift
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(nums: inout [Int], n: Int, i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1\n        let r = 2 * i + 2\n        var ma = i\n        if l < n, nums[l] > nums[ma] {\n            ma = l\n        }\n        if r < n, nums[r] > nums[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        nums.swapAt(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunc heapSort(nums: inout [Int]) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in stride(from: nums.count / 2 - 1, through: 0, by: -1) {\n        siftDown(nums: &nums, n: nums.count, i: i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in nums.indices.dropFirst().reversed() {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        nums.swapAt(0, i)\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums: &nums, n: i, i: 0)\n    }\n}\n
    heap_sort.js
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunction siftDown(nums, n, i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let ma = i;\n        if (l < n && nums[l] > nums[ma]) {\n            ma = l;\n        }\n        if (r < n && nums[r] > nums[ma]) {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        [nums[i], nums[ma]] = [nums[ma], nums[i]];\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunction heapSort(nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        [nums[0], nums[i]] = [nums[i], nums[0]];\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.ts
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunction siftDown(nums: number[], n: number, i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let ma = i;\n        if (l < n && nums[l] > nums[ma]) {\n            ma = l;\n        }\n        if (r < n && nums[r] > nums[ma]) {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        [nums[i], nums[ma]] = [nums[ma], nums[i]];\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunction heapSort(nums: number[]): void {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        [nums[0], nums[i]] = [nums[i], nums[0]];\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.dart
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(List<int> nums, int n, int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = 2 * i + 1;\n    int r = 2 * i + 2;\n    int ma = i;\n    if (l < n && nums[l] > nums[ma]) ma = l;\n    if (r < n && nums[r] > nums[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    int temp = nums[i];\n    nums[i] = nums[ma];\n    nums[ma] = temp;\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(List<int> nums) {\n  // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = nums.length ~/ 2 - 1; i >= 0; i--) {\n    siftDown(nums, nums.length, i);\n  }\n  // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n  for (int i = nums.length - 1; i > 0; i--) {\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    int tmp = nums[0];\n    nums[0] = nums[i];\n    nums[i] = tmp;\n    // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n    siftDown(nums, i, 0);\n  }\n}\n
    heap_sort.rs
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(nums: &mut [i32], n: usize, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let mut ma = i;\n        if l < n && nums[l] > nums[ma] {\n            ma = l;\n        }\n        if r < n && nums[r] > nums[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        let temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfn heap_sort(nums: &mut [i32]) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=nums.len() / 2 - 1).rev() {\n        sift_down(nums, nums.len(), i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in (1..=nums.len() - 1).rev() {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        let tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        sift_down(nums, i, 0);\n    }\n}\n
    heap_sort.c
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int nums[], int n, int i) {\n    while (1) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        int temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(int nums[], int n) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = n / 2 - 1; i >= 0; --i) {\n        siftDown(nums, n, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = n - 1; i > 0; --i) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        int tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.kt
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(nums: IntArray, n: Int, li: Int) {\n    var i = li\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = 2 * i + 1\n        val r = 2 * i + 2\n        var ma = i\n        if (l < n && nums[l] > nums[ma]) \n            ma = l\n        if (r < n && nums[r] > nums[ma]) \n            ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) \n            break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        val temp = nums[i]\n        nums[i] = nums[ma]\n        nums[ma] = temp\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfun heapSort(nums: IntArray) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (i in nums.size / 2 - 1 downTo 0) {\n        siftDown(nums, nums.size, i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (i in nums.size - 1 downTo 1) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        val temp = nums[0]\n        nums[0] = nums[i]\n        nums[i] = temp\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0)\n    }\n}\n
    heap_sort.rb
    [class]{}-[func]{sift_down}\n\n[class]{}-[func]{heap_sort}\n
    heap_sort.zig
    [class]{}-[func]{siftDown}\n\n[class]{}-[func]{heapSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/heap_sort/#1172","title":"11.7.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5efa\u5806\u64cd\u4f5c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002\u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \uff0c\u5171\u5faa\u73af \\(n - 1\\) \u8f6e\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u51e0\u4e2a\u6307\u9488\u53d8\u91cf\u4f7f\u7528 \\(O(1)\\) \u7a7a\u95f4\u3002\u5143\u7d20\u4ea4\u6362\u548c\u5806\u5316\u64cd\u4f5c\u90fd\u662f\u5728\u539f\u6570\u7ec4\u4e0a\u8fdb\u884c\u7684\u3002
    • \u975e\u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u4ea4\u6362\u5806\u9876\u5143\u7d20\u548c\u5806\u5e95\u5143\u7d20\u65f6\uff0c\u76f8\u7b49\u5143\u7d20\u7684\u76f8\u5bf9\u4f4d\u7f6e\u53ef\u80fd\u53d1\u751f\u53d8\u5316\u3002
    "},{"location":"chapter_sorting/insertion_sort/","title":"11.4 \u00a0 \u63d2\u5165\u6392\u5e8f","text":"

    \u63d2\u5165\u6392\u5e8f\uff08insertion sort\uff09\u662f\u4e00\u79cd\u7b80\u5355\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u7684\u5de5\u4f5c\u539f\u7406\u4e0e\u624b\u52a8\u6574\u7406\u4e00\u526f\u724c\u7684\u8fc7\u7a0b\u975e\u5e38\u76f8\u4f3c\u3002

    \u5177\u4f53\u6765\u8bf4\uff0c\u6211\u4eec\u5728\u672a\u6392\u5e8f\u533a\u95f4\u9009\u62e9\u4e00\u4e2a\u57fa\u51c6\u5143\u7d20\uff0c\u5c06\u8be5\u5143\u7d20\u4e0e\u5176\u5de6\u4fa7\u5df2\u6392\u5e8f\u533a\u95f4\u7684\u5143\u7d20\u9010\u4e00\u6bd4\u8f83\u5927\u5c0f\uff0c\u5e76\u5c06\u8be5\u5143\u7d20\u63d2\u5165\u5230\u6b63\u786e\u7684\u4f4d\u7f6e\u3002

    \u56fe 11-6 \u5c55\u793a\u4e86\u6570\u7ec4\u63d2\u5165\u5143\u7d20\u7684\u64cd\u4f5c\u6d41\u7a0b\u3002\u8bbe\u57fa\u51c6\u5143\u7d20\u4e3a base \uff0c\u6211\u4eec\u9700\u8981\u5c06\u4ece\u76ee\u6807\u7d22\u5f15\u5230 base \u4e4b\u95f4\u7684\u6240\u6709\u5143\u7d20\u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\uff0c\u7136\u540e\u5c06 base \u8d4b\u503c\u7ed9\u76ee\u6807\u7d22\u5f15\u3002

    \u56fe 11-6 \u00a0 \u5355\u6b21\u63d2\u5165\u64cd\u4f5c

    "},{"location":"chapter_sorting/insertion_sort/#1141","title":"11.4.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u63d2\u5165\u6392\u5e8f\u7684\u6574\u4f53\u6d41\u7a0b\u5982\u56fe 11-7 \u6240\u793a\u3002

    1. \u521d\u59cb\u72b6\u6001\u4e0b\uff0c\u6570\u7ec4\u7684\u7b2c 1 \u4e2a\u5143\u7d20\u5df2\u5b8c\u6210\u6392\u5e8f\u3002
    2. \u9009\u53d6\u6570\u7ec4\u7684\u7b2c 2 \u4e2a\u5143\u7d20\u4f5c\u4e3a base \uff0c\u5c06\u5176\u63d2\u5165\u5230\u6b63\u786e\u4f4d\u7f6e\u540e\uff0c\u6570\u7ec4\u7684\u524d 2 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    3. \u9009\u53d6\u7b2c 3 \u4e2a\u5143\u7d20\u4f5c\u4e3a base \uff0c\u5c06\u5176\u63d2\u5165\u5230\u6b63\u786e\u4f4d\u7f6e\u540e\uff0c\u6570\u7ec4\u7684\u524d 3 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    4. \u4ee5\u6b64\u7c7b\u63a8\uff0c\u5728\u6700\u540e\u4e00\u8f6e\u4e2d\uff0c\u9009\u53d6\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a base \uff0c\u5c06\u5176\u63d2\u5165\u5230\u6b63\u786e\u4f4d\u7f6e\u540e\uff0c\u6240\u6709\u5143\u7d20\u5747\u5df2\u6392\u5e8f\u3002

    \u56fe 11-7 \u00a0 \u63d2\u5165\u6392\u5e8f\u6d41\u7a0b

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig insertion_sort.py
    def insertion_sort(nums: list[int]):\n    \"\"\"\u63d2\u5165\u6392\u5e8f\"\"\"\n    # \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in range(1, len(nums)):\n        base = nums[i]\n        j = i - 1\n        # \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0 and nums[j] > base:\n            nums[j + 1] = nums[j]  # \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1\n        nums[j + 1] = base  # \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n
    insertion_sort.cpp
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.size(); i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.java
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.length; i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base;        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.cs
    /* \u63d2\u5165\u6392\u5e8f */\nvoid InsertionSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.Length; i++) {\n        int bas = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > bas) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = bas;         // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.go
    /* \u63d2\u5165\u6392\u5e8f */\nfunc insertionSort(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i := 1; i < len(nums); i++ {\n        base := nums[i]\n        j := i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        for j >= 0 && nums[j] > base {\n            nums[j+1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--\n        }\n        nums[j+1] = base // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.swift
    /* \u63d2\u5165\u6392\u5e8f */\nfunc insertionSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in nums.indices.dropFirst() {\n        let base = nums[i]\n        var j = i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0, nums[j] > base {\n            nums[j + 1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1\n        }\n        nums[j + 1] = base // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.js
    /* \u63d2\u5165\u6392\u5e8f */\nfunction insertionSort(nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (let i = 1; i < nums.length; i++) {\n        let base = nums[i],\n            j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.ts
    /* \u63d2\u5165\u6392\u5e8f */\nfunction insertionSort(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (let i = 1; i < nums.length; i++) {\n        const base = nums[i];\n        let j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.dart
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n  for (int i = 1; i < nums.length; i++) {\n    int base = nums[i], j = i - 1;\n    // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n    while (j >= 0 && nums[j] > base) {\n      nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n      j--;\n    }\n    nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n  }\n}\n
    insertion_sort.rs
    /* \u63d2\u5165\u6392\u5e8f */\nfn insertion_sort(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in 1..nums.len() {\n        let (base, mut j) = (nums[i], (i - 1) as i32);\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0 && nums[j as usize] > base {\n            nums[(j + 1) as usize] = nums[j as usize]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1;\n        }\n        nums[(j + 1) as usize] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.c
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < size; i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            nums[j + 1] = nums[j];\n            j--;\n        }\n        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n        nums[j + 1] = base;\n    }\n}\n
    insertion_sort.kt
    /* \u63d2\u5165\u6392\u5e8f */\nfun insertionSort(nums: IntArray) {\n    //\u5916\u5faa\u73af: \u5df2\u6392\u5e8f\u5143\u7d20\u4e3a 1, 2, ..., n\n    for (i in nums.indices) {\n        val base = nums[i]\n        var j = i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--\n        }\n        nums[j + 1] = base        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.rb
    ### \u63d2\u5165\u6392\u5e8f ###\ndef insertion_sort(nums)\n  n = nums.length\n  # \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n  for i in 1...n\n    base = nums[i]\n    j = i - 1\n    # \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n    while j >= 0 && nums[j] > base\n      nums[j + 1] = nums[j] # \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n      j -= 1\n    end\n    nums[j + 1] = base # \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n  end\nend\n
    insertion_sort.zig
    // \u63d2\u5165\u6392\u5e8f\nfn insertionSort(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    var i: usize = 1;\n    while (i < nums.len) : (i += 1) {\n        var base = nums[i];\n        var j: usize = i;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 1 and nums[j - 1] > base) : (j -= 1) {\n            nums[j] = nums[j - 1];  // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n        }\n        nums[j] = base;             // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/insertion_sort/#1142","title":"11.4.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\u3001\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u63d2\u5165\u64cd\u4f5c\u5206\u522b\u9700\u8981\u5faa\u73af \\(n - 1\\)\u3001\\(n-2\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \u6b21\uff0c\u6c42\u548c\u5f97\u5230 \\((n - 1) n / 2\\) \uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002\u5728\u9047\u5230\u6709\u5e8f\u6570\u636e\u65f6\uff0c\u63d2\u5165\u64cd\u4f5c\u4f1a\u63d0\u524d\u7ec8\u6b62\u3002\u5f53\u8f93\u5165\u6570\u7ec4\u5b8c\u5168\u6709\u5e8f\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u63d2\u5165\u64cd\u4f5c\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u4f1a\u5c06\u5143\u7d20\u63d2\u5165\u5230\u76f8\u7b49\u5143\u7d20\u7684\u53f3\u4fa7\uff0c\u4e0d\u4f1a\u6539\u53d8\u5b83\u4eec\u7684\u987a\u5e8f\u3002
    "},{"location":"chapter_sorting/insertion_sort/#1143","title":"11.4.3 \u00a0 \u63d2\u5165\u6392\u5e8f\u7684\u4f18\u52bf","text":"

    \u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u800c\u6211\u4eec\u5373\u5c06\u5b66\u4e60\u7684\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002\u5c3d\u7ba1\u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u66f4\u9ad8\uff0c\u4f46\u5728\u6570\u636e\u91cf\u8f83\u5c0f\u7684\u60c5\u51b5\u4e0b\uff0c\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u66f4\u5feb\u3002

    \u8fd9\u4e2a\u7ed3\u8bba\u4e0e\u7ebf\u6027\u67e5\u627e\u548c\u4e8c\u5206\u67e5\u627e\u7684\u9002\u7528\u60c5\u51b5\u7684\u7ed3\u8bba\u7c7b\u4f3c\u3002\u5feb\u901f\u6392\u5e8f\u8fd9\u7c7b \\(O(n \\log n)\\) \u7684\u7b97\u6cd5\u5c5e\u4e8e\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5f80\u5f80\u5305\u542b\u66f4\u591a\u5355\u5143\u8ba1\u7b97\u64cd\u4f5c\u3002\u800c\u5728\u6570\u636e\u91cf\u8f83\u5c0f\u65f6\uff0c\\(n^2\\) \u548c \\(n \\log n\\) \u7684\u6570\u503c\u6bd4\u8f83\u63a5\u8fd1\uff0c\u590d\u6742\u5ea6\u4e0d\u5360\u4e3b\u5bfc\u5730\u4f4d\uff0c\u6bcf\u8f6e\u4e2d\u7684\u5355\u5143\u64cd\u4f5c\u6570\u91cf\u8d77\u5230\u51b3\u5b9a\u6027\u4f5c\u7528\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\uff08\u4f8b\u5982 Java\uff09\u7684\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\u91c7\u7528\u4e86\u63d2\u5165\u6392\u5e8f\uff0c\u5927\u81f4\u601d\u8def\u4e3a\uff1a\u5bf9\u4e8e\u957f\u6570\u7ec4\uff0c\u91c7\u7528\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u4f8b\u5982\u5feb\u901f\u6392\u5e8f\uff1b\u5bf9\u4e8e\u77ed\u6570\u7ec4\uff0c\u76f4\u63a5\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u3002

    \u867d\u7136\u5192\u6ce1\u6392\u5e8f\u3001\u9009\u62e9\u6392\u5e8f\u548c\u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n^2)\\) \uff0c\u4f46\u5728\u5b9e\u9645\u60c5\u51b5\u4e2d\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u4f7f\u7528\u9891\u7387\u663e\u8457\u9ad8\u4e8e\u5192\u6ce1\u6392\u5e8f\u548c\u9009\u62e9\u6392\u5e8f\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u5192\u6ce1\u6392\u5e8f\u57fa\u4e8e\u5143\u7d20\u4ea4\u6362\u5b9e\u73b0\uff0c\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cf\uff0c\u5171\u6d89\u53ca 3 \u4e2a\u5355\u5143\u64cd\u4f5c\uff1b\u63d2\u5165\u6392\u5e8f\u57fa\u4e8e\u5143\u7d20\u8d4b\u503c\u5b9e\u73b0\uff0c\u4ec5\u9700 1 \u4e2a\u5355\u5143\u64cd\u4f5c\u3002\u56e0\u6b64\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u8ba1\u7b97\u5f00\u9500\u901a\u5e38\u6bd4\u63d2\u5165\u6392\u5e8f\u66f4\u9ad8\u3002
    • \u9009\u62e9\u6392\u5e8f\u5728\u4efb\u4f55\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n^2)\\) \u3002\u5982\u679c\u7ed9\u5b9a\u4e00\u7ec4\u90e8\u5206\u6709\u5e8f\u7684\u6570\u636e\uff0c\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u6bd4\u9009\u62e9\u6392\u5e8f\u6548\u7387\u66f4\u9ad8\u3002
    • \u9009\u62e9\u6392\u5e8f\u4e0d\u7a33\u5b9a\uff0c\u65e0\u6cd5\u5e94\u7528\u4e8e\u591a\u7ea7\u6392\u5e8f\u3002
    "},{"location":"chapter_sorting/merge_sort/","title":"11.6 \u00a0 \u5f52\u5e76\u6392\u5e8f","text":"

    \u5f52\u5e76\u6392\u5e8f\uff08merge sort\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5305\u542b\u56fe 11-10 \u6240\u793a\u7684\u201c\u5212\u5206\u201d\u548c\u201c\u5408\u5e76\u201d\u9636\u6bb5\u3002

    1. \u5212\u5206\u9636\u6bb5\uff1a\u901a\u8fc7\u9012\u5f52\u4e0d\u65ad\u5730\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5904\u5206\u5f00\uff0c\u5c06\u957f\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u8f6c\u6362\u4e3a\u77ed\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u3002
    2. \u5408\u5e76\u9636\u6bb5\uff1a\u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u5212\u5206\uff0c\u5f00\u59cb\u5408\u5e76\uff0c\u6301\u7eed\u5730\u5c06\u5de6\u53f3\u4e24\u4e2a\u8f83\u77ed\u7684\u6709\u5e8f\u6570\u7ec4\u5408\u5e76\u4e3a\u4e00\u4e2a\u8f83\u957f\u7684\u6709\u5e8f\u6570\u7ec4\uff0c\u76f4\u81f3\u7ed3\u675f\u3002

    \u56fe 11-10 \u00a0 \u5f52\u5e76\u6392\u5e8f\u7684\u5212\u5206\u4e0e\u5408\u5e76\u9636\u6bb5

    "},{"location":"chapter_sorting/merge_sort/#1161","title":"11.6.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u5982\u56fe 11-11 \u6240\u793a\uff0c\u201c\u5212\u5206\u9636\u6bb5\u201d\u4ece\u9876\u81f3\u5e95\u9012\u5f52\u5730\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5207\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\u3002

    1. \u8ba1\u7b97\u6570\u7ec4\u4e2d\u70b9 mid \uff0c\u9012\u5f52\u5212\u5206\u5de6\u5b50\u6570\u7ec4\uff08\u533a\u95f4 [left, mid] \uff09\u548c\u53f3\u5b50\u6570\u7ec4\uff08\u533a\u95f4 [mid + 1, right] \uff09\u3002
    2. \u9012\u5f52\u6267\u884c\u6b65\u9aa4 1. \uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u533a\u95f4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u3002

    \u201c\u5408\u5e76\u9636\u6bb5\u201d\u4ece\u5e95\u81f3\u9876\u5730\u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u5408\u5e76\u4e3a\u4e00\u4e2a\u6709\u5e8f\u6570\u7ec4\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4ece\u957f\u5ea6\u4e3a 1 \u7684\u5b50\u6570\u7ec4\u5f00\u59cb\u5408\u5e76\uff0c\u5408\u5e76\u9636\u6bb5\u4e2d\u7684\u6bcf\u4e2a\u5b50\u6570\u7ec4\u90fd\u662f\u6709\u5e8f\u7684\u3002

    <1><2><3><4><5><6><7><8><9><10>

    \u56fe 11-11 \u00a0 \u5f52\u5e76\u6392\u5e8f\u6b65\u9aa4

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u5f52\u5e76\u6392\u5e8f\u4e0e\u4e8c\u53c9\u6811\u540e\u5e8f\u904d\u5386\u7684\u9012\u5f52\u987a\u5e8f\u662f\u4e00\u81f4\u7684\u3002

    • \u540e\u5e8f\u904d\u5386\uff1a\u5148\u9012\u5f52\u5de6\u5b50\u6811\uff0c\u518d\u9012\u5f52\u53f3\u5b50\u6811\uff0c\u6700\u540e\u5904\u7406\u6839\u8282\u70b9\u3002
    • \u5f52\u5e76\u6392\u5e8f\uff1a\u5148\u9012\u5f52\u5de6\u5b50\u6570\u7ec4\uff0c\u518d\u9012\u5f52\u53f3\u5b50\u6570\u7ec4\uff0c\u6700\u540e\u5904\u7406\u5408\u5e76\u3002

    \u5f52\u5e76\u6392\u5e8f\u7684\u5b9e\u73b0\u5982\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\u3002\u8bf7\u6ce8\u610f\uff0cnums \u7684\u5f85\u5408\u5e76\u533a\u95f4\u4e3a [left, right] \uff0c\u800c tmp \u7684\u5bf9\u5e94\u533a\u95f4\u4e3a [0, right - left] \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig merge_sort.py
    def merge(nums: list[int], left: int, mid: int, right: int):\n    \"\"\"\u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\"\"\"\n    # \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    # \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    tmp = [0] * (right - left + 1)\n    # \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    i, j, k = left, mid + 1, 0\n    # \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid and j <= right:\n        if nums[i] <= nums[j]:\n            tmp[k] = nums[i]\n            i += 1\n        else:\n            tmp[k] = nums[j]\n            j += 1\n        k += 1\n    # \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid:\n        tmp[k] = nums[i]\n        i += 1\n        k += 1\n    while j <= right:\n        tmp[k] = nums[j]\n        j += 1\n        k += 1\n    # \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in range(0, len(tmp)):\n        nums[left + k] = tmp[k]\n\ndef merge_sort(nums: list[int], left: int, right: int):\n    \"\"\"\u5f52\u5e76\u6392\u5e8f\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if left >= right:\n        return  # \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    # \u5212\u5206\u9636\u6bb5\n    mid = (left + right) // 2  # \u8ba1\u7b97\u4e2d\u70b9\n    merge_sort(nums, left, mid)  # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    merge_sort(nums, mid + 1, right)  # \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    # \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n
    merge_sort.cpp
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(vector<int> &nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    vector<int> tmp(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.size(); k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(vector<int> &nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.java
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(int[] nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int[] tmp = new int[right - left + 1];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(int[] nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2; // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.cs
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid Merge(int[] nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int[] tmp = new int[right - left + 1];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.Length; ++k) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid MergeSort(int[] nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return;       // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    MergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    MergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    Merge(nums, left, mid, right);\n}\n
    merge_sort.go
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunc merge(nums []int, left, mid, right int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    tmp := make([]int, right-left+1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    i, j, k := left, mid+1, 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    for i <= mid && j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i]\n            i++\n        } else {\n            tmp[k] = nums[j]\n            j++\n        }\n        k++\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    for i <= mid {\n        tmp[k] = nums[i]\n        i++\n        k++\n    }\n    for j <= right {\n        tmp[k] = nums[j]\n        j++\n        k++\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k := 0; k < len(tmp); k++ {\n        nums[left+k] = tmp[k]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunc mergeSort(nums []int, left, right int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right {\n        return\n    }\n    // \u5212\u5206\u9636\u6bb5\n    mid := (left + right) / 2\n    mergeSort(nums, left, mid)\n    mergeSort(nums, mid+1, right)\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n}\n
    merge_sort.swift
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunc merge(nums: inout [Int], left: Int, mid: Int, right: Int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    var tmp = Array(repeating: 0, count: right - left + 1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    var i = left, j = mid + 1, k = 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid, j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i]\n            i += 1\n        } else {\n            tmp[k] = nums[j]\n            j += 1\n        }\n        k += 1\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid {\n        tmp[k] = nums[i]\n        i += 1\n        k += 1\n    }\n    while j <= right {\n        tmp[k] = nums[j]\n        j += 1\n        k += 1\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in tmp.indices {\n        nums[left + k] = tmp[k]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunc mergeSort(nums: inout [Int], left: Int, right: Int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right { // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n        return\n    }\n    // \u5212\u5206\u9636\u6bb5\n    let mid = (left + right) / 2 // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums: &nums, left: left, right: mid) // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums: &nums, left: mid + 1, right: right) // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums: &nums, left: left, mid: mid, right: right)\n}\n
    merge_sort.js
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunction merge(nums, left, mid, right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    const tmp = new Array(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let i = left,\n        j = mid + 1,\n        k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunction mergeSort(nums, left, right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    let mid = Math.floor((left + right) / 2); // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.ts
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunction merge(nums: number[], left: number, mid: number, right: number): void {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    const tmp = new Array(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let i = left,\n        j = mid + 1,\n        k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunction mergeSort(nums: number[], left: number, right: number): void {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    let mid = Math.floor((left + right) / 2); // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.dart
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(List<int> nums, int left, int mid, int right) {\n  // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n  // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n  List<int> tmp = List.filled(right - left + 1, 0);\n  // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n  int i = left, j = mid + 1, k = 0;\n  // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while (i <= mid && j <= right) {\n    if (nums[i] <= nums[j])\n      tmp[k++] = nums[i++];\n    else\n      tmp[k++] = nums[j++];\n  }\n  // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while (i <= mid) {\n    tmp[k++] = nums[i++];\n  }\n  while (j <= right) {\n    tmp[k++] = nums[j++];\n  }\n  // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n  for (k = 0; k < tmp.length; k++) {\n    nums[left + k] = tmp[k];\n  }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(List<int> nums, int left, int right) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  // \u5212\u5206\u9636\u6bb5\n  int mid = (left + right) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\n  mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n  mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n  // \u5408\u5e76\u9636\u6bb5\n  merge(nums, left, mid, right);\n}\n
    merge_sort.rs
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfn merge(nums: &mut [i32], left: usize, mid: usize, right: usize) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    let tmp_size = right - left + 1;\n    let mut tmp = vec![0; tmp_size];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let (mut i, mut j, mut k) = (left, mid + 1, 0);\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid && j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i];\n            i += 1;\n        } else {\n            tmp[k] = nums[j];\n            j += 1;\n        }\n        k += 1;\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid {\n        tmp[k] = nums[i];\n        k += 1;\n        i += 1;\n    }\n    while j <= right {\n        tmp[k] = nums[j];\n        k += 1;\n        j += 1;\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in 0..tmp_size {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfn merge_sort(nums: &mut [i32], left: usize, right: usize) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right {\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    }\n\n    // \u5212\u5206\u9636\u6bb5\n    let mid = (left + right) / 2; // \u8ba1\u7b97\u4e2d\u70b9\n    merge_sort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    merge_sort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.c
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(int *nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int tmpSize = right - left + 1;\n    int *tmp = (int *)malloc(tmpSize * sizeof(int));\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmpSize; ++k) {\n        nums[left + k] = tmp[k];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(int *nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.kt
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfun merge(nums: IntArray, left: Int, mid: Int, right: Int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    val tmp = IntArray(right - left + 1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    var i = left\n    var j = mid + 1\n    var k = 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++]\n        else \n            tmp[k++] = nums[j++]\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++]\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++]\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (l in tmp.indices) {\n        nums[left + l] = tmp[l]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfun mergeSort(nums: IntArray, left: Int, right: Int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return  // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    val mid = (left + right) / 2 // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid) // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right) // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n}\n
    merge_sort.rb
    [class]{}-[func]{merge}\n\n[class]{}-[func]{merge_sort}\n
    merge_sort.zig
    // \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\n// \u5de6\u5b50\u6570\u7ec4\u533a\u95f4 [left, mid]\n// \u53f3\u5b50\u6570\u7ec4\u533a\u95f4 [mid + 1, right]\nfn merge(nums: []i32, left: usize, mid: usize, right: usize) !void {\n    // \u521d\u59cb\u5316\u8f85\u52a9\u6570\u7ec4\n    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);\n    defer mem_arena.deinit();\n    const mem_allocator = mem_arena.allocator();\n    var tmp = try mem_allocator.alloc(i32, right + 1 - left);\n    std.mem.copy(i32, tmp, nums[left..right+1]);\n    // \u5de6\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\u548c\u7ed3\u675f\u7d22\u5f15  \n    var leftStart = left - left;\n    var leftEnd = mid - left;\n    // \u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\u548c\u7ed3\u675f\u7d22\u5f15       \n    var rightStart = mid + 1 - left;\n    var rightEnd = right - left;\n    // i, j \u5206\u522b\u6307\u5411\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\u7684\u9996\u5143\u7d20\n    var i = leftStart;\n    var j = rightStart;\n    // \u901a\u8fc7\u8986\u76d6\u539f\u6570\u7ec4 nums \u6765\u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\n    var k = left;\n    while (k <= right) : (k += 1) {\n        // \u82e5\u201c\u5de6\u5b50\u6570\u7ec4\u5df2\u5168\u90e8\u5408\u5e76\u5b8c\u201d\uff0c\u5219\u9009\u53d6\u53f3\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 j++\n        if (i > leftEnd) {\n            nums[k] = tmp[j];\n            j += 1;\n        // \u5426\u5219\uff0c\u82e5\u201c\u53f3\u5b50\u6570\u7ec4\u5df2\u5168\u90e8\u5408\u5e76\u5b8c\u201d\u6216\u201c\u5de6\u5b50\u6570\u7ec4\u5143\u7d20 <= \u53f3\u5b50\u6570\u7ec4\u5143\u7d20\u201d\uff0c\u5219\u9009\u53d6\u5de6\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 i++\n        } else if  (j > rightEnd or tmp[i] <= tmp[j]) {\n            nums[k] = tmp[i];\n            i += 1;\n        // \u5426\u5219\uff0c\u82e5\u201c\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u672a\u5168\u90e8\u5408\u5e76\u5b8c\u201d\u4e14\u201c\u5de6\u5b50\u6570\u7ec4\u5143\u7d20 > \u53f3\u5b50\u6570\u7ec4\u5143\u7d20\u201d\uff0c\u5219\u9009\u53d6\u53f3\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 j++\n        } else {\n            nums[k] = tmp[j];\n            j += 1;\n        }\n    }\n}\n\n// \u5f52\u5e76\u6392\u5e8f\nfn mergeSort(nums: []i32, left: usize, right: usize) !void {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return;              // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    var mid = (left + right) / 2;           // \u8ba1\u7b97\u4e2d\u70b9\n    try mergeSort(nums, left, mid);         // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    try mergeSort(nums, mid + 1, right);    // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    try merge(nums, left, mid, right);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/merge_sort/#1162","title":"11.6.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5212\u5206\u4ea7\u751f\u9ad8\u5ea6\u4e3a \\(\\log n\\) \u7684\u9012\u5f52\u6811\uff0c\u6bcf\u5c42\u5408\u5e76\u7684\u603b\u64cd\u4f5c\u6570\u91cf\u4e3a \\(n\\) \uff0c\u56e0\u6b64\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u9012\u5f52\u6df1\u5ea6\u4e3a \\(\\log n\\) \uff0c\u4f7f\u7528 \\(O(\\log n)\\) \u5927\u5c0f\u7684\u6808\u5e27\u7a7a\u95f4\u3002\u5408\u5e76\u64cd\u4f5c\u9700\u8981\u501f\u52a9\u8f85\u52a9\u6570\u7ec4\u5b9e\u73b0\uff0c\u4f7f\u7528 \\(O(n)\\) \u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u5408\u5e76\u8fc7\u7a0b\u4e2d\uff0c\u76f8\u7b49\u5143\u7d20\u7684\u6b21\u5e8f\u4fdd\u6301\u4e0d\u53d8\u3002
    "},{"location":"chapter_sorting/merge_sort/#1163","title":"11.6.3 \u00a0 \u94fe\u8868\u6392\u5e8f","text":"

    \u5bf9\u4e8e\u94fe\u8868\uff0c\u5f52\u5e76\u6392\u5e8f\u76f8\u8f83\u4e8e\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\u5177\u6709\u663e\u8457\u4f18\u52bf\uff0c\u53ef\u4ee5\u5c06\u94fe\u8868\u6392\u5e8f\u4efb\u52a1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(1)\\) \u3002

    • \u5212\u5206\u9636\u6bb5\uff1a\u53ef\u4ee5\u4f7f\u7528\u201c\u8fed\u4ee3\u201d\u66ff\u4ee3\u201c\u9012\u5f52\u201d\u6765\u5b9e\u73b0\u94fe\u8868\u5212\u5206\u5de5\u4f5c\uff0c\u4ece\u800c\u7701\u53bb\u9012\u5f52\u4f7f\u7528\u7684\u6808\u5e27\u7a7a\u95f4\u3002
    • \u5408\u5e76\u9636\u6bb5\uff1a\u5728\u94fe\u8868\u4e2d\uff0c\u8282\u70b9\u589e\u5220\u64cd\u4f5c\u4ec5\u9700\u6539\u53d8\u5f15\u7528\uff08\u6307\u9488\uff09\u5373\u53ef\u5b9e\u73b0\uff0c\u56e0\u6b64\u5408\u5e76\u9636\u6bb5\uff08\u5c06\u4e24\u4e2a\u77ed\u6709\u5e8f\u94fe\u8868\u5408\u5e76\u4e3a\u4e00\u4e2a\u957f\u6709\u5e8f\u94fe\u8868\uff09\u65e0\u987b\u521b\u5efa\u989d\u5916\u94fe\u8868\u3002

    \u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u6bd4\u8f83\u590d\u6742\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u67e5\u9605\u76f8\u5173\u8d44\u6599\u8fdb\u884c\u5b66\u4e60\u3002

    "},{"location":"chapter_sorting/quick_sort/","title":"11.5 \u00a0 \u5feb\u901f\u6392\u5e8f","text":"

    \u5feb\u901f\u6392\u5e8f\uff08quick sort\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u8fd0\u884c\u9ad8\u6548\uff0c\u5e94\u7528\u5e7f\u6cdb\u3002

    \u5feb\u901f\u6392\u5e8f\u7684\u6838\u5fc3\u64cd\u4f5c\u662f\u201c\u54e8\u5175\u5212\u5206\u201d\uff0c\u5176\u76ee\u6807\u662f\uff1a\u9009\u62e9\u6570\u7ec4\u4e2d\u7684\u67d0\u4e2a\u5143\u7d20\u4f5c\u4e3a\u201c\u57fa\u51c6\u6570\u201d\uff0c\u5c06\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\u79fb\u5230\u5176\u5de6\u4fa7\uff0c\u800c\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\u79fb\u5230\u5176\u53f3\u4fa7\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u54e8\u5175\u5212\u5206\u7684\u6d41\u7a0b\u5982\u56fe 11-8 \u6240\u793a\u3002

    1. \u9009\u53d6\u6570\u7ec4\u6700\u5de6\u7aef\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u6570\uff0c\u521d\u59cb\u5316\u4e24\u4e2a\u6307\u9488 i \u548c j \u5206\u522b\u6307\u5411\u6570\u7ec4\u7684\u4e24\u7aef\u3002
    2. \u8bbe\u7f6e\u4e00\u4e2a\u5faa\u73af\uff0c\u5728\u6bcf\u8f6e\u4e2d\u4f7f\u7528 i\uff08j\uff09\u5206\u522b\u5bfb\u627e\u7b2c\u4e00\u4e2a\u6bd4\u57fa\u51c6\u6570\u5927\uff08\u5c0f\uff09\u7684\u5143\u7d20\uff0c\u7136\u540e\u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\u3002
    3. \u5faa\u73af\u6267\u884c\u6b65\u9aa4 2. \uff0c\u76f4\u5230 i \u548c j \u76f8\u9047\u65f6\u505c\u6b62\uff0c\u6700\u540e\u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u4e2a\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\u3002
    <1><2><3><4><5><6><7><8><9>

    \u56fe 11-8 \u00a0 \u54e8\u5175\u5212\u5206\u6b65\u9aa4

    \u54e8\u5175\u5212\u5206\u5b8c\u6210\u540e\uff0c\u539f\u6570\u7ec4\u88ab\u5212\u5206\u6210\u4e09\u90e8\u5206\uff1a\u5de6\u5b50\u6570\u7ec4\u3001\u57fa\u51c6\u6570\u3001\u53f3\u5b50\u6570\u7ec4\uff0c\u4e14\u6ee1\u8db3\u201c\u5de6\u5b50\u6570\u7ec4\u4efb\u610f\u5143\u7d20 \\(\\leq\\) \u57fa\u51c6\u6570 \\(\\leq\\) \u53f3\u5b50\u6570\u7ec4\u4efb\u610f\u5143\u7d20\u201d\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u63a5\u4e0b\u6765\u53ea\u9700\u5bf9\u8fd9\u4e24\u4e2a\u5b50\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\u3002

    \u5feb\u901f\u6392\u5e8f\u7684\u5206\u6cbb\u7b56\u7565

    \u54e8\u5175\u5212\u5206\u7684\u5b9e\u8d28\u662f\u5c06\u4e00\u4e2a\u8f83\u957f\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u7b80\u5316\u4e3a\u4e24\u4e2a\u8f83\u77ed\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def partition(self, nums: list[int], left: int, right: int) -> int:\n    \"\"\"\u54e8\u5175\u5212\u5206\"\"\"\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j = left, right\n    while i < j:\n        while i < j and nums[j] >= nums[left]:\n            j -= 1  # \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while i < j and nums[i] <= nums[left]:\n            i += 1  # \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        # \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    # \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i  # \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n
    quick_sort.cpp
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(vector<int> &nums, int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(vector<int> &nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.java
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(int[] nums, int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(int[] nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.cs
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid Swap(int[] nums, int i, int j) {\n    (nums[j], nums[i]) = (nums[i], nums[j]);\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint Partition(int[] nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        Swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    Swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.go
    /* \u54e8\u5175\u5212\u5206 */\nfunc (q *quickSort) partition(nums []int, left, right int) int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j := left, right\n    for i < j {\n        for i < j && nums[j] >= nums[left] {\n            j-- // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        for i < j && nums[i] <= nums[left] {\n            i++ // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    }\n    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.swift
    /* \u54e8\u5175\u5212\u5206 */\nfunc partition(nums: inout [Int], left: Int, right: Int) -> Int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while i < j {\n        while i < j, nums[j] >= nums[left] {\n            j -= 1 // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j, nums[i] <= nums[left] {\n            i += 1 // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swapAt(i, j) // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swapAt(i, left) // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.js
    /* \u5143\u7d20\u4ea4\u6362 */\nswap(nums, i, j) {\n    let tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\npartition(nums, left, right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.ts
    /* \u5143\u7d20\u4ea4\u6362 */\nswap(nums: number[], i: number, j: number): void {\n    let tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\npartition(nums: number[], left: number, right: number): number {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.dart
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid _swap(List<int> nums, int i, int j) {\n  int tmp = nums[i];\n  nums[i] = nums[j];\n  nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint _partition(List<int> nums, int left, int right) {\n  // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n  int i = left, j = right;\n  while (i < j) {\n    while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    _swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n  }\n  _swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n  return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rs
    /* \u54e8\u5175\u5212\u5206 */\nfn partition(nums: &mut [i32], left: usize, right: usize) -> usize {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let (mut i, mut j) = (left, right);\n    while i < j {\n        while i < j && nums[j] >= nums[left] {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j && nums[i] <= nums[left] {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swap(i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swap(i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.c
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(int nums[], int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(int nums[], int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n        swap(nums, i, j);\n    }\n    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    swap(nums, i, left);\n    // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n    return i;\n}\n
    quick_sort.kt
    /* \u5143\u7d20\u4ea4\u6362 */\nfun swap(nums: IntArray, i: Int, j: Int) {\n    val temp = nums[i]\n    nums[i] = nums[j]\n    nums[j] = temp\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nfun partition(nums: IntArray, left: Int, right: Int): Int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--           // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++           // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j)  // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left)   // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i              // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rb
    [class]{QuickSort}-[func]{partition}\n
    quick_sort.zig
    // \u5143\u7d20\u4ea4\u6362\nfn swap(nums: []i32, i: usize, j: usize) void {\n    var tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n// \u54e8\u5175\u5212\u5206\nfn partition(nums: []i32, left: usize, right: usize) usize {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left;\n    var j = right;\n    while (i < j) {\n        while (i < j and nums[j] >= nums[left]) j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j and nums[i] <= nums[left]) i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j);   // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;               // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/quick_sort/#1151","title":"11.5.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u5feb\u901f\u6392\u5e8f\u7684\u6574\u4f53\u6d41\u7a0b\u5982\u56fe 11-9 \u6240\u793a\u3002

    1. \u9996\u5148\uff0c\u5bf9\u539f\u6570\u7ec4\u6267\u884c\u4e00\u6b21\u201c\u54e8\u5175\u5212\u5206\u201d\uff0c\u5f97\u5230\u672a\u6392\u5e8f\u7684\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u3002
    2. \u7136\u540e\uff0c\u5bf9\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u5206\u522b\u9012\u5f52\u6267\u884c\u201c\u54e8\u5175\u5212\u5206\u201d\u3002
    3. \u6301\u7eed\u9012\u5f52\uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\uff0c\u4ece\u800c\u5b8c\u6210\u6574\u4e2a\u6570\u7ec4\u7684\u6392\u5e8f\u3002

    \u56fe 11-9 \u00a0 \u5feb\u901f\u6392\u5e8f\u6d41\u7a0b

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):\n    \"\"\"\u5feb\u901f\u6392\u5e8f\"\"\"\n    # \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right:\n        return\n    # \u54e8\u5175\u5212\u5206\n    pivot = self.partition(nums, left, right)\n    # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    self.quick_sort(nums, left, pivot - 1)\n    self.quick_sort(nums, pivot + 1, right)\n
    quick_sort.cpp
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(vector<int> &nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.java
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.cs
    /* \u5feb\u901f\u6392\u5e8f */\nvoid QuickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = Partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    QuickSort(nums, left, pivot - 1);\n    QuickSort(nums, pivot + 1, right);\n}\n
    quick_sort.go
    /* \u5feb\u901f\u6392\u5e8f */\nfunc (q *quickSort) quickSort(nums []int, left, right int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return\n    }\n    // \u54e8\u5175\u5212\u5206\n    pivot := q.partition(nums, left, right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    q.quickSort(nums, left, pivot-1)\n    q.quickSort(nums, pivot+1, right)\n}\n
    quick_sort.swift
    /* \u5feb\u901f\u6392\u5e8f */\nfunc quickSort(nums: inout [Int], left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return\n    }\n    // \u54e8\u5175\u5212\u5206\n    let pivot = partition(nums: &nums, left: left, right: right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums: &nums, left: left, right: pivot - 1)\n    quickSort(nums: &nums, left: pivot + 1, right: right)\n}\n
    quick_sort.js
    /* \u5feb\u901f\u6392\u5e8f */\nquickSort(nums, left, right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return;\n    // \u54e8\u5175\u5212\u5206\n    const pivot = this.partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    this.quickSort(nums, left, pivot - 1);\n    this.quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.ts
    /* \u5feb\u901f\u6392\u5e8f */\nquickSort(nums: number[], left: number, right: number): void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    const pivot = this.partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    this.quickSort(nums, left, pivot - 1);\n    this.quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.dart
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(List<int> nums, int left, int right) {\n  // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  if (left >= right) return;\n  // \u54e8\u5175\u5212\u5206\n  int pivot = _partition(nums, left, right);\n  // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n  quickSort(nums, left, pivot - 1);\n  quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.rs
    /* \u5feb\u901f\u6392\u5e8f */\npub fn quick_sort(left: i32, right: i32, nums: &mut [i32]) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    let pivot = Self::partition(nums, left as usize, right as usize) as i32;\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    Self::quick_sort(left, pivot - 1, nums);\n    Self::quick_sort(pivot + 1, right, nums);\n}\n
    quick_sort.c
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(int nums[], int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.kt
    /* \u5feb\u901f\u6392\u5e8f */\nfun quickSort(nums: IntArray, left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return\n    // \u54e8\u5175\u5212\u5206\n    val pivot = partition(nums, left, right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1)\n    quickSort(nums, pivot + 1, right)\n}\n
    quick_sort.rb
    [class]{QuickSort}-[func]{quick_sort}\n
    quick_sort.zig
    // \u5feb\u901f\u6392\u5e8f\nfn quickSort(nums: []i32, left: usize, right: usize) void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return;\n    // \u54e8\u5175\u5212\u5206\n    var pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/quick_sort/#1152","title":"11.5.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\)\u3001\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u54e8\u5175\u5212\u5206\u7684\u9012\u5f52\u5c42\u6570\u4e3a \\(\\log n\\) \uff0c\u6bcf\u5c42\u4e2d\u7684\u603b\u5faa\u73af\u6570\u4e3a \\(n\\) \uff0c\u603b\u4f53\u4f7f\u7528 \\(O(n \\log n)\\) \u65f6\u95f4\u3002\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u90fd\u5c06\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\u5212\u5206\u4e3a\u957f\u5ea6\u4e3a \\(0\\) \u548c \\(n - 1\\) \u7684\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u6b64\u65f6\u9012\u5f52\u5c42\u6570\u8fbe\u5230 \\(n\\) \uff0c\u6bcf\u5c42\u4e2d\u7684\u5faa\u73af\u6570\u4e3a \\(n\\) \uff0c\u603b\u4f53\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u5728\u8f93\u5165\u6570\u7ec4\u5b8c\u5168\u5012\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u8fbe\u5230\u6700\u5dee\u9012\u5f52\u6df1\u5ea6 \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002\u6392\u5e8f\u64cd\u4f5c\u662f\u5728\u539f\u6570\u7ec4\u4e0a\u8fdb\u884c\u7684\uff0c\u672a\u501f\u52a9\u989d\u5916\u6570\u7ec4\u3002
    • \u975e\u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u54e8\u5175\u5212\u5206\u7684\u6700\u540e\u4e00\u6b65\uff0c\u57fa\u51c6\u6570\u53ef\u80fd\u4f1a\u88ab\u4ea4\u6362\u81f3\u76f8\u7b49\u5143\u7d20\u7684\u53f3\u4fa7\u3002
    "},{"location":"chapter_sorting/quick_sort/#1153","title":"11.5.3 \u00a0 \u5feb\u901f\u6392\u5e8f\u4e3a\u4ec0\u4e48\u5feb","text":"

    \u4ece\u540d\u79f0\u4e0a\u5c31\u80fd\u770b\u51fa\uff0c\u5feb\u901f\u6392\u5e8f\u5728\u6548\u7387\u65b9\u9762\u5e94\u8be5\u5177\u6709\u4e00\u5b9a\u7684\u4f18\u52bf\u3002\u5c3d\u7ba1\u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e0e\u201c\u5f52\u5e76\u6392\u5e8f\u201d\u548c\u201c\u5806\u6392\u5e8f\u201d\u76f8\u540c\uff0c\u4f46\u901a\u5e38\u5feb\u901f\u6392\u5e8f\u7684\u6548\u7387\u66f4\u9ad8\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u51fa\u73b0\u6700\u5dee\u60c5\u51b5\u7684\u6982\u7387\u5f88\u4f4e\uff1a\u867d\u7136\u5feb\u901f\u6392\u5e8f\u7684\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u6ca1\u6709\u5f52\u5e76\u6392\u5e8f\u7a33\u5b9a\uff0c\u4f46\u5728\u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u80fd\u5728 \\(O(n \\log n)\\) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e0b\u8fd0\u884c\u3002
    • \u7f13\u5b58\u4f7f\u7528\u6548\u7387\u9ad8\uff1a\u5728\u6267\u884c\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u65f6\uff0c\u7cfb\u7edf\u53ef\u5c06\u6574\u4e2a\u5b50\u6570\u7ec4\u52a0\u8f7d\u5230\u7f13\u5b58\uff0c\u56e0\u6b64\u8bbf\u95ee\u5143\u7d20\u7684\u6548\u7387\u8f83\u9ad8\u3002\u800c\u50cf\u201c\u5806\u6392\u5e8f\u201d\u8fd9\u7c7b\u7b97\u6cd5\u9700\u8981\u8df3\u8dc3\u5f0f\u8bbf\u95ee\u5143\u7d20\uff0c\u4ece\u800c\u7f3a\u4e4f\u8fd9\u4e00\u7279\u6027\u3002
    • \u590d\u6742\u5ea6\u7684\u5e38\u6570\u7cfb\u6570\u5c0f\uff1a\u5728\u4e0a\u8ff0\u4e09\u79cd\u7b97\u6cd5\u4e2d\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u6bd4\u8f83\u3001\u8d4b\u503c\u3001\u4ea4\u6362\u7b49\u64cd\u4f5c\u7684\u603b\u6570\u91cf\u6700\u5c11\u3002\u8fd9\u4e0e\u201c\u63d2\u5165\u6392\u5e8f\u201d\u6bd4\u201c\u5192\u6ce1\u6392\u5e8f\u201d\u66f4\u5feb\u7684\u539f\u56e0\u7c7b\u4f3c\u3002
    "},{"location":"chapter_sorting/quick_sort/#1154","title":"11.5.4 \u00a0 \u57fa\u51c6\u6570\u4f18\u5316","text":"

    \u5feb\u901f\u6392\u5e8f\u5728\u67d0\u4e9b\u8f93\u5165\u4e0b\u7684\u65f6\u95f4\u6548\u7387\u53ef\u80fd\u964d\u4f4e\u3002\u4e3e\u4e00\u4e2a\u6781\u7aef\u4f8b\u5b50\uff0c\u5047\u8bbe\u8f93\u5165\u6570\u7ec4\u662f\u5b8c\u5168\u5012\u5e8f\u7684\uff0c\u7531\u4e8e\u6211\u4eec\u9009\u62e9\u6700\u5de6\u7aef\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u6570\uff0c\u90a3\u4e48\u5728\u54e8\u5175\u5212\u5206\u5b8c\u6210\u540e\uff0c\u57fa\u51c6\u6570\u88ab\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u53f3\u7aef\uff0c\u5bfc\u81f4\u5de6\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a \\(n - 1\\)\u3001\u53f3\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a \\(0\\) \u3002\u5982\u6b64\u9012\u5f52\u4e0b\u53bb\uff0c\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u540e\u90fd\u6709\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(0\\) \uff0c\u5206\u6cbb\u7b56\u7565\u5931\u6548\uff0c\u5feb\u901f\u6392\u5e8f\u9000\u5316\u4e3a\u201c\u5192\u6ce1\u6392\u5e8f\u201d\u7684\u8fd1\u4f3c\u5f62\u5f0f\u3002

    \u4e3a\u4e86\u5c3d\u91cf\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u53d1\u751f\uff0c\u6211\u4eec\u53ef\u4ee5\u4f18\u5316\u54e8\u5175\u5212\u5206\u4e2d\u7684\u57fa\u51c6\u6570\u7684\u9009\u53d6\u7b56\u7565\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u968f\u673a\u9009\u53d6\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u6570\u3002\u7136\u800c\uff0c\u5982\u679c\u8fd0\u6c14\u4e0d\u4f73\uff0c\u6bcf\u6b21\u90fd\u9009\u5230\u4e0d\u7406\u60f3\u7684\u57fa\u51c6\u6570\uff0c\u6548\u7387\u4ecd\u7136\u4e0d\u5c3d\u5982\u4eba\u610f\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u751f\u6210\u7684\u662f\u201c\u4f2a\u968f\u673a\u6570\u201d\u3002\u5982\u679c\u6211\u4eec\u9488\u5bf9\u4f2a\u968f\u673a\u6570\u5e8f\u5217\u6784\u5efa\u4e00\u4e2a\u7279\u5b9a\u7684\u6d4b\u8bd5\u6837\u4f8b\uff0c\u90a3\u4e48\u5feb\u901f\u6392\u5e8f\u7684\u6548\u7387\u4ecd\u7136\u53ef\u80fd\u52a3\u5316\u3002

    \u4e3a\u4e86\u8fdb\u4e00\u6b65\u6539\u8fdb\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u6570\u7ec4\u4e2d\u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\uff08\u901a\u5e38\u4e3a\u6570\u7ec4\u7684\u9996\u3001\u5c3e\u3001\u4e2d\u70b9\u5143\u7d20\uff09\uff0c\u5e76\u5c06\u8fd9\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\u4f5c\u4e3a\u57fa\u51c6\u6570\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u57fa\u51c6\u6570\u201c\u65e2\u4e0d\u592a\u5c0f\u4e5f\u4e0d\u592a\u5927\u201d\u7684\u6982\u7387\u5c06\u5927\u5e45\u63d0\u5347\u3002\u5f53\u7136\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u9009\u53d6\u66f4\u591a\u5019\u9009\u5143\u7d20\uff0c\u4ee5\u8fdb\u4e00\u6b65\u63d0\u9ad8\u7b97\u6cd5\u7684\u7a33\u5065\u6027\u3002\u91c7\u7528\u8fd9\u79cd\u65b9\u6cd5\u540e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u52a3\u5316\u81f3 \\(O(n^2)\\) \u7684\u6982\u7387\u5927\u5927\u964d\u4f4e\u3002

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:\n    \"\"\"\u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\"\"\"\n    l, m, r = nums[left], nums[mid], nums[right]\n    if (l <= m <= r) or (r <= m <= l):\n        return mid  # m \u5728 l \u548c r \u4e4b\u95f4\n    if (m <= l <= r) or (r <= l <= m):\n        return left  # l \u5728 m \u548c r \u4e4b\u95f4\n    return right\n\ndef partition(self, nums: list[int], left: int, right: int) -> int:\n    \"\"\"\u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09\"\"\"\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    med = self.median_three(nums, left, (left + right) // 2, right)\n    # \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums[left], nums[med] = nums[med], nums[left]\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j = left, right\n    while i < j:\n        while i < j and nums[j] >= nums[left]:\n            j -= 1  # \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while i < j and nums[i] <= nums[left]:\n            i += 1  # \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        # \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    # \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i  # \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n
    quick_sort.cpp
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(vector<int> &nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partition(vector<int> &nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.java
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(int[] nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partition(int[] nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.cs
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint MedianThree(int[] nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint Partition(int[] nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = MedianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    Swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        Swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    Swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.go
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfunc (q *quickSortMedian) medianThree(nums []int, left, mid, right int) int {\n    l, m, r := nums[left], nums[mid], nums[right]\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09*/\nfunc (q *quickSortMedian) partition(nums []int, left, right int) int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    med := q.medianThree(nums, left, (left+right)/2, right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums[left], nums[med] = nums[med], nums[left]\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j := left, right\n    for i < j {\n        for i < j && nums[j] >= nums[left] {\n            j-- //\u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        for i < j && nums[i] <= nums[left] {\n            i++ //\u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        //\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    }\n    //\u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i //\u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.swift
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfunc medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {\n    let l = nums[left]\n    let m = nums[mid]\n    let r = nums[right]\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfunc partitionMedian(nums: inout [Int], left: Int, right: Int) -> Int {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums.swapAt(left, med)\n    return partition(nums: &nums, left: left, right: right)\n}\n
    quick_sort.js
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nmedianThree(nums, left, mid, right) {\n    let l = nums[left],\n        m = nums[mid],\n        r = nums[right];\n    // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;\n    // l \u5728 m \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\npartition(nums, left, right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = this.medianThree(\n        nums,\n        left,\n        Math.floor((left + right) / 2),\n        right\n    );\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    this.swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.ts
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nmedianThree(\n    nums: number[],\n    left: number,\n    mid: number,\n    right: number\n): number {\n    let l = nums[left],\n        m = nums[mid],\n        r = nums[right];\n    // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;\n    // l \u5728 m \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\npartition(nums: number[], left: number, right: number): number {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = this.medianThree(\n        nums,\n        left,\n        Math.floor((left + right) / 2),\n        right\n    );\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    this.swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.dart
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint _medianThree(List<int> nums, int left, int mid, int right) {\n  int l = nums[left], m = nums[mid], r = nums[right];\n  if ((l <= m && m <= r) || (r <= m && m <= l))\n    return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n  if ((m <= l && l <= r) || (r <= l && l <= m))\n    return left; // l \u5728 m \u548c r \u4e4b\u95f4\n  return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint _partition(List<int> nums, int left, int right) {\n  // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n  int med = _medianThree(nums, left, (left + right) ~/ 2, right);\n  // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n  _swap(nums, left, med);\n  // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n  int i = left, j = right;\n  while (i < j) {\n    while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    _swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n  }\n  _swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n  return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rs
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfn median_three(nums: &mut [i32], left: usize, mid: usize, right: usize) -> usize {\n    let (l, m, r) = (nums[left], nums[mid], nums[right]);\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfn partition(nums: &mut [i32], left: usize, right: usize) -> usize {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = Self::median_three(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums.swap(left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let (mut i, mut j) = (left, right);\n    while i < j {\n        while i < j && nums[j] >= nums[left] {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j && nums[i] <= nums[left] {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swap(i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swap(i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.c
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(int nums[], int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partitionMedian(int nums[], int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.kt
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfun medianThree(nums: IntArray, left: Int, mid: Int, right: Int): Int {\n    val l = nums[left]\n    val m = nums[mid]\n    val r = nums[right]\n    if ((m in l..r) || (m in r..l))\n        return mid  // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l in m..r) || (l in r..m))\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfun partitionMedian(nums: IntArray, left: Int, right: Int): Int {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    val med = medianThree(nums, left, (left + right) / 2, right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med)\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--                      // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++                      // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j)             // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left)              // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i                         // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rb
    [class]{QuickSortMedian}-[func]{median_three}\n\n[class]{QuickSortMedian}-[func]{partition}\n
    quick_sort.zig
    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\nfn medianThree(nums: []i32, left: usize, mid: usize, right: usize) usize {\n    var l = nums[left];\n    var m = nums[mid];\n    var r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n// \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09\nfn partition(nums: []i32, left: usize, right: usize) usize {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    var med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left;\n    var j = right;\n    while (i < j) {\n        while (i < j and nums[j] >= nums[left]) j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j and nums[i] <= nums[left]) i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j);   // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;               // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/quick_sort/#1155","title":"11.5.5 \u00a0 \u5c3e\u9012\u5f52\u4f18\u5316","text":"

    \u5728\u67d0\u4e9b\u8f93\u5165\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u53ef\u80fd\u5360\u7528\u7a7a\u95f4\u8f83\u591a\u3002\u4ee5\u5b8c\u5168\u6709\u5e8f\u7684\u8f93\u5165\u6570\u7ec4\u4e3a\u4f8b\uff0c\u8bbe\u9012\u5f52\u4e2d\u7684\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a \\(m\\) \uff0c\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u90fd\u5c06\u4ea7\u751f\u957f\u5ea6\u4e3a \\(0\\) \u7684\u5de6\u5b50\u6570\u7ec4\u548c\u957f\u5ea6\u4e3a \\(m - 1\\) \u7684\u53f3\u5b50\u6570\u7ec4\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u4e00\u5c42\u9012\u5f52\u8c03\u7528\u51cf\u5c11\u7684\u95ee\u9898\u89c4\u6a21\u975e\u5e38\u5c0f\uff08\u53ea\u51cf\u5c11\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u9012\u5f52\u6811\u7684\u9ad8\u5ea6\u4f1a\u8fbe\u5230 \\(n - 1\\) \uff0c\u6b64\u65f6\u9700\u8981\u5360\u7528 \\(O(n)\\) \u5927\u5c0f\u7684\u6808\u5e27\u7a7a\u95f4\u3002

    \u4e3a\u4e86\u9632\u6b62\u6808\u5e27\u7a7a\u95f4\u7684\u7d2f\u79ef\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u6bcf\u8f6e\u54e8\u5175\u6392\u5e8f\u5b8c\u6210\u540e\uff0c\u6bd4\u8f83\u4e24\u4e2a\u5b50\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u4ec5\u5bf9\u8f83\u77ed\u7684\u5b50\u6570\u7ec4\u8fdb\u884c\u9012\u5f52\u3002\u7531\u4e8e\u8f83\u77ed\u5b50\u6570\u7ec4\u7684\u957f\u5ea6\u4e0d\u4f1a\u8d85\u8fc7 \\(n / 2\\) \uff0c\u56e0\u6b64\u8fd9\u79cd\u65b9\u6cd5\u80fd\u786e\u4fdd\u9012\u5f52\u6df1\u5ea6\u4e0d\u8d85\u8fc7 \\(\\log n\\) \uff0c\u4ece\u800c\u5c06\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(\\log n)\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):\n    \"\"\"\u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09\"\"\"\n    # \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right:\n        # \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        pivot = self.partition(nums, left, right)\n        # \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot - left < right - pivot:\n            self.quick_sort(nums, left, pivot - 1)  # \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1  # \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        else:\n            self.quick_sort(nums, pivot + 1, right)  # \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1  # \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n
    quick_sort.cpp
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(vector<int> &nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1;                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.java
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.cs
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid QuickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = Partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            QuickSort(nums, left, pivot - 1);  // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;  // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            QuickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.go
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09*/\nfunc (q *quickSortTailCall) quickSort(nums []int, left, right int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    for left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        pivot := q.partition(nums, left, right)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot-left < right-pivot {\n            q.quickSort(nums, left, pivot-1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            q.quickSort(nums, pivot+1, right) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.swift
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nfunc quickSortTailCall(nums: inout [Int], left: Int, right: Int) {\n    var left = left\n    var right = right\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = partition(nums: &nums, left: left, right: right)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left) < (right - pivot) {\n            quickSortTailCall(nums: &nums, left: left, right: pivot - 1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSortTailCall(nums: &nums, left: pivot + 1, right: right) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.js
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nquickSort(nums, left, right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = this.partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            this.quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            this.quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.ts
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nquickSort(nums: number[], left: number, right: number): void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = this.partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            this.quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            this.quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.dart
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(List<int> nums, int left, int right) {\n  // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n  while (left < right) {\n    // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n    int pivot = _partition(nums, left, right);\n    // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n    if (pivot - left < right - pivot) {\n      quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n      left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n    } else {\n      quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n      right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n    }\n  }\n}\n
    quick_sort.rs
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\npub fn quick_sort(mut left: i32, mut right: i32, nums: &mut [i32]) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = Self::partition(nums, left as usize, right as usize) as i32;\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot - left < right - pivot {\n            Self::quick_sort(left, pivot - 1, nums); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            Self::quick_sort(pivot + 1, right, nums); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.c
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSortTailCall(int nums[], int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            quickSortTailCall(nums, left, pivot - 1);\n            // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n            left = pivot + 1;\n        } else {\n            // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            quickSortTailCall(nums, pivot + 1, right);\n            // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n            right = pivot - 1;\n        }\n    }\n}\n
    quick_sort.kt
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nfun quickSortTailCall(nums: IntArray, left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    var l = left\n    var r = right\n    while (l < r) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        val pivot = partition(nums, l, r)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - l < r - pivot) {\n            quickSort(nums, l, pivot - 1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            l = pivot + 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, r) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            r = pivot - 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.rb
    [class]{QuickSortTailCall}-[func]{quick_sort}\n
    quick_sort.zig
    // \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09\nfn quickSort(nums: []i32, left_: usize, right_: usize) void {\n    var left = left_;\n    var right = right_;\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        var pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1);   // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;                   // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right);  // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1;                  // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/radix_sort/","title":"11.10 \u00a0 \u57fa\u6570\u6392\u5e8f","text":"

    \u4e0a\u4e00\u8282\u4ecb\u7ecd\u4e86\u8ba1\u6570\u6392\u5e8f\uff0c\u5b83\u9002\u7528\u4e8e\u6570\u636e\u91cf \\(n\\) \u8f83\u5927\u4f46\u6570\u636e\u8303\u56f4 \\(m\\) \u8f83\u5c0f\u7684\u60c5\u51b5\u3002\u5047\u8bbe\u6211\u4eec\u9700\u8981\u5bf9 \\(n = 10^6\\) \u4e2a\u5b66\u53f7\u8fdb\u884c\u6392\u5e8f\uff0c\u800c\u5b66\u53f7\u662f\u4e00\u4e2a \\(8\\) \u4f4d\u6570\u5b57\uff0c\u8fd9\u610f\u5473\u7740\u6570\u636e\u8303\u56f4 \\(m = 10^8\\) \u975e\u5e38\u5927\uff0c\u4f7f\u7528\u8ba1\u6570\u6392\u5e8f\u9700\u8981\u5206\u914d\u5927\u91cf\u5185\u5b58\u7a7a\u95f4\uff0c\u800c\u57fa\u6570\u6392\u5e8f\u53ef\u4ee5\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u3002

    \u57fa\u6570\u6392\u5e8f\uff08radix sort\uff09\u7684\u6838\u5fc3\u601d\u60f3\u4e0e\u8ba1\u6570\u6392\u5e8f\u4e00\u81f4\uff0c\u4e5f\u901a\u8fc7\u7edf\u8ba1\u4e2a\u6570\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u57fa\u6570\u6392\u5e8f\u5229\u7528\u6570\u5b57\u5404\u4f4d\u4e4b\u95f4\u7684\u9012\u8fdb\u5173\u7cfb\uff0c\u4f9d\u6b21\u5bf9\u6bcf\u4e00\u4f4d\u8fdb\u884c\u6392\u5e8f\uff0c\u4ece\u800c\u5f97\u5230\u6700\u7ec8\u7684\u6392\u5e8f\u7ed3\u679c\u3002

    "},{"location":"chapter_sorting/radix_sort/#11101","title":"11.10.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u4ee5\u5b66\u53f7\u6570\u636e\u4e3a\u4f8b\uff0c\u5047\u8bbe\u6570\u5b57\u7684\u6700\u4f4e\u4f4d\u662f\u7b2c \\(1\\) \u4f4d\uff0c\u6700\u9ad8\u4f4d\u662f\u7b2c \\(8\\) \u4f4d\uff0c\u57fa\u6570\u6392\u5e8f\u7684\u6d41\u7a0b\u5982\u56fe 11-18 \u6240\u793a\u3002

    1. \u521d\u59cb\u5316\u4f4d\u6570 \\(k = 1\\) \u3002
    2. \u5bf9\u5b66\u53f7\u7684\u7b2c \\(k\\) \u4f4d\u6267\u884c\u201c\u8ba1\u6570\u6392\u5e8f\u201d\u3002\u5b8c\u6210\u540e\uff0c\u6570\u636e\u4f1a\u6839\u636e\u7b2c \\(k\\) \u4f4d\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u3002
    3. \u5c06 \\(k\\) \u589e\u52a0 \\(1\\) \uff0c\u7136\u540e\u8fd4\u56de\u6b65\u9aa4 2. \u7ee7\u7eed\u8fed\u4ee3\uff0c\u76f4\u5230\u6240\u6709\u4f4d\u90fd\u6392\u5e8f\u5b8c\u6210\u540e\u7ed3\u675f\u3002

    \u56fe 11-18 \u00a0 \u57fa\u6570\u6392\u5e8f\u7b97\u6cd5\u6d41\u7a0b

    \u4e0b\u9762\u5256\u6790\u4ee3\u7801\u5b9e\u73b0\u3002\u5bf9\u4e8e\u4e00\u4e2a \\(d\\) \u8fdb\u5236\u7684\u6570\u5b57 \\(x\\) \uff0c\u8981\u83b7\u53d6\u5176\u7b2c \\(k\\) \u4f4d \\(x_k\\) \uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u8ba1\u7b97\u516c\u5f0f\uff1a

    \\[ x_k = \\lfloor\\frac{x}{d^{k-1}}\\rfloor \\bmod d \\]

    \u5176\u4e2d \\(\\lfloor a \\rfloor\\) \u8868\u793a\u5bf9\u6d6e\u70b9\u6570 \\(a\\) \u5411\u4e0b\u53d6\u6574\uff0c\u800c \\(\\bmod \\: d\\) \u8868\u793a\u5bf9 \\(d\\) \u53d6\u6a21\uff08\u53d6\u4f59\uff09\u3002\u5bf9\u4e8e\u5b66\u53f7\u6570\u636e\uff0c\\(d = 10\\) \u4e14 \\(k \\in [1, 8]\\) \u3002

    \u6b64\u5916\uff0c\u6211\u4eec\u9700\u8981\u5c0f\u5e45\u6539\u52a8\u8ba1\u6570\u6392\u5e8f\u4ee3\u7801\uff0c\u4f7f\u4e4b\u53ef\u4ee5\u6839\u636e\u6570\u5b57\u7684\u7b2c \\(k\\) \u4f4d\u8fdb\u884c\u6392\u5e8f\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig radix_sort.py
    def digit(num: int, exp: int) -> int:\n    \"\"\"\u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1)\"\"\"\n    # \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num // exp) % 10\n\ndef counting_sort_digit(nums: list[int], exp: int):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09\"\"\"\n    # \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    counter = [0] * 10\n    n = len(nums)\n    # \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in range(n):\n        d = digit(nums[i], exp)  # \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1  # \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    # \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in range(1, 10):\n        counter[i] += counter[i - 1]\n    # \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    res = [0] * n\n    for i in range(n - 1, -1, -1):\n        d = digit(nums[i], exp)\n        j = counter[d] - 1  # \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]  # \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1  # \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    # \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in range(n):\n        nums[i] = res[i]\n\ndef radix_sort(nums: list[int]):\n    \"\"\"\u57fa\u6570\u6392\u5e8f\"\"\"\n    # \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    m = max(nums)\n    # \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    exp = 1\n    while exp <= m:\n        # \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        # k = 1 -> exp = 1\n        # k = 2 -> exp = 10\n        # \u5373 exp = 10^(k-1)\n        counting_sort_digit(nums, exp)\n        exp *= 10\n
    radix_sort.cpp
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(vector<int> &nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    vector<int> counter(10, 0);\n    int n = nums.size();\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    vector<int> res(n, 0);\n    for (int i = n - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++)\n        nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(vector<int> &nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = *max_element(nums.begin(), nums.end());\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10)\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n}\n
    radix_sort.java
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(int[] nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int[] counter = new int[10];\n    int n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++)\n        nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(int[] nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = Integer.MIN_VALUE;\n    for (int num : nums)\n        if (num > m)\n            m = num;\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.cs
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint Digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid CountingSortDigit(int[] nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int[] counter = new int[10];\n    int n = nums.Length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = Digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int d = Digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid RadixSort(int[] nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = int.MinValue;\n    foreach (int num in nums) {\n        if (num > m) m = num;\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        CountingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.go
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunc digit(num, exp int) int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunc countingSortDigit(nums []int, exp int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    counter := make([]int, 10)\n    n := len(nums)\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i := 0; i < n; i++ {\n        d := digit(nums[i], exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++             // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i := 1; i < 10; i++ {\n        counter[i] += counter[i-1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    res := make([]int, n)\n    for i := n - 1; i >= 0; i-- {\n        d := digit(nums[i], exp)\n        j := counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]    // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--        // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i := 0; i < n; i++ {\n        nums[i] = res[i]\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunc radixSort(nums []int) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    max := math.MinInt\n    for _, num := range nums {\n        if num > max {\n            max = num\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for exp := 1; max >= exp; exp *= 10 {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp)\n    }\n}\n
    radix_sort.swift
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunc digit(num: Int, exp: Int) -> Int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunc countingSortDigit(nums: inout [Int], exp: Int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    var counter = Array(repeating: 0, count: 10)\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in nums.indices {\n        let d = digit(num: nums[i], exp: exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1 // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in 1 ..< 10 {\n        counter[i] += counter[i - 1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    var res = Array(repeating: 0, count: nums.count)\n    for i in nums.indices.reversed() {\n        let d = digit(num: nums[i], exp: exp)\n        let j = counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i] // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1 // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in nums.indices {\n        nums[i] = res[i]\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunc radixSort(nums: inout [Int]) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m = Int.min\n    for num in nums {\n        if num > m {\n            m = num\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for exp in sequence(first: 1, next: { m >= ($0 * 10) ? $0 * 10 : nil }) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums: &nums, exp: exp)\n    }\n}\n
    radix_sort.js
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunction digit(num, exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return Math.floor(num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunction countingSortDigit(nums, exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    const counter = new Array(10).fill(0);\n    const n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (let i = 0; i < n; i++) {\n        const d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (let i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    const res = new Array(n).fill(0);\n    for (let i = n - 1; i >= 0; i--) {\n        const d = digit(nums[i], exp);\n        const j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunction radixSort(nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = Number.MIN_VALUE;\n    for (const num of nums) {\n        if (num > m) {\n            m = num;\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (let exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.ts
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunction digit(num: number, exp: number): number {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return Math.floor(num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunction countingSortDigit(nums: number[], exp: number): void {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    const counter = new Array(10).fill(0);\n    const n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (let i = 0; i < n; i++) {\n        const d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (let i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    const res = new Array(n).fill(0);\n    for (let i = n - 1; i >= 0; i--) {\n        const d = digit(nums[i], exp);\n        const j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunction radixSort(nums: number[]): void {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = Number.MIN_VALUE;\n    for (const num of nums) {\n        if (num > m) {\n            m = num;\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (let exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.dart
    /* \u83b7\u53d6\u5143\u7d20 _num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int _num, int exp) {\n  // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n  return (_num ~/ exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(List<int> nums, int exp) {\n  // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n  List<int> counter = List<int>.filled(10, 0);\n  int n = nums.length;\n  // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  for (int i = 0; i < n; i++) {\n    int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n    counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n  }\n  // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n  for (int i = 1; i < 10; i++) {\n    counter[i] += counter[i - 1];\n  }\n  // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n  List<int> res = List<int>.filled(n, 0);\n  for (int i = n - 1; i >= 0; i--) {\n    int d = digit(nums[i], exp);\n    int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n    res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n    counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n  }\n  // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n  for (int i = 0; i < n; i++) nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(List<int> nums) {\n  // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n  // dart \u4e2d int \u7684\u957f\u5ea6\u662f 64 \u4f4d\u7684\n  int m = -1 << 63;\n  for (int _num in nums) if (_num > m) m = _num;\n  // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n  for (int exp = 1; exp <= m; exp *= 10)\n    // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n    // k = 1 -> exp = 1\n    // k = 2 -> exp = 10\n    // \u5373 exp = 10^(k-1)\n    countingSortDigit(nums, exp);\n}\n
    radix_sort.rs
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfn digit(num: i32, exp: i32) -> usize {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return ((num / exp) % 10) as usize;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfn counting_sort_digit(nums: &mut [i32], exp: i32) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    let mut counter = [0; 10];\n    let n = nums.len();\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in 0..n {\n        let d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in 1..10 {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    let mut res = vec![0; n];\n    for i in (0..n).rev() {\n        let d = digit(nums[i], exp);\n        let j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in 0..n {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfn radix_sort(nums: &mut [i32]) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = *nums.into_iter().max().unwrap();\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    let mut exp = 1;\n    while exp <= m {\n        counting_sort_digit(nums, exp);\n        exp *= 10;\n    }\n}\n
    radix_sort.c
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(int nums[], int size, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int *counter = (int *)malloc((sizeof(int) * 10));\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < size; i++) {\n        // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        int d = digit(nums[i], exp);\n        // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n        counter[d]++;\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int *res = (int *)malloc(sizeof(int) * size);\n    for (int i = size - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < size; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(int nums[], int size) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int max = INT32_MIN;\n    for (size_t i = 0; i < size - 1; i++) {\n        if (nums[i] > max) {\n            max = nums[i];\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; max >= exp; exp *= 10)\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, size, exp);\n}\n
    radix_sort.kt
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfun digit(num: Int, exp: Int): Int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfun countingSortDigit(nums: IntArray, exp: Int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    val counter = IntArray(10)\n    val n = nums.size\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (i in 0..<n) {\n        val d = digit(nums[i], exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (i in 1..9) {\n        counter[i] += counter[i - 1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    val res = IntArray(n)\n    for (i in n - 1 downTo 0) {\n        val d = digit(nums[i], exp)\n        val j = counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (i in 0..<n)\n        nums[i] = res[i]\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfun radixSort(nums: IntArray) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m = Int.MIN_VALUE\n    for (num in nums) if (num > m) m = num\n    var exp = 1\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    while (exp <= m) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp)\n        exp *= 10\n    }\n}\n
    radix_sort.rb
    [class]{}-[func]{digit}\n\n[class]{}-[func]{counting_sort_digit}\n\n[class]{}-[func]{radix_sort}\n
    radix_sort.zig
    // \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1)\nfn digit(num: i32, exp: i32) i32 {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return @mod(@divFloor(num, exp), 10);\n}\n\n// \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09\nfn countingSortDigit(nums: []i32, exp: i32) !void {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);\n    // defer mem_arena.deinit();\n    const mem_allocator = mem_arena.allocator();\n    var counter = try mem_allocator.alloc(usize, 10);\n    @memset(counter, 0);\n    var n = nums.len;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (nums) |num| {\n        var d: u32 = @bitCast(digit(num, exp)); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    var i: usize = 1;\n    while (i < 10) : (i += 1) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    var res = try mem_allocator.alloc(i32, n);\n    i = n - 1;\n    while (i >= 0) : (i -= 1) {\n        var d: u32 = @bitCast(digit(nums[i], exp));\n        var j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1;        // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n        if (i == 0) break;\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    i = 0;\n    while (i < n) : (i += 1) {\n        nums[i] = res[i];\n    }\n}\n\n// \u57fa\u6570\u6392\u5e8f\nfn radixSort(nums: []i32) !void {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m: i32 = std.math.minInt(i32);\n    for (nums) |num| {\n        if (num > m) m = num;\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    var exp: i32 = 1;\n    while (exp <= m) : (exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        try countingSortDigit(nums, exp);    \n    }\n} \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4e3a\u4ec0\u4e48\u4ece\u6700\u4f4e\u4f4d\u5f00\u59cb\u6392\u5e8f\uff1f

    \u5728\u8fde\u7eed\u7684\u6392\u5e8f\u8f6e\u6b21\u4e2d\uff0c\u540e\u4e00\u8f6e\u6392\u5e8f\u4f1a\u8986\u76d6\u524d\u4e00\u8f6e\u6392\u5e8f\u7684\u7ed3\u679c\u3002\u4e3e\u4f8b\u6765\u8bf4\uff0c\u5982\u679c\u7b2c\u4e00\u8f6e\u6392\u5e8f\u7ed3\u679c \\(a < b\\) \uff0c\u800c\u7b2c\u4e8c\u8f6e\u6392\u5e8f\u7ed3\u679c \\(a > b\\) \uff0c\u90a3\u4e48\u7b2c\u4e8c\u8f6e\u7684\u7ed3\u679c\u5c06\u53d6\u4ee3\u7b2c\u4e00\u8f6e\u7684\u7ed3\u679c\u3002\u7531\u4e8e\u6570\u5b57\u7684\u9ad8\u4f4d\u4f18\u5148\u7ea7\u9ad8\u4e8e\u4f4e\u4f4d\uff0c\u56e0\u6b64\u5e94\u8be5\u5148\u6392\u5e8f\u4f4e\u4f4d\u518d\u6392\u5e8f\u9ad8\u4f4d\u3002

    "},{"location":"chapter_sorting/radix_sort/#11102","title":"11.10.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"

    \u76f8\u8f83\u4e8e\u8ba1\u6570\u6392\u5e8f\uff0c\u57fa\u6570\u6392\u5e8f\u9002\u7528\u4e8e\u6570\u503c\u8303\u56f4\u8f83\u5927\u7684\u60c5\u51b5\uff0c\u4f46\u524d\u63d0\u662f\u6570\u636e\u5fc5\u987b\u53ef\u4ee5\u8868\u793a\u4e3a\u56fa\u5b9a\u4f4d\u6570\u7684\u683c\u5f0f\uff0c\u4e14\u4f4d\u6570\u4e0d\u80fd\u8fc7\u5927\u3002\u4f8b\u5982\uff0c\u6d6e\u70b9\u6570\u4e0d\u9002\u5408\u4f7f\u7528\u57fa\u6570\u6392\u5e8f\uff0c\u56e0\u4e3a\u5176\u4f4d\u6570 \\(k\\) \u8fc7\u5927\uff0c\u53ef\u80fd\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(nk) \\gg O(n^2)\\) \u3002

    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nk)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u8bbe\u6570\u636e\u91cf\u4e3a \\(n\\)\u3001\u6570\u636e\u4e3a \\(d\\) \u8fdb\u5236\u3001\u6700\u5927\u4f4d\u6570\u4e3a \\(k\\) \uff0c\u5219\u5bf9\u67d0\u4e00\u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\u4f7f\u7528 \\(O(n + d)\\) \u65f6\u95f4\uff0c\u6392\u5e8f\u6240\u6709 \\(k\\) \u4f4d\u4f7f\u7528 \\(O((n + d)k)\\) \u65f6\u95f4\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\\(d\\) \u548c \\(k\\) \u90fd\u76f8\u5bf9\u8f83\u5c0f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u5411 \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + d)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u4e0e\u8ba1\u6570\u6392\u5e8f\u76f8\u540c\uff0c\u57fa\u6570\u6392\u5e8f\u9700\u8981\u501f\u52a9\u957f\u5ea6\u4e3a \\(n\\) \u548c \\(d\\) \u7684\u6570\u7ec4 res \u548c counter \u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u5f53\u8ba1\u6570\u6392\u5e8f\u7a33\u5b9a\u65f6\uff0c\u57fa\u6570\u6392\u5e8f\u4e5f\u7a33\u5b9a\uff1b\u5f53\u8ba1\u6570\u6392\u5e8f\u4e0d\u7a33\u5b9a\u65f6\uff0c\u57fa\u6570\u6392\u5e8f\u65e0\u6cd5\u4fdd\u8bc1\u5f97\u5230\u6b63\u786e\u7684\u6392\u5e8f\u7ed3\u679c\u3002
    "},{"location":"chapter_sorting/selection_sort/","title":"11.2 \u00a0 \u9009\u62e9\u6392\u5e8f","text":"

    \u9009\u62e9\u6392\u5e8f\uff08selection sort\uff09\u7684\u5de5\u4f5c\u539f\u7406\u975e\u5e38\u7b80\u5355\uff1a\u5f00\u542f\u4e00\u4e2a\u5faa\u73af\uff0c\u6bcf\u8f6e\u4ece\u672a\u6392\u5e8f\u533a\u95f4\u9009\u62e9\u6700\u5c0f\u7684\u5143\u7d20\uff0c\u5c06\u5176\u653e\u5230\u5df2\u6392\u5e8f\u533a\u95f4\u7684\u672b\u5c3e\u3002

    \u8bbe\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u9009\u62e9\u6392\u5e8f\u7684\u7b97\u6cd5\u6d41\u7a0b\u5982\u56fe 11-2 \u6240\u793a\u3002

    1. \u521d\u59cb\u72b6\u6001\u4e0b\uff0c\u6240\u6709\u5143\u7d20\u672a\u6392\u5e8f\uff0c\u5373\u672a\u6392\u5e8f\uff08\u7d22\u5f15\uff09\u533a\u95f4\u4e3a \\([0, n-1]\\) \u3002
    2. \u9009\u53d6\u533a\u95f4 \\([0, n-1]\\) \u4e2d\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5c06\u5176\u4e0e\u7d22\u5f15 \\(0\\) \u5904\u7684\u5143\u7d20\u4ea4\u6362\u3002\u5b8c\u6210\u540e\uff0c\u6570\u7ec4\u524d 1 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    3. \u9009\u53d6\u533a\u95f4 \\([1, n-1]\\) \u4e2d\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5c06\u5176\u4e0e\u7d22\u5f15 \\(1\\) \u5904\u7684\u5143\u7d20\u4ea4\u6362\u3002\u5b8c\u6210\u540e\uff0c\u6570\u7ec4\u524d 2 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    4. \u4ee5\u6b64\u7c7b\u63a8\u3002\u7ecf\u8fc7 \\(n - 1\\) \u8f6e\u9009\u62e9\u4e0e\u4ea4\u6362\u540e\uff0c\u6570\u7ec4\u524d \\(n - 1\\) \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    5. \u4ec5\u5269\u7684\u4e00\u4e2a\u5143\u7d20\u5fc5\u5b9a\u662f\u6700\u5927\u5143\u7d20\uff0c\u65e0\u987b\u6392\u5e8f\uff0c\u56e0\u6b64\u6570\u7ec4\u6392\u5e8f\u5b8c\u6210\u3002
    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 11-2 \u00a0 \u9009\u62e9\u6392\u5e8f\u6b65\u9aa4

    \u5728\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u7528 \\(k\\) \u6765\u8bb0\u5f55\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig selection_sort.py
    def selection_sort(nums: list[int]):\n    \"\"\"\u9009\u62e9\u6392\u5e8f\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in range(n - 1):\n        # \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        k = i\n        for j in range(i + 1, n):\n            if nums[j] < nums[k]:\n                k = j  # \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        # \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[k] = nums[k], nums[i]\n
    selection_sort.cpp
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(vector<int> &nums) {\n    int n = nums.size();\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        swap(nums[i], nums[k]);\n    }\n}\n
    selection_sort.java
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(int[] nums) {\n    int n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        int temp = nums[i];\n        nums[i] = nums[k];\n        nums[k] = temp;\n    }\n}\n
    selection_sort.cs
    /* \u9009\u62e9\u6392\u5e8f */\nvoid SelectionSort(int[] nums) {\n    int n = nums.Length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        (nums[k], nums[i]) = (nums[i], nums[k]);\n    }\n}\n
    selection_sort.go
    /* \u9009\u62e9\u6392\u5e8f */\nfunc selectionSort(nums []int) {\n    n := len(nums)\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i := 0; i < n-1; i++ {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        k := i\n        for j := i + 1; j < n; j++ {\n            if nums[j] < nums[k] {\n                // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n                k = j\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[k] = nums[k], nums[i]\n\n    }\n}\n
    selection_sort.swift
    /* \u9009\u62e9\u6392\u5e8f */\nfunc selectionSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in nums.indices.dropLast() {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        var k = i\n        for j in nums.indices.dropFirst(i + 1) {\n            if nums[j] < nums[k] {\n                k = j // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums.swapAt(i, k)\n    }\n}\n
    selection_sort.js
    /* \u9009\u62e9\u6392\u5e8f */\nfunction selectionSort(nums) {\n    let n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (let i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let k = i;\n        for (let j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k]) {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        [nums[i], nums[k]] = [nums[k], nums[i]];\n    }\n}\n
    selection_sort.ts
    /* \u9009\u62e9\u6392\u5e8f */\nfunction selectionSort(nums: number[]): void {\n    let n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (let i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let k = i;\n        for (let j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k]) {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        [nums[i], nums[k]] = [nums[k], nums[i]];\n    }\n}\n
    selection_sort.dart
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(List<int> nums) {\n  int n = nums.length;\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n  for (int i = 0; i < n - 1; i++) {\n    // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n    int k = i;\n    for (int j = i + 1; j < n; j++) {\n      if (nums[j] < nums[k]) k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n    }\n    // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n    int temp = nums[i];\n    nums[i] = nums[k];\n    nums[k] = temp;\n  }\n}\n
    selection_sort.rs
    /* \u9009\u62e9\u6392\u5e8f */\nfn selection_sort(nums: &mut [i32]) {\n    if nums.is_empty() {\n        return;\n    }\n    let n = nums.len();\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in 0..n - 1 {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let mut k = i;\n        for j in i + 1..n {\n            if nums[j] < nums[k] {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums.swap(i, k);\n    }\n}\n
    selection_sort.c
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(int nums[], int n) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        int temp = nums[i];\n        nums[i] = nums[k];\n        nums[k] = temp;\n    }\n}\n
    selection_sort.kt
    /* \u9009\u62e9\u6392\u5e8f */\nfun selectionSort(nums: IntArray) {\n    val n = nums.size\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (i in 0..<n - 1) {\n        var k = i\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        for (j in i + 1..<n) {\n            if (nums[j] < nums[k])\n                k = j // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        val temp = nums[i]\n        nums[i] = nums[k]\n        nums[k] = temp\n    }\n}\n
    selection_sort.rb
    [class]{}-[func]{selection_sort}\n
    selection_sort.zig
    [class]{}-[func]{selectionSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/selection_sort/#1121","title":"11.2.1 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5916\u5faa\u73af\u5171 \\(n - 1\\) \u8f6e\uff0c\u7b2c\u4e00\u8f6e\u7684\u672a\u6392\u5e8f\u533a\u95f4\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u6700\u540e\u4e00\u8f6e\u7684\u672a\u6392\u5e8f\u533a\u95f4\u957f\u5ea6\u4e3a \\(2\\) \uff0c\u5373\u5404\u8f6e\u5916\u5faa\u73af\u5206\u522b\u5305\u542b \\(n\\)\u3001\\(n - 1\\)\u3001\\(\\dots\\)\u3001\\(3\\)\u3001\\(2\\) \u8f6e\u5185\u5faa\u73af\uff0c\u6c42\u548c\u4e3a \\(\\frac{(n - 1)(n + 2)}{2}\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u975e\u7a33\u5b9a\u6392\u5e8f\uff1a\u5982\u56fe 11-3 \u6240\u793a\uff0c\u5143\u7d20 nums[i] \u6709\u53ef\u80fd\u88ab\u4ea4\u6362\u81f3\u4e0e\u5176\u76f8\u7b49\u7684\u5143\u7d20\u7684\u53f3\u8fb9\uff0c\u5bfc\u81f4\u4e24\u8005\u7684\u76f8\u5bf9\u987a\u5e8f\u53d1\u751f\u6539\u53d8\u3002

    \u56fe 11-3 \u00a0 \u9009\u62e9\u6392\u5e8f\u975e\u7a33\u5b9a\u793a\u4f8b

    "},{"location":"chapter_sorting/sorting_algorithm/","title":"11.1 \u00a0 \u6392\u5e8f\u7b97\u6cd5","text":"

    \u6392\u5e8f\u7b97\u6cd5\uff08sorting algorithm\uff09\u7528\u4e8e\u5bf9\u4e00\u7ec4\u6570\u636e\u6309\u7167\u7279\u5b9a\u987a\u5e8f\u8fdb\u884c\u6392\u5217\u3002\u6392\u5e8f\u7b97\u6cd5\u6709\u7740\u5e7f\u6cdb\u7684\u5e94\u7528\uff0c\u56e0\u4e3a\u6709\u5e8f\u6570\u636e\u901a\u5e38\u80fd\u591f\u88ab\u66f4\u9ad8\u6548\u5730\u67e5\u627e\u3001\u5206\u6790\u548c\u5904\u7406\u3002

    \u5982\u56fe 11-1 \u6240\u793a\uff0c\u6392\u5e8f\u7b97\u6cd5\u4e2d\u7684\u6570\u636e\u7c7b\u578b\u53ef\u4ee5\u662f\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u6216\u5b57\u7b26\u4e32\u7b49\u3002\u6392\u5e8f\u7684\u5224\u65ad\u89c4\u5219\u53ef\u6839\u636e\u9700\u6c42\u8bbe\u5b9a\uff0c\u5982\u6570\u5b57\u5927\u5c0f\u3001\u5b57\u7b26 ASCII \u7801\u987a\u5e8f\u6216\u81ea\u5b9a\u4e49\u89c4\u5219\u3002

    \u56fe 11-1 \u00a0 \u6570\u636e\u7c7b\u578b\u548c\u5224\u65ad\u89c4\u5219\u793a\u4f8b

    "},{"location":"chapter_sorting/sorting_algorithm/#1111","title":"11.1.1 \u00a0 \u8bc4\u4ef7\u7ef4\u5ea6","text":"

    \u8fd0\u884c\u6548\u7387\uff1a\u6211\u4eec\u671f\u671b\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5c3d\u91cf\u4f4e\uff0c\u4e14\u603b\u4f53\u64cd\u4f5c\u6570\u91cf\u8f83\u5c11\uff08\u65f6\u95f4\u590d\u6742\u5ea6\u4e2d\u7684\u5e38\u6570\u9879\u53d8\u5c0f\uff09\u3002\u5bf9\u4e8e\u5927\u6570\u636e\u91cf\u7684\u60c5\u51b5\uff0c\u8fd0\u884c\u6548\u7387\u663e\u5f97\u5c24\u4e3a\u91cd\u8981\u3002

    \u5c31\u5730\u6027\uff1a\u987e\u540d\u601d\u4e49\uff0c\u539f\u5730\u6392\u5e8f\u901a\u8fc7\u5728\u539f\u6570\u7ec4\u4e0a\u76f4\u63a5\u64cd\u4f5c\u5b9e\u73b0\u6392\u5e8f\uff0c\u65e0\u987b\u501f\u52a9\u989d\u5916\u7684\u8f85\u52a9\u6570\u7ec4\uff0c\u4ece\u800c\u8282\u7701\u5185\u5b58\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u539f\u5730\u6392\u5e8f\u7684\u6570\u636e\u642c\u8fd0\u64cd\u4f5c\u8f83\u5c11\uff0c\u8fd0\u884c\u901f\u5ea6\u4e5f\u66f4\u5feb\u3002

    \u7a33\u5b9a\u6027\uff1a\u7a33\u5b9a\u6392\u5e8f\u5728\u5b8c\u6210\u6392\u5e8f\u540e\uff0c\u76f8\u7b49\u5143\u7d20\u5728\u6570\u7ec4\u4e2d\u7684\u76f8\u5bf9\u987a\u5e8f\u4e0d\u53d1\u751f\u6539\u53d8\u3002

    \u7a33\u5b9a\u6392\u5e8f\u662f\u591a\u7ea7\u6392\u5e8f\u573a\u666f\u7684\u5fc5\u8981\u6761\u4ef6\u3002\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5b58\u50a8\u5b66\u751f\u4fe1\u606f\u7684\u8868\u683c\uff0c\u7b2c 1 \u5217\u548c\u7b2c 2 \u5217\u5206\u522b\u662f\u59d3\u540d\u548c\u5e74\u9f84\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u975e\u7a33\u5b9a\u6392\u5e8f\u53ef\u80fd\u5bfc\u81f4\u8f93\u5165\u6570\u636e\u7684\u6709\u5e8f\u6027\u4e27\u5931\uff1a

    # \u8f93\u5165\u6570\u636e\u662f\u6309\u7167\u59d3\u540d\u6392\u5e8f\u597d\u7684\n# (name, age)\n  ('A', 19)\n  ('B', 18)\n  ('C', 21)\n  ('D', 19)\n  ('E', 23)\n\n# \u5047\u8bbe\u4f7f\u7528\u975e\u7a33\u5b9a\u6392\u5e8f\u7b97\u6cd5\u6309\u5e74\u9f84\u6392\u5e8f\u5217\u8868\uff0c\n# \u7ed3\u679c\u4e2d ('D', 19) \u548c ('A', 19) \u7684\u76f8\u5bf9\u4f4d\u7f6e\u6539\u53d8\uff0c\n# \u8f93\u5165\u6570\u636e\u6309\u59d3\u540d\u6392\u5e8f\u7684\u6027\u8d28\u4e22\u5931\n  ('B', 18)\n  ('D', 19)\n  ('A', 19)\n  ('C', 21)\n  ('E', 23)\n

    \u81ea\u9002\u5e94\u6027\uff1a\u81ea\u9002\u5e94\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u53d7\u8f93\u5165\u6570\u636e\u7684\u5f71\u54cd\uff0c\u5373\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u3001\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u3001\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u5e76\u4e0d\u5b8c\u5168\u76f8\u7b49\u3002

    \u81ea\u9002\u5e94\u6027\u9700\u8981\u6839\u636e\u5177\u4f53\u60c5\u51b5\u6765\u8bc4\u4f30\u3002\u5982\u679c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u5dee\u4e8e\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8bf4\u660e\u6392\u5e8f\u7b97\u6cd5\u5728\u67d0\u4e9b\u6570\u636e\u4e0b\u6027\u80fd\u53ef\u80fd\u52a3\u5316\uff0c\u56e0\u6b64\u88ab\u89c6\u4e3a\u8d1f\u9762\u5c5e\u6027\uff1b\u800c\u5982\u679c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u4e8e\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u5219\u88ab\u89c6\u4e3a\u6b63\u9762\u5c5e\u6027\u3002

    \u662f\u5426\u57fa\u4e8e\u6bd4\u8f83\uff1a\u57fa\u4e8e\u6bd4\u8f83\u7684\u6392\u5e8f\u4f9d\u8d56\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff08\\(<\\)\u3001\\(=\\)\u3001\\(>\\)\uff09\u6765\u5224\u65ad\u5143\u7d20\u7684\u76f8\u5bf9\u987a\u5e8f\uff0c\u4ece\u800c\u6392\u5e8f\u6574\u4e2a\u6570\u7ec4\uff0c\u7406\u8bba\u6700\u4f18\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002\u800c\u975e\u6bd4\u8f83\u6392\u5e8f\u4e0d\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe \\(O(n)\\) \uff0c\u4f46\u5176\u901a\u7528\u6027\u76f8\u5bf9\u8f83\u5dee\u3002

    "},{"location":"chapter_sorting/sorting_algorithm/#1112","title":"11.1.2 \u00a0 \u7406\u60f3\u6392\u5e8f\u7b97\u6cd5","text":"

    \u8fd0\u884c\u5feb\u3001\u539f\u5730\u3001\u7a33\u5b9a\u3001\u6b63\u5411\u81ea\u9002\u5e94\u3001\u901a\u7528\u6027\u597d\u3002\u663e\u7136\uff0c\u8fc4\u4eca\u4e3a\u6b62\u5c1a\u672a\u53d1\u73b0\u517c\u5177\u4ee5\u4e0a\u6240\u6709\u7279\u6027\u7684\u6392\u5e8f\u7b97\u6cd5\u3002\u56e0\u6b64\uff0c\u5728\u9009\u62e9\u6392\u5e8f\u7b97\u6cd5\u65f6\uff0c\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u6570\u636e\u7279\u70b9\u548c\u95ee\u9898\u9700\u6c42\u6765\u51b3\u5b9a\u3002

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u5171\u540c\u5b66\u4e60\u5404\u79cd\u6392\u5e8f\u7b97\u6cd5\uff0c\u5e76\u57fa\u4e8e\u4e0a\u8ff0\u8bc4\u4ef7\u7ef4\u5ea6\u5bf9\u5404\u4e2a\u6392\u5e8f\u7b97\u6cd5\u7684\u4f18\u7f3a\u70b9\u8fdb\u884c\u5206\u6790\u3002

    "},{"location":"chapter_sorting/summary/","title":"11.11 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_sorting/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u5192\u6ce1\u6392\u5e8f\u901a\u8fc7\u4ea4\u6362\u76f8\u90bb\u5143\u7d20\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u6807\u5fd7\u4f4d\u6765\u5b9e\u73b0\u63d0\u524d\u8fd4\u56de\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5192\u6ce1\u6392\u5e8f\u7684\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u5230 \\(O(n)\\) \u3002
    • \u63d2\u5165\u6392\u5e8f\u6bcf\u8f6e\u5c06\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u5143\u7d20\u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4\u7684\u6b63\u786e\u4f4d\u7f6e\uff0c\u4ece\u800c\u5b8c\u6210\u6392\u5e8f\u3002\u867d\u7136\u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u4f46\u7531\u4e8e\u5355\u5143\u64cd\u4f5c\u76f8\u5bf9\u8f83\u5c11\uff0c\u56e0\u6b64\u5728\u5c0f\u6570\u636e\u91cf\u7684\u6392\u5e8f\u4efb\u52a1\u4e2d\u975e\u5e38\u53d7\u6b22\u8fce\u3002
    • \u5feb\u901f\u6392\u5e8f\u57fa\u4e8e\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u5b9e\u73b0\u6392\u5e8f\u3002\u5728\u54e8\u5175\u5212\u5206\u4e2d\uff0c\u6709\u53ef\u80fd\u6bcf\u6b21\u90fd\u9009\u53d6\u5230\u6700\u5dee\u7684\u57fa\u51c6\u6570\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u52a3\u5316\u81f3 \\(O(n^2)\\) \u3002\u5f15\u5165\u4e2d\u4f4d\u6570\u57fa\u51c6\u6570\u6216\u968f\u673a\u57fa\u51c6\u6570\u53ef\u4ee5\u964d\u4f4e\u8fd9\u79cd\u52a3\u5316\u7684\u6982\u7387\u3002\u5c3e\u9012\u5f52\u65b9\u6cd5\u53ef\u4ee5\u6709\u6548\u5730\u51cf\u5c11\u9012\u5f52\u6df1\u5ea6\uff0c\u5c06\u7a7a\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u5230 \\(O(\\log n)\\) \u3002
    • \u5f52\u5e76\u6392\u5e8f\u5305\u62ec\u5212\u5206\u548c\u5408\u5e76\u4e24\u4e2a\u9636\u6bb5\uff0c\u5178\u578b\u5730\u4f53\u73b0\u4e86\u5206\u6cbb\u7b56\u7565\u3002\u5728\u5f52\u5e76\u6392\u5e8f\u4e2d\uff0c\u6392\u5e8f\u6570\u7ec4\u9700\u8981\u521b\u5efa\u8f85\u52a9\u6570\u7ec4\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1b\u7136\u800c\u6392\u5e8f\u94fe\u8868\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f18\u5316\u81f3 \\(O(1)\\) \u3002
    • \u6876\u6392\u5e8f\u5305\u542b\u4e09\u4e2a\u6b65\u9aa4\uff1a\u6570\u636e\u5206\u6876\u3001\u6876\u5185\u6392\u5e8f\u548c\u5408\u5e76\u7ed3\u679c\u3002\u5b83\u540c\u6837\u4f53\u73b0\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u9002\u7528\u4e8e\u6570\u636e\u4f53\u91cf\u5f88\u5927\u7684\u60c5\u51b5\u3002\u6876\u6392\u5e8f\u7684\u5173\u952e\u5728\u4e8e\u5bf9\u6570\u636e\u8fdb\u884c\u5e73\u5747\u5206\u914d\u3002
    • \u8ba1\u6570\u6392\u5e8f\u662f\u6876\u6392\u5e8f\u7684\u4e00\u4e2a\u7279\u4f8b\uff0c\u5b83\u901a\u8fc7\u7edf\u8ba1\u6570\u636e\u51fa\u73b0\u7684\u6b21\u6570\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u8ba1\u6570\u6392\u5e8f\u9002\u7528\u4e8e\u6570\u636e\u91cf\u5927\u4f46\u6570\u636e\u8303\u56f4\u6709\u9650\u7684\u60c5\u51b5\uff0c\u5e76\u4e14\u8981\u6c42\u6570\u636e\u80fd\u591f\u8f6c\u6362\u4e3a\u6b63\u6574\u6570\u3002
    • \u57fa\u6570\u6392\u5e8f\u901a\u8fc7\u9010\u4f4d\u6392\u5e8f\u6765\u5b9e\u73b0\u6570\u636e\u6392\u5e8f\uff0c\u8981\u6c42\u6570\u636e\u80fd\u591f\u8868\u793a\u4e3a\u56fa\u5b9a\u4f4d\u6570\u7684\u6570\u5b57\u3002
    • \u603b\u7684\u6765\u8bf4\uff0c\u6211\u4eec\u5e0c\u671b\u627e\u5230\u4e00\u79cd\u6392\u5e8f\u7b97\u6cd5\uff0c\u5177\u6709\u9ad8\u6548\u7387\u3001\u7a33\u5b9a\u3001\u539f\u5730\u4ee5\u53ca\u6b63\u5411\u81ea\u9002\u5e94\u6027\u7b49\u4f18\u70b9\u3002\u7136\u800c\uff0c\u6b63\u5982\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u4e00\u6837\uff0c\u6ca1\u6709\u4e00\u79cd\u6392\u5e8f\u7b97\u6cd5\u80fd\u591f\u540c\u65f6\u6ee1\u8db3\u6240\u6709\u8fd9\u4e9b\u6761\u4ef6\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u6570\u636e\u7684\u7279\u6027\u6765\u9009\u62e9\u5408\u9002\u7684\u6392\u5e8f\u7b97\u6cd5\u3002
    • \u56fe 11-19 \u5bf9\u6bd4\u4e86\u4e3b\u6d41\u6392\u5e8f\u7b97\u6cd5\u7684\u6548\u7387\u3001\u7a33\u5b9a\u6027\u3001\u5c31\u5730\u6027\u548c\u81ea\u9002\u5e94\u6027\u7b49\u3002

    \u56fe 11-19 \u00a0 \u6392\u5e8f\u7b97\u6cd5\u5bf9\u6bd4

    "},{"location":"chapter_sorting/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6392\u5e8f\u7b97\u6cd5\u7a33\u5b9a\u6027\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u662f\u5fc5\u9700\u7684\uff1f

    \u5728\u73b0\u5b9e\u4e2d\uff0c\u6211\u4eec\u6709\u53ef\u80fd\u57fa\u4e8e\u5bf9\u8c61\u7684\u67d0\u4e2a\u5c5e\u6027\u8fdb\u884c\u6392\u5e8f\u3002\u4f8b\u5982\uff0c\u5b66\u751f\u6709\u59d3\u540d\u548c\u8eab\u9ad8\u4e24\u4e2a\u5c5e\u6027\uff0c\u6211\u4eec\u5e0c\u671b\u5b9e\u73b0\u4e00\u4e2a\u591a\u7ea7\u6392\u5e8f\uff1a\u5148\u6309\u7167\u59d3\u540d\u8fdb\u884c\u6392\u5e8f\uff0c\u5f97\u5230 (A, 180) (B, 185) (C, 170) (D, 170) \uff1b\u518d\u5bf9\u8eab\u9ad8\u8fdb\u884c\u6392\u5e8f\u3002\u7531\u4e8e\u6392\u5e8f\u7b97\u6cd5\u4e0d\u7a33\u5b9a\uff0c\u56e0\u6b64\u53ef\u80fd\u5f97\u5230 (D, 170) (C, 170) (A, 180) (B, 185) \u3002

    \u53ef\u4ee5\u53d1\u73b0\uff0c\u5b66\u751f D \u548c C \u7684\u4f4d\u7f6e\u53d1\u751f\u4e86\u4ea4\u6362\uff0c\u59d3\u540d\u7684\u6709\u5e8f\u6027\u88ab\u7834\u574f\u4e86\uff0c\u800c\u8fd9\u662f\u6211\u4eec\u4e0d\u5e0c\u671b\u770b\u5230\u7684\u3002

    Q\uff1a\u54e8\u5175\u5212\u5206\u4e2d\u201c\u4ece\u53f3\u5f80\u5de6\u67e5\u627e\u201d\u4e0e\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\u7684\u987a\u5e8f\u53ef\u4ee5\u4ea4\u6362\u5417\uff1f

    \u4e0d\u884c\uff0c\u5f53\u6211\u4eec\u4ee5\u6700\u5de6\u7aef\u5143\u7d20\u4e3a\u57fa\u51c6\u6570\u65f6\uff0c\u5fc5\u987b\u5148\u201c\u4ece\u53f3\u5f80\u5de6\u67e5\u627e\u201d\u518d\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\u3002\u8fd9\u4e2a\u7ed3\u8bba\u6709\u4e9b\u53cd\u76f4\u89c9\uff0c\u6211\u4eec\u6765\u5256\u6790\u4e00\u4e0b\u539f\u56e0\u3002

    \u54e8\u5175\u5212\u5206 partition() \u7684\u6700\u540e\u4e00\u6b65\u662f\u4ea4\u6362 nums[left] \u548c nums[i] \u3002\u5b8c\u6210\u4ea4\u6362\u540e\uff0c\u57fa\u51c6\u6570\u5de6\u8fb9\u7684\u5143\u7d20\u90fd <= \u57fa\u51c6\u6570\uff0c\u8fd9\u5c31\u8981\u6c42\u6700\u540e\u4e00\u6b65\u4ea4\u6362\u524d nums[left] >= nums[i] \u5fc5\u987b\u6210\u7acb\u3002\u5047\u8bbe\u6211\u4eec\u5148\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\uff0c\u90a3\u4e48\u5982\u679c\u627e\u4e0d\u5230\u6bd4\u57fa\u51c6\u6570\u66f4\u5927\u7684\u5143\u7d20\uff0c\u5219\u4f1a\u5728 i == j \u65f6\u8df3\u51fa\u5faa\u73af\uff0c\u6b64\u65f6\u53ef\u80fd nums[j] == nums[i] > nums[left]\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u6b64\u65f6\u6700\u540e\u4e00\u6b65\u4ea4\u6362\u64cd\u4f5c\u4f1a\u628a\u4e00\u4e2a\u6bd4\u57fa\u51c6\u6570\u66f4\u5927\u7684\u5143\u7d20\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\uff0c\u5bfc\u81f4\u54e8\u5175\u5212\u5206\u5931\u8d25\u3002

    \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u7ed9\u5b9a\u6570\u7ec4 [0, 0, 0, 0, 1] \uff0c\u5982\u679c\u5148\u201c\u4ece\u5de6\u5411\u53f3\u67e5\u627e\u201d\uff0c\u54e8\u5175\u5212\u5206\u540e\u6570\u7ec4\u4e3a [1, 0, 0, 0, 0] \uff0c\u8fd9\u4e2a\u7ed3\u679c\u662f\u4e0d\u6b63\u786e\u7684\u3002

    \u518d\u6df1\u5165\u601d\u8003\u4e00\u4e0b\uff0c\u5982\u679c\u6211\u4eec\u9009\u62e9 nums[right] \u4e3a\u57fa\u51c6\u6570\uff0c\u90a3\u4e48\u6b63\u597d\u53cd\u8fc7\u6765\uff0c\u5fc5\u987b\u5148\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\u3002

    Q\uff1a\u5173\u4e8e\u5c3e\u9012\u5f52\u4f18\u5316\uff0c\u4e3a\u4ec0\u4e48\u9009\u77ed\u7684\u6570\u7ec4\u80fd\u4fdd\u8bc1\u9012\u5f52\u6df1\u5ea6\u4e0d\u8d85\u8fc7 \\(\\log n\\) \uff1f

    \u9012\u5f52\u6df1\u5ea6\u5c31\u662f\u5f53\u524d\u672a\u8fd4\u56de\u7684\u9012\u5f52\u65b9\u6cd5\u7684\u6570\u91cf\u3002\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u6211\u4eec\u5c06\u539f\u6570\u7ec4\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\u3002\u5728\u5c3e\u9012\u5f52\u4f18\u5316\u540e\uff0c\u5411\u4e0b\u9012\u5f52\u7684\u5b50\u6570\u7ec4\u957f\u5ea6\u6700\u5927\u4e3a\u539f\u6570\u7ec4\u957f\u5ea6\u7684\u4e00\u534a\u3002\u5047\u8bbe\u6700\u5dee\u60c5\u51b5\uff0c\u4e00\u76f4\u4e3a\u4e00\u534a\u957f\u5ea6\uff0c\u90a3\u4e48\u6700\u7ec8\u7684\u9012\u5f52\u6df1\u5ea6\u5c31\u662f \\(\\log n\\) \u3002

    \u56de\u987e\u539f\u59cb\u7684\u5feb\u901f\u6392\u5e8f\uff0c\u6211\u4eec\u6709\u53ef\u80fd\u4f1a\u8fde\u7eed\u5730\u9012\u5f52\u957f\u5ea6\u8f83\u5927\u7684\u6570\u7ec4\uff0c\u6700\u5dee\u60c5\u51b5\u4e0b\u4e3a \\(n\\)\u3001\\(n - 1\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \uff0c\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \u3002\u5c3e\u9012\u5f52\u4f18\u5316\u53ef\u4ee5\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u51fa\u73b0\u3002

    Q\uff1a\u5f53\u6570\u7ec4\u4e2d\u6240\u6709\u5143\u7d20\u90fd\u76f8\u7b49\u65f6\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(n^2)\\) \u5417\uff1f\u8be5\u5982\u4f55\u5904\u7406\u8fd9\u79cd\u9000\u5316\u60c5\u51b5\uff1f

    \u662f\u7684\u3002\u5bf9\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u53ef\u4ee5\u8003\u8651\u901a\u8fc7\u54e8\u5175\u5212\u5206\u5c06\u6570\u7ec4\u5212\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\uff1a\u5c0f\u4e8e\u3001\u7b49\u4e8e\u3001\u5927\u4e8e\u57fa\u51c6\u6570\u3002\u4ec5\u5411\u4e0b\u9012\u5f52\u5c0f\u4e8e\u548c\u5927\u4e8e\u7684\u4e24\u90e8\u5206\u3002\u5728\u8be5\u65b9\u6cd5\u4e0b\uff0c\u8f93\u5165\u5143\u7d20\u5168\u90e8\u76f8\u7b49\u7684\u6570\u7ec4\uff0c\u4ec5\u4e00\u8f6e\u54e8\u5175\u5212\u5206\u5373\u53ef\u5b8c\u6210\u6392\u5e8f\u3002

    Q\uff1a\u6876\u6392\u5e8f\u7684\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\u4ec0\u4e48\u662f \\(O(n^2)\\) \uff1f

    \u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u5143\u7d20\u88ab\u5206\u81f3\u540c\u4e00\u4e2a\u6876\u4e2d\u3002\u5982\u679c\u6211\u4eec\u91c7\u7528\u4e00\u4e2a \\(O(n^2)\\) \u7b97\u6cd5\u6765\u6392\u5e8f\u8fd9\u4e9b\u5143\u7d20\uff0c\u5219\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_stack_and_queue/","title":"\u7b2c 5 \u7ae0 \u00a0 \u6808\u4e0e\u961f\u5217","text":"

    Abstract

    \u6808\u5982\u540c\u53e0\u732b\u732b\uff0c\u800c\u961f\u5217\u5c31\u50cf\u732b\u732b\u6392\u961f\u3002

    \u4e24\u8005\u5206\u522b\u4ee3\u8868\u5148\u5165\u540e\u51fa\u548c\u5148\u5165\u5148\u51fa\u7684\u903b\u8f91\u5173\u7cfb\u3002

    "},{"location":"chapter_stack_and_queue/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 5.1 \u00a0 \u6808
    • 5.2 \u00a0 \u961f\u5217
    • 5.3 \u00a0 \u53cc\u5411\u961f\u5217
    • 5.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_stack_and_queue/deque/","title":"5.3 \u00a0 \u53cc\u5411\u961f\u5217","text":"

    \u5728\u961f\u5217\u4e2d\uff0c\u6211\u4eec\u4ec5\u80fd\u5220\u9664\u5934\u90e8\u5143\u7d20\u6216\u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\u3002\u5982\u56fe 5-7 \u6240\u793a\uff0c\u53cc\u5411\u961f\u5217\uff08double-ended queue\uff09\u63d0\u4f9b\u4e86\u66f4\u9ad8\u7684\u7075\u6d3b\u6027\uff0c\u5141\u8bb8\u5728\u5934\u90e8\u548c\u5c3e\u90e8\u6267\u884c\u5143\u7d20\u7684\u6dfb\u52a0\u6216\u5220\u9664\u64cd\u4f5c\u3002

    \u56fe 5-7 \u00a0 \u53cc\u5411\u961f\u5217\u7684\u64cd\u4f5c

    "},{"location":"chapter_stack_and_queue/deque/#531","title":"5.3.1 \u00a0 \u53cc\u5411\u961f\u5217\u5e38\u7528\u64cd\u4f5c","text":"

    \u53cc\u5411\u961f\u5217\u7684\u5e38\u7528\u64cd\u4f5c\u5982\u8868 5-3 \u6240\u793a\uff0c\u5177\u4f53\u7684\u65b9\u6cd5\u540d\u79f0\u9700\u8981\u6839\u636e\u6240\u4f7f\u7528\u7684\u7f16\u7a0b\u8bed\u8a00\u6765\u786e\u5b9a\u3002

    \u8868 5-3 \u00a0 \u53cc\u5411\u961f\u5217\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5\u540d \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push_first() \u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u961f\u9996 \\(O(1)\\) push_last() \u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u961f\u5c3e \\(O(1)\\) pop_first() \u5220\u9664\u961f\u9996\u5143\u7d20 \\(O(1)\\) pop_last() \u5220\u9664\u961f\u5c3e\u5143\u7d20 \\(O(1)\\) peek_first() \u8bbf\u95ee\u961f\u9996\u5143\u7d20 \\(O(1)\\) peek_last() \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 \\(O(1)\\)

    \u540c\u6837\u5730\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u4e2d\u5df2\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\u7c7b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig deque.py
    from collections import deque\n\n# \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217\ndeq: deque[int] = deque()\n\n# \u5143\u7d20\u5165\u961f\ndeq.append(2)      # \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeq.append(5)\ndeq.append(4)\ndeq.appendleft(3)  # \u6dfb\u52a0\u81f3\u961f\u9996\ndeq.appendleft(1)\n\n# \u8bbf\u95ee\u5143\u7d20\nfront: int = deq[0]  # \u961f\u9996\u5143\u7d20\nrear: int = deq[-1]  # \u961f\u5c3e\u5143\u7d20\n\n# \u5143\u7d20\u51fa\u961f\npop_front: int = deq.popleft()  # \u961f\u9996\u5143\u7d20\u51fa\u961f\npop_rear: int = deq.pop()       # \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n# \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\nsize: int = len(deq)\n\n# \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = len(deq) == 0\n
    deque.cpp
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\ndeque<int> deque;\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push_back(2);   // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3);  // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.push_front(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint front = deque.front(); // \u961f\u9996\u5143\u7d20\nint back = deque.back();   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\ndeque.pop_front();  // \u961f\u9996\u5143\u7d20\u51fa\u961f\ndeque.pop_back();   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.size();\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty = deque.empty();\n
    deque.java
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\nDeque<Integer> deque = new LinkedList<>();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.offerLast(2);   // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.offerLast(5);\ndeque.offerLast(4);\ndeque.offerFirst(3);  // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.offerFirst(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint peekFirst = deque.peekFirst();  // \u961f\u9996\u5143\u7d20\nint peekLast = deque.peekLast();    // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\nint popFirst = deque.pollFirst();  // \u961f\u9996\u5143\u7d20\u51fa\u961f\nint popLast = deque.pollLast();    // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.size();\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = deque.isEmpty();\n
    deque.cs
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 C# \u4e2d\uff0c\u5c06\u94fe\u8868 LinkedList \u770b\u4f5c\u53cc\u5411\u961f\u5217\u6765\u4f7f\u7528\nLinkedList<int> deque = new();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.AddLast(2);   // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.AddLast(5);\ndeque.AddLast(4);\ndeque.AddFirst(3);  // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.AddFirst(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint peekFirst = deque.First.Value;  // \u961f\u9996\u5143\u7d20\nint peekLast = deque.Last.Value;    // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\ndeque.RemoveFirst();  // \u961f\u9996\u5143\u7d20\u51fa\u961f\ndeque.RemoveLast();   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.Count;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = deque.Count == 0;\n
    deque_test.go
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 Go \u4e2d\uff0c\u5c06 list \u4f5c\u4e3a\u53cc\u5411\u961f\u5217\u4f7f\u7528\ndeque := list.New()\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.PushBack(2)      // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.PushBack(5)\ndeque.PushBack(4)\ndeque.PushFront(3)     // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.PushFront(1)\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nfront := deque.Front() // \u961f\u9996\u5143\u7d20\nrear := deque.Back()   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\ndeque.Remove(front)    // \u961f\u9996\u5143\u7d20\u51fa\u961f\ndeque.Remove(rear)     // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nsize := deque.Len()\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nisEmpty := deque.Len() == 0\n
    deque.swift
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// Swift \u6ca1\u6709\u5185\u7f6e\u7684\u53cc\u5411\u961f\u5217\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u53cc\u5411\u961f\u5217\u6765\u4f7f\u7528\nvar deque: [Int] = []\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.append(2) // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.append(5)\ndeque.append(4)\ndeque.insert(3, at: 0) // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.insert(1, at: 0)\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nlet peekFirst = deque.first! // \u961f\u9996\u5143\u7d20\nlet peekLast = deque.last! // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u4f7f\u7528 Array \u6a21\u62df\u65f6 popFirst \u7684\u590d\u6742\u5ea6\u4e3a O(n)\nlet popFirst = deque.removeFirst() // \u961f\u9996\u5143\u7d20\u51fa\u961f\nlet popLast = deque.removeLast() // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = deque.count\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = deque.isEmpty\n
    deque.js
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// JavaScript \u6ca1\u6709\u5185\u7f6e\u7684\u53cc\u7aef\u961f\u5217\uff0c\u53ea\u80fd\u628a Array \u5f53\u4f5c\u53cc\u7aef\u961f\u5217\u6765\u4f7f\u7528\nconst deque = [];\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cunshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nconst peekFirst = deque[0];\nconst peekLast = deque[deque.length - 1];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst popFront = deque.shift();\nconst popBack = deque.pop();\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nconst size = deque.length;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst isEmpty = size === 0;\n
    deque.ts
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// TypeScript \u6ca1\u6709\u5185\u7f6e\u7684\u53cc\u7aef\u961f\u5217\uff0c\u53ea\u80fd\u628a Array \u5f53\u4f5c\u53cc\u7aef\u961f\u5217\u6765\u4f7f\u7528\nconst deque: number[] = [];\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cunshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nconst peekFirst: number = deque[0];\nconst peekLast: number = deque[deque.length - 1];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst popFront: number = deque.shift() as number;\nconst popBack: number = deque.pop() as number;\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nconst size: number = deque.length;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst isEmpty: boolean = size === 0;\n
    deque.dart
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 Dart \u4e2d\uff0cQueue \u88ab\u5b9a\u4e49\u4e3a\u53cc\u5411\u961f\u5217\nQueue<int> deque = Queue<int>();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.addLast(2);  // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.addLast(5);\ndeque.addLast(4);\ndeque.addFirst(3); // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.addFirst(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint peekFirst = deque.first; // \u961f\u9996\u5143\u7d20\nint peekLast = deque.last;   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\nint popFirst = deque.removeFirst(); // \u961f\u9996\u5143\u7d20\u51fa\u961f\nint popLast = deque.removeLast();   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.length;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = deque.isEmpty;\n
    deque.rs
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push_back(2);  // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3); // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.push_front(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nif let Some(front) = deque.front() { // \u961f\u9996\u5143\u7d20\n}\nif let Some(rear) = deque.back() {   // \u961f\u5c3e\u5143\u7d20\n}\n\n/* \u5143\u7d20\u51fa\u961f */\nif let Some(pop_front) = deque.pop_front() { // \u961f\u9996\u5143\u7d20\u51fa\u961f\n}\nif let Some(pop_rear) = deque.pop_back() {   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = deque.len();\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = deque.is_empty();\n
    deque.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u53cc\u5411\u961f\u5217\n
    deque.kt
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\nval deque = LinkedList<Int>()\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.offerLast(2)  // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.offerLast(5)\ndeque.offerLast(4)\ndeque.offerFirst(3) // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.offerFirst(1)\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nval peekFirst = deque.peekFirst() // \u961f\u9996\u5143\u7d20\nval peekLast = deque.peekLast()   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\nval popFirst = deque.pollFirst() // \u961f\u9996\u5143\u7d20\u51fa\u961f\nval popLast = deque.pollLast()   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nval size = deque.size\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = deque.isEmpty()\n
    deque.rb
    # \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217\n# Ruby \u6ca1\u6709\u5185\u76f4\u7684\u53cc\u7aef\u961f\u5217\uff0c\u53ea\u80fd\u628a Array \u5f53\u4f5c\u53cc\u7aef\u961f\u5217\u6765\u4f7f\u7528\ndeque = []\n\n# \u5143\u7d20\u5982\u961f\ndeque << 2\ndeque << 5\ndeque << 4\n# \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cArray#unshift \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\ndeque.unshift(3)\ndeque.unshift(1)\n\n# \u8bbf\u95ee\u5143\u7d20\npeek_first = deque.first\npeek_last = deque.last\n\n# \u5143\u7d20\u51fa\u961f\n# \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0c Array#shift \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\npop_front = deque.shift\npop_back = deque.pop\n\n# \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\nsize = deque.length\n\n# \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty = size.zero?\n
    deque.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/deque/#532","title":"5.3.2 \u00a0 \u53cc\u5411\u961f\u5217\u5b9e\u73b0 *","text":"

    \u53cc\u5411\u961f\u5217\u7684\u5b9e\u73b0\u4e0e\u961f\u5217\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u9009\u62e9\u94fe\u8868\u6216\u6570\u7ec4\u4f5c\u4e3a\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u3002

    "},{"location":"chapter_stack_and_queue/deque/#1","title":"1. \u00a0 \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0","text":"

    \u56de\u987e\u4e0a\u4e00\u8282\u5185\u5bb9\uff0c\u6211\u4eec\u4f7f\u7528\u666e\u901a\u5355\u5411\u94fe\u8868\u6765\u5b9e\u73b0\u961f\u5217\uff0c\u56e0\u4e3a\u5b83\u53ef\u4ee5\u65b9\u4fbf\u5730\u5220\u9664\u5934\u8282\u70b9\uff08\u5bf9\u5e94\u51fa\u961f\u64cd\u4f5c\uff09\u548c\u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0\u65b0\u8282\u70b9\uff08\u5bf9\u5e94\u5165\u961f\u64cd\u4f5c\uff09\u3002

    \u5bf9\u4e8e\u53cc\u5411\u961f\u5217\u800c\u8a00\uff0c\u5934\u90e8\u548c\u5c3e\u90e8\u90fd\u53ef\u4ee5\u6267\u884c\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u53cc\u5411\u961f\u5217\u9700\u8981\u5b9e\u73b0\u53e6\u4e00\u4e2a\u5bf9\u79f0\u65b9\u5411\u7684\u64cd\u4f5c\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u91c7\u7528\u201c\u53cc\u5411\u94fe\u8868\u201d\u4f5c\u4e3a\u53cc\u5411\u961f\u5217\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u3002

    \u5982\u56fe 5-8 \u6240\u793a\uff0c\u6211\u4eec\u5c06\u53cc\u5411\u94fe\u8868\u7684\u5934\u8282\u70b9\u548c\u5c3e\u8282\u70b9\u89c6\u4e3a\u53cc\u5411\u961f\u5217\u7684\u961f\u9996\u548c\u961f\u5c3e\uff0c\u540c\u65f6\u5b9e\u73b0\u5728\u4e24\u7aef\u6dfb\u52a0\u548c\u5220\u9664\u8282\u70b9\u7684\u529f\u80fd\u3002

    LinkedListDequepush_last()push_first()pop_last()pop_first()

    \u56fe 5-8 \u00a0 \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u53cc\u5411\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_deque.py
    class ListNode:\n    \"\"\"\u53cc\u5411\u94fe\u8868\u8282\u70b9\"\"\"\n\n    def __init__(self, val: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.val: int = val\n        self.next: ListNode | None = None  # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n        self.prev: ListNode | None = None  # \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\nclass LinkedListDeque:\n    \"\"\"\u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0  # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int, is_front: bool):\n        \"\"\"\u5165\u961f\u64cd\u4f5c\"\"\"\n        node = ListNode(num)\n        # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if self.is_empty():\n            self._front = self._rear = node\n        # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        elif is_front:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            self._front.prev = node\n            node.next = self._front\n            self._front = node  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            self._rear.next = node\n            node.prev = self._rear\n            self._rear = node  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size += 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        self.push(num, True)\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        self.push(num, False)\n\n    def pop(self, is_front: bool) -> int:\n        \"\"\"\u51fa\u961f\u64cd\u4f5c\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front:\n            val: int = self._front.val  # \u6682\u5b58\u5934\u8282\u70b9\u503c\n            # \u5220\u9664\u5934\u8282\u70b9\n            fnext: ListNode | None = self._front.next\n            if fnext != None:\n                fnext.prev = None\n                self._front.next = None\n            self._front = fnext  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else:\n            val: int = self._rear.val  # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            # \u5220\u9664\u5c3e\u8282\u70b9\n            rprev: ListNode | None = self._rear.prev\n            if rprev != None:\n                rprev.next = None\n                self._rear.prev = None\n            self._rear = rprev  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size -= 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        return self.pop(True)\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        return self.pop(False)\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._rear.val\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        node = self._front\n        res = [0] * self.size()\n        for i in range(self.size()):\n            res[i] = node.val\n            node = node.next\n        return res\n
    linkedlist_deque.cpp
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nstruct DoublyListNode {\n    int val;              // \u8282\u70b9\u503c\n    DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\u6307\u9488\n    DoublyListNode(int val) : val(val), prev(nullptr), next(nullptr) {\n    }\n};\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n  private:\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize = 0;              // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    LinkedListDeque() : front(nullptr), rear(nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~LinkedListDeque() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        DoublyListNode *pre, *cur = front;\n        while (cur != nullptr) {\n            pre = cur;\n            cur = cur->next;\n            delete pre;\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void push(int num, bool isFront) {\n        DoublyListNode *node = new DoublyListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front->prev = node;\n            node->next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear->next = node;\n            node->prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int pop(bool isFront) {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front->val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            DoublyListNode *fNext = front->next;\n            if (fNext != nullptr) {\n                fNext->prev = nullptr;\n                front->next = nullptr;\n            }\n            delete front;\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear->val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            DoublyListNode *rPrev = rear->prev;\n            if (rPrev != nullptr) {\n                rPrev->next = nullptr;\n                rear->prev = nullptr;\n            }\n            delete rear;\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return rear->val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        DoublyListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_deque.java
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    int val; // \u8282\u70b9\u503c\n    ListNode next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    ListNode prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    ListNode(int val) {\n        this.val = val;\n        prev = next = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private void push(int num, boolean isFront) {\n        ListNode node = new ListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear.next = node;\n            node.prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private int pop(boolean isFront) {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode fNext = front.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front.next = null;\n            }\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode rPrev = rear.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear.prev = null;\n            }\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return rear.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_deque.cs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(int val) {\n    public int val = val;       // \u8282\u70b9\u503c\n    public ListNode? next = null; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    public ListNode? prev = null; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    ListNode? front, rear; // \u5934\u8282\u70b9 front, \u5c3e\u8282\u70b9 rear\n    int queSize = 0;      // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void Push(int num, bool isFront) {\n        ListNode node = new(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (IsEmpty()) {\n            front = node;\n            rear = node;\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front!.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9                           \n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear!.next = node;\n            node.prev = rear;\n            rear = node;  // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        Push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        Push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int? Pop(bool isFront) {\n        if (IsEmpty())\n            throw new Exception();\n        int? val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front?.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode? fNext = front?.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front!.next = null;\n            }\n            front = fNext;   // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear?.val;  // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode? rPrev = rear?.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear!.prev = null;\n            }\n            rear = rPrev;    // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int? PopFirst() {\n        return Pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int? PopLast() {\n        return Pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int? PeekFirst() {\n        if (IsEmpty())\n            throw new Exception();\n        return front?.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int? PeekLast() {\n        if (IsEmpty())\n            throw new Exception();\n        return rear?.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int?[] ToArray() {\n        ListNode? node = front;\n        int?[] res = new int?[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node?.val;\n            node = node?.next;\n        }\n\n        return res;\n    }\n}\n
    linkedlist_deque.go
    /* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype linkedListDeque struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u53cc\u7aef\u961f\u5217 */\nfunc newLinkedListDeque() *linkedListDeque {\n    return &linkedListDeque{\n        data: list.New(),\n    }\n}\n\n/* \u961f\u9996\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushFirst(value any) {\n    s.data.PushFront(value)\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushLast(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u961f\u9996\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListDeque) peekFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (s *linkedListDeque) peekLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListDeque) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListDeque) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListDeque) toList() *list.List {\n    return s.data\n}\n
    linkedlist_deque.swift
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    weak var prev: ListNode? // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    init(val: Int) {\n        self.val = val\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? // \u5934\u8282\u70b9 front\n    private var rear: ListNode? // \u5c3e\u8282\u70b9 rear\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private func push(num: Int, isFront: Bool) {\n        let node = ListNode(val: num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if isEmpty() {\n            front = node\n            rear = node\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if isFront {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size += 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        push(num: num, isFront: true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        push(num: num, isFront: false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private func pop(isFront: Bool) -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        let val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if isFront {\n            val = front!.val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            let fNext = front?.next\n            if fNext != nil {\n                fNext?.prev = nil\n                front?.next = nil\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear!.val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            let rPrev = rear?.prev\n            if rPrev != nil {\n                rPrev?.next = nil\n                rear?.prev = nil\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size -= 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        pop(isFront: true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        pop(isFront: false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return rear!.val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.js
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val; // \u8282\u70b9\u503c\n\n    constructor(val) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    #front; // \u5934\u8282\u70b9 front\n    #rear; // \u5c3e\u8282\u70b9 rear\n    #queSize; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n        this.#queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.#rear.next = node;\n            node.prev = this.#rear;\n            this.#rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.#front.prev = node;\n            node.next = this.#front;\n            this.#front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp = this.#rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.#rear.prev = null;\n        }\n        this.#rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp = this.#front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.#front.next = null;\n        }\n        this.#front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        return this.#queSize === 0 ? null : this.#rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        return this.#queSize === 0 ? null : this.#front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print() {\n        const arr = [];\n        let temp = this.#front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.ts
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev: ListNode; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next: ListNode; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val: number; // \u8282\u70b9\u503c\n\n    constructor(val: number) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private front: ListNode; // \u5934\u8282\u70b9 front\n    private rear: ListNode; // \u5c3e\u8282\u70b9 rear\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n        this.queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.rear.next = node;\n            node.prev = this.rear;\n            this.rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.front.prev = node;\n            node.next = this.front;\n            this.front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp: ListNode = this.rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.rear.prev = null;\n        }\n        this.rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp: ListNode = this.front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.front.next = null;\n        }\n        this.front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        return this.queSize === 0 ? null : this.rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        return this.queSize === 0 ? null : this.front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print(): void {\n        const arr: number[] = [];\n        let temp: ListNode = this.front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.dart
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n  int val; // \u8282\u70b9\u503c\n  ListNode? next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  ListNode? prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n  ListNode(this.val, {this.next, this.prev});\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u5bf9\u5217 */\nclass LinkedListDeque {\n  late ListNode? _front; // \u5934\u8282\u70b9 _front\n  late ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  LinkedListDeque() {\n    this._front = null;\n    this._rear = null;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u957f\u5ea6 */\n  int size() {\n    return this._queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return size() == 0;\n  }\n\n  /* \u5165\u961f\u64cd\u4f5c */\n  void push(int _num, bool isFront) {\n    final ListNode node = ListNode(_num);\n    if (isEmpty()) {\n      // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 _front \u548c _rear \u90fd\u6307\u5411 node\n      _front = _rear = node;\n    } else if (isFront) {\n      // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      _front!.prev = node;\n      node.next = _front;\n      _front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      _rear!.next = node;\n      node.prev = _rear;\n      _rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    push(_num, true);\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    push(_num, false);\n  }\n\n  /* \u51fa\u961f\u64cd\u4f5c */\n  int? pop(bool isFront) {\n    // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de null\n    if (isEmpty()) {\n      return null;\n    }\n    final int val;\n    if (isFront) {\n      // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n      val = _front!.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n      // \u5220\u9664\u5934\u8282\u70b9\n      ListNode? fNext = _front!.next;\n      if (fNext != null) {\n        fNext.prev = null;\n        _front!.next = null;\n      }\n      _front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n      val = _rear!.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      // \u5220\u9664\u5c3e\u8282\u70b9\n      ListNode? rPrev = _rear!.prev;\n      if (rPrev != null) {\n        rPrev.next = null;\n        _rear!.prev = null;\n      }\n      _rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int? popFirst() {\n    return pop(true);\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int? popLast() {\n    return pop(false);\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int? peekFirst() {\n    return _front?.val;\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int? peekLast() {\n    return _rear?.val;\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> res = [];\n    for (int i = 0; i < _queSize; i++) {\n      res.add(node!.val);\n      node = node.next;\n    }\n    return res;\n  }\n}\n
    linkedlist_deque.rs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\npub struct ListNode<T> {\n    pub val: T,                                 // \u8282\u70b9\u503c\n    pub next: Option<Rc<RefCell<ListNode<T>>>>, // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    pub prev: Option<Rc<RefCell<ListNode<T>>>>, // \u524d\u9a71\u8282\u70b9\u6307\u9488\n}\n\nimpl<T> ListNode<T> {\n    pub fn new(val: T) -> Rc<RefCell<ListNode<T>>> {\n        Rc::new(RefCell::new(ListNode {\n            val,\n            next: None,\n            prev: None,\n        }))\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListDeque<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListDeque<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    pub fn push(&mut self, num: T, is_front: bool) {\n        let node = ListNode::new(num);\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        if is_front {\n            match self.front.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.rear = Some(node.clone());\n                    self.front = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                Some(old_front) => {\n                    old_front.borrow_mut().prev = Some(node.clone());\n                    node.borrow_mut().next = Some(old_front);\n                    self.front = Some(node); // \u66f4\u65b0\u5934\u8282\u70b9\n                }\n            }\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            match self.rear.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.front = Some(node.clone());\n                    self.rear = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                Some(old_rear) => {\n                    old_rear.borrow_mut().next = Some(node.clone());\n                    node.borrow_mut().prev = Some(old_rear);\n                    self.rear = Some(node); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                }\n            }\n        }\n        self.que_size += 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: T) {\n        self.push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: T) {\n        self.push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    pub fn pop(&mut self, is_front: bool) -> Option<T> {\n        // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de None\n        if self.is_empty() {\n            return None;\n        };\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front {\n            self.front.take().map(|old_front| {\n                match old_front.borrow_mut().next.take() {\n                    Some(new_front) => {\n                        new_front.borrow_mut().prev.take();\n                        self.front = Some(new_front); // \u66f4\u65b0\u5934\u8282\u70b9\n                    }\n                    None => {\n                        self.rear.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n            })\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            self.rear.take().map(|old_rear| {\n                match old_rear.borrow_mut().prev.take() {\n                    Some(new_rear) => {\n                        new_rear.borrow_mut().next.take();\n                        self.rear = Some(new_rear); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                    }\n                    None => {\n                        self.front.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_rear).ok().unwrap().into_inner().val\n            })\n        }\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    pub fn pop_first(&mut self) -> Option<T> {\n        return self.pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    pub fn pop_last(&mut self) -> Option<T> {\n        return self.pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek_first(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    pub fn peek_last(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.rear.as_ref()\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_deque.c
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\ntypedef struct DoublyListNode {\n    int val;                     // \u8282\u70b9\u503c\n    struct DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\n    struct DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\n} DoublyListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nDoublyListNode *newDoublyListNode(int num) {\n    DoublyListNode *new = (DoublyListNode *)malloc(sizeof(DoublyListNode));\n    new->val = num;\n    new->next = NULL;\n    new->prev = NULL;\n    return new;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delDoublyListNode(DoublyListNode *node) {\n    free(node);\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;                  // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n} LinkedListDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListDeque *newLinkedListDeque() {\n    LinkedListDeque *deque = (LinkedListDeque *)malloc(sizeof(LinkedListDeque));\n    deque->front = NULL;\n    deque->rear = NULL;\n    deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListdeque(LinkedListDeque *deque) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    for (int i = 0; i < deque->queSize && deque->front != NULL; i++) {\n        DoublyListNode *tmp = deque->front;\n        deque->front = deque->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e deque \u7ed3\u6784\u4f53\n    free(deque);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListDeque *deque) {\n    return (size(deque) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListDeque *deque, int num, bool isFront) {\n    DoublyListNode *node = newDoublyListNode(num);\n    // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411node\n    if (empty(deque)) {\n        deque->front = deque->rear = node;\n    }\n    // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    else if (isFront) {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n        deque->front->prev = node;\n        node->next = deque->front;\n        deque->front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n        deque->rear->next = node;\n        node->prev = deque->rear;\n        deque->rear = node;\n    }\n    deque->queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(LinkedListDeque *deque, int num) {\n    push(deque, num, true);\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(LinkedListDeque *deque, int num) {\n    push(deque, num, false);\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(LinkedListDeque *deque) {\n    assert(size(deque) && deque->front);\n    return deque->front->val;\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(LinkedListDeque *deque) {\n    assert(size(deque) && deque->rear);\n    return deque->rear->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListDeque *deque, bool isFront) {\n    if (empty(deque))\n        return -1;\n    int val;\n    // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if (isFront) {\n        val = peekFirst(deque); // \u6682\u5b58\u5934\u8282\u70b9\u503c\n        DoublyListNode *fNext = deque->front->next;\n        if (fNext) {\n            fNext->prev = NULL;\n            deque->front->next = NULL;\n        }\n        delDoublyListNode(deque->front);\n        deque->front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else {\n        val = peekLast(deque); // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n        DoublyListNode *rPrev = deque->rear->prev;\n        if (rPrev) {\n            rPrev->next = NULL;\n            deque->rear->prev = NULL;\n        }\n        delDoublyListNode(deque->rear);\n        deque->rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    deque->queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(LinkedListDeque *deque) {\n    return pop(deque, true);\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(LinkedListDeque *deque) {\n    return pop(deque, false);\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListDeque(LinkedListDeque *deque) {\n    int *arr = malloc(sizeof(int) * deque->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    DoublyListNode *node;\n    for (i = 0, node = deque->front; i < deque->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, deque->queSize);\n    free(arr);\n}\n
    linkedlist_deque.kt
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(var _val: Int) {\n    // \u8282\u70b9\u503c\n    var next: ListNode? = null // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    var prev: ListNode? = null // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? = null // \u5934\u8282\u70b9 front\n    private var rear: ListNode? = null // \u5c3e\u8282\u70b9 rear\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    fun push(num: Int, isFront: Boolean) {\n        val node = ListNode(num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty()) {\n            rear = node\n            front = rear\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        } else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++ // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        push(num, true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        push(num, false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    fun pop(isFront: Boolean): Int {\n        if (isEmpty()) \n            throw IndexOutOfBoundsException()\n        val _val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            _val = front!!._val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            val fNext = front!!.next\n            if (fNext != null) {\n                fNext.prev = null\n                front!!.next = null\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            _val = rear!!._val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            val rPrev = rear!!.prev\n            if (rPrev != null) {\n                rPrev.next = null\n                rear!!.prev = null\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize-- // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return _val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        return pop(true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        return pop(false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return rear!!._val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.rb
    =begin\nFile: linkedlist_deque.rb\nCreated Time: 2024-04-06\nAuthor: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)\n=end\n\n### \u53cc\u5411\u94fe\u8868\u8282\u70b9\nclass ListNode\n  attr_accessor :val\n  attr_accessor :next # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  attr_accessor :prev # \u524d\u8eaf\u8282\u70b9\u5f15\u7528\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(val)\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass LinkedListDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0     # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f\u64cd\u4f5c ###\n  def push(num, is_front)\n    node = ListNode.new(num)\n    # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c \u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n    if is_empty?\n      @front = @rear = node\n    # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    elsif is_front\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      @front.prev = node\n      node.next = @front\n      @front = node # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      @rear.next = node\n      node.prev = @rear\n      @rear = node # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size += 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    push(num, true)\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    push(num, false)\n  end\n\n  ### \u51fa\u961f\u64cd\u4f5c ###\n  def pop(is_front)\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if is_front\n      val = @front.val # \u6682\u5b58\u5934\u8282\u70b9\u503c\n      # \u5220\u9664\u5934\u8282\u70b9\n      fnext = @front.next\n      unless fnext.nil?\n        fnext.prev = nil\n        @front.next = nil\n      end\n      @front = fnext # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else\n      val = @rear.val # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      # \u5220\u9664\u5c3e\u8282\u70b9\n      rprev = @rear.prev\n      unless rprev.nil?\n        rprev.next = nil\n        @rear.prev = nil\n      end\n      @rear = rprev # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size -= 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    val\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    pop(true)\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_last\n    pop(false)\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @rear.val\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    node = @front\n    res = Array.new(size, 0)\n    for i in 0...size\n      res[i] = node.val\n      node = node.next\n    end\n    res\n  end\nend\n
    linkedlist_deque.zig
    // \u53cc\u5411\u94fe\u8868\u8282\u70b9\nfn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = undefined,     // \u8282\u70b9\u503c\n        next: ?*Self = null,    // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n        prev: ?*Self = null,    // \u524d\u9a71\u8282\u70b9\u6307\u9488\n\n        // Initialize a list node with specific value\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n\n// \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\nfn LinkedListDeque(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*ListNode(T) = null,                    // \u5934\u8282\u70b9 front\n        rear: ?*ListNode(T) = null,                     // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                             // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u5165\u961f\u64cd\u4f5c\n        pub fn push(self: *Self, num: T, is_front: bool) !void {\n            var node = try self.mem_allocator.create(ListNode(T));\n            node.init(num);\n            // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n            if (self.isEmpty()) {\n                self.front = node;\n                self.rear = node;\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n            } else if (is_front) {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                self.front.?.prev = node;\n                node.next = self.front;\n                self.front = node;  // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n            } else {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                self.rear.?.next = node;\n                node.prev = self.rear;\n                self.rear = node;   // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size += 1;      // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        } \n\n        // \u961f\u9996\u5165\u961f\n        pub fn pushFirst(self: *Self, num: T) !void {\n            try self.push(num, true);\n        } \n\n        // \u961f\u5c3e\u5165\u961f\n        pub fn pushLast(self: *Self, num: T) !void {\n            try self.push(num, false);\n        } \n\n        // \u51fa\u961f\u64cd\u4f5c\n        pub fn pop(self: *Self, is_front: bool) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            var val: T = undefined;\n            // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n            if (is_front) {\n                val = self.front.?.val;     // \u6682\u5b58\u5934\u8282\u70b9\u503c\n                // \u5220\u9664\u5934\u8282\u70b9\n                var fNext = self.front.?.next;\n                if (fNext != null) {\n                    fNext.?.prev = null;\n                    self.front.?.next = null;\n                }\n                self.front = fNext;         // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n            } else {\n                val = self.rear.?.val;      // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n                // \u5220\u9664\u5c3e\u8282\u70b9\n                var rPrev = self.rear.?.prev;\n                if (rPrev != null) {\n                    rPrev.?.next = null;\n                    self.rear.?.prev = null;\n                }\n                self.rear = rPrev;          // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size -= 1;              // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n            return val;\n        } \n\n        // \u961f\u9996\u51fa\u961f\n        pub fn popFirst(self: *Self) T {\n            return self.pop(true);\n        } \n\n        // \u961f\u5c3e\u51fa\u961f\n        pub fn popLast(self: *Self) T {\n            return self.pop(false);\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peekFirst(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\n        pub fn peekLast(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.rear.?.val;\n        }\n\n        // \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    "},{"location":"chapter_stack_and_queue/deque/#2","title":"2. \u00a0 \u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0","text":"

    \u5982\u56fe 5-9 \u6240\u793a\uff0c\u4e0e\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u961f\u5217\u7c7b\u4f3c\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528\u73af\u5f62\u6570\u7ec4\u6765\u5b9e\u73b0\u53cc\u5411\u961f\u5217\u3002

    ArrayDequepush_last()push_first()pop_last()pop_first()

    \u56fe 5-9 \u00a0 \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u53cc\u5411\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u5728\u961f\u5217\u7684\u5b9e\u73b0\u57fa\u7840\u4e0a\uff0c\u4ec5\u9700\u589e\u52a0\u201c\u961f\u9996\u5165\u961f\u201d\u548c\u201c\u961f\u5c3e\u51fa\u961f\u201d\u7684\u65b9\u6cd5\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_deque.py
    class ArrayDeque:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self, capacity: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * capacity\n        self._front: int = 0\n        self._size: int = 0\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def index(self, i: int) -> int:\n        \"\"\"\u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15\"\"\"\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + self.capacity()) % self.capacity()\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self._front = self.index(self._front - 1)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self._nums[self._front] = num\n        self._size += 1\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        rear = self.index(self._front + self._size)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        num = self.peek_first()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self._front = self.index(self._front + 1)\n        self._size -= 1\n        return num\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        num = self.peek_last()\n        self._size -= 1\n        return num\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        last = self.index(self._front + self._size - 1)\n        return self._nums[last]\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        res = []\n        for i in range(self._size):\n            res.append(self._nums[self.index(self._front + i)])\n        return res\n
    array_deque.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  private:\n    vector<int> nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;      // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayDeque(int capacity) {\n        nums.resize(capacity);\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return nums.size();\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> res(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n};\n
    array_deque.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        this.nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int Index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + Capacity()) % Capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = Index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = Index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int PopFirst() {\n        int num = PeekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = Index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int PopLast() {\n        int num = PeekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int PeekFirst() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int PeekLast() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = Index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[Index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype arrayDeque struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayDeque(queCapacity int) *arrayDeque {\n    return &arrayDeque{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayDeque) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayDeque) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nfunc (q *arrayDeque) index(i int) int {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + q.queCapacity) % q.queCapacity\n}\n\n/* \u961f\u9996\u5165\u961f */\nfunc (q *arrayDeque) pushFirst(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    q.front = q.index(q.front - 1)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    q.nums[q.front] = num\n    q.queSize++\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nfunc (q *arrayDeque) pushLast(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear := q.index(q.front + q.queSize)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u961f\u9996\u51fa\u961f */\nfunc (q *arrayDeque) popFirst() any {\n    num := q.peekFirst()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    q.front = q.index(q.front + 1)\n    q.queSize--\n    return num\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nfunc (q *arrayDeque) popLast() any {\n    num := q.peekLast()\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayDeque) peekFirst() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (q *arrayDeque) peekLast() any {\n    if q.isEmpty() {\n        return nil\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last := q.index(q.front + q.queSize - 1)\n    return q.nums[last]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayDeque) toSlice() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res := make([]int, q.queSize)\n    for i, j := 0, q.front; i < q.queSize; i++ {\n        res[i] = q.nums[q.index(j)]\n        j++\n    }\n    return res\n}\n
    array_deque.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(capacity: Int) {\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private func index(i: Int) -> Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(i: front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        _size += 1\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = index(i: front + size())\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        let num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(i: front + 1)\n        _size -= 1\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        let num = peekLast()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = index(i: front + size() - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[index(i: $0)] }\n    }\n}\n
    array_deque.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n        this.#front = 0;\n        this.#queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.#front = this.index(this.#front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.#nums[this.#front] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear = this.index(this.#front + this.#queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst() {\n        const num = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.#front = this.index(this.#front + 1);\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast() {\n        const num = this.peekLast();\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.#front + this.#queSize - 1);\n        return this.#nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res = [];\n        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {\n            res[i] = this.#nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = 0;\n        this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i: number): number {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.front = this.index(this.front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.nums[this.front] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear: number = this.index(this.front + this.queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst(): number {\n        const num: number = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.front = this.index(this.front + 1);\n        this.queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast(): number {\n        const num: number = this.peekLast();\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.nums[this.front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.front + this.queSize - 1);\n        return this.nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res: number[] = [];\n        for (let i = 0, j = this.front; i < this.queSize; i++, j++) {\n            res[i] = this.nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  late List<int> _nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayDeque(int capacity) {\n    this._nums = List.filled(capacity, 0);\n    this._front = this._queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n  int capacity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n  int index(int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + capacity()) % capacity();\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 _front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    _front = index(_front - 1);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u9996\n    _nums[_front] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = index(_front + _queSize);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int popFirst() {\n    int _num = peekFirst();\n    // \u961f\u9996\u6307\u9488\u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n    _front = index(_front + 1);\n    _queSize--;\n    return _num;\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int popLast() {\n    int _num = peekLast();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peekFirst() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int peekLast() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    int last = index(_front + _queSize - 1);\n    return _nums[last];\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[index(j)];\n    }\n    return res;\n  }\n}\n
    array_deque.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nstruct ArrayDeque {\n    nums: Vec<i32>,  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: usize,    // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: usize, // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n}\n\nimpl ArrayDeque {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        Self {\n            nums: vec![0; capacity],\n            front: 0,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        self.nums.len()\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    fn index(&self, i: i32) -> usize {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return ((i + self.capacity() as i32) % self.capacity() as i32) as usize;\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self.front = self.index(self.front as i32 - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self.nums[self.front] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = self.index(self.front as i32 + self.que_size as i32);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fn pop_first(&mut self) -> i32 {\n        let num = self.peek_first();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self.front = self.index(self.front as i32 + 1);\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fn pop_last(&mut self) -> i32 {\n        let num = self.peek_last();\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek_first(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        self.nums[self.front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fn peek_last(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = self.index(self.front as i32 + self.que_size as i32 - 1);\n        self.nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fn to_array(&self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut res = vec![0; self.que_size];\n        let mut j = self.front;\n        for i in 0..self.que_size {\n            res[i] = self.nums[self.index(j as i32)];\n            j += 1;\n        }\n        res\n    }\n}\n
    array_deque.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayDeque *newArrayDeque(int capacity) {\n    ArrayDeque *deque = (ArrayDeque *)malloc(sizeof(ArrayDeque));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    deque->queCapacity = capacity;\n    deque->nums = (int *)malloc(sizeof(int) * deque->queCapacity);\n    deque->front = deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayDeque(ArrayDeque *deque) {\n    free(deque->nums);\n    free(deque);\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayDeque *deque) {\n    return deque->queCapacity;\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayDeque *deque) {\n    return deque->queSize == 0;\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nint dequeIndex(ArrayDeque *deque, int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return ((i + capacity(deque)) % capacity(deque));\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u56de\u5230\u5c3e\u90e8\n    deque->front = dequeIndex(deque, deque->front - 1);\n    // \u5c06 num \u6dfb\u52a0\u5230\u961f\u9996\n    deque->nums[deque->front] = num;\n    deque->queSize++;\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = dequeIndex(deque, deque->front + deque->queSize);\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    deque->nums[rear] = num;\n    deque->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    return deque->nums[deque->front];\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    int last = dequeIndex(deque, deque->front + deque->queSize - 1);\n    return deque->nums[last];\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(ArrayDeque *deque) {\n    int num = peekFirst(deque);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    deque->front = dequeIndex(deque, deque->front + 1);\n    deque->queSize--;\n    return num;\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(ArrayDeque *deque) {\n    int num = peekLast(deque);\n    deque->queSize--;\n    return num;\n}\n
    array_deque.kt
    /* \u6784\u9020\u65b9\u6cd5 */\nclass ArrayDeque(capacity: Int) {\n    private var nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private fun index(i: Int): Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        queSize++\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        val rear = index(front + queSize)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        val num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1)\n        queSize--\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        val num = peekLast()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        val last = index(front + queSize - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[index(j)]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_deque.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass ArrayDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(capacity)\n    @nums = Array.new(capacity, 0)\n    @front = 0\n    @size = 0\n  end\n\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    @front = index(@front - 1)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    @nums[@front] = num\n    @size += 1\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear = index(@front + size)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    num = peek_first\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    @front = index(@front + 1)\n    @size -= 1\n    num\n  end\n\n  ### \u961f\u5c3e\u51fa\u961f ###\n  def pop_last\n    num = peek_last\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last = index(@front + size - 1)\n    @nums[last]\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res = []\n    for i in 0...size\n      res << @nums[index(@front + i)]\n    end\n    res\n  end\n\n  private\n\n  ### \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 ###\n  def index(i)\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    (i + capacity) % capacity\n  end\nend\n
    array_deque.zig
    [class]{ArrayDeque}-[func]{}\n
    "},{"location":"chapter_stack_and_queue/deque/#533","title":"5.3.3 \u00a0 \u53cc\u5411\u961f\u5217\u5e94\u7528","text":"

    \u53cc\u5411\u961f\u5217\u517c\u5177\u6808\u4e0e\u961f\u5217\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u5b83\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u4e24\u8005\u7684\u6240\u6709\u5e94\u7528\u573a\u666f\uff0c\u540c\u65f6\u63d0\u4f9b\u66f4\u9ad8\u7684\u81ea\u7531\u5ea6\u3002

    \u6211\u4eec\u77e5\u9053\uff0c\u8f6f\u4ef6\u7684\u201c\u64a4\u9500\u201d\u529f\u80fd\u901a\u5e38\u4f7f\u7528\u6808\u6765\u5b9e\u73b0\uff1a\u7cfb\u7edf\u5c06\u6bcf\u6b21\u66f4\u6539\u64cd\u4f5c push \u5230\u6808\u4e2d\uff0c\u7136\u540e\u901a\u8fc7 pop \u5b9e\u73b0\u64a4\u9500\u3002\u7136\u800c\uff0c\u8003\u8651\u5230\u7cfb\u7edf\u8d44\u6e90\u7684\u9650\u5236\uff0c\u8f6f\u4ef6\u901a\u5e38\u4f1a\u9650\u5236\u64a4\u9500\u7684\u6b65\u6570\uff08\u4f8b\u5982\u4ec5\u5141\u8bb8\u4fdd\u5b58 \\(50\\) \u6b65\uff09\u3002\u5f53\u6808\u7684\u957f\u5ea6\u8d85\u8fc7 \\(50\\) \u65f6\uff0c\u8f6f\u4ef6\u9700\u8981\u5728\u6808\u5e95\uff08\u961f\u9996\uff09\u6267\u884c\u5220\u9664\u64cd\u4f5c\u3002\u4f46\u6808\u65e0\u6cd5\u5b9e\u73b0\u8be5\u529f\u80fd\uff0c\u6b64\u65f6\u5c31\u9700\u8981\u4f7f\u7528\u53cc\u5411\u961f\u5217\u6765\u66ff\u4ee3\u6808\u3002\u8bf7\u6ce8\u610f\uff0c\u201c\u64a4\u9500\u201d\u7684\u6838\u5fc3\u903b\u8f91\u4ecd\u7136\u9075\u5faa\u6808\u7684\u5148\u5165\u540e\u51fa\u539f\u5219\uff0c\u53ea\u662f\u53cc\u5411\u961f\u5217\u80fd\u591f\u66f4\u52a0\u7075\u6d3b\u5730\u5b9e\u73b0\u4e00\u4e9b\u989d\u5916\u903b\u8f91\u3002

    "},{"location":"chapter_stack_and_queue/queue/","title":"5.2 \u00a0 \u961f\u5217","text":"

    \u961f\u5217\uff08queue\uff09\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u5148\u51fa\u89c4\u5219\u7684\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002\u987e\u540d\u601d\u4e49\uff0c\u961f\u5217\u6a21\u62df\u4e86\u6392\u961f\u73b0\u8c61\uff0c\u5373\u65b0\u6765\u7684\u4eba\u4e0d\u65ad\u52a0\u5165\u961f\u5217\u5c3e\u90e8\uff0c\u800c\u4f4d\u4e8e\u961f\u5217\u5934\u90e8\u7684\u4eba\u9010\u4e2a\u79bb\u5f00\u3002

    \u5982\u56fe 5-4 \u6240\u793a\uff0c\u6211\u4eec\u5c06\u961f\u5217\u5934\u90e8\u79f0\u4e3a\u201c\u961f\u9996\u201d\uff0c\u5c3e\u90e8\u79f0\u4e3a\u201c\u961f\u5c3e\u201d\uff0c\u5c06\u628a\u5143\u7d20\u52a0\u5165\u961f\u5c3e\u7684\u64cd\u4f5c\u79f0\u4e3a\u201c\u5165\u961f\u201d\uff0c\u5220\u9664\u961f\u9996\u5143\u7d20\u7684\u64cd\u4f5c\u79f0\u4e3a\u201c\u51fa\u961f\u201d\u3002

    \u56fe 5-4 \u00a0 \u961f\u5217\u7684\u5148\u5165\u5148\u51fa\u89c4\u5219

    "},{"location":"chapter_stack_and_queue/queue/#521","title":"5.2.1 \u00a0 \u961f\u5217\u5e38\u7528\u64cd\u4f5c","text":"

    \u961f\u5217\u7684\u5e38\u89c1\u64cd\u4f5c\u5982\u8868 5-2 \u6240\u793a\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u7684\u65b9\u6cd5\u540d\u79f0\u53ef\u80fd\u4f1a\u6709\u6240\u4e0d\u540c\u3002\u6211\u4eec\u5728\u6b64\u91c7\u7528\u4e0e\u6808\u76f8\u540c\u7684\u65b9\u6cd5\u547d\u540d\u3002

    \u8868 5-2 \u00a0 \u961f\u5217\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5\u540d \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push() \u5143\u7d20\u5165\u961f\uff0c\u5373\u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u961f\u5c3e \\(O(1)\\) pop() \u961f\u9996\u5143\u7d20\u51fa\u961f \\(O(1)\\) peek() \u8bbf\u95ee\u961f\u9996\u5143\u7d20 \\(O(1)\\)

    \u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u4e2d\u73b0\u6210\u7684\u961f\u5217\u7c7b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig queue.py
    from collections import deque\n\n# \u521d\u59cb\u5316\u961f\u5217\n# \u5728 Python \u4e2d\uff0c\u6211\u4eec\u4e00\u822c\u5c06\u53cc\u5411\u961f\u5217\u7c7b deque \u5f53\u4f5c\u961f\u5217\u4f7f\u7528\n# \u867d\u7136 queue.Queue() \u662f\u7eaf\u6b63\u7684\u961f\u5217\u7c7b\uff0c\u4f46\u4e0d\u592a\u597d\u7528\uff0c\u56e0\u6b64\u4e0d\u63a8\u8350\nque: deque[int] = deque()\n\n# \u5143\u7d20\u5165\u961f\nque.append(1)\nque.append(3)\nque.append(2)\nque.append(5)\nque.append(4)\n\n# \u8bbf\u95ee\u961f\u9996\u5143\u7d20\nfront: int = que[0]\n\n# \u5143\u7d20\u51fa\u961f\npop: int = que.popleft()\n\n# \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\nsize: int = len(que)\n\n# \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = len(que) == 0\n
    queue.cpp
    /* \u521d\u59cb\u5316\u961f\u5217 */\nqueue<int> queue;\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint front = queue.front();\n\n/* \u5143\u7d20\u51fa\u961f */\nqueue.pop();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.size();\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty = queue.empty();\n
    queue.java
    /* \u521d\u59cb\u5316\u961f\u5217 */\nQueue<Integer> queue = new LinkedList<>();\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.offer(1);\nqueue.offer(3);\nqueue.offer(2);\nqueue.offer(5);\nqueue.offer(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek = queue.peek();\n\n/* \u5143\u7d20\u51fa\u961f */\nint pop = queue.poll();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.size();\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = queue.isEmpty();\n
    queue.cs
    /* \u521d\u59cb\u5316\u961f\u5217 */\nQueue<int> queue = new();\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.Enqueue(1);\nqueue.Enqueue(3);\nqueue.Enqueue(2);\nqueue.Enqueue(5);\nqueue.Enqueue(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek = queue.Peek();\n\n/* \u5143\u7d20\u51fa\u961f */\nint pop = queue.Dequeue();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.Count;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = queue.Count == 0;\n
    queue_test.go
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// \u5728 Go \u4e2d\uff0c\u5c06 list \u4f5c\u4e3a\u961f\u5217\u6765\u4f7f\u7528\nqueue := list.New()\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.PushBack(1)\nqueue.PushBack(3)\nqueue.PushBack(2)\nqueue.PushBack(5)\nqueue.PushBack(4)\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\npeek := queue.Front()\n\n/* \u5143\u7d20\u51fa\u961f */\npop := queue.Front()\nqueue.Remove(pop)\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nsize := queue.Len()\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nisEmpty := queue.Len() == 0\n
    queue.swift
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// Swift \u6ca1\u6709\u5185\u7f6e\u7684\u961f\u5217\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nvar queue: [Int] = []\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.append(1)\nqueue.append(3)\nqueue.append(2)\nqueue.append(5)\nqueue.append(4)\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nlet peek = queue.first!\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u7531\u4e8e\u662f\u6570\u7ec4\uff0c\u56e0\u6b64 removeFirst \u7684\u590d\u6742\u5ea6\u4e3a O(n)\nlet pool = queue.removeFirst()\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = queue.count\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = queue.isEmpty\n
    queue.js
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// JavaScript \u6ca1\u6709\u5185\u7f6e\u7684\u961f\u5217\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nconst queue = [];\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nconst peek = queue[0];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u56e0\u6b64 shift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst pop = queue.shift();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nconst size = queue.length;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst empty = queue.length === 0;\n
    queue.ts
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// TypeScript \u6ca1\u6709\u5185\u7f6e\u7684\u961f\u5217\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nconst queue: number[] = [];\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nconst peek = queue[0];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u56e0\u6b64 shift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst pop = queue.shift();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nconst size = queue.length;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst empty = queue.length === 0;\n
    queue.dart
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// \u5728 Dart \u4e2d\uff0c\u961f\u5217\u7c7b Qeque \u662f\u53cc\u5411\u961f\u5217\uff0c\u4e5f\u53ef\u4f5c\u4e3a\u961f\u5217\u4f7f\u7528\nQueue<int> queue = Queue();\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.add(1);\nqueue.add(3);\nqueue.add(2);\nqueue.add(5);\nqueue.add(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek = queue.first;\n\n/* \u5143\u7d20\u51fa\u961f */\nint pop = queue.removeFirst();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.length;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = queue.isEmpty;\n
    queue.rs
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 Rust \u4e2d\u4f7f\u7528\u53cc\u5411\u961f\u5217\u4f5c\u4e3a\u666e\u901a\u961f\u5217\u6765\u4f7f\u7528\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push_back(1);\ndeque.push_back(3);\ndeque.push_back(2);\ndeque.push_back(5);\ndeque.push_back(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nif let Some(front) = deque.front() {\n}\n\n/* \u5143\u7d20\u51fa\u961f */\nif let Some(pop) = deque.pop_front() {\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = deque.len();\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = deque.is_empty();\n
    queue.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u961f\u5217\n
    queue.kt
    /* \u521d\u59cb\u5316\u961f\u5217 */\nval queue = LinkedList<Int>()\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.offer(1)\nqueue.offer(3)\nqueue.offer(2)\nqueue.offer(5)\nqueue.offer(4)\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nval peek = queue.peek()\n\n/* \u5143\u7d20\u51fa\u961f */\nval pop = queue.poll()\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nval size = queue.size\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = queue.isEmpty()\n
    queue.rb
    # \u521d\u59cb\u5316\u961f\u5217\n# Ruby \u5185\u7f6e\u7684\u961f\u5217\uff08Thread::Queue) \u6ca1\u6709 peek \u548c\u904d\u5386\u65b9\u6cd5\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nqueue = []\n\n# \u5143\u7d20\u5165\u961f\nqueue.push(1)\nqueue.push(3)\nqueue.push(2)\nqueue.push(5)\nqueue.push(4)\n\n# \u8bbf\u95ee\u961f\u5217\u5143\u7d20\npeek = queue.first\n\n# \u5143\u7d20\u51fa\u961f\n# \u6e05\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cArray#shift \u65b9\u6cd5\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\npop = queue.shift\n\n# \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\nsize = queue.length\n\n# \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty = queue.empty?\n
    queue.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/queue/#522","title":"5.2.2 \u00a0 \u961f\u5217\u5b9e\u73b0","text":"

    \u4e3a\u4e86\u5b9e\u73b0\u961f\u5217\uff0c\u6211\u4eec\u9700\u8981\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u5728\u4e00\u7aef\u6dfb\u52a0\u5143\u7d20\uff0c\u5e76\u5728\u53e6\u4e00\u7aef\u5220\u9664\u5143\u7d20\uff0c\u94fe\u8868\u548c\u6570\u7ec4\u90fd\u7b26\u5408\u8981\u6c42\u3002

    "},{"location":"chapter_stack_and_queue/queue/#1","title":"1. \u00a0 \u57fa\u4e8e\u94fe\u8868\u7684\u5b9e\u73b0","text":"

    \u5982\u56fe 5-5 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u94fe\u8868\u7684\u201c\u5934\u8282\u70b9\u201d\u548c\u201c\u5c3e\u8282\u70b9\u201d\u5206\u522b\u89c6\u4e3a\u201c\u961f\u9996\u201d\u548c\u201c\u961f\u5c3e\u201d\uff0c\u89c4\u5b9a\u961f\u5c3e\u4ec5\u53ef\u6dfb\u52a0\u8282\u70b9\uff0c\u961f\u9996\u4ec5\u53ef\u5220\u9664\u8282\u70b9\u3002

    LinkedListQueuepush()pop()

    \u56fe 5-5 \u00a0 \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u4ee5\u4e0b\u662f\u7528\u94fe\u8868\u5b9e\u73b0\u961f\u5217\u7684\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_queue.py
    class LinkedListQueue:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        node = ListNode(num)\n        # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if self._front is None:\n            self._front = node\n            self._rear = node\n        # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else:\n            self._rear.next = node\n            self._rear = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num = self.peek()\n        # \u5220\u9664\u5934\u8282\u70b9\n        self._front = self._front.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        queue = []\n        temp = self._front\n        while temp:\n            queue.append(temp.val)\n            temp = temp.next\n        return queue\n
    linkedlist_queue.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  private:\n    ListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;\n\n  public:\n    LinkedListQueue() {\n        front = nullptr;\n        rear = nullptr;\n        queSize = 0;\n    }\n\n    ~LinkedListQueue() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(front);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode *node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == nullptr) {\n            front = node;\n            rear = node;\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear->next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        ListNode *tmp = front;\n        front = front->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (size() == 0)\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_queue.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    ListNode? front, rear;  // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear \n    int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else if (rear != null) {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (front == null)\n            return [];\n\n        ListNode? node = front;\n        int[] res = new int[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntype linkedListQueue struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u961f\u5217\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newLinkedListQueue() *linkedListQueue {\n    return &linkedListQueue{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u961f */\nfunc (s *linkedListQueue) push(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u961f */\nfunc (s *linkedListQueue) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListQueue) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListQueue) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListQueue) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListQueue) toList() *list.List {\n    return s.data\n}\n
    linkedlist_queue.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private var front: ListNode? // \u5934\u8282\u70b9\n    private var rear: ListNode? // \u5c3e\u8282\u70b9\n    private var _size: Int\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let node = ListNode(x: num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if front == nil {\n            front = node\n            rear = node\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear?.next = node\n            rear = node\n        }\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    #front; // \u5934\u8282\u70b9 #front\n    #rear; // \u5c3e\u8282\u70b9 #rear\n    #queSize = 0;\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.#front) {\n            this.#front = node;\n            this.#rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.#rear.next = node;\n            this.#rear = node;\n        }\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.#front = this.#front.next;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#front;\n        const res = new Array(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private front: ListNode | null; // \u5934\u8282\u70b9 front\n    private rear: ListNode | null; // \u5c3e\u8282\u70b9 rear\n    private queSize: number = 0;\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.front) {\n            this.front = node;\n            this.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.rear!.next = node;\n            this.rear = node;\n        }\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        if (!this.front) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.front = this.front.next;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.front;\n        const res = new Array<number>(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.dart
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  ListNode? _front; // \u5934\u8282\u70b9 _front\n  ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n  LinkedListQueue() {\n    _front = null;\n    _rear = null;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 _num\n    final node = ListNode(_num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (_front == null) {\n      _front = node;\n      _rear = node;\n    } else {\n      // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n      _rear!.next = node;\n      _rear = node;\n    }\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    final int _num = peek();\n    // \u5220\u9664\u5934\u8282\u70b9\n    _front = _front!.next;\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (_queSize == 0) {\n      throw Exception('\u961f\u5217\u4e3a\u7a7a');\n    }\n    return _front!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> queue = [];\n    while (node != null) {\n      queue.add(node.val);\n      node = node.next;\n    }\n    return queue;\n  }\n}\n
    linkedlist_queue.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListQueue<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListQueue<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f */\n    pub fn push(&mut self, num: T) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let new_rear = ListNode::new(num);\n        match self.rear.take() {\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            Some(old_rear) => {\n                old_rear.borrow_mut().next = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            None => {\n                self.front = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n        }\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    pub fn pop(&mut self) -> Option<T> {\n        self.front.take().map(|old_front| {\n            match old_front.borrow_mut().next.take() {\n                Some(new_front) => {\n                    self.front = Some(new_front);\n                }\n                None => {\n                    self.rear.take();\n                }\n            }\n            self.que_size -= 1;\n            Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_queue.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    ListNode *front, *rear;\n    int queSize;\n} LinkedListQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListQueue *newLinkedListQueue() {\n    LinkedListQueue *queue = (LinkedListQueue *)malloc(sizeof(LinkedListQueue));\n    queue->front = NULL;\n    queue->rear = NULL;\n    queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListQueue(LinkedListQueue *queue) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    while (queue->front != NULL) {\n        ListNode *tmp = queue->front;\n        queue->front = queue->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e queue \u7ed3\u6784\u4f53\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListQueue *queue) {\n    return (size(queue) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListQueue *queue, int num) {\n    // \u5c3e\u8282\u70b9\u5904\u6dfb\u52a0 node\n    ListNode *node = newListNode(num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (queue->front == NULL) {\n        queue->front = node;\n        queue->rear = node;\n    }\n    // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else {\n        queue->rear->next = node;\n        queue->rear = node;\n    }\n    queue->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(LinkedListQueue *queue) {\n    assert(size(queue) && queue->front);\n    return queue->front->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListQueue *queue) {\n    int num = peek(queue);\n    ListNode *tmp = queue->front;\n    queue->front = queue->front->next;\n    free(tmp);\n    queue->queSize--;\n    return num;\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListQueue(LinkedListQueue *queue) {\n    int *arr = malloc(sizeof(int) * queue->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    ListNode *node;\n    for (i = 0, node = queue->front; i < queue->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, queue->queSize);\n    free(arr);\n}\n
    linkedlist_queue.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue(\n    // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private var front: ListNode? = null,\n    private var rear: ListNode? = null,\n    private var queSize: Int = 0\n) {\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        val node = ListNode(num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node\n            rear = node\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear?.next = node\n            rear = node\n        }\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5934\u73b0\u7684\u961f\u5217 ###\nclass LinkedListQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @front.nil?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n    node = ListNode.new(num)\n\n    # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\uff0c\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if @front.nil?\n      @front = node\n      @rear = node\n    # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u4ee4\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else\n      @rear.next = node\n      @rear = node\n    end\n\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u5220\u9664\u5934\u8282\u70b9\n    @front = @front.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u5c06\u94fe\u8868\u4e3a Array \u5e76\u8fd4\u56de ###\n  def to_array\n    queue = []\n    temp = @front\n    while temp\n      queue << temp.val\n      temp = temp.next\n    end\n    queue\n  end\nend\n
    linkedlist_queue.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\nfn LinkedListQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*inc.ListNode(T) = null,                // \u5934\u8282\u70b9 front\n        rear: ?*inc.ListNode(T) = null,                 // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                            // \u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            if (self.front == null) {\n                self.front = node;\n                self.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            } else {\n                self.rear.?.next = node;\n                self.rear = node;\n            }\n            self.que_size += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u5220\u9664\u5934\u8282\u70b9\n            self.front = self.front.?.next;\n            self.que_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/queue/#2","title":"2. \u00a0 \u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0","text":"

    \u5728\u6570\u7ec4\u4e2d\u5220\u9664\u9996\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u8fd9\u4f1a\u5bfc\u81f4\u51fa\u961f\u64cd\u4f5c\u6548\u7387\u8f83\u4f4e\u3002\u7136\u800c\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u4ee5\u4e0b\u5de7\u5999\u65b9\u6cd5\u6765\u907f\u514d\u8fd9\u4e2a\u95ee\u9898\u3002

    \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u53d8\u91cf front \u6307\u5411\u961f\u9996\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u5e76\u7ef4\u62a4\u4e00\u4e2a\u53d8\u91cf size \u7528\u4e8e\u8bb0\u5f55\u961f\u5217\u957f\u5ea6\u3002\u5b9a\u4e49 rear = front + size \uff0c\u8fd9\u4e2a\u516c\u5f0f\u8ba1\u7b97\u51fa\u7684 rear \u6307\u5411\u961f\u5c3e\u5143\u7d20\u4e4b\u540e\u7684\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\u3002

    \u57fa\u4e8e\u6b64\u8bbe\u8ba1\uff0c\u6570\u7ec4\u4e2d\u5305\u542b\u5143\u7d20\u7684\u6709\u6548\u533a\u95f4\u4e3a [front, rear - 1]\uff0c\u5404\u79cd\u64cd\u4f5c\u7684\u5b9e\u73b0\u65b9\u6cd5\u5982\u56fe 5-6 \u6240\u793a\u3002

    • \u5165\u961f\u64cd\u4f5c\uff1a\u5c06\u8f93\u5165\u5143\u7d20\u8d4b\u503c\u7ed9 rear \u7d22\u5f15\u5904\uff0c\u5e76\u5c06 size \u589e\u52a0 1 \u3002
    • \u51fa\u961f\u64cd\u4f5c\uff1a\u53ea\u9700\u5c06 front \u589e\u52a0 1 \uff0c\u5e76\u5c06 size \u51cf\u5c11 1 \u3002

    \u53ef\u4ee5\u770b\u5230\uff0c\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u90fd\u53ea\u9700\u8fdb\u884c\u4e00\u6b21\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(1)\\) \u3002

    ArrayQueuepush()pop()

    \u56fe 5-6 \u00a0 \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0\u4e00\u4e2a\u95ee\u9898\uff1a\u5728\u4e0d\u65ad\u8fdb\u884c\u5165\u961f\u548c\u51fa\u961f\u7684\u8fc7\u7a0b\u4e2d\uff0cfront \u548c rear \u90fd\u5728\u5411\u53f3\u79fb\u52a8\uff0c\u5f53\u5b83\u4eec\u5230\u8fbe\u6570\u7ec4\u5c3e\u90e8\u65f6\u5c31\u65e0\u6cd5\u7ee7\u7eed\u79fb\u52a8\u4e86\u3002\u4e3a\u4e86\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u7ec4\u89c6\u4e3a\u9996\u5c3e\u76f8\u63a5\u7684\u201c\u73af\u5f62\u6570\u7ec4\u201d\u3002

    \u5bf9\u4e8e\u73af\u5f62\u6570\u7ec4\uff0c\u6211\u4eec\u9700\u8981\u8ba9 front \u6216 rear \u5728\u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u76f4\u63a5\u56de\u5230\u6570\u7ec4\u5934\u90e8\u7ee7\u7eed\u904d\u5386\u3002\u8fd9\u79cd\u5468\u671f\u6027\u89c4\u5f8b\u53ef\u4ee5\u901a\u8fc7\u201c\u53d6\u4f59\u64cd\u4f5c\u201d\u6765\u5b9e\u73b0\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_queue.py
    class ArrayQueue:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self, size: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * size  # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n        self._front: int = 0  # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        self._size: int = 0  # \u961f\u5217\u957f\u5ea6\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            raise IndexError(\"\u961f\u5217\u5df2\u6ee1\")\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        rear: int = (self._front + self._size) % self.capacity()\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num: int = self.peek()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self._front = (self._front + 1) % self.capacity()\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        res = [0] * self.size()\n        j: int = self._front\n        for i in range(self.size()):\n            res[i] = self._nums[(j % self.capacity())]\n            j += 1\n        return res\n
    array_queue.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  private:\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u961f\u5217\u957f\u5ea6\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n\n  public:\n    ArrayQueue(int capacity) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = new int[capacity];\n        queCapacity = capacity;\n        front = queSize = 0;\n    }\n\n    ~ArrayQueue() {\n        delete[] nums;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return queCapacity;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        if (queSize == queCapacity) {\n            cout << \"\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % queCapacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % queCapacity;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u5c06\u6570\u7ec4\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> arr(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            arr[i] = nums[j % queCapacity];\n        }\n        return arr;\n    }\n};\n
    array_queue.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % Capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % Capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % this.Capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntype arrayQueue struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayQueue(queCapacity int) *arrayQueue {\n    return &arrayQueue{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayQueue) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayQueue) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u5165\u961f */\nfunc (q *arrayQueue) push(num int) {\n    // \u5f53 rear == queCapacity \u8868\u793a\u961f\u5217\u5df2\u6ee1\n    if q.queSize == q.queCapacity {\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear := (q.front + q.queSize) % q.queCapacity\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u51fa\u961f */\nfunc (q *arrayQueue) pop() any {\n    num := q.peek()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    q.front = (q.front + 1) % q.queCapacity\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayQueue) peek() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayQueue) toSlice() []int {\n    rear := (q.front + q.queSize)\n    if rear >= q.queCapacity {\n        rear %= q.queCapacity\n        return append(q.nums[q.front:], q.nums[:rear]...)\n    }\n    return q.nums[q.front:rear]\n}\n
    array_queue.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u961f\u5217\u957f\u5ea6\n\n    init(capacity: Int) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        if size() == capacity() {\n            print(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (front + size()) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[$0 % capacity()] }\n    }\n}\n
    array_queue.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front = 0; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.#front + this.size) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.#front = (this.#front + 1) % this.capacity;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.#front; i < this.size; i++, j++) {\n            arr[i] = this.#nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.front + this.queSize) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.front = (this.front + 1) % this.capacity;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.nums[this.front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.front; i < this.size; i++, j++) {\n            arr[i] = this.nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  late List<int> _nums; // \u7528\u4e8e\u50a8\u5b58\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u961f\u5217\u957f\u5ea6\n\n  ArrayQueue(int capacity) {\n    _nums = List.filled(capacity, 0);\n    _front = _queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n  int capaCity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    if (_queSize == capaCity()) {\n      throw Exception(\"\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (_front + _queSize) % capaCity();\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    int _num = peek();\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    _front = (_front + 1) % capaCity();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8fd4\u56de Array */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    final List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[j % capaCity()];\n    }\n    return res;\n  }\n}\n
    array_queue.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nstruct ArrayQueue {\n    nums: Vec<i32>,    // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: i32,        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: i32,     // \u961f\u5217\u957f\u5ea6\n    que_capacity: i32, // \u961f\u5217\u5bb9\u91cf\n}\n\nimpl ArrayQueue {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(capacity: i32) -> ArrayQueue {\n        ArrayQueue {\n            nums: vec![0; capacity as usize],\n            front: 0,\n            que_size: 0,\n            que_capacity: capacity,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fn capacity(&self) -> i32 {\n        self.que_capacity\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fn size(&self) -> i32 {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u5165\u961f */\n    fn push(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (self.front + self.que_size) % self.que_capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear as usize] = num;\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    fn pop(&mut self) -> i32 {\n        let num = self.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self.front = (self.front + 1) % self.que_capacity;\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"index out of bounds\");\n        }\n        self.nums[self.front as usize]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fn to_vector(&self) -> Vec<i32> {\n        let cap = self.que_capacity;\n        let mut j = self.front;\n        let mut arr = vec![0; self.que_size as usize];\n        for i in 0..self.que_size {\n            arr[i as usize] = self.nums[(j % cap) as usize];\n            j += 1;\n        }\n        arr\n    }\n}\n
    array_queue.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayQueue *newArrayQueue(int capacity) {\n    ArrayQueue *queue = (ArrayQueue *)malloc(sizeof(ArrayQueue));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    queue->queCapacity = capacity;\n    queue->nums = (int *)malloc(sizeof(int) * queue->queCapacity);\n    queue->front = queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayQueue(ArrayQueue *queue) {\n    free(queue->nums);\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayQueue *queue) {\n    return queue->queCapacity;\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayQueue *queue) {\n    return queue->queSize == 0;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(ArrayQueue *queue) {\n    assert(size(queue) != 0);\n    return queue->nums[queue->front];\n}\n\n/* \u5165\u961f */\nvoid push(ArrayQueue *queue, int num) {\n    if (size(queue) == capacity(queue)) {\n        printf(\"\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (queue->front + queue->queSize) % queue->queCapacity;\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    queue->nums[rear] = num;\n    queue->queSize++;\n}\n\n/* \u51fa\u961f */\nint pop(ArrayQueue *queue) {\n    int num = peek(queue);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    queue->front = (queue->front + 1) % queue->queCapacity;\n    queue->queSize--;\n    return num;\n}\n
    array_queue.kt
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue(capacity: Int) {\n    private val nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        val rear = (front + queSize) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[j % capacity()]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_queue.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 ###\nclass ArrayQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(size)\n    @nums = Array.new(size, 0) # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    @front = 0 # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    @size = 0 # \u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    raise IndexError, '\u961f\u5217\u5df2\u6ee1' if size == capacity\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear = (@front + size) % capacity\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    @front = (@front + 1) % capacity\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    res = Array.new(size, 0)\n    j = @front\n\n    for i in 0...size\n      res[i] = @nums[j % capacity]\n      j += 1\n    end\n\n    res\n  end\nend\n
    array_queue.zig
    // \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\nfn ArrayQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        nums: []T = undefined,                          // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4     \n        cap: usize = 0,                                 // \u961f\u5217\u5bb9\u91cf\n        front: usize = 0,                               // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        queSize: usize = 0,                             // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6570\u7ec4\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator, cap: usize) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.cap = cap;\n            self.nums = try self.mem_allocator.alloc(T, self.cap);\n            @memset(self.nums, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.cap;\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.queSize;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.queSize == 0;\n        }\n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            if (self.size() == self.capacity()) {\n                std.debug.print(\"\u961f\u5217\u5df2\u6ee1\\n\", .{});\n                return;\n            }\n            // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n            // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n            var rear = (self.front + self.queSize) % self.capacity();\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            self.nums[rear] = num;\n            self.queSize += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n            self.front = (self.front + 1) % self.capacity();\n            self.queSize -= 1;\n            return num;\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.nums[self.front];\n        } \n\n        // \u8fd4\u56de\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            var j: usize = self.front;\n            while (i < self.size()) : ({ i += 1; j += 1; }) {\n                res[i] = self.nums[j % self.capacity()];\n            }\n            return res;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4ee5\u4e0a\u5b9e\u73b0\u7684\u961f\u5217\u4ecd\u7136\u5177\u6709\u5c40\u9650\u6027\uff1a\u5176\u957f\u5ea6\u4e0d\u53ef\u53d8\u3002\u7136\u800c\uff0c\u8fd9\u4e2a\u95ee\u9898\u4e0d\u96be\u89e3\u51b3\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u7ec4\u66ff\u6362\u4e3a\u52a8\u6001\u6570\u7ec4\uff0c\u4ece\u800c\u5f15\u5165\u6269\u5bb9\u673a\u5236\u3002\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u5c1d\u8bd5\u81ea\u884c\u5b9e\u73b0\u3002

    \u4e24\u79cd\u5b9e\u73b0\u7684\u5bf9\u6bd4\u7ed3\u8bba\u4e0e\u6808\u4e00\u81f4\uff0c\u5728\u6b64\u4e0d\u518d\u8d58\u8ff0\u3002

    "},{"location":"chapter_stack_and_queue/queue/#523","title":"5.2.3 \u00a0 \u961f\u5217\u5178\u578b\u5e94\u7528","text":"
    • \u6dd8\u5b9d\u8ba2\u5355\u3002\u8d2d\u7269\u8005\u4e0b\u5355\u540e\uff0c\u8ba2\u5355\u5c06\u52a0\u5165\u961f\u5217\u4e2d\uff0c\u7cfb\u7edf\u968f\u540e\u4f1a\u6839\u636e\u987a\u5e8f\u5904\u7406\u961f\u5217\u4e2d\u7684\u8ba2\u5355\u3002\u5728\u53cc\u5341\u4e00\u671f\u95f4\uff0c\u77ed\u65f6\u95f4\u5185\u4f1a\u4ea7\u751f\u6d77\u91cf\u8ba2\u5355\uff0c\u9ad8\u5e76\u53d1\u6210\u4e3a\u5de5\u7a0b\u5e08\u4eec\u9700\u8981\u91cd\u70b9\u653b\u514b\u7684\u95ee\u9898\u3002
    • \u5404\u7c7b\u5f85\u529e\u4e8b\u9879\u3002\u4efb\u4f55\u9700\u8981\u5b9e\u73b0\u201c\u5148\u6765\u540e\u5230\u201d\u529f\u80fd\u7684\u573a\u666f\uff0c\u4f8b\u5982\u6253\u5370\u673a\u7684\u4efb\u52a1\u961f\u5217\u3001\u9910\u5385\u7684\u51fa\u9910\u961f\u5217\u7b49\uff0c\u961f\u5217\u5728\u8fd9\u4e9b\u573a\u666f\u4e2d\u53ef\u4ee5\u6709\u6548\u5730\u7ef4\u62a4\u5904\u7406\u987a\u5e8f\u3002
    "},{"location":"chapter_stack_and_queue/stack/","title":"5.1 \u00a0 \u6808","text":"

    \u6808\uff08stack\uff09\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u540e\u51fa\u903b\u8f91\u7684\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002

    \u6211\u4eec\u53ef\u4ee5\u5c06\u6808\u7c7b\u6bd4\u4e3a\u684c\u9762\u4e0a\u7684\u4e00\u645e\u76d8\u5b50\uff0c\u5982\u679c\u60f3\u53d6\u51fa\u5e95\u90e8\u7684\u76d8\u5b50\uff0c\u5219\u9700\u8981\u5148\u5c06\u4e0a\u9762\u7684\u76d8\u5b50\u4f9d\u6b21\u79fb\u8d70\u3002\u6211\u4eec\u5c06\u76d8\u5b50\u66ff\u6362\u4e3a\u5404\u79cd\u7c7b\u578b\u7684\u5143\u7d20\uff08\u5982\u6574\u6570\u3001\u5b57\u7b26\u3001\u5bf9\u8c61\u7b49\uff09\uff0c\u5c31\u5f97\u5230\u4e86\u6808\u8fd9\u79cd\u6570\u636e\u7ed3\u6784\u3002

    \u5982\u56fe 5-1 \u6240\u793a\uff0c\u6211\u4eec\u628a\u5806\u53e0\u5143\u7d20\u7684\u9876\u90e8\u79f0\u4e3a\u201c\u6808\u9876\u201d\uff0c\u5e95\u90e8\u79f0\u4e3a\u201c\u6808\u5e95\u201d\u3002\u5c06\u628a\u5143\u7d20\u6dfb\u52a0\u5230\u6808\u9876\u7684\u64cd\u4f5c\u53eb\u4f5c\u201c\u5165\u6808\u201d\uff0c\u5220\u9664\u6808\u9876\u5143\u7d20\u7684\u64cd\u4f5c\u53eb\u4f5c\u201c\u51fa\u6808\u201d\u3002

    \u56fe 5-1 \u00a0 \u6808\u7684\u5148\u5165\u540e\u51fa\u89c4\u5219

    "},{"location":"chapter_stack_and_queue/stack/#511","title":"5.1.1 \u00a0 \u6808\u7684\u5e38\u7528\u64cd\u4f5c","text":"

    \u6808\u7684\u5e38\u7528\u64cd\u4f5c\u5982\u8868 5-1 \u6240\u793a\uff0c\u5177\u4f53\u7684\u65b9\u6cd5\u540d\u9700\u8981\u6839\u636e\u6240\u4f7f\u7528\u7684\u7f16\u7a0b\u8bed\u8a00\u6765\u786e\u5b9a\u3002\u5728\u6b64\uff0c\u6211\u4eec\u4ee5\u5e38\u89c1\u7684 push()\u3001pop()\u3001peek() \u547d\u540d\u4e3a\u4f8b\u3002

    \u8868 5-1 \u00a0 \u6808\u7684\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5 \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push() \u5143\u7d20\u5165\u6808\uff08\u6dfb\u52a0\u81f3\u6808\u9876\uff09 \\(O(1)\\) pop() \u6808\u9876\u5143\u7d20\u51fa\u6808 \\(O(1)\\) peek() \u8bbf\u95ee\u6808\u9876\u5143\u7d20 \\(O(1)\\)

    \u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u5185\u7f6e\u7684\u6808\u7c7b\u3002\u7136\u800c\uff0c\u67d0\u4e9b\u8bed\u8a00\u53ef\u80fd\u6ca1\u6709\u4e13\u95e8\u63d0\u4f9b\u6808\u7c7b\uff0c\u8fd9\u65f6\u6211\u4eec\u53ef\u4ee5\u5c06\u8be5\u8bed\u8a00\u7684\u201c\u6570\u7ec4\u201d\u6216\u201c\u94fe\u8868\u201d\u5f53\u4f5c\u6808\u6765\u4f7f\u7528\uff0c\u5e76\u5728\u7a0b\u5e8f\u903b\u8f91\u4e0a\u5ffd\u7565\u4e0e\u6808\u65e0\u5173\u7684\u64cd\u4f5c\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig stack.py
    # \u521d\u59cb\u5316\u6808\n# Python \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a list \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nstack: list[int] = []\n\n# \u5143\u7d20\u5165\u6808\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n# \u8bbf\u95ee\u6808\u9876\u5143\u7d20\npeek: int = stack[-1]\n\n# \u5143\u7d20\u51fa\u6808\npop: int = stack.pop()\n\n# \u83b7\u53d6\u6808\u7684\u957f\u5ea6\nsize: int = len(stack)\n\n# \u5224\u65ad\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = len(stack) == 0\n
    stack.cpp
    /* \u521d\u59cb\u5316\u6808 */\nstack<int> stack;\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint top = stack.top();\n\n/* \u5143\u7d20\u51fa\u6808 */\nstack.pop(); // \u65e0\u8fd4\u56de\u503c\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.size();\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nbool empty = stack.empty();\n
    stack.java
    /* \u521d\u59cb\u5316\u6808 */\nStack<Integer> stack = new Stack<>();\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek = stack.peek();\n\n/* \u5143\u7d20\u51fa\u6808 */\nint pop = stack.pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.size();\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = stack.isEmpty();\n
    stack.cs
    /* \u521d\u59cb\u5316\u6808 */\nStack<int> stack = new();\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.Push(1);\nstack.Push(3);\nstack.Push(2);\nstack.Push(5);\nstack.Push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek = stack.Peek();\n\n/* \u5143\u7d20\u51fa\u6808 */\nint pop = stack.Pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.Count;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = stack.Count == 0;\n
    stack_test.go
    /* \u521d\u59cb\u5316\u6808 */\n// \u5728 Go \u4e2d\uff0c\u63a8\u8350\u5c06 Slice \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nvar stack []int\n\n/* \u5143\u7d20\u5165\u6808 */\nstack = append(stack, 1)\nstack = append(stack, 3)\nstack = append(stack, 2)\nstack = append(stack, 5)\nstack = append(stack, 4)\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\npeek := stack[len(stack)-1]\n\n/* \u5143\u7d20\u51fa\u6808 */\npop := stack[len(stack)-1]\nstack = stack[:len(stack)-1]\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nsize := len(stack)\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nisEmpty := len(stack) == 0\n
    stack.swift
    /* \u521d\u59cb\u5316\u6808 */\n// Swift \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nvar stack: [Int] = []\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nlet peek = stack.last!\n\n/* \u5143\u7d20\u51fa\u6808 */\nlet pop = stack.removeLast()\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nlet size = stack.count\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = stack.isEmpty\n
    stack.js
    /* \u521d\u59cb\u5316\u6808 */\n// JavaScript \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nconst stack = [];\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nconst peek = stack[stack.length-1];\n\n/* \u5143\u7d20\u51fa\u6808 */\nconst pop = stack.pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nconst size = stack.length;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nconst is_empty = stack.length === 0;\n
    stack.ts
    /* \u521d\u59cb\u5316\u6808 */\n// TypeScript \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nconst stack: number[] = [];\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nconst peek = stack[stack.length - 1];\n\n/* \u5143\u7d20\u51fa\u6808 */\nconst pop = stack.pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nconst size = stack.length;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nconst is_empty = stack.length === 0;\n
    stack.dart
    /* \u521d\u59cb\u5316\u6808 */\n// Dart \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a List \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nList<int> stack = [];\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.add(1);\nstack.add(3);\nstack.add(2);\nstack.add(5);\nstack.add(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek = stack.last;\n\n/* \u5143\u7d20\u51fa\u6808 */\nint pop = stack.removeLast();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.length;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = stack.isEmpty;\n
    stack.rs
    /* \u521d\u59cb\u5316\u6808 */\n// \u628a Vec \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nlet mut stack: Vec<i32> = Vec::new();\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nlet top = stack.last().unwrap();\n\n/* \u5143\u7d20\u51fa\u6808 */\nlet pop = stack.pop().unwrap();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nlet size = stack.len();\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = stack.is_empty();\n
    stack.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u6808\n
    stack.kt
    /* \u521d\u59cb\u5316\u6808 */\nval stack = Stack<Int>()\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1)\nstack.push(3)\nstack.push(2)\nstack.push(5)\nstack.push(4)\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nval peek = stack.peek()\n\n/* \u5143\u7d20\u51fa\u6808 */\nval pop = stack.pop()\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nval size = stack.size\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = stack.isEmpty()\n
    stack.rb
    # \u521d\u59cb\u5316\u6808\n# Ruby \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nstack = []\n\n# \u5143\u7d20\u5165\u6808\nstack << 1\nstack << 3\nstack << 2\nstack << 5\nstack << 4\n\n# \u8bbf\u95ee\u6808\u9876\u5143\u7d20\npeek = stack.last\n\n# \u5143\u7d20\u51fa\u6808\npop = stack.pop\n\n# \u83b7\u53d6\u6808\u7684\u957f\u5ea6\nsize = stack.length\n\n# \u5224\u65ad\u662f\u5426\u4e3a\u7a7a\nis_empty = stack.empty?\n
    stack.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/stack/#512","title":"5.1.2 \u00a0 \u6808\u7684\u5b9e\u73b0","text":"

    \u4e3a\u4e86\u6df1\u5165\u4e86\u89e3\u6808\u7684\u8fd0\u884c\u673a\u5236\uff0c\u6211\u4eec\u6765\u5c1d\u8bd5\u81ea\u5df1\u5b9e\u73b0\u4e00\u4e2a\u6808\u7c7b\u3002

    \u6808\u9075\u5faa\u5148\u5165\u540e\u51fa\u7684\u539f\u5219\uff0c\u56e0\u6b64\u6211\u4eec\u53ea\u80fd\u5728\u6808\u9876\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u3002\u7136\u800c\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u90fd\u53ef\u4ee5\u5728\u4efb\u610f\u4f4d\u7f6e\u6dfb\u52a0\u548c\u5220\u9664\u5143\u7d20\uff0c\u56e0\u6b64\u6808\u53ef\u4ee5\u89c6\u4e3a\u4e00\u79cd\u53d7\u9650\u5236\u7684\u6570\u7ec4\u6216\u94fe\u8868\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6211\u4eec\u53ef\u4ee5\u201c\u5c4f\u853d\u201d\u6570\u7ec4\u6216\u94fe\u8868\u7684\u90e8\u5206\u65e0\u5173\u64cd\u4f5c\uff0c\u4f7f\u5176\u5bf9\u5916\u8868\u73b0\u7684\u903b\u8f91\u7b26\u5408\u6808\u7684\u7279\u6027\u3002

    "},{"location":"chapter_stack_and_queue/stack/#1","title":"1. \u00a0 \u57fa\u4e8e\u94fe\u8868\u7684\u5b9e\u73b0","text":"

    \u4f7f\u7528\u94fe\u8868\u5b9e\u73b0\u6808\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u94fe\u8868\u7684\u5934\u8282\u70b9\u89c6\u4e3a\u6808\u9876\uff0c\u5c3e\u8282\u70b9\u89c6\u4e3a\u6808\u5e95\u3002

    \u5982\u56fe 5-2 \u6240\u793a\uff0c\u5bf9\u4e8e\u5165\u6808\u64cd\u4f5c\uff0c\u6211\u4eec\u53ea\u9700\u5c06\u5143\u7d20\u63d2\u5165\u94fe\u8868\u5934\u90e8\uff0c\u8fd9\u79cd\u8282\u70b9\u63d2\u5165\u65b9\u6cd5\u88ab\u79f0\u4e3a\u201c\u5934\u63d2\u6cd5\u201d\u3002\u800c\u5bf9\u4e8e\u51fa\u6808\u64cd\u4f5c\uff0c\u53ea\u9700\u5c06\u5934\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u5220\u9664\u5373\u53ef\u3002

    LinkedListStackpush()pop()

    \u56fe 5-2 \u00a0 \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u6808\u7684\u5165\u6808\u51fa\u6808\u64cd\u4f5c

    \u4ee5\u4e0b\u662f\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u6808\u7684\u793a\u4f8b\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_stack.py
    class LinkedListStack:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._peek: ListNode | None = None\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, val: int):\n        \"\"\"\u5165\u6808\"\"\"\n        node = ListNode(val)\n        node.next = self._peek\n        self._peek = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        num = self.peek()\n        self._peek = self._peek.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._peek.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        arr = []\n        node = self._peek\n        while node:\n            arr.append(node.val)\n            node = node.next\n        arr.reverse()\n        return arr\n
    linkedlist_stack.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  private:\n    ListNode *stackTop; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize;        // \u6808\u7684\u957f\u5ea6\n\n  public:\n    LinkedListStack() {\n        stackTop = nullptr;\n        stkSize = 0;\n    }\n\n    ~LinkedListStack() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(stackTop);\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        ListNode *node = new ListNode(num);\n        node->next = stackTop;\n        stackTop = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        ListNode *tmp = stackTop;\n        stackTop = stackTop->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stackTop->val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = stackTop;\n        vector<int> res(size());\n        for (int i = res.size() - 1; i >= 0; i--) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_stack.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private ListNode stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private int stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        ListNode node = new ListNode(num);\n        node.next = stackPeek;\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        int num = peek();\n        stackPeek = stackPeek.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stackPeek.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = stackPeek;\n        int[] res = new int[size()];\n        for (int i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    ListNode? stackPeek;  // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize = 0;   // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        ListNode node = new(num) {\n            next = stackPeek\n        };\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        int num = Peek();\n        stackPeek = stackPeek!.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stackPeek!.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (stackPeek == null)\n            return [];\n\n        ListNode? node = stackPeek;\n        int[] res = new int[Size()];\n        for (int i = res.Length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntype linkedListStack struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u6808\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newLinkedListStack() *linkedListStack {\n    return &linkedListStack{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u6808 */\nfunc (s *linkedListStack) push(value int) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u6808 */\nfunc (s *linkedListStack) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nfunc (s *linkedListStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nfunc (s *linkedListStack) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListStack) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListStack) toList() *list.List {\n    return s.data\n}\n
    linkedlist_stack.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private var _peek: ListNode? // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var _size: Int // \u6808\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        let node = ListNode(x: num)\n        node.next = _peek\n        _peek = node\n        _size += 1\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        _peek = _peek?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return _peek!.val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = _peek\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices.reversed() {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    #stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    #stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        const node = new ListNode(num);\n        node.next = this.#stackPeek;\n        this.#stackPeek = node;\n        this.#stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        const num = this.peek();\n        this.#stackPeek = this.#stackPeek.next;\n        this.#stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek() {\n        if (!this.#stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#stackPeek;\n        const res = new Array(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private stackPeek: ListNode | null; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private stkSize: number = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        const node = new ListNode(num);\n        node.next = this.stackPeek;\n        this.stackPeek = node;\n        this.stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        this.stackPeek = this.stackPeek.next;\n        this.stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek(): number {\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.stackPeek;\n        const res = new Array<number>(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.dart
    /* \u57fa\u4e8e\u94fe\u8868\u7c7b\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  ListNode? _stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n  int _stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n  LinkedListStack() {\n    _stackPeek = null;\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stkSize;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stkSize == 0;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    final ListNode node = ListNode(_num);\n    node.next = _stackPeek;\n    _stackPeek = node;\n    _stkSize++;\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    final int _num = peek();\n    _stackPeek = _stackPeek!.next;\n    _stkSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (_stackPeek == null) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stackPeek!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a List \u5e76\u8fd4\u56de */\n  List<int> toList() {\n    ListNode? node = _stackPeek;\n    List<int> list = [];\n    while (node != null) {\n      list.add(node.val);\n      node = node.next;\n    }\n    list = list.reversed.toList();\n    return list;\n  }\n}\n
    linkedlist_stack.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\n#[allow(dead_code)]\npub struct LinkedListStack<T> {\n    stack_peek: Option<Rc<RefCell<ListNode<T>>>>, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    stk_size: usize,                              // \u6808\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListStack<T> {\n    pub fn new() -> Self {\n        Self {\n            stack_peek: None,\n            stk_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.stk_size;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    pub fn push(&mut self, num: T) {\n        let node = ListNode::new(num);\n        node.borrow_mut().next = self.stack_peek.take();\n        self.stack_peek = Some(node);\n        self.stk_size += 1;\n    }\n\n    /* \u51fa\u6808 */\n    pub fn pop(&mut self) -> Option<T> {\n        self.stack_peek.take().map(|old_head| {\n            match old_head.borrow_mut().next.take() {\n                Some(new_head) => {\n                    self.stack_peek = Some(new_head);\n                }\n                None => {\n                    self.stack_peek = None;\n                }\n            }\n            self.stk_size -= 1;\n            Rc::try_unwrap(old_head).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.stack_peek.as_ref()\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.push(node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_stack.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    ListNode *top; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int size;      // \u6808\u7684\u957f\u5ea6\n} LinkedListStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListStack *newLinkedListStack() {\n    LinkedListStack *s = malloc(sizeof(LinkedListStack));\n    s->top = NULL;\n    s->size = 0;\n    return s;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListStack(LinkedListStack *s) {\n    while (s->top) {\n        ListNode *n = s->top->next;\n        free(s->top);\n        s->top = n;\n    }\n    free(s);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(LinkedListStack *s) {\n    return s->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(LinkedListStack *s) {\n    return size(s) == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(LinkedListStack *s, int num) {\n    ListNode *node = (ListNode *)malloc(sizeof(ListNode));\n    node->next = s->top; // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6307\u9488\u57df\n    node->val = num;     // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6570\u636e\u57df\n    s->top = node;       // \u66f4\u65b0\u6808\u9876\n    s->size++;           // \u66f4\u65b0\u6808\u5927\u5c0f\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(LinkedListStack *s) {\n    if (s->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return s->top->val;\n}\n\n/* \u51fa\u6808 */\nint pop(LinkedListStack *s) {\n    int val = peek(s);\n    ListNode *tmp = s->top;\n    s->top = s->top->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n    s->size--;\n    return val;\n}\n
    linkedlist_stack.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack(\n    private var stackPeek: ListNode? = null, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var stkSize: Int = 0 // \u6808\u7684\u957f\u5ea6\n) {\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stkSize\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        val node = ListNode(num)\n        node.next = stackPeek\n        stackPeek = node\n        stkSize++\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int? {\n        val num = peek()\n        stackPeek = stackPeek?.next\n        stkSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int? {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stackPeek?._val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = stackPeek\n        val res = IntArray(size())\n        for (i in res.size - 1 downTo 0) {\n            res[i] = node?._val!!\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 ###\nclass LinkedListStack\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @peek.nil?\n  end\n\n  ### \u5165\u6808 ###\n  def push(val)\n    node = ListNode.new(val)\n    node.next = @peek\n    @peek = node\n    @size += 1\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    num = peek\n    @peek = @peek.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @peek.val\n  end\n\n  ### \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u53cd\u56de ###\n  def to_array\n    arr = []\n    node = @peek\n    while node\n      arr << node.val\n      node = node.next\n    end\n    arr.reverse\n  end\nend\n
    linkedlist_stack.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\nfn LinkedListStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack_top: ?*inc.ListNode(T) = null,             // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n        stk_size: usize = 0,                             // \u6808\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,    // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.stack_top = null;\n            self.stk_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stk_size;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack_top.?.val;\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            node.next = self.stack_top;\n            self.stack_top = node;\n            self.stk_size += 1;\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            self.stack_top = self.stack_top.?.next;\n            self.stk_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u6808\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.stack_top;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[res.len - i - 1] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/stack/#2","title":"2. \u00a0 \u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0","text":"

    \u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\u6808\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u7ec4\u7684\u5c3e\u90e8\u4f5c\u4e3a\u6808\u9876\u3002\u5982\u56fe 5-3 \u6240\u793a\uff0c\u5165\u6808\u4e0e\u51fa\u6808\u64cd\u4f5c\u5206\u522b\u5bf9\u5e94\u5728\u6570\u7ec4\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\u4e0e\u5220\u9664\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(1)\\) \u3002

    ArrayStackpush()pop()

    \u56fe 5-3 \u00a0 \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u6808\u7684\u5165\u6808\u51fa\u6808\u64cd\u4f5c

    \u7531\u4e8e\u5165\u6808\u7684\u5143\u7d20\u53ef\u80fd\u4f1a\u6e90\u6e90\u4e0d\u65ad\u5730\u589e\u52a0\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u52a8\u6001\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u65e0\u987b\u81ea\u884c\u5904\u7406\u6570\u7ec4\u6269\u5bb9\u95ee\u9898\u3002\u4ee5\u4e0b\u4e3a\u793a\u4f8b\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_stack.py
    class ArrayStack:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._stack: list[int] = []\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return len(self._stack)\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self.size() == 0\n\n    def push(self, item: int):\n        \"\"\"\u5165\u6808\"\"\"\n        self._stack.append(item)\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack.pop()\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack[-1]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        return self._stack\n
    array_stack.cpp
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  private:\n    vector<int> stack;\n\n  public:\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return stack.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        stack.push_back(num);\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        stack.pop_back();\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stack.back();\n    }\n\n    /* \u8fd4\u56de Vector */\n    vector<int> toVector() {\n        return stack;\n    }\n};\n
    array_stack.java
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private ArrayList<Integer> stack;\n\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = new ArrayList<>();\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        stack.add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.remove(size() - 1);\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.get(size() - 1);\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public Object[] toArray() {\n        return stack.toArray();\n    }\n}\n
    array_stack.cs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    List<int> stack;\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stack.Count;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        stack.Add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        if (IsEmpty())\n            throw new Exception();\n        var val = Peek();\n        stack.RemoveAt(Size() - 1);\n        return val;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stack[Size() - 1];\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        return [.. stack];\n    }\n}\n
    array_stack.go
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntype arrayStack struct {\n    data []int // \u6570\u636e\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newArrayStack() *arrayStack {\n    return &arrayStack{\n        // \u8bbe\u7f6e\u6808\u7684\u957f\u5ea6\u4e3a 0\uff0c\u5bb9\u91cf\u4e3a 16\n        data: make([]int, 0, 16),\n    }\n}\n\n/* \u6808\u7684\u957f\u5ea6 */\nfunc (s *arrayStack) size() int {\n    return len(s.data)\n}\n\n/* \u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *arrayStack) isEmpty() bool {\n    return s.size() == 0\n}\n\n/* \u5165\u6808 */\nfunc (s *arrayStack) push(v int) {\n    // \u5207\u7247\u4f1a\u81ea\u52a8\u6269\u5bb9\n    s.data = append(s.data, v)\n}\n\n/* \u51fa\u6808 */\nfunc (s *arrayStack) pop() any {\n    val := s.peek()\n    s.data = s.data[:len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6\u6808\u9876\u5143\u7d20 */\nfunc (s *arrayStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    val := s.data[len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (s *arrayStack) toSlice() []int {\n    return s.data\n}\n
    array_stack.swift
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private var stack: [Int]\n\n    init() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = []\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        stack.count\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        stack.isEmpty\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        stack.append(num)\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.removeLast()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.last!\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        stack\n    }\n}\n
    array_stack.js
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    #stack;\n    constructor() {\n        this.#stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        this.#stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack[this.#stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.#stack;\n    }\n}\n
    array_stack.ts
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private stack: number[];\n    constructor() {\n        this.stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        this.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack[this.stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.stack;\n    }\n}\n
    array_stack.dart
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  late List<int> _stack;\n  ArrayStack() {\n    _stack = [];\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stack.length;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stack.isEmpty;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    _stack.add(_num);\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.removeLast();\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.last;\n  }\n\n  /* \u5c06\u6808\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() => _stack;\n}\n
    array_stack.rs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nstruct ArrayStack<T> {\n    stack: Vec<T>,\n}\n\nimpl<T> ArrayStack<T> {\n    /* \u521d\u59cb\u5316\u6808 */\n    fn new() -> ArrayStack<T> {\n        ArrayStack::<T> {\n            stack: Vec::<T>::new(),\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fn size(&self) -> usize {\n        self.stack.len()\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fn push(&mut self, num: T) {\n        self.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    fn pop(&mut self) -> Option<T> {\n        self.stack.pop()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fn peek(&self) -> Option<&T> {\n        if self.is_empty() {\n            panic!(\"\u6808\u4e3a\u7a7a\")\n        };\n        self.stack.last()\n    }\n\n    /* \u8fd4\u56de &Vec */\n    fn to_array(&self) -> &Vec<T> {\n        &self.stack\n    }\n}\n
    array_stack.c
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    int *data;\n    int size;\n} ArrayStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayStack *newArrayStack() {\n    ArrayStack *stack = malloc(sizeof(ArrayStack));\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5927\u5bb9\u91cf\uff0c\u907f\u514d\u6269\u5bb9\n    stack->data = malloc(sizeof(int) * MAX_SIZE);\n    stack->size = 0;\n    return stack;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayStack(ArrayStack *stack) {\n    free(stack->data);\n    free(stack);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(ArrayStack *stack) {\n    return stack->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(ArrayStack *stack) {\n    return stack->size == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(ArrayStack *stack, int num) {\n    if (stack->size == MAX_SIZE) {\n        printf(\"\u6808\u5df2\u6ee1\\n\");\n        return;\n    }\n    stack->data[stack->size] = num;\n    stack->size++;\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(ArrayStack *stack) {\n    if (stack->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return stack->data[stack->size - 1];\n}\n\n/* \u51fa\u6808 */\nint pop(ArrayStack *stack) {\n    int val = peek(stack);\n    stack->size--;\n    return val;\n}\n
    array_stack.kt
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n    private val stack = mutableListOf<Int>()\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stack.size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        stack.add(num)\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack.removeAt(size() - 1)\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack[size() - 1]\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): Array<Any> {\n        return stack.toTypedArray()\n    }\n}\n
    array_stack.rb
    ### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 ###\nclass ArrayStack\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @stack = []\n  end\n\n  ### \u83b7\u53d6\u6808\u7684\u957f\u5ea6 ###\n  def size\n    @stack.length\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @stack.empty?\n  end\n\n  ### \u5165\u6808 ###\n  def push(item)\n    @stack << item\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.pop\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.last\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    @stack\n  end\nend\n
    array_stack.zig
    // \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\nfn ArrayStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack: ?std.ArrayList(T) = null,     \n\n        // \u6784\u9020\u65b9\u6cd5\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) void {\n            if (self.stack == null) {\n                self.stack = std.ArrayList(T).init(allocator);\n            }\n        }\n\n        // \u6790\u6784\u65b9\u6cd5\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.stack == null) return;\n            self.stack.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stack.?.items.len;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack.?.items[self.size() - 1];\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            try self.stack.?.append(num);\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.stack.?.pop();\n            return num;\n        } \n\n        // \u8fd4\u56de ArrayList\n        pub fn toList(self: *Self) std.ArrayList(T) {\n            return self.stack.?;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/stack/#513","title":"5.1.3 \u00a0 \u4e24\u79cd\u5b9e\u73b0\u5bf9\u6bd4","text":"

    \u652f\u6301\u64cd\u4f5c

    \u4e24\u79cd\u5b9e\u73b0\u90fd\u652f\u6301\u6808\u5b9a\u4e49\u4e2d\u7684\u5404\u9879\u64cd\u4f5c\u3002\u6570\u7ec4\u5b9e\u73b0\u989d\u5916\u652f\u6301\u968f\u673a\u8bbf\u95ee\uff0c\u4f46\u8fd9\u5df2\u8d85\u51fa\u4e86\u6808\u7684\u5b9a\u4e49\u8303\u7574\uff0c\u56e0\u6b64\u4e00\u822c\u4e0d\u4f1a\u7528\u5230\u3002

    \u65f6\u95f4\u6548\u7387

    \u5728\u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0\u4e2d\uff0c\u5165\u6808\u548c\u51fa\u6808\u64cd\u4f5c\u90fd\u5728\u9884\u5148\u5206\u914d\u597d\u7684\u8fde\u7eed\u5185\u5b58\u4e2d\u8fdb\u884c\uff0c\u5177\u6709\u5f88\u597d\u7684\u7f13\u5b58\u672c\u5730\u6027\uff0c\u56e0\u6b64\u6548\u7387\u8f83\u9ad8\u3002\u7136\u800c\uff0c\u5982\u679c\u5165\u6808\u65f6\u8d85\u51fa\u6570\u7ec4\u5bb9\u91cf\uff0c\u4f1a\u89e6\u53d1\u6269\u5bb9\u673a\u5236\uff0c\u5bfc\u81f4\u8be5\u6b21\u5165\u6808\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d8\u4e3a \\(O(n)\\) \u3002

    \u5728\u57fa\u4e8e\u94fe\u8868\u7684\u5b9e\u73b0\u4e2d\uff0c\u94fe\u8868\u7684\u6269\u5bb9\u975e\u5e38\u7075\u6d3b\uff0c\u4e0d\u5b58\u5728\u4e0a\u8ff0\u6570\u7ec4\u6269\u5bb9\u65f6\u6548\u7387\u964d\u4f4e\u7684\u95ee\u9898\u3002\u4f46\u662f\uff0c\u5165\u6808\u64cd\u4f5c\u9700\u8981\u521d\u59cb\u5316\u8282\u70b9\u5bf9\u8c61\u5e76\u4fee\u6539\u6307\u9488\uff0c\u56e0\u6b64\u6548\u7387\u76f8\u5bf9\u8f83\u4f4e\u3002\u4e0d\u8fc7\uff0c\u5982\u679c\u5165\u6808\u5143\u7d20\u672c\u8eab\u5c31\u662f\u8282\u70b9\u5bf9\u8c61\uff0c\u90a3\u4e48\u53ef\u4ee5\u7701\u53bb\u521d\u59cb\u5316\u6b65\u9aa4\uff0c\u4ece\u800c\u63d0\u9ad8\u6548\u7387\u3002

    \u7efc\u4e0a\u6240\u8ff0\uff0c\u5f53\u5165\u6808\u4e0e\u51fa\u6808\u64cd\u4f5c\u7684\u5143\u7d20\u662f\u57fa\u672c\u6570\u636e\u7c7b\u578b\u65f6\uff0c\u4f8b\u5982 int \u6216 double \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u51fa\u4ee5\u4e0b\u7ed3\u8bba\u3002

    • \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\u5728\u89e6\u53d1\u6269\u5bb9\u65f6\u6548\u7387\u4f1a\u964d\u4f4e\uff0c\u4f46\u7531\u4e8e\u6269\u5bb9\u662f\u4f4e\u9891\u64cd\u4f5c\uff0c\u56e0\u6b64\u5e73\u5747\u6548\u7387\u66f4\u9ad8\u3002
    • \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\u53ef\u4ee5\u63d0\u4f9b\u66f4\u52a0\u7a33\u5b9a\u7684\u6548\u7387\u8868\u73b0\u3002

    \u7a7a\u95f4\u6548\u7387

    \u5728\u521d\u59cb\u5316\u5217\u8868\u65f6\uff0c\u7cfb\u7edf\u4f1a\u4e3a\u5217\u8868\u5206\u914d\u201c\u521d\u59cb\u5bb9\u91cf\u201d\uff0c\u8be5\u5bb9\u91cf\u53ef\u80fd\u8d85\u51fa\u5b9e\u9645\u9700\u6c42\uff1b\u5e76\u4e14\uff0c\u6269\u5bb9\u673a\u5236\u901a\u5e38\u662f\u6309\u7167\u7279\u5b9a\u500d\u7387\uff08\u4f8b\u5982 2 \u500d\uff09\u8fdb\u884c\u6269\u5bb9\u7684\uff0c\u6269\u5bb9\u540e\u7684\u5bb9\u91cf\u4e5f\u53ef\u80fd\u8d85\u51fa\u5b9e\u9645\u9700\u6c42\u3002\u56e0\u6b64\uff0c\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\u53ef\u80fd\u9020\u6210\u4e00\u5b9a\u7684\u7a7a\u95f4\u6d6a\u8d39\u3002

    \u7136\u800c\uff0c\u7531\u4e8e\u94fe\u8868\u8282\u70b9\u9700\u8981\u989d\u5916\u5b58\u50a8\u6307\u9488\uff0c\u56e0\u6b64\u94fe\u8868\u8282\u70b9\u5360\u7528\u7684\u7a7a\u95f4\u76f8\u5bf9\u8f83\u5927\u3002

    \u7efc\u4e0a\uff0c\u6211\u4eec\u4e0d\u80fd\u7b80\u5355\u5730\u786e\u5b9a\u54ea\u79cd\u5b9e\u73b0\u66f4\u52a0\u8282\u7701\u5185\u5b58\uff0c\u9700\u8981\u9488\u5bf9\u5177\u4f53\u60c5\u51b5\u8fdb\u884c\u5206\u6790\u3002

    "},{"location":"chapter_stack_and_queue/stack/#514","title":"5.1.4 \u00a0 \u6808\u7684\u5178\u578b\u5e94\u7528","text":"
    • \u6d4f\u89c8\u5668\u4e2d\u7684\u540e\u9000\u4e0e\u524d\u8fdb\u3001\u8f6f\u4ef6\u4e2d\u7684\u64a4\u9500\u4e0e\u53cd\u64a4\u9500\u3002\u6bcf\u5f53\u6211\u4eec\u6253\u5f00\u65b0\u7684\u7f51\u9875\uff0c\u6d4f\u89c8\u5668\u5c31\u4f1a\u5bf9\u4e0a\u4e00\u4e2a\u7f51\u9875\u6267\u884c\u5165\u6808\uff0c\u8fd9\u6837\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u540e\u9000\u64cd\u4f5c\u56de\u5230\u4e0a\u4e00\u4e2a\u7f51\u9875\u3002\u540e\u9000\u64cd\u4f5c\u5b9e\u9645\u4e0a\u662f\u5728\u6267\u884c\u51fa\u6808\u3002\u5982\u679c\u8981\u540c\u65f6\u652f\u6301\u540e\u9000\u548c\u524d\u8fdb\uff0c\u90a3\u4e48\u9700\u8981\u4e24\u4e2a\u6808\u6765\u914d\u5408\u5b9e\u73b0\u3002
    • \u7a0b\u5e8f\u5185\u5b58\u7ba1\u7406\u3002\u6bcf\u6b21\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u7cfb\u7edf\u90fd\u4f1a\u5728\u6808\u9876\u6dfb\u52a0\u4e00\u4e2a\u6808\u5e27\uff0c\u7528\u4e8e\u8bb0\u5f55\u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f\u3002\u5728\u9012\u5f52\u51fd\u6570\u4e2d\uff0c\u5411\u4e0b\u9012\u63a8\u9636\u6bb5\u4f1a\u4e0d\u65ad\u6267\u884c\u5165\u6808\u64cd\u4f5c\uff0c\u800c\u5411\u4e0a\u56de\u6eaf\u9636\u6bb5\u5219\u4f1a\u4e0d\u65ad\u6267\u884c\u51fa\u6808\u64cd\u4f5c\u3002
    "},{"location":"chapter_stack_and_queue/summary/","title":"5.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_stack_and_queue/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u6808\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u540e\u51fa\u539f\u5219\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u901a\u8fc7\u6570\u7ec4\u6216\u94fe\u8868\u6765\u5b9e\u73b0\u3002
    • \u5728\u65f6\u95f4\u6548\u7387\u65b9\u9762\uff0c\u6808\u7684\u6570\u7ec4\u5b9e\u73b0\u5177\u6709\u8f83\u9ad8\u7684\u5e73\u5747\u6548\u7387\uff0c\u4f46\u5728\u6269\u5bb9\u8fc7\u7a0b\u4e2d\uff0c\u5355\u6b21\u5165\u6808\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u52a3\u5316\u81f3 \\(O(n)\\) \u3002\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u6808\u7684\u94fe\u8868\u5b9e\u73b0\u5177\u6709\u66f4\u4e3a\u7a33\u5b9a\u7684\u6548\u7387\u8868\u73b0\u3002
    • \u5728\u7a7a\u95f4\u6548\u7387\u65b9\u9762\uff0c\u6808\u7684\u6570\u7ec4\u5b9e\u73b0\u53ef\u80fd\u5bfc\u81f4\u4e00\u5b9a\u7a0b\u5ea6\u7684\u7a7a\u95f4\u6d6a\u8d39\u3002\u4f46\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u94fe\u8868\u8282\u70b9\u6240\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u6bd4\u6570\u7ec4\u5143\u7d20\u66f4\u5927\u3002
    • \u961f\u5217\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u5148\u51fa\u539f\u5219\u7684\u6570\u636e\u7ed3\u6784\uff0c\u540c\u6837\u53ef\u4ee5\u901a\u8fc7\u6570\u7ec4\u6216\u94fe\u8868\u6765\u5b9e\u73b0\u3002\u5728\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u7684\u5bf9\u6bd4\u4e0a\uff0c\u961f\u5217\u7684\u7ed3\u8bba\u4e0e\u524d\u8ff0\u6808\u7684\u7ed3\u8bba\u76f8\u4f3c\u3002
    • \u53cc\u5411\u961f\u5217\u662f\u4e00\u79cd\u5177\u6709\u66f4\u9ad8\u81ea\u7531\u5ea6\u7684\u961f\u5217\uff0c\u5b83\u5141\u8bb8\u5728\u4e24\u7aef\u8fdb\u884c\u5143\u7d20\u7684\u6dfb\u52a0\u548c\u5220\u9664\u64cd\u4f5c\u3002
    "},{"location":"chapter_stack_and_queue/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6d4f\u89c8\u5668\u7684\u524d\u8fdb\u540e\u9000\u662f\u5426\u662f\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\uff1f

    \u6d4f\u89c8\u5668\u7684\u524d\u8fdb\u540e\u9000\u529f\u80fd\u672c\u8d28\u4e0a\u662f\u201c\u6808\u201d\u7684\u4f53\u73b0\u3002\u5f53\u7528\u6237\u8bbf\u95ee\u4e00\u4e2a\u65b0\u9875\u9762\u65f6\uff0c\u8be5\u9875\u9762\u4f1a\u88ab\u6dfb\u52a0\u5230\u6808\u9876\uff1b\u5f53\u7528\u6237\u70b9\u51fb\u540e\u9000\u6309\u94ae\u65f6\uff0c\u8be5\u9875\u9762\u4f1a\u4ece\u6808\u9876\u5f39\u51fa\u3002\u4f7f\u7528\u53cc\u5411\u961f\u5217\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u4e00\u4e9b\u989d\u5916\u64cd\u4f5c\uff0c\u8fd9\u4e2a\u5728\u201c\u53cc\u5411\u961f\u5217\u201d\u7ae0\u8282\u6709\u63d0\u5230\u3002

    Q\uff1a\u5728\u51fa\u6808\u540e\uff0c\u662f\u5426\u9700\u8981\u91ca\u653e\u51fa\u6808\u8282\u70b9\u7684\u5185\u5b58\uff1f

    \u5982\u679c\u540e\u7eed\u4ecd\u9700\u8981\u4f7f\u7528\u5f39\u51fa\u8282\u70b9\uff0c\u5219\u4e0d\u9700\u8981\u91ca\u653e\u5185\u5b58\u3002\u82e5\u4e4b\u540e\u4e0d\u9700\u8981\u7528\u5230\uff0cJava \u548c Python \u7b49\u8bed\u8a00\u62e5\u6709\u81ea\u52a8\u5783\u573e\u56de\u6536\u673a\u5236\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u624b\u52a8\u91ca\u653e\u5185\u5b58\uff1b\u5728 C \u548c C++ \u4e2d\u9700\u8981\u624b\u52a8\u91ca\u653e\u5185\u5b58\u3002

    Q\uff1a\u53cc\u5411\u961f\u5217\u50cf\u662f\u4e24\u4e2a\u6808\u62fc\u63a5\u5728\u4e86\u4e00\u8d77\uff0c\u5b83\u7684\u7528\u9014\u662f\u4ec0\u4e48\uff1f

    \u53cc\u5411\u961f\u5217\u5c31\u50cf\u662f\u6808\u548c\u961f\u5217\u7684\u7ec4\u5408\u6216\u4e24\u4e2a\u6808\u62fc\u5728\u4e86\u4e00\u8d77\u3002\u5b83\u8868\u73b0\u7684\u662f\u6808 + \u961f\u5217\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u53ef\u4ee5\u5b9e\u73b0\u6808\u4e0e\u961f\u5217\u7684\u6240\u6709\u5e94\u7528\uff0c\u5e76\u4e14\u66f4\u52a0\u7075\u6d3b\u3002

    Q\uff1a\u64a4\u9500\uff08undo\uff09\u548c\u53cd\u64a4\u9500\uff08redo\uff09\u5177\u4f53\u662f\u5982\u4f55\u5b9e\u73b0\u7684\uff1f

    \u4f7f\u7528\u4e24\u4e2a\u6808\uff0c\u6808 A \u7528\u4e8e\u64a4\u9500\uff0c\u6808 B \u7528\u4e8e\u53cd\u64a4\u9500\u3002

    1. \u6bcf\u5f53\u7528\u6237\u6267\u884c\u4e00\u4e2a\u64cd\u4f5c\uff0c\u5c06\u8fd9\u4e2a\u64cd\u4f5c\u538b\u5165\u6808 A \uff0c\u5e76\u6e05\u7a7a\u6808 B \u3002
    2. \u5f53\u7528\u6237\u6267\u884c\u201c\u64a4\u9500\u201d\u65f6\uff0c\u4ece\u6808 A \u4e2d\u5f39\u51fa\u6700\u8fd1\u7684\u64cd\u4f5c\uff0c\u5e76\u5c06\u5176\u538b\u5165\u6808 B \u3002
    3. \u5f53\u7528\u6237\u6267\u884c\u201c\u53cd\u64a4\u9500\u201d\u65f6\uff0c\u4ece\u6808 B \u4e2d\u5f39\u51fa\u6700\u8fd1\u7684\u64cd\u4f5c\uff0c\u5e76\u5c06\u5176\u538b\u5165\u6808 A \u3002
    "},{"location":"chapter_tree/","title":"\u7b2c 7 \u7ae0 \u00a0 \u6811","text":"

    Abstract

    \u53c2\u5929\u5927\u6811\u5145\u6ee1\u751f\u547d\u529b\uff0c\u6839\u6df1\u53f6\u8302\uff0c\u5206\u679d\u6276\u758f\u3002

    \u5b83\u4e3a\u6211\u4eec\u5c55\u73b0\u4e86\u6570\u636e\u5206\u6cbb\u7684\u751f\u52a8\u5f62\u6001\u3002

    "},{"location":"chapter_tree/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 7.1 \u00a0 \u4e8c\u53c9\u6811
    • 7.2 \u00a0 \u4e8c\u53c9\u6811\u904d\u5386
    • 7.3 \u00a0 \u4e8c\u53c9\u6811\u6570\u7ec4\u8868\u793a
    • 7.4 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811
    • 7.5 \u00a0 AVL \u6811 *
    • 7.6 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_tree/array_representation_of_tree/","title":"7.3 \u00a0 \u4e8c\u53c9\u6811\u6570\u7ec4\u8868\u793a","text":"

    \u5728\u94fe\u8868\u8868\u793a\u4e0b\uff0c\u4e8c\u53c9\u6811\u7684\u5b58\u50a8\u5355\u5143\u4e3a\u8282\u70b9 TreeNode \uff0c\u8282\u70b9\u4e4b\u95f4\u901a\u8fc7\u6307\u9488\u76f8\u8fde\u63a5\u3002\u4e0a\u4e00\u8282\u4ecb\u7ecd\u4e86\u94fe\u8868\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7684\u5404\u9879\u57fa\u672c\u64cd\u4f5c\u3002

    \u90a3\u4e48\uff0c\u6211\u4eec\u80fd\u5426\u7528\u6570\u7ec4\u6765\u8868\u793a\u4e8c\u53c9\u6811\u5462\uff1f\u7b54\u6848\u662f\u80af\u5b9a\u7684\u3002

    "},{"location":"chapter_tree/array_representation_of_tree/#731","title":"7.3.1 \u00a0 \u8868\u793a\u5b8c\u7f8e\u4e8c\u53c9\u6811","text":"

    \u5148\u5206\u6790\u4e00\u4e2a\u7b80\u5355\u6848\u4f8b\u3002\u7ed9\u5b9a\u4e00\u68f5\u5b8c\u7f8e\u4e8c\u53c9\u6811\uff0c\u6211\u4eec\u5c06\u6240\u6709\u8282\u70b9\u6309\u7167\u5c42\u5e8f\u904d\u5386\u7684\u987a\u5e8f\u5b58\u50a8\u5728\u4e00\u4e2a\u6570\u7ec4\u4e2d\uff0c\u5219\u6bcf\u4e2a\u8282\u70b9\u90fd\u5bf9\u5e94\u552f\u4e00\u7684\u6570\u7ec4\u7d22\u5f15\u3002

    \u6839\u636e\u5c42\u5e8f\u904d\u5386\u7684\u7279\u6027\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u5bfc\u51fa\u7236\u8282\u70b9\u7d22\u5f15\u4e0e\u5b50\u8282\u70b9\u7d22\u5f15\u4e4b\u95f4\u7684\u201c\u6620\u5c04\u516c\u5f0f\u201d\uff1a\u82e5\u67d0\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\(i\\) \uff0c\u5219\u8be5\u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7d22\u5f15\u4e3a \\(2i + 1\\) \uff0c\u53f3\u5b50\u8282\u70b9\u7d22\u5f15\u4e3a \\(2i + 2\\) \u3002\u56fe 7-12 \u5c55\u793a\u4e86\u5404\u4e2a\u8282\u70b9\u7d22\u5f15\u4e4b\u95f4\u7684\u6620\u5c04\u5173\u7cfb\u3002

    \u56fe 7-12 \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a

    \u6620\u5c04\u516c\u5f0f\u7684\u89d2\u8272\u76f8\u5f53\u4e8e\u94fe\u8868\u4e2d\u7684\u8282\u70b9\u5f15\u7528\uff08\u6307\u9488\uff09\u3002\u7ed9\u5b9a\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u4e00\u4e2a\u8282\u70b9\uff0c\u6211\u4eec\u90fd\u53ef\u4ee5\u901a\u8fc7\u6620\u5c04\u516c\u5f0f\u6765\u8bbf\u95ee\u5b83\u7684\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\u3002

    "},{"location":"chapter_tree/array_representation_of_tree/#732","title":"7.3.2 \u00a0 \u8868\u793a\u4efb\u610f\u4e8c\u53c9\u6811","text":"

    \u5b8c\u7f8e\u4e8c\u53c9\u6811\u662f\u4e00\u4e2a\u7279\u4f8b\uff0c\u5728\u4e8c\u53c9\u6811\u7684\u4e2d\u95f4\u5c42\u901a\u5e38\u5b58\u5728\u8bb8\u591a None \u3002\u7531\u4e8e\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u5e76\u4e0d\u5305\u542b\u8fd9\u4e9b None \uff0c\u56e0\u6b64\u6211\u4eec\u65e0\u6cd5\u4ec5\u51ed\u8be5\u5e8f\u5217\u6765\u63a8\u6d4b None \u7684\u6570\u91cf\u548c\u5206\u5e03\u4f4d\u7f6e\u3002\u8fd9\u610f\u5473\u7740\u5b58\u5728\u591a\u79cd\u4e8c\u53c9\u6811\u7ed3\u6784\u90fd\u7b26\u5408\u8be5\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u3002

    \u5982\u56fe 7-13 \u6240\u793a\uff0c\u7ed9\u5b9a\u4e00\u68f5\u975e\u5b8c\u7f8e\u4e8c\u53c9\u6811\uff0c\u4e0a\u8ff0\u6570\u7ec4\u8868\u793a\u65b9\u6cd5\u5df2\u7ecf\u5931\u6548\u3002

    \u56fe 7-13 \u00a0 \u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u5bf9\u5e94\u591a\u79cd\u4e8c\u53c9\u6811\u53ef\u80fd\u6027

    \u4e3a\u4e86\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u8003\u8651\u5728\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u4e2d\u663e\u5f0f\u5730\u5199\u51fa\u6240\u6709 None \u3002\u5982\u56fe 7-14 \u6240\u793a\uff0c\u8fd9\u6837\u5904\u7406\u540e\uff0c\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u5c31\u53ef\u4ee5\u552f\u4e00\u8868\u793a\u4e8c\u53c9\u6811\u4e86\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a\n# \u4f7f\u7528 None \u6765\u8868\u793a\u7a7a\u4f4d\ntree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int \u6700\u5927\u503c INT_MAX \u6807\u8bb0\u7a7a\u4f4d\nvector<int> tree = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int \u7684\u5305\u88c5\u7c7b Integer \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 null \u6765\u6807\u8bb0\u7a7a\u4f4d\nInteger[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int? \u53ef\u7a7a\u7c7b\u578b \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 null \u6765\u6807\u8bb0\u7a7a\u4f4d\nint?[] tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 any \u7c7b\u578b\u7684\u5207\u7247, \u5c31\u53ef\u4ee5\u4f7f\u7528 nil \u6765\u6807\u8bb0\u7a7a\u4f4d\ntree := []any{1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15}\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 Int? \u53ef\u7a7a\u7c7b\u578b \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 nil \u6765\u6807\u8bb0\u7a7a\u4f4d\nlet tree: [Int?] = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 null \u6765\u8868\u793a\u7a7a\u4f4d\nlet tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 null \u6765\u8868\u793a\u7a7a\u4f4d\nlet tree: (number | null)[] = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int? \u53ef\u7a7a\u7c7b\u578b \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 null \u6765\u6807\u8bb0\u7a7a\u4f4d\nList<int?> tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 None \u6765\u6807\u8bb0\u7a7a\u4f4d\nlet tree = [Some(1), Some(2), Some(3), Some(4), None, Some(6), Some(7), Some(8), Some(9), None, None, Some(12), None, None, Some(15)];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int \u6700\u5927\u503c\u6807\u8bb0\u7a7a\u4f4d\uff0c\u56e0\u6b64\u8981\u6c42\u8282\u70b9\u503c\u4e0d\u80fd\u4e3a INT_MAX\nint tree[] = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 null \u6765\u8868\u793a\u7a7a\u4f4d\nval tree = arrayOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )\n
    ### \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a ###\n# \u4f7f\u7528 nil \u6765\u8868\u793a\u7a7a\u4f4d\ntree = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]\n
    \n

    \u56fe 7-14 \u00a0 \u4efb\u610f\u7c7b\u578b\u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u5b8c\u5168\u4e8c\u53c9\u6811\u975e\u5e38\u9002\u5408\u4f7f\u7528\u6570\u7ec4\u6765\u8868\u793a\u3002\u56de\u987e\u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u5b9a\u4e49\uff0cNone \u53ea\u51fa\u73b0\u5728\u6700\u5e95\u5c42\u4e14\u9760\u53f3\u7684\u4f4d\u7f6e\uff0c\u56e0\u6b64\u6240\u6709 None \u4e00\u5b9a\u51fa\u73b0\u5728\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u7684\u672b\u5c3e\u3002

    \u8fd9\u610f\u5473\u7740\u4f7f\u7528\u6570\u7ec4\u8868\u793a\u5b8c\u5168\u4e8c\u53c9\u6811\u65f6\uff0c\u53ef\u4ee5\u7701\u7565\u5b58\u50a8\u6240\u6709 None \uff0c\u975e\u5e38\u65b9\u4fbf\u3002\u56fe 7-15 \u7ed9\u51fa\u4e86\u4e00\u4e2a\u4f8b\u5b50\u3002

    \u56fe 7-15 \u00a0 \u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a

    \u4ee5\u4e0b\u4ee3\u7801\u5b9e\u73b0\u4e86\u4e00\u68f5\u57fa\u4e8e\u6570\u7ec4\u8868\u793a\u7684\u4e8c\u53c9\u6811\uff0c\u5305\u62ec\u4ee5\u4e0b\u51e0\u79cd\u64cd\u4f5c\u3002

    • \u7ed9\u5b9a\u67d0\u8282\u70b9\uff0c\u83b7\u53d6\u5b83\u7684\u503c\u3001\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\u3001\u7236\u8282\u70b9\u3002
    • \u83b7\u53d6\u524d\u5e8f\u904d\u5386\u3001\u4e2d\u5e8f\u904d\u5386\u3001\u540e\u5e8f\u904d\u5386\u3001\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_binary_tree.py
    class ArrayBinaryTree:\n    \"\"\"\u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b\"\"\"\n\n    def __init__(self, arr: list[int | None]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._tree = list(arr)\n\n    def size(self):\n        \"\"\"\u5217\u8868\u5bb9\u91cf\"\"\"\n        return len(self._tree)\n\n    def val(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c\"\"\"\n        # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 or i >= self.size():\n            return None\n        return self._tree[i]\n\n    def left(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 1\n\n    def right(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 2\n\n    def parent(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return (i - 1) // 2\n\n    def level_order(self) -> list[int]:\n        \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in range(self.size()):\n            if self.val(i) is not None:\n                self.res.append(self.val(i))\n        return self.res\n\n    def dfs(self, i: int, order: str):\n        \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n        if self.val(i) is None:\n            return\n        # \u524d\u5e8f\u904d\u5386\n        if order == \"pre\":\n            self.res.append(self.val(i))\n        self.dfs(self.left(i), order)\n        # \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\":\n            self.res.append(self.val(i))\n        self.dfs(self.right(i), order)\n        # \u540e\u5e8f\u904d\u5386\n        if order == \"post\":\n            self.res.append(self.val(i))\n\n    def pre_order(self) -> list[int]:\n        \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"pre\")\n        return self.res\n\n    def in_order(self) -> list[int]:\n        \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"in\")\n        return self.res\n\n    def post_order(self) -> list[int]:\n        \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"post\")\n        return self.res\n
    array_binary_tree.cpp
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayBinaryTree(vector<int> arr) {\n        tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    int val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return INT_MAX;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    int parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    vector<int> levelOrder() {\n        vector<int> res;\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != INT_MAX)\n                res.push_back(val(i));\n        }\n        return res;\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    vector<int> preOrder() {\n        vector<int> res;\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    vector<int> inOrder() {\n        vector<int> res;\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    vector<int> postOrder() {\n        vector<int> res;\n        dfs(0, \"post\", res);\n        return res;\n    }\n\n  private:\n    vector<int> tree;\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void dfs(int i, string order, vector<int> &res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == INT_MAX)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.push_back(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.push_back(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.push_back(val(i));\n    }\n};\n
    array_binary_tree.java
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private List<Integer> tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayBinaryTree(List<Integer> arr) {\n        tree = new ArrayList<>(arr);\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public Integer val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return null;\n        return tree.get(i);\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<Integer> levelOrder() {\n        List<Integer> res = new ArrayList<>();\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != null)\n                res.add(val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private void dfs(Integer i, String order, List<Integer> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == null)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\".equals(order))\n            res.add(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\".equals(order))\n            res.add(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\".equals(order))\n            res.add(val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<Integer> preOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<Integer> inOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<Integer> postOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.cs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(List<int?> arr) {\n    List<int?> tree = new(arr);\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int Size() {\n        return tree.Count;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public int? Val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= Size())\n            return null;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<int> LevelOrder() {\n        List<int> res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < Size(); i++) {\n            if (Val(i).HasValue)\n                res.Add(Val(i)!.Value);\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void DFS(int i, string order, List<int> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (!Val(i).HasValue)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.Add(Val(i)!.Value);\n        DFS(Left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.Add(Val(i)!.Value);\n        DFS(Right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.Add(Val(i)!.Value);\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<int> PreOrder() {\n        List<int> res = [];\n        DFS(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<int> InOrder() {\n        List<int> res = [];\n        DFS(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<int> PostOrder() {\n        List<int> res = [];\n        DFS(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.go
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\ntype arrayBinaryTree struct {\n    tree []any\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newArrayBinaryTree(arr []any) *arrayBinaryTree {\n    return &arrayBinaryTree{\n        tree: arr,\n    }\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nfunc (abt *arrayBinaryTree) size() int {\n    return len(abt.tree)\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nfunc (abt *arrayBinaryTree) val(i int) any {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if i < 0 || i >= abt.size() {\n        return nil\n    }\n    return abt.tree[i]\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) parent(i int) int {\n    return (i - 1) / 2\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) levelOrder() []any {\n    var res []any\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i := 0; i < abt.size(); i++ {\n        if abt.val(i) != nil {\n            res = append(res, abt.val(i))\n        }\n    }\n    return res\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nfunc (abt *arrayBinaryTree) dfs(i int, order string, res *[]any) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if abt.val(i) == nil {\n        return\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if order == \"pre\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.left(i), order, res)\n    // \u4e2d\u5e8f\u904d\u5386\n    if order == \"in\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.right(i), order, res)\n    // \u540e\u5e8f\u904d\u5386\n    if order == \"post\" {\n        *res = append(*res, abt.val(i))\n    }\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) preOrder() []any {\n    var res []any\n    abt.dfs(0, \"pre\", &res)\n    return res\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) inOrder() []any {\n    var res []any\n    abt.dfs(0, \"in\", &res)\n    return res\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) postOrder() []any {\n    var res []any\n    abt.dfs(0, \"post\", &res)\n    return res\n}\n
    array_binary_tree.swift
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private var tree: [Int?]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(arr: [Int?]) {\n        tree = arr\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    func size() -> Int {\n        tree.count\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    func val(i: Int) -> Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= size() {\n            return nil\n        }\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func left(i: Int) -> Int {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func right(i: Int) -> Int {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    func parent(i: Int) -> Int {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    func levelOrder() -> [Int] {\n        var res: [Int] = []\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0 ..< size() {\n            if let val = val(i: i) {\n                res.append(val)\n            }\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private func dfs(i: Int, order: String, res: inout [Int]) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        guard let val = val(i: i) else {\n            return\n        }\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.append(val)\n        }\n        dfs(i: left(i: i), order: order, res: &res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.append(val)\n        }\n        dfs(i: right(i: i), order: order, res: &res)\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.append(val)\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    func preOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"pre\", res: &res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    func inOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"in\", res: &res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    func postOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"post\", res: &res)\n        return res\n    }\n}\n
    array_binary_tree.js
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size() {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i) {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder() {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i, order, res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder() {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder() {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder() {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.ts
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree: (number | null)[];\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr: (number | null)[]) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size(): number {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i: number): number | null {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i: number): number {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i: number): number {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i: number): number {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder(): number[] {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i: number, order: Order, res: (number | null)[]): void {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.dart
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  late List<int?> _tree;\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayBinaryTree(this._tree);\n\n  /* \u5217\u8868\u5bb9\u91cf */\n  int size() {\n    return _tree.length;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n  int? val(int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size()) {\n      return null;\n    }\n    return _tree[i];\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? left(int i) {\n    return 2 * i + 1;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? right(int i) {\n    return 2 * i + 2;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? parent(int i) {\n    return (i - 1) ~/ 2;\n  }\n\n  /* \u5c42\u5e8f\u904d\u5386 */\n  List<int> levelOrder() {\n    List<int> res = [];\n    for (int i = 0; i < size(); i++) {\n      if (val(i) != null) {\n        res.add(val(i)!);\n      }\n    }\n    return res;\n  }\n\n  /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n  void dfs(int i, String order, List<int?> res) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(i) == null) {\n      return;\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if (order == 'pre') {\n      res.add(val(i));\n    }\n    dfs(left(i)!, order, res);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (order == 'in') {\n      res.add(val(i));\n    }\n    dfs(right(i)!, order, res);\n    // \u540e\u5e8f\u904d\u5386\n    if (order == 'post') {\n      res.add(val(i));\n    }\n  }\n\n  /* \u524d\u5e8f\u904d\u5386 */\n  List<int?> preOrder() {\n    List<int?> res = [];\n    dfs(0, 'pre', res);\n    return res;\n  }\n\n  /* \u4e2d\u5e8f\u904d\u5386 */\n  List<int?> inOrder() {\n    List<int?> res = [];\n    dfs(0, 'in', res);\n    return res;\n  }\n\n  /* \u540e\u5e8f\u904d\u5386 */\n  List<int?> postOrder() {\n    List<int?> res = [];\n    dfs(0, 'post', res);\n    return res;\n  }\n}\n
    array_binary_tree.rs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nstruct ArrayBinaryTree {\n    tree: Vec<Option<i32>>,\n}\n\nimpl ArrayBinaryTree {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(arr: Vec<Option<i32>>) -> Self {\n        Self { tree: arr }\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    fn size(&self) -> i32 {\n        self.tree.len() as i32\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fn val(&self, i: i32) -> Option<i32> {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= self.size() {\n            None\n        } else {\n            self.tree[i as usize]\n        }\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn left(&self, i: i32) -> i32 {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn right(&self, i: i32) -> i32 {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn parent(&self, i: i32) -> i32 {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fn level_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0..self.size() {\n            if let Some(val) = self.val(i) {\n                res.push(val)\n            }\n        }\n        res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fn dfs(&self, i: i32, order: &str, res: &mut Vec<i32>) {\n        if self.val(i).is_none() {\n            return;\n        }\n        let val = self.val(i).unwrap();\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.push(val);\n        }\n        self.dfs(self.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.push(val);\n        }\n        self.dfs(self.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.push(val);\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fn pre_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"pre\", &mut res);\n        res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fn in_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"in\", &mut res);\n        res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fn post_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"post\", &mut res);\n        res\n    }\n}\n
    array_binary_tree.c
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int *tree;\n    int size;\n} ArrayBinaryTree;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayBinaryTree *newArrayBinaryTree(int *arr, int arrSize) {\n    ArrayBinaryTree *abt = (ArrayBinaryTree *)malloc(sizeof(ArrayBinaryTree));\n    abt->tree = malloc(sizeof(int) * arrSize);\n    memcpy(abt->tree, arr, sizeof(int) * arrSize);\n    abt->size = arrSize;\n    return abt;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayBinaryTree(ArrayBinaryTree *abt) {\n    free(abt->tree);\n    free(abt);\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nint size(ArrayBinaryTree *abt) {\n    return abt->size;\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nint val(ArrayBinaryTree *abt, int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size(abt))\n        return INT_MAX;\n    return abt->tree[i];\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size(abt); i++) {\n        if (val(abt, i) != INT_MAX)\n            res[index++] = val(abt, i);\n    }\n    *returnSize = index;\n    return res;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nvoid dfs(ArrayBinaryTree *abt, int i, char *order, int *res, int *index) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(abt, i) == INT_MAX)\n        return;\n    // \u524d\u5e8f\u904d\u5386\n    if (strcmp(order, \"pre\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, left(i), order, res, index);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (strcmp(order, \"in\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, right(i), order, res, index);\n    // \u540e\u5e8f\u904d\u5386\n    if (strcmp(order, \"post\") == 0)\n        res[(*index)++] = val(abt, i);\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nint *preOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"pre\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nint *inOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"in\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nint *postOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"post\", res, &index);\n    *returnSize = index;\n    return res;\n}\n
    array_binary_tree.kt
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(val tree: MutableList<Int?>) {\n    /* \u5217\u8868\u5bb9\u91cf */\n    fun size(): Int {\n        return tree.size\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fun _val(i: Int): Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size()) return null\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun parent(i: Int): Int {\n        return (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fun levelOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (i in 0..<size()) {\n            if (_val(i) != null)\n                res.add(_val(i))\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fun dfs(i: Int, order: String, res: MutableList<Int?>) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (_val(i) == null)\n            return\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\" == order)\n            res.add(_val(i))\n        dfs(left(i), order, res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\" == order)\n            res.add(_val(i))\n        dfs(right(i), order, res)\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\" == order)\n            res.add(_val(i))\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fun preOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"pre\", res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fun inOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"in\", res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fun postOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"post\", res)\n        return res\n    }\n}\n
    array_binary_tree.rb
    ### \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b ###\nclass ArrayBinaryTree\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(arr)\n    @tree = arr.to_a\n  end\n\n  ### \u5217\u8868\u5bb9\u91cf ###\n  def size\n    @tree.length\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c ###\n  def val(i)\n    # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de nil \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    return if i < 0 || i >= size\n\n    @tree[i]\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def left(i)\n    2 * i + 1\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def right(i)\n    2 * i + 2\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def parent(i)\n    (i - 1) / 2\n  end\n\n  ### \u5c42\u5e8f\u904d\u5386 ###\n  def level_order\n    @res = []\n\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i in 0...size\n      @res << val(i) unless val(i).nil?\n    end\n\n    @res\n  end\n\n  ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\n  def dfs(i, order)\n    return if val(i).nil?\n    # \u524d\u5e8f\u904d\u5386\n    @res << val(i) if order == :pre\n    dfs(left(i), order)\n    # \u4e2d\u5e8f\u904d\u5386\n    @res << val(i) if order == :in\n    dfs(right(i), order)\n    # \u540e\u5e8f\u904d\u5386\n    @res << val(i) if order == :post\n  end\n\n  ### \u524d\u5e8f\u904d\u5386 ###\n  def pre_order\n    @res = []\n    dfs(0, :pre)\n    @res\n  end\n\n  ### \u4e2d\u5e8f\u904d\u5386 ###\n  def in_order\n    @res = []\n    dfs(0, :in)\n    @res\n  end\n\n  ### \u540e\u5e8f\u904d\u5386 ###\n  def post_order\n    @res = []\n    dfs(0, :post)\n    @res\n  end\nend\n
    array_binary_tree.zig
    [class]{ArrayBinaryTree}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/array_representation_of_tree/#733","title":"7.3.3 \u00a0 \u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a\u4e3b\u8981\u6709\u4ee5\u4e0b\u4f18\u70b9\u3002

    • \u6570\u7ec4\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\uff0c\u5bf9\u7f13\u5b58\u53cb\u597d\uff0c\u8bbf\u95ee\u4e0e\u904d\u5386\u901f\u5ea6\u8f83\u5feb\u3002
    • \u4e0d\u9700\u8981\u5b58\u50a8\u6307\u9488\uff0c\u6bd4\u8f83\u8282\u7701\u7a7a\u95f4\u3002
    • \u5141\u8bb8\u968f\u673a\u8bbf\u95ee\u8282\u70b9\u3002

    \u7136\u800c\uff0c\u6570\u7ec4\u8868\u793a\u4e5f\u5b58\u5728\u4e00\u4e9b\u5c40\u9650\u6027\u3002

    • \u6570\u7ec4\u5b58\u50a8\u9700\u8981\u8fde\u7eed\u5185\u5b58\u7a7a\u95f4\uff0c\u56e0\u6b64\u4e0d\u9002\u5408\u5b58\u50a8\u6570\u636e\u91cf\u8fc7\u5927\u7684\u6811\u3002
    • \u589e\u5220\u8282\u70b9\u9700\u8981\u901a\u8fc7\u6570\u7ec4\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u5b9e\u73b0\uff0c\u6548\u7387\u8f83\u4f4e\u3002
    • \u5f53\u4e8c\u53c9\u6811\u4e2d\u5b58\u5728\u5927\u91cf None \u65f6\uff0c\u6570\u7ec4\u4e2d\u5305\u542b\u7684\u8282\u70b9\u6570\u636e\u6bd4\u91cd\u8f83\u4f4e\uff0c\u7a7a\u95f4\u5229\u7528\u7387\u8f83\u4f4e\u3002
    "},{"location":"chapter_tree/avl_tree/","title":"7.5 \u00a0 AVL \u6811 *","text":"

    \u5728\u201c\u4e8c\u53c9\u641c\u7d22\u6811\u201d\u7ae0\u8282\u4e2d\u6211\u4eec\u63d0\u5230\uff0c\u5728\u591a\u6b21\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u540e\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u53ef\u80fd\u9000\u5316\u4e3a\u94fe\u8868\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5c06\u4ece \\(O(\\log n)\\) \u52a3\u5316\u4e3a \\(O(n)\\) \u3002

    \u5982\u56fe 7-24 \u6240\u793a\uff0c\u7ecf\u8fc7\u4e24\u6b21\u5220\u9664\u8282\u70b9\u64cd\u4f5c\uff0c\u8fd9\u68f5\u4e8c\u53c9\u641c\u7d22\u6811\u4fbf\u4f1a\u9000\u5316\u4e3a\u94fe\u8868\u3002

    \u56fe 7-24 \u00a0 AVL \u6811\u5728\u5220\u9664\u8282\u70b9\u540e\u53d1\u751f\u9000\u5316

    \u518d\u4f8b\u5982\uff0c\u5728\u56fe 7-25 \u6240\u793a\u7684\u5b8c\u7f8e\u4e8c\u53c9\u6811\u4e2d\u63d2\u5165\u4e24\u4e2a\u8282\u70b9\u540e\uff0c\u6811\u5c06\u4e25\u91cd\u5411\u5de6\u503e\u659c\uff0c\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u968f\u4e4b\u52a3\u5316\u3002

    \u56fe 7-25 \u00a0 AVL \u6811\u5728\u63d2\u5165\u8282\u70b9\u540e\u53d1\u751f\u9000\u5316

    1962 \u5e74 G. M. Adelson-Velsky \u548c E. M. Landis \u5728\u8bba\u6587\u201cAn algorithm for the organization of information\u201d\u4e2d\u63d0\u51fa\u4e86 AVL \u6811\u3002\u8bba\u6587\u4e2d\u8be6\u7ec6\u63cf\u8ff0\u4e86\u4e00\u7cfb\u5217\u64cd\u4f5c\uff0c\u786e\u4fdd\u5728\u6301\u7eed\u6dfb\u52a0\u548c\u5220\u9664\u8282\u70b9\u540e\uff0cAVL \u6811\u4e0d\u4f1a\u9000\u5316\uff0c\u4ece\u800c\u4f7f\u5f97\u5404\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4fdd\u6301\u5728 \\(O(\\log n)\\) \u7ea7\u522b\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u5728\u9700\u8981\u9891\u7e41\u8fdb\u884c\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u7684\u573a\u666f\u4e2d\uff0cAVL \u6811\u80fd\u59cb\u7ec8\u4fdd\u6301\u9ad8\u6548\u7684\u6570\u636e\u64cd\u4f5c\u6027\u80fd\uff0c\u5177\u6709\u5f88\u597d\u7684\u5e94\u7528\u4ef7\u503c\u3002

    "},{"location":"chapter_tree/avl_tree/#751-avl","title":"7.5.1 \u00a0 AVL \u6811\u5e38\u89c1\u672f\u8bed","text":"

    AVL \u6811\u65e2\u662f\u4e8c\u53c9\u641c\u7d22\u6811\uff0c\u4e5f\u662f\u5e73\u8861\u4e8c\u53c9\u6811\uff0c\u540c\u65f6\u6ee1\u8db3\u8fd9\u4e24\u7c7b\u4e8c\u53c9\u6811\u7684\u6240\u6709\u6027\u8d28\uff0c\u56e0\u6b64\u662f\u4e00\u79cd\u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811\uff08balanced binary search tree\uff09\u3002

    "},{"location":"chapter_tree/avl_tree/#1","title":"1. \u00a0 \u8282\u70b9\u9ad8\u5ea6","text":"

    \u7531\u4e8e AVL \u6811\u7684\u76f8\u5173\u64cd\u4f5c\u9700\u8981\u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u4e3a\u8282\u70b9\u7c7b\u6dfb\u52a0 height \u53d8\u91cf\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"AVL \u6811\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                 # \u8282\u70b9\u503c\n        self.height: int = 0                # \u8282\u70b9\u9ad8\u5ea6\n        self.left: TreeNode | None = None   # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n        self.right: TreeNode | None = None  # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nstruct TreeNode {\n    int val{};          // \u8282\u70b9\u503c\n    int height = 0;     // \u8282\u70b9\u9ad8\u5ea6\n    TreeNode *left{};   // \u5de6\u5b50\u8282\u70b9\n    TreeNode *right{};  // \u53f3\u5b50\u8282\u70b9\n    TreeNode() = default;\n    explicit TreeNode(int x) : val(x){}\n};\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    public int val;        // \u8282\u70b9\u503c\n    public int height;     // \u8282\u70b9\u9ad8\u5ea6\n    public TreeNode left;  // \u5de6\u5b50\u8282\u70b9\n    public TreeNode right; // \u53f3\u5b50\u8282\u70b9\n    public TreeNode(int x) { val = x; }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode(int? x) {\n    public int? val = x;    // \u8282\u70b9\u503c\n    public int height;      // \u8282\u70b9\u9ad8\u5ea6\n    public TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    public TreeNode? right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    /* AVL \u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype TreeNode struct {\n    Val    int       // \u8282\u70b9\u503c\n    Height int       // \u8282\u70b9\u9ad8\u5ea6\n    Left   *TreeNode // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    Right  *TreeNode // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    var val: Int // \u8282\u70b9\u503c\n    var height: Int // \u8282\u70b9\u9ad8\u5ea6\n    var left: TreeNode? // \u5de6\u5b50\u8282\u70b9\n    var right: TreeNode? // \u53f3\u5b50\u8282\u70b9\n\n    init(x: Int) {\n        val = x\n        height = 0\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val; // \u8282\u70b9\u503c\n    height; //\u8282\u70b9\u9ad8\u5ea6\n    left; // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    right; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    constructor(val, left, right, height) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val: number;            // \u8282\u70b9\u503c\n    height: number;         // \u8282\u70b9\u9ad8\u5ea6\n    left: TreeNode | null;  // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    right: TreeNode | null; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    constructor(val?: number, height?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n  int val;         // \u8282\u70b9\u503c\n  int height;      // \u8282\u70b9\u9ad8\u5ea6\n  TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\n  TreeNode? right; // \u53f3\u5b50\u8282\u70b9\n  TreeNode(this.val, [this.height = 0, this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* AVL \u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct TreeNode {\n    val: i32,                               // \u8282\u70b9\u503c\n    height: i32,                            // \u8282\u70b9\u9ad8\u5ea6\n    left: Option<Rc<RefCell<TreeNode>>>,    // \u5de6\u5b50\u8282\u70b9\n    right: Option<Rc<RefCell<TreeNode>>>,   // \u53f3\u5b50\u8282\u70b9\n}\n\nimpl TreeNode {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            height: 0,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nTreeNode struct TreeNode {\n    int val;\n    int height;\n    struct TreeNode *left;\n    struct TreeNode *right;\n} TreeNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode(val _val: Int) {  // \u8282\u70b9\u503c\n    val height: Int = 0          // \u8282\u70b9\u9ad8\u5ea6\n    val left: TreeNode? = null   // \u5de6\u5b50\u8282\u70b9\n    val right: TreeNode? = null  // \u53f3\u5b50\u8282\u70b9\n}\n
    ### AVL \u6811\u8282\u70b9\u7c7b ###\nclass TreeNode\n  attr_accessor :val    # \u8282\u70b9\u503c\n  attr_accessor :height # \u8282\u70b9\u9ad8\u5ea6\n  attr_accessor :left   # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n  attr_accessor :right  # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n\n  def initialize(val)\n    @val = val\n    @height = 0\n  end\nend\n
    \n

    \u201c\u8282\u70b9\u9ad8\u5ea6\u201d\u662f\u6307\u4ece\u8be5\u8282\u70b9\u5230\u5b83\u7684\u6700\u8fdc\u53f6\u8282\u70b9\u7684\u8ddd\u79bb\uff0c\u5373\u6240\u7ecf\u8fc7\u7684\u201c\u8fb9\u201d\u7684\u6570\u91cf\u3002\u9700\u8981\u7279\u522b\u6ce8\u610f\u7684\u662f\uff0c\u53f6\u8282\u70b9\u7684\u9ad8\u5ea6\u4e3a \\(0\\) \uff0c\u800c\u7a7a\u8282\u70b9\u7684\u9ad8\u5ea6\u4e3a \\(-1\\) \u3002\u6211\u4eec\u5c06\u521b\u5efa\u4e24\u4e2a\u5de5\u5177\u51fd\u6570\uff0c\u5206\u522b\u7528\u4e8e\u83b7\u53d6\u548c\u66f4\u65b0\u8282\u70b9\u7684\u9ad8\u5ea6\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def height(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node is not None:\n        return node.height\n    return -1\n\ndef update_height(self, node: TreeNode | None):\n    \"\"\"\u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = max([self.height(node.left), self.height(node.right)]) + 1\n
    avl_tree.cpp
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == nullptr ? -1 : node->height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node->height = max(height(node->left), height(node->right)) + 1;\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint Height(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid UpdateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.Max(Height(node.left), Height(node.right)) + 1;\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) height(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node != nil {\n        return node.Height\n    }\n    return -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) updateHeight(node *TreeNode) {\n    lh := t.height(node.Left)\n    rh := t.height(node.Right)\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if lh > rh {\n        node.Height = lh + 1\n    } else {\n        node.Height = rh + 1\n    }\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc height(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    node?.height ?? -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node: node?.left), height(node: node?.right)) + 1\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\n#updateHeight(node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nupdateHeight(node: TreeNode): void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode? node) {\n  // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node!.height = max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfn height(node: OptionTreeNodeRc) -> i32 {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    match node {\n        Some(node) => node.borrow().height,\n        None => -1,\n    }\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfn update_height(node: OptionTreeNodeRc) {\n    if let Some(node) = node {\n        let left = node.borrow().left.clone();\n        let right = node.borrow().right.clone();\n        // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n        node.borrow_mut().height = std::cmp::max(Self::height(left), Self::height(right)) + 1;\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if (node != NULL) {\n        return node->height;\n    }\n    return -1;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    int lh = height(node->left);\n    int rh = height(node->right);\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if (lh > rh) {\n        node->height = lh + 1;\n    } else {\n        node->height = rh + 1;\n    }\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfun height(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node?.height ?: -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfun updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node?.left), height(node?.right)) + 1\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 ###\ndef height(node)\n  # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node.height unless node.nil?\n\n  -1\nend\n\n### \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 ###\ndef update_height(node)\n  # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node.height = [height(node.left), height(node.right)].max + 1\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\nfn height(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    _ = self;\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return if (node == null) -1 else node.?.height;\n}\n\n// \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\nfn updateHeight(self: *Self, node: ?*inc.TreeNode(T)) void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.?.height = @max(self.height(node.?.left), self.height(node.?.right)) + 1;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2","title":"2. \u00a0 \u8282\u70b9\u5e73\u8861\u56e0\u5b50","text":"

    \u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\uff08balance factor\uff09\u5b9a\u4e49\u4e3a\u8282\u70b9\u5de6\u5b50\u6811\u7684\u9ad8\u5ea6\u51cf\u53bb\u53f3\u5b50\u6811\u7684\u9ad8\u5ea6\uff0c\u540c\u65f6\u89c4\u5b9a\u7a7a\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u4e3a \\(0\\) \u3002\u6211\u4eec\u540c\u6837\u5c06\u83b7\u53d6\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u7684\u529f\u80fd\u5c01\u88c5\u6210\u51fd\u6570\uff0c\u65b9\u4fbf\u540e\u7eed\u4f7f\u7528\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def balance_factor(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u5e73\u8861\u56e0\u5b50\"\"\"\n    # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node is None:\n        return 0\n    # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.left) - self.height(node.right)\n
    avl_tree.cpp
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == nullptr)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right);\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint BalanceFactor(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return Height(node.left) - Height(node.right);\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc (t *aVLTree) balanceFactor(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node == nil {\n        return 0\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return t.height(node.Left) - t.height(node.Right)\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc balanceFactor(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    guard let node = node else { return 0 }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node: node.left) - height(node: node.right)\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  if (node == null) return 0;\n  // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  return height(node.left) - height(node.right);\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfn balance_factor(node: OptionTreeNodeRc) -> i32 {\n    match node {\n        // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n        None => 0,\n        // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n        Some(node) => {\n            Self::height(node.borrow().left.clone()) - Self::height(node.borrow().right.clone())\n        }\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == NULL) {\n        return 0;\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfun balanceFactor(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right)\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 ###\ndef balance_factor(node)\n  # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  return 0 if node.nil?\n\n  # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  height(node.left) - height(node.right)\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u5e73\u8861\u56e0\u5b50\nfn balanceFactor(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.?.left) - self.height(node.?.right);\n}\n

    Tip

    \u8bbe\u5e73\u8861\u56e0\u5b50\u4e3a \\(f\\) \uff0c\u5219\u4e00\u68f5 AVL \u6811\u7684\u4efb\u610f\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u7686\u6ee1\u8db3 \\(-1 \\le f \\le 1\\) \u3002

    "},{"location":"chapter_tree/avl_tree/#752-avl","title":"7.5.2 \u00a0 AVL \u6811\u65cb\u8f6c","text":"

    AVL \u6811\u7684\u7279\u70b9\u5728\u4e8e\u201c\u65cb\u8f6c\u201d\u64cd\u4f5c\uff0c\u5b83\u80fd\u591f\u5728\u4e0d\u5f71\u54cd\u4e8c\u53c9\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217\u7684\u524d\u63d0\u4e0b\uff0c\u4f7f\u5931\u8861\u8282\u70b9\u91cd\u65b0\u6062\u590d\u5e73\u8861\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u65cb\u8f6c\u64cd\u4f5c\u65e2\u80fd\u4fdd\u6301\u201c\u4e8c\u53c9\u641c\u7d22\u6811\u201d\u7684\u6027\u8d28\uff0c\u4e5f\u80fd\u4f7f\u6811\u91cd\u65b0\u53d8\u4e3a\u201c\u5e73\u8861\u4e8c\u53c9\u6811\u201d\u3002

    \u6211\u4eec\u5c06\u5e73\u8861\u56e0\u5b50\u7edd\u5bf9\u503c \\(> 1\\) \u7684\u8282\u70b9\u79f0\u4e3a\u201c\u5931\u8861\u8282\u70b9\u201d\u3002\u6839\u636e\u8282\u70b9\u5931\u8861\u60c5\u51b5\u7684\u4e0d\u540c\uff0c\u65cb\u8f6c\u64cd\u4f5c\u5206\u4e3a\u56db\u79cd\uff1a\u53f3\u65cb\u3001\u5de6\u65cb\u3001\u5148\u53f3\u65cb\u540e\u5de6\u65cb\u3001\u5148\u5de6\u65cb\u540e\u53f3\u65cb\u3002\u4e0b\u9762\u8be6\u7ec6\u4ecb\u7ecd\u8fd9\u4e9b\u65cb\u8f6c\u64cd\u4f5c\u3002

    "},{"location":"chapter_tree/avl_tree/#1_1","title":"1. \u00a0 \u53f3\u65cb","text":"

    \u5982\u56fe 7-26 \u6240\u793a\uff0c\u8282\u70b9\u4e0b\u65b9\u4e3a\u5e73\u8861\u56e0\u5b50\u3002\u4ece\u5e95\u81f3\u9876\u770b\uff0c\u4e8c\u53c9\u6811\u4e2d\u9996\u4e2a\u5931\u8861\u8282\u70b9\u662f\u201c\u8282\u70b9 3\u201d\u3002\u6211\u4eec\u5173\u6ce8\u4ee5\u8be5\u5931\u8861\u8282\u70b9\u4e3a\u6839\u8282\u70b9\u7684\u5b50\u6811\uff0c\u5c06\u8be5\u8282\u70b9\u8bb0\u4e3a node \uff0c\u5176\u5de6\u5b50\u8282\u70b9\u8bb0\u4e3a child \uff0c\u6267\u884c\u201c\u53f3\u65cb\u201d\u64cd\u4f5c\u3002\u5b8c\u6210\u53f3\u65cb\u540e\uff0c\u5b50\u6811\u6062\u590d\u5e73\u8861\uff0c\u5e76\u4e14\u4ecd\u7136\u4fdd\u6301\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6027\u8d28\u3002

    <1><2><3><4>

    \u56fe 7-26 \u00a0 \u53f3\u65cb\u64cd\u4f5c\u6b65\u9aa4

    \u5982\u56fe 7-27 \u6240\u793a\uff0c\u5f53\u8282\u70b9 child \u6709\u53f3\u5b50\u8282\u70b9\uff08\u8bb0\u4e3a grand_child \uff09\u65f6\uff0c\u9700\u8981\u5728\u53f3\u65cb\u4e2d\u6dfb\u52a0\u4e00\u6b65\uff1a\u5c06 grand_child \u4f5c\u4e3a node \u7684\u5de6\u5b50\u8282\u70b9\u3002

    \u56fe 7-27 \u00a0 \u6709 grand_child \u7684\u53f3\u65cb\u64cd\u4f5c

    \u201c\u5411\u53f3\u65cb\u8f6c\u201d\u662f\u4e00\u79cd\u5f62\u8c61\u5316\u7684\u8bf4\u6cd5\uff0c\u5b9e\u9645\u4e0a\u9700\u8981\u901a\u8fc7\u4fee\u6539\u8282\u70b9\u6307\u9488\u6765\u5b9e\u73b0\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def right_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u53f3\u65cb\u64cd\u4f5c\"\"\"\n    child = node.left\n    grand_child = child.right\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child = node->left;\n    TreeNode *grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode rightRotate(TreeNode node) {\n    TreeNode child = node.left;\n    TreeNode grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? RightRotate(TreeNode? node) {\n    TreeNode? child = node?.left;\n    TreeNode? grandChild = child?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) rightRotate(node *TreeNode) *TreeNode {\n    child := node.Left\n    grandChild := child.Right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.Right = node\n    node.Left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc rightRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.left\n    let grandChild = child?.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child?.right = node\n    node?.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u53f3\u65cb\u64cd\u4f5c */\n#rightRotate(node) {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u53f3\u65cb\u64cd\u4f5c */\nrightRotate(node: TreeNode): TreeNode {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? rightRotate(TreeNode? node) {\n  TreeNode? child = node!.left;\n  TreeNode? grandChild = child!.right;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node;\n  node.left = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u53f3\u65cb\u64cd\u4f5c */\nfn right_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().left.clone().unwrap();\n            let grand_child = child.borrow().right.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n            child.borrow_mut().right = Some(node.clone());\n            node.borrow_mut().left = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->left;\n    grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u53f3\u65cb\u64cd\u4f5c */\nfun rightRotate(node: TreeNode?): TreeNode {\n    val child = node!!.left\n    val grandChild = child!!.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u53f3\u65cb\u64cd\u4f5c ###\ndef right_rotate(node)\n  child = node.left\n  grand_child = child.right\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node\n  node.left = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u53f3\u65cb\u64cd\u4f5c\nfn rightRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.left;\n    var grandChild = child.?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.?.right = node;\n    node.?.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2_1","title":"2. \u00a0 \u5de6\u65cb","text":"

    \u76f8\u5e94\u5730\uff0c\u5982\u679c\u8003\u8651\u4e0a\u8ff0\u5931\u8861\u4e8c\u53c9\u6811\u7684\u201c\u955c\u50cf\u201d\uff0c\u5219\u9700\u8981\u6267\u884c\u56fe 7-28 \u6240\u793a\u7684\u201c\u5de6\u65cb\u201d\u64cd\u4f5c\u3002

    \u56fe 7-28 \u00a0 \u5de6\u65cb\u64cd\u4f5c

    \u540c\u7406\uff0c\u5982\u56fe 7-29 \u6240\u793a\uff0c\u5f53\u8282\u70b9 child \u6709\u5de6\u5b50\u8282\u70b9\uff08\u8bb0\u4e3a grand_child \uff09\u65f6\uff0c\u9700\u8981\u5728\u5de6\u65cb\u4e2d\u6dfb\u52a0\u4e00\u6b65\uff1a\u5c06 grand_child \u4f5c\u4e3a node \u7684\u53f3\u5b50\u8282\u70b9\u3002

    \u56fe 7-29 \u00a0 \u6709 grand_child \u7684\u5de6\u65cb\u64cd\u4f5c

    \u53ef\u4ee5\u89c2\u5bdf\u5230\uff0c\u53f3\u65cb\u548c\u5de6\u65cb\u64cd\u4f5c\u5728\u903b\u8f91\u4e0a\u662f\u955c\u50cf\u5bf9\u79f0\u7684\uff0c\u5b83\u4eec\u5206\u522b\u89e3\u51b3\u7684\u4e24\u79cd\u5931\u8861\u60c5\u51b5\u4e5f\u662f\u5bf9\u79f0\u7684\u3002\u57fa\u4e8e\u5bf9\u79f0\u6027\uff0c\u6211\u4eec\u53ea\u9700\u5c06\u53f3\u65cb\u7684\u5b9e\u73b0\u4ee3\u7801\u4e2d\u7684\u6240\u6709\u7684 left \u66ff\u6362\u4e3a right \uff0c\u5c06\u6240\u6709\u7684 right \u66ff\u6362\u4e3a left \uff0c\u5373\u53ef\u5f97\u5230\u5de6\u65cb\u7684\u5b9e\u73b0\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def left_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u5de6\u65cb\u64cd\u4f5c\"\"\"\n    child = node.right\n    grand_child = child.left\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child = node->right;\n    TreeNode *grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode leftRotate(TreeNode node) {\n    TreeNode child = node.right;\n    TreeNode grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? LeftRotate(TreeNode? node) {\n    TreeNode? child = node?.right;\n    TreeNode? grandChild = child?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) leftRotate(node *TreeNode) *TreeNode {\n    child := node.Right\n    grandChild := child.Left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.Left = node\n    node.Right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc leftRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.right\n    let grandChild = child?.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child?.left = node\n    node?.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u5de6\u65cb\u64cd\u4f5c */\n#leftRotate(node) {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u5de6\u65cb\u64cd\u4f5c */\nleftRotate(node: TreeNode): TreeNode {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? leftRotate(TreeNode? node) {\n  TreeNode? child = node!.right;\n  TreeNode? grandChild = child!.left;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node;\n  node.right = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u5de6\u65cb\u64cd\u4f5c */\nfn left_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().right.clone().unwrap();\n            let grand_child = child.borrow().left.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n            child.borrow_mut().left = Some(node.clone());\n            node.borrow_mut().right = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->right;\n    grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u5de6\u65cb\u64cd\u4f5c */\nfun leftRotate(node: TreeNode?): TreeNode {\n    val child = node!!.right\n    val grandChild = child!!.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u5de6\u65cb\u64cd\u4f5c ###\ndef left_rotate(node)\n  child = node.right\n  grand_child = child.left\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node\n  node.right = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u5de6\u65cb\u64cd\u4f5c\nfn leftRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.right;\n    var grandChild = child.?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.?.left = node;\n    node.?.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3","title":"3. \u00a0 \u5148\u5de6\u65cb\u540e\u53f3\u65cb","text":"

    \u5bf9\u4e8e\u56fe 7-30 \u4e2d\u7684\u5931\u8861\u8282\u70b9 3 \uff0c\u4ec5\u4f7f\u7528\u5de6\u65cb\u6216\u53f3\u65cb\u90fd\u65e0\u6cd5\u4f7f\u5b50\u6811\u6062\u590d\u5e73\u8861\u3002\u6b64\u65f6\u9700\u8981\u5148\u5bf9 child \u6267\u884c\u201c\u5de6\u65cb\u201d\uff0c\u518d\u5bf9 node \u6267\u884c\u201c\u53f3\u65cb\u201d\u3002

    \u56fe 7-30 \u00a0 \u5148\u5de6\u65cb\u540e\u53f3\u65cb

    "},{"location":"chapter_tree/avl_tree/#4","title":"4. \u00a0 \u5148\u53f3\u65cb\u540e\u5de6\u65cb","text":"

    \u5982\u56fe 7-31 \u6240\u793a\uff0c\u5bf9\u4e8e\u4e0a\u8ff0\u5931\u8861\u4e8c\u53c9\u6811\u7684\u955c\u50cf\u60c5\u51b5\uff0c\u9700\u8981\u5148\u5bf9 child \u6267\u884c\u201c\u53f3\u65cb\u201d\uff0c\u518d\u5bf9 node \u6267\u884c\u201c\u5de6\u65cb\u201d\u3002

    \u56fe 7-31 \u00a0 \u5148\u53f3\u65cb\u540e\u5de6\u65cb

    "},{"location":"chapter_tree/avl_tree/#5","title":"5. \u00a0 \u65cb\u8f6c\u7684\u9009\u62e9","text":"

    \u56fe 7-32 \u5c55\u793a\u7684\u56db\u79cd\u5931\u8861\u60c5\u51b5\u4e0e\u4e0a\u8ff0\u6848\u4f8b\u9010\u4e2a\u5bf9\u5e94\uff0c\u5206\u522b\u9700\u8981\u91c7\u7528\u53f3\u65cb\u3001\u5148\u5de6\u65cb\u540e\u53f3\u65cb\u3001\u5148\u53f3\u65cb\u540e\u5de6\u65cb\u3001\u5de6\u65cb\u7684\u64cd\u4f5c\u3002

    \u56fe 7-32 \u00a0 AVL \u6811\u7684\u56db\u79cd\u65cb\u8f6c\u60c5\u51b5

    \u5982\u4e0b\u8868\u6240\u793a\uff0c\u6211\u4eec\u901a\u8fc7\u5224\u65ad\u5931\u8861\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u4ee5\u53ca\u8f83\u9ad8\u4e00\u4fa7\u5b50\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u7684\u6b63\u8d1f\u53f7\uff0c\u6765\u786e\u5b9a\u5931\u8861\u8282\u70b9\u5c5e\u4e8e\u56fe 7-32 \u4e2d\u7684\u54ea\u79cd\u60c5\u51b5\u3002

    \u8868 7-3 \u00a0 \u56db\u79cd\u65cb\u8f6c\u60c5\u51b5\u7684\u9009\u62e9\u6761\u4ef6

    \u5931\u8861\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50 \u5b50\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50 \u5e94\u91c7\u7528\u7684\u65cb\u8f6c\u65b9\u6cd5 \\(> 1\\) \uff08\u5de6\u504f\u6811\uff09 \\(\\geq 0\\) \u53f3\u65cb \\(> 1\\) \uff08\u5de6\u504f\u6811\uff09 \\(<0\\) \u5148\u5de6\u65cb\u540e\u53f3\u65cb \\(< -1\\) \uff08\u53f3\u504f\u6811\uff09 \\(\\leq 0\\) \u5de6\u65cb \\(< -1\\) \uff08\u53f3\u504f\u6811\uff09 \\(>0\\) \u5148\u53f3\u65cb\u540e\u5de6\u65cb

    \u4e3a\u4e86\u4fbf\u4e8e\u4f7f\u7528\uff0c\u6211\u4eec\u5c06\u65cb\u8f6c\u64cd\u4f5c\u5c01\u88c5\u6210\u4e00\u4e2a\u51fd\u6570\u3002\u6709\u4e86\u8fd9\u4e2a\u51fd\u6570\uff0c\u6211\u4eec\u5c31\u80fd\u5bf9\u5404\u79cd\u5931\u8861\u60c5\u51b5\u8fdb\u884c\u65cb\u8f6c\uff0c\u4f7f\u5931\u8861\u8282\u70b9\u91cd\u65b0\u6062\u590d\u5e73\u8861\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\"\"\"\n    # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    balance_factor = self.balance_factor(node)\n    # \u5de6\u504f\u6811\n    if balance_factor > 1:\n        if self.balance_factor(node.left) >= 0:\n            # \u53f3\u65cb\n            return self.right_rotate(node)\n        else:\n            # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = self.left_rotate(node.left)\n            return self.right_rotate(node)\n    # \u53f3\u504f\u6811\n    elif balance_factor < -1:\n        if self.balance_factor(node.right) <= 0:\n            # \u5de6\u65cb\n            return self.left_rotate(node)\n        else:\n            # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = self.right_rotate(node.right)\n            return self.left_rotate(node)\n    # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n
    avl_tree.cpp
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int _balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (_balanceFactor > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (_balanceFactor < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.java
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode rotate(TreeNode node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.cs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? Rotate(TreeNode? node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactorInt = BalanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactorInt > 1) {\n        if (BalanceFactor(node?.left) >= 0) {\n            // \u53f3\u65cb\n            return RightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node!.left = LeftRotate(node!.left);\n            return RightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactorInt < -1) {\n        if (BalanceFactor(node?.right) <= 0) {\n            // \u5de6\u65cb\n            return LeftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node!.right = RightRotate(node!.right);\n            return LeftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.go
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc (t *aVLTree) rotate(node *TreeNode) *TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    // Go \u63a8\u8350\u77ed\u53d8\u91cf\uff0c\u8fd9\u91cc bf \u6307\u4ee3 t.balanceFactor\n    bf := t.balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if bf > 1 {\n        if t.balanceFactor(node.Left) >= 0 {\n            // \u53f3\u65cb\n            return t.rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.Left = t.leftRotate(node.Left)\n            return t.rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if bf < -1 {\n        if t.balanceFactor(node.Right) <= 0 {\n            // \u5de6\u65cb\n            return t.leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.Right = t.rightRotate(node.Right)\n            return t.leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.swift
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc rotate(node: TreeNode?) -> TreeNode? {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balanceFactor = balanceFactor(node: node)\n    // \u5de6\u504f\u6811\n    if balanceFactor > 1 {\n        if self.balanceFactor(node: node?.left) >= 0 {\n            // \u53f3\u65cb\n            return rightRotate(node: node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node?.left = leftRotate(node: node?.left)\n            return rightRotate(node: node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if balanceFactor < -1 {\n        if self.balanceFactor(node: node?.right) <= 0 {\n            // \u5de6\u65cb\n            return leftRotate(node: node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node?.right = rightRotate(node: node?.right)\n            return leftRotate(node: node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.js
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n#rotate(node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.#rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.#leftRotate(node.left);\n            return this.#rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.#leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.#rightRotate(node.right);\n            return this.#leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.ts
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nrotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.leftRotate(node.left);\n            return this.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.rightRotate(node.right);\n            return this.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.dart
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? rotate(TreeNode? node) {\n  // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  int factor = balanceFactor(node);\n  // \u5de6\u504f\u6811\n  if (factor > 1) {\n    if (balanceFactor(node!.left) >= 0) {\n      // \u53f3\u65cb\n      return rightRotate(node);\n    } else {\n      // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = leftRotate(node.left);\n      return rightRotate(node);\n    }\n  }\n  // \u53f3\u504f\u6811\n  if (factor < -1) {\n    if (balanceFactor(node!.right) <= 0) {\n      // \u5de6\u65cb\n      return leftRotate(node);\n    } else {\n      // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = rightRotate(node.right);\n      return leftRotate(node);\n    }\n  }\n  // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  return node;\n}\n
    avl_tree.rs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfn rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balance_factor = Self::balance_factor(node.clone());\n    // \u5de6\u504f\u6811\n    if balance_factor > 1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().left.clone()) >= 0 {\n            // \u53f3\u65cb\n            Self::right_rotate(Some(node))\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            let left = node.borrow().left.clone();\n            node.borrow_mut().left = Self::left_rotate(left);\n            Self::right_rotate(Some(node))\n        }\n    }\n    // \u53f3\u504f\u6811\n    else if balance_factor < -1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().right.clone()) <= 0 {\n            // \u5de6\u65cb\n            Self::left_rotate(Some(node))\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            let right = node.borrow().right.clone();\n            node.borrow_mut().right = Self::right_rotate(right);\n            Self::left_rotate(Some(node))\n        }\n    } else {\n        // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n        node\n    }\n}\n
    avl_tree.c
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int bf = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (bf > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (bf < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.kt
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfun rotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    val balanceFactor = balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left)\n            return rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right)\n            return leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.rb
    ### \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 ###\ndef rotate(node)\n  # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  balance_factor = balance_factor(node)\n  # \u5de6\u904d\u6811\n  if balance_factor > 1\n    if balance_factor(node.left) >= 0\n      # \u53f3\u65cb\n      return right_rotate(node)\n    else\n      # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = left_rotate(node.left)\n      return right_rotate(node)\n    end\n  # \u53f3\u904d\u6811\n  elsif balance_factor < -1\n    if balance_factor(node.right) <= 0\n      # \u5de6\u65cb\n      return left_rotate(node)\n    else\n      # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = right_rotate(node.right)\n      return left_rotate(node)\n    end\n  end\n  # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  node\nend\n
    avl_tree.zig
    // \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\nfn rotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    var balance_factor = self.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balance_factor > 1) {\n        if (self.balanceFactor(node.?.left) >= 0) {\n            // \u53f3\u65cb\n            return self.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.?.left = self.leftRotate(node.?.left);\n            return self.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balance_factor < -1) {\n        if (self.balanceFactor(node.?.right) <= 0) {\n            // \u5de6\u65cb\n            return self.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.?.right = self.rightRotate(node.?.right);\n            return self.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#753-avl","title":"7.5.3 \u00a0 AVL \u6811\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_tree/avl_tree/#1_2","title":"1. \u00a0 \u63d2\u5165\u8282\u70b9","text":"

    AVL \u6811\u7684\u8282\u70b9\u63d2\u5165\u64cd\u4f5c\u4e0e\u4e8c\u53c9\u641c\u7d22\u6811\u5728\u4e3b\u4f53\u4e0a\u7c7b\u4f3c\u3002\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff0c\u5728 AVL \u6811\u4e2d\u63d2\u5165\u8282\u70b9\u540e\uff0c\u4ece\u8be5\u8282\u70b9\u5230\u6839\u8282\u70b9\u7684\u8def\u5f84\u4e0a\u53ef\u80fd\u4f1a\u51fa\u73b0\u4e00\u7cfb\u5217\u5931\u8861\u8282\u70b9\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u9700\u8981\u4ece\u8fd9\u4e2a\u8282\u70b9\u5f00\u59cb\uff0c\u81ea\u5e95\u5411\u4e0a\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u6240\u6709\u5931\u8861\u8282\u70b9\u6062\u590d\u5e73\u8861\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def insert(self, val):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    self._root = self.insert_helper(self._root, val)\n\ndef insert_helper(self, node: TreeNode | None, val: int) -> TreeNode:\n    \"\"\"\u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return TreeNode(val)\n    # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if val < node.val:\n        node.left = self.insert_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.insert_helper(node.right, val)\n    else:\n        # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val)\n        node->left = insertHelper(node->left, val);\n    else if (val > node->val)\n        node->right = insertHelper(node->right, val);\n    else\n        return node;    // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode insertHelper(TreeNode node, int val) {\n    if (node == null)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = insertHelper(node.right, val);\n    else\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int val) {\n    root = InsertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? InsertHelper(TreeNode? node, int val) {\n    if (node == null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = InsertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = InsertHelper(node.right, val);\n    else\n        return node;     // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (t *aVLTree) insert(val int) {\n    t.root = t.insertHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return NewTreeNode(val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node.Val.(int) {\n        node.Left = t.insertHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.insertHelper(node.Right, val)\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(val: Int) {\n    root = insertHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc insertHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return TreeNode(x: val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node!.val {\n        node?.left = insertHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = insertHelper(node: node?.right, val: val)\n    } else {\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val) {\n    this.root = this.#insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#insertHelper(node, val) {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) node.left = this.#insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#insertHelper(node.right, val);\n    else return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val: number): void {\n    this.root = this.insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\ninsertHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) {\n        node.left = this.insertHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.insertHelper(node.right, val);\n    } else {\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n  root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? insertHelper(TreeNode? node, int val) {\n  if (node == null) return TreeNode(val);\n  /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n  if (val < node.val)\n    node.left = insertHelper(node.left, val);\n  else if (val > node.val)\n    node.right = insertHelper(node.right, val);\n  else\n    return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\nfn insert(&mut self, val: i32) {\n    self.root = Self::insert_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn insert_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n            match {\n                let node_val = node.borrow().val;\n                node_val\n            }\n            .cmp(&val)\n            {\n                Ordering::Greater => {\n                    let left = node.borrow().left.clone();\n                    node.borrow_mut().left = Self::insert_helper(left, val);\n                }\n                Ordering::Less => {\n                    let right = node.borrow().right.clone();\n                    node.borrow_mut().right = Self::insert_helper(right, val);\n                }\n                Ordering::Equal => {\n                    return Some(node); // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n                }\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => Some(TreeNode::new(val)),\n    }\n}\n
    avl_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(AVLTree *tree, int val) {\n    tree->root = insertHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == NULL) {\n        return newTreeNode(val);\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val) {\n        node->left = insertHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = insertHelper(node->right, val);\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node;\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(_val: Int) {\n    root = insertHelper(root, _val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun insertHelper(n: TreeNode?, _val: Int): TreeNode {\n    if (n == null)\n        return TreeNode(_val)\n    var node = n\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (_val < node._val)\n        node.left = insertHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = insertHelper(node.right, _val)\n    else\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(val)\n  @root = insert_helper(@root, val)\nend\n\n### \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef insert_helper(node, val)\n  return TreeNode.new(val) if node.nil?\n  # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n  if val < node.val\n    node.left = insert_helper(node.left, val)\n  elsif val > node.val\n    node.right = insert_helper(node.right, val)\n  else\n    # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, val: T) !void {\n    self.root = (try self.insertHelper(self.root, val)).?;\n}\n\n// \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn insertHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) !?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) {\n        var tmp_node = try self.mem_allocator.create(inc.TreeNode(T));\n        tmp_node.init(val);\n        return tmp_node;\n    }\n    // 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if (val < node.?.val) {\n        node.?.left = try self.insertHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = try self.insertHelper(node.?.right, val);\n    } else {\n        return node;            // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    self.updateHeight(node);    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2_2","title":"2. \u00a0 \u5220\u9664\u8282\u70b9","text":"

    \u7c7b\u4f3c\u5730\uff0c\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u5220\u9664\u8282\u70b9\u65b9\u6cd5\u7684\u57fa\u7840\u4e0a\uff0c\u9700\u8981\u4ece\u5e95\u81f3\u9876\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u6240\u6709\u5931\u8861\u8282\u70b9\u6062\u590d\u5e73\u8861\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def remove(self, val: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    self._root = self.remove_helper(self._root, val)\n\ndef remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None:\n    \"\"\"\u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return None\n    # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if val < node.val:\n        node.left = self.remove_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.remove_helper(node.right, val)\n    else:\n        if node.left is None or node.right is None:\n            child = node.left or node.right\n            # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child is None:\n                return None\n            # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else:\n                node = child\n        else:\n            # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp = node.right\n            while temp.left is not None:\n                temp = temp.left\n            node.right = self.remove_helper(node.right, temp.val)\n            node.val = temp.val\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return nullptr;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val)\n        node->left = removeHelper(node->left, val);\n    else if (val > node->val)\n        node->right = removeHelper(node->right, val);\n    else {\n        if (node->left == nullptr || node->right == nullptr) {\n            TreeNode *child = node->left != nullptr ? node->left : node->right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == nullptr) {\n                delete node;\n                return nullptr;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                delete node;\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != nullptr) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode removeHelper(TreeNode node, int val) {\n    if (node == null)\n        return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = removeHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode child = node.left != null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int val) {\n    root = RemoveHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? RemoveHelper(TreeNode? node, int val) {\n    if (node == null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = RemoveHelper(node.left, val);\n    else if (val > node.val)\n        node.right = RemoveHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode? child = node.left ?? node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode? temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = RemoveHelper(node.right, temp.val!.Value);\n            node.val = temp.val;\n        }\n    }\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (t *aVLTree) remove(val int) {\n    t.root = t.removeHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node.Val.(int) {\n        node.Left = t.removeHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.removeHelper(node.Right, val)\n    } else {\n        if node.Left == nil || node.Right == nil {\n            child := node.Left\n            if node.Right != nil {\n                child = node.Right\n            }\n            if child == nil {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                return nil\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp := node.Right\n            for temp.Left != nil {\n                temp = temp.Left\n            }\n            node.Right = t.removeHelper(node.Right, temp.Val.(int))\n            node.Val = temp.Val\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(val: Int) {\n    root = removeHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc removeHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node!.val {\n        node?.left = removeHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = removeHelper(node: node?.right, val: val)\n    } else {\n        if node?.left == nil || node?.right == nil {\n            let child = node?.left ?? node?.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child == nil {\n                return nil\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node?.right\n            while temp?.left != nil {\n                temp = temp?.left\n            }\n            node?.right = removeHelper(node: node?.right, val: temp!.val)\n            node?.val = temp!.val\n        }\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(val) {\n    this.root = this.#removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#removeHelper(node, val) {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) node.left = this.#removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#removeHelper(node.right, val);\n    else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.#removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(val: number): void {\n    this.root = this.removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nremoveHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) {\n        node.left = this.removeHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.removeHelper(node.right, val);\n    } else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) {\n                return null;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n  root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? removeHelper(TreeNode? node, int val) {\n  if (node == null) return null;\n  /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n  if (val < node.val)\n    node.left = removeHelper(node.left, val);\n  else if (val > node.val)\n    node.right = removeHelper(node.right, val);\n  else {\n    if (node.left == null || node.right == null) {\n      TreeNode? child = node.left ?? node.right;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      if (child == null)\n        return null;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      else\n        node = child;\n    } else {\n      // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      TreeNode? temp = node.right;\n      while (temp!.left != null) {\n        temp = temp.left;\n      }\n      node.right = removeHelper(node.right, temp.val);\n      node.val = temp.val;\n    }\n  }\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\nfn remove(&self, val: i32) {\n    Self::remove_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn remove_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n            if val < node.borrow().val {\n                let left = node.borrow().left.clone();\n                node.borrow_mut().left = Self::remove_helper(left, val);\n            } else if val > node.borrow().val {\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, val);\n            } else if node.borrow().left.is_none() || node.borrow().right.is_none() {\n                let child = if node.borrow().left.is_some() {\n                    node.borrow().left.clone()\n                } else {\n                    node.borrow().right.clone()\n                };\n                match child {\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                    None => {\n                        return None;\n                    }\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                    Some(child) => node = child,\n                }\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n                let mut temp = node.borrow().right.clone().unwrap();\n                loop {\n                    let temp_left = temp.borrow().left.clone();\n                    if temp_left.is_none() {\n                        break;\n                    }\n                    temp = temp_left.unwrap();\n                }\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, temp.borrow().val);\n                node.borrow_mut().val = temp.borrow().val;\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(AVLTree *tree, int val) {\n    TreeNode *root = removeHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    TreeNode *child, *grandChild;\n    if (node == NULL) {\n        return NULL;\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val) {\n        node->left = removeHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = removeHelper(node->right, val);\n    } else {\n        if (node->left == NULL || node->right == NULL) {\n            child = node->left;\n            if (node->right != NULL) {\n                child = node->right;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == NULL) {\n                return NULL;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != NULL) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(_val: Int) {\n    root = removeHelper(root, _val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun removeHelper(n: TreeNode?, _val: Int): TreeNode? {\n    var node = n ?: return null\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (_val < node._val)\n        node.left = removeHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = removeHelper(node.right, _val)\n    else {\n        if (node.left == null || node.right == null) {\n            val child = if (node.left != null)\n                node.left\n            else\n                node.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.right\n            while (temp!!.left != null) {\n                temp = temp.left\n            }\n            node.right = removeHelper(node.right, temp._val)\n            node._val = temp._val\n        }\n    }\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(val)\n  @root = remove_helper(@root, val)\nend\n\n### \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef remove_helper(node, val)\n  return if node.nil?\n  # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n  if val < node.val\n    node.left = remove_helper(node.left, val)\n  elsif val > node.val\n    node.right = remove_helper(node.right, val)\n  else\n    if node.left.nil? || node.right.nil?\n      child = node.left || node.right\n      # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      return if child.nil?\n      # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      node = child\n    else\n      # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      temp = node.right\n      while !temp.left.nil?\n        temp = temp.left\n      end\n      node.right = remove_helper(node.right, temp.val)\n      node.val = temp.val\n    end\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, val: T) void {\n   self.root = self.removeHelper(self.root, val).?;\n}\n\n// \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn removeHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) ?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) return null;\n    // 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if (val < node.?.val) {\n        node.?.left = self.removeHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = self.removeHelper(node.?.right, val);\n    } else {\n        if (node.?.left == null or node.?.right == null) {\n            var child = if (node.?.left != null) node.?.left else node.?.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null) {\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            } else {\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.?.right;\n            while (temp.?.left != null) {\n                temp = temp.?.left;\n            }\n            node.?.right = self.removeHelper(node.?.right, temp.?.val);\n            node.?.val = temp.?.val;\n        }\n    }\n    self.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3_1","title":"3. \u00a0 \u67e5\u627e\u8282\u70b9","text":"

    AVL \u6811\u7684\u8282\u70b9\u67e5\u627e\u64cd\u4f5c\u4e0e\u4e8c\u53c9\u641c\u7d22\u6811\u4e00\u81f4\uff0c\u5728\u6b64\u4e0d\u518d\u8d58\u8ff0\u3002

    "},{"location":"chapter_tree/avl_tree/#754-avl","title":"7.5.4 \u00a0 AVL \u6811\u5178\u578b\u5e94\u7528","text":"
    • \u7ec4\u7ec7\u548c\u5b58\u50a8\u5927\u578b\u6570\u636e\uff0c\u9002\u7528\u4e8e\u9ad8\u9891\u67e5\u627e\u3001\u4f4e\u9891\u589e\u5220\u7684\u573a\u666f\u3002
    • \u7528\u4e8e\u6784\u5efa\u6570\u636e\u5e93\u4e2d\u7684\u7d22\u5f15\u7cfb\u7edf\u3002
    • \u7ea2\u9ed1\u6811\u4e5f\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811\u3002\u76f8\u8f83\u4e8e AVL \u6811\uff0c\u7ea2\u9ed1\u6811\u7684\u5e73\u8861\u6761\u4ef6\u66f4\u5bbd\u677e\uff0c\u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\u6240\u9700\u7684\u65cb\u8f6c\u64cd\u4f5c\u66f4\u5c11\uff0c\u8282\u70b9\u589e\u5220\u64cd\u4f5c\u7684\u5e73\u5747\u6548\u7387\u66f4\u9ad8\u3002
    "},{"location":"chapter_tree/binary_search_tree/","title":"7.4 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811","text":"

    \u5982\u56fe 7-16 \u6240\u793a\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\uff08binary search tree\uff09\u6ee1\u8db3\u4ee5\u4e0b\u6761\u4ef6\u3002

    1. \u5bf9\u4e8e\u6839\u8282\u70b9\uff0c\u5de6\u5b50\u6811\u4e2d\u6240\u6709\u8282\u70b9\u7684\u503c \\(<\\) \u6839\u8282\u70b9\u7684\u503c \\(<\\) \u53f3\u5b50\u6811\u4e2d\u6240\u6709\u8282\u70b9\u7684\u503c\u3002
    2. \u4efb\u610f\u8282\u70b9\u7684\u5de6\u3001\u53f3\u5b50\u6811\u4e5f\u662f\u4e8c\u53c9\u641c\u7d22\u6811\uff0c\u5373\u540c\u6837\u6ee1\u8db3\u6761\u4ef6 1. \u3002

    \u56fe 7-16 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811

    "},{"location":"chapter_tree/binary_search_tree/#741","title":"7.4.1 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u64cd\u4f5c","text":"

    \u6211\u4eec\u5c06\u4e8c\u53c9\u641c\u7d22\u6811\u5c01\u88c5\u4e3a\u4e00\u4e2a\u7c7b BinarySearchTree \uff0c\u5e76\u58f0\u660e\u4e00\u4e2a\u6210\u5458\u53d8\u91cf root \uff0c\u6307\u5411\u6811\u7684\u6839\u8282\u70b9\u3002

    "},{"location":"chapter_tree/binary_search_tree/#1","title":"1. \u00a0 \u67e5\u627e\u8282\u70b9","text":"

    \u7ed9\u5b9a\u76ee\u6807\u8282\u70b9\u503c num \uff0c\u53ef\u4ee5\u6839\u636e\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6027\u8d28\u6765\u67e5\u627e\u3002\u5982\u56fe 7-17 \u6240\u793a\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u8282\u70b9 cur \uff0c\u4ece\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9 root \u51fa\u53d1\uff0c\u5faa\u73af\u6bd4\u8f83\u8282\u70b9\u503c cur.val \u548c num \u4e4b\u95f4\u7684\u5927\u5c0f\u5173\u7cfb\u3002

    • \u82e5 cur.val < num \uff0c\u8bf4\u660e\u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\uff0c\u56e0\u6b64\u6267\u884c cur = cur.right \u3002
    • \u82e5 cur.val > num \uff0c\u8bf4\u660e\u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\uff0c\u56e0\u6b64\u6267\u884c cur = cur.left \u3002
    • \u82e5 cur.val = num \uff0c\u8bf4\u660e\u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\u5e76\u8fd4\u56de\u8be5\u8282\u70b9\u3002
    <1><2><3><4>

    \u56fe 7-17 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u67e5\u627e\u8282\u70b9\u793a\u4f8b

    \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u67e5\u627e\u64cd\u4f5c\u4e0e\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u4e00\u81f4\uff0c\u90fd\u662f\u6bcf\u8f6e\u6392\u9664\u4e00\u534a\u60c5\u51b5\u3002\u5faa\u73af\u6b21\u6570\u6700\u591a\u4e3a\u4e8c\u53c9\u6811\u7684\u9ad8\u5ea6\uff0c\u5f53\u4e8c\u53c9\u6811\u5e73\u8861\u65f6\uff0c\u4f7f\u7528 \\(O(\\log n)\\) \u65f6\u95f4\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def search(self, num: int) -> TreeNode | None:\n    \"\"\"\u67e5\u627e\u8282\u70b9\"\"\"\n    cur = self._root\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur is not None:\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        elif cur.val > num:\n            cur = cur.left\n        # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else:\n            break\n    return cur\n
    binary_search_tree.cpp
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(int num) {\n    TreeNode *cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur->val > num)\n            cur = cur->left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.java
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode search(int num) {\n    TreeNode cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.cs
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? Search(int num) {\n    TreeNode? cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur =\n            cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.go
    /* \u67e5\u627e\u8282\u70b9 */\nfunc (bst *binarySearchTree) search(num int) *TreeNode {\n    node := bst.root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for node != nil {\n        if node.Val.(int) < num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            node = node.Right\n        } else if node.Val.(int) > num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            node = node.Left\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return node\n}\n
    binary_search_tree.swift
    /* \u67e5\u627e\u8282\u70b9 */\nfunc search(num: Int) -> TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if cur!.val > num {\n            cur = cur?.left\n        }\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else {\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.js
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num) {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.ts
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num: number): TreeNode | null {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.dart
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? search(int _num) {\n  TreeNode? cur = _root;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else if (cur.val > _num)\n      cur = cur.left;\n    // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break;\n  }\n  // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n  return cur;\n}\n
    binary_search_tree.rs
    /* \u67e5\u627e\u8282\u70b9 */\npub fn search(&self, num: i32) -> OptionTreeNodeRc {\n    let mut cur = self.root.clone();\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => cur = node.borrow().right.clone(),\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => cur = node.borrow().left.clone(),\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n        }\n    }\n\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    cur\n}\n
    binary_search_tree.c
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(BinarySearchTree *bst, int num) {\n    TreeNode *cur = bst->root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        if (cur->val < num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else if (cur->val > num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.kt
    /* \u67e5\u627e\u8282\u70b9 */\nfun search(num: Int): TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur._val > num)\n            cur.left\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.rb
    ### \u67e5\u627e\u8282\u70b9 ###\ndef search(num)\n  cur = @root\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while !cur.nil?\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    elsif cur.val > num\n      cur = cur.left\n    # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break\n    end\n  end\n\n  cur\nend\n
    binary_search_tree.zig
    // \u67e5\u627e\u8282\u70b9\nfn search(self: *Self, num: T) ?*inc.TreeNode(T) {\n    var cur = self.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else if (cur.?.val > num) {\n            cur = cur.?.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        } else {\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_search_tree/#2","title":"2. \u00a0 \u63d2\u5165\u8282\u70b9","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u5f85\u63d2\u5165\u5143\u7d20 num \uff0c\u4e3a\u4e86\u4fdd\u6301\u4e8c\u53c9\u641c\u7d22\u6811\u201c\u5de6\u5b50\u6811 < \u6839\u8282\u70b9 < \u53f3\u5b50\u6811\u201d\u7684\u6027\u8d28\uff0c\u63d2\u5165\u64cd\u4f5c\u6d41\u7a0b\u5982\u56fe 7-18 \u6240\u793a\u3002

    1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\uff1a\u4e0e\u67e5\u627e\u64cd\u4f5c\u76f8\u4f3c\uff0c\u4ece\u6839\u8282\u70b9\u51fa\u53d1\uff0c\u6839\u636e\u5f53\u524d\u8282\u70b9\u503c\u548c num \u7684\u5927\u5c0f\u5173\u7cfb\u5faa\u73af\u5411\u4e0b\u641c\u7d22\uff0c\u76f4\u5230\u8d8a\u8fc7\u53f6\u8282\u70b9\uff08\u904d\u5386\u81f3 None \uff09\u65f6\u8df3\u51fa\u5faa\u73af\u3002
    2. \u5728\u8be5\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9\uff1a\u521d\u59cb\u5316\u8282\u70b9 num \uff0c\u5c06\u8be5\u8282\u70b9\u7f6e\u4e8e None \u7684\u4f4d\u7f6e\u3002

    \u56fe 7-18 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u63d2\u5165\u8282\u70b9

    \u5728\u4ee3\u7801\u5b9e\u73b0\u4e2d\uff0c\u9700\u8981\u6ce8\u610f\u4ee5\u4e0b\u4e24\u70b9\u3002

    • \u4e8c\u53c9\u641c\u7d22\u6811\u4e0d\u5141\u8bb8\u5b58\u5728\u91cd\u590d\u8282\u70b9\uff0c\u5426\u5219\u5c06\u8fdd\u53cd\u5176\u5b9a\u4e49\u3002\u56e0\u6b64\uff0c\u82e5\u5f85\u63d2\u5165\u8282\u70b9\u5728\u6811\u4e2d\u5df2\u5b58\u5728\uff0c\u5219\u4e0d\u6267\u884c\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\u3002
    • \u4e3a\u4e86\u5b9e\u73b0\u63d2\u5165\u8282\u70b9\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u8282\u70b9 pre \u4fdd\u5b58\u4e0a\u4e00\u8f6e\u5faa\u73af\u7684\u8282\u70b9\u3002\u8fd9\u6837\u5728\u904d\u5386\u81f3 None \u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6\u5230\u5176\u7236\u8282\u70b9\uff0c\u4ece\u800c\u5b8c\u6210\u8282\u70b9\u63d2\u5165\u64cd\u4f5c\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def insert(self, num: int):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self._root is None:\n        self._root = TreeNode(num)\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur.val == num:\n            return\n        pre = cur\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u63d2\u5165\u8282\u70b9\n    node = TreeNode(num)\n    if pre.val < num:\n        pre.right = node\n    else:\n        pre.left = node\n
    binary_search_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == nullptr) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = new TreeNode(num);\n    if (pre->val < num)\n        pre->right = node;\n    else\n        pre->left = node;\n}\n
    binary_search_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new TreeNode(num);\n    if (pre.val < num)\n        pre.right = node;\n    else\n        pre.left = node;\n}\n
    binary_search_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new(num);\n    if (pre != null) {\n        if (pre.val < num)\n            pre.right = node;\n        else\n            pre.left = node;\n    }\n}\n
    binary_search_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (bst *binarySearchTree) insert(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if cur == nil {\n        bst.root = NewTreeNode(num)\n        return\n    }\n    // \u5f85\u63d2\u5165\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            return\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            cur = cur.Right\n        } else {\n            cur = cur.Left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    node := NewTreeNode(num)\n    if pre.Val.(int) < num {\n        pre.Right = node\n    } else {\n        pre.Left = node\n    }\n}\n
    binary_search_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if root == nil {\n        root = TreeNode(x: num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur!.val == num {\n            return\n        }\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let node = TreeNode(x: num)\n    if pre!.val < num {\n        pre?.right = node\n    } else {\n        pre?.left = node\n    }\n}\n
    binary_search_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre.val < num) pre.right = node;\n    else pre.left = node;\n}\n
    binary_search_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre!.val < num) pre!.right = node;\n    else pre!.left = node;\n}\n
    binary_search_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if (_root == null) {\n    _root = TreeNode(_num);\n    return;\n  }\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    if (cur.val == _num) return;\n    pre = cur;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u63d2\u5165\u8282\u70b9\n  TreeNode? node = TreeNode(_num);\n  if (pre!.val < _num)\n    pre.right = node;\n  else\n    pre.left = node;\n}\n
    binary_search_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\npub fn insert(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self.root.is_none() {\n        self.root = Some(TreeNode::new(num));\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n            Ordering::Equal => return,\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let pre = pre.unwrap();\n    let node = Some(TreeNode::new(num));\n    if num > pre.borrow().val {\n        pre.borrow_mut().right = node;\n    } else {\n        pre.borrow_mut().left = node;\n    }\n}\n
    binary_search_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (bst->root == NULL) {\n        bst->root = newTreeNode(num);\n        return;\n    }\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num) {\n            return;\n        }\n        pre = cur;\n        if (cur->val < num) {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = newTreeNode(num);\n    if (pre->val < num) {\n        pre->right = node;\n    } else {\n        pre->left = node;\n    }\n}\n
    binary_search_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = TreeNode(num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur._val == num)\n            return\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u63d2\u5165\u8282\u70b9\n    val node = TreeNode(num)\n    if (pre?._val!! < num)\n        pre.right = node\n    else\n        pre.left = node\n}\n
    binary_search_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if @root.nil?\n    @root = TreeNode.new(num)\n    return\n  end\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    return if cur.val == num\n\n    pre = cur\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n\n  # \u63d2\u5165\u8282\u70b9\n  node = TreeNode.new(num)\n  if pre.val < num\n    pre.right = node\n  else\n    pre.left = node\n  end\nend\n
    binary_search_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, num: T) !void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (self.root == null) {\n        self.root = try self.mem_allocator.create(inc.TreeNode(T));\n        return;\n    }\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.?.val == num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    var node = try self.mem_allocator.create(inc.TreeNode(T));\n    node.init(num);\n    if (pre.?.val < num) {\n        pre.?.right = node;\n    } else {\n        pre.?.left = node;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4e0e\u67e5\u627e\u8282\u70b9\u76f8\u540c\uff0c\u63d2\u5165\u8282\u70b9\u4f7f\u7528 \\(O(\\log n)\\) \u65f6\u95f4\u3002

    "},{"location":"chapter_tree/binary_search_tree/#3","title":"3. \u00a0 \u5220\u9664\u8282\u70b9","text":"

    \u5148\u5728\u4e8c\u53c9\u6811\u4e2d\u67e5\u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u518d\u5c06\u5176\u5220\u9664\u3002\u4e0e\u63d2\u5165\u8282\u70b9\u7c7b\u4f3c\uff0c\u6211\u4eec\u9700\u8981\u4fdd\u8bc1\u5728\u5220\u9664\u64cd\u4f5c\u5b8c\u6210\u540e\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u201c\u5de6\u5b50\u6811 < \u6839\u8282\u70b9 < \u53f3\u5b50\u6811\u201d\u7684\u6027\u8d28\u4ecd\u7136\u6ee1\u8db3\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u6839\u636e\u76ee\u6807\u8282\u70b9\u7684\u5b50\u8282\u70b9\u6570\u91cf\uff0c\u5206 0\u30011 \u548c 2 \u4e09\u79cd\u60c5\u51b5\uff0c\u6267\u884c\u5bf9\u5e94\u7684\u5220\u9664\u8282\u70b9\u64cd\u4f5c\u3002

    \u5982\u56fe 7-19 \u6240\u793a\uff0c\u5f53\u5f85\u5220\u9664\u8282\u70b9\u7684\u5ea6\u4e3a \\(0\\) \u65f6\uff0c\u8868\u793a\u8be5\u8282\u70b9\u662f\u53f6\u8282\u70b9\uff0c\u53ef\u4ee5\u76f4\u63a5\u5220\u9664\u3002

    \u56fe 7-19 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u5220\u9664\u8282\u70b9\uff08\u5ea6\u4e3a 0 \uff09

    \u5982\u56fe 7-20 \u6240\u793a\uff0c\u5f53\u5f85\u5220\u9664\u8282\u70b9\u7684\u5ea6\u4e3a \\(1\\) \u65f6\uff0c\u5c06\u5f85\u5220\u9664\u8282\u70b9\u66ff\u6362\u4e3a\u5176\u5b50\u8282\u70b9\u5373\u53ef\u3002

    \u56fe 7-20 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u5220\u9664\u8282\u70b9\uff08\u5ea6\u4e3a 1 \uff09

    \u5f53\u5f85\u5220\u9664\u8282\u70b9\u7684\u5ea6\u4e3a \\(2\\) \u65f6\uff0c\u6211\u4eec\u65e0\u6cd5\u76f4\u63a5\u5220\u9664\u5b83\uff0c\u800c\u9700\u8981\u4f7f\u7528\u4e00\u4e2a\u8282\u70b9\u66ff\u6362\u8be5\u8282\u70b9\u3002\u7531\u4e8e\u8981\u4fdd\u6301\u4e8c\u53c9\u641c\u7d22\u6811\u201c\u5de6\u5b50\u6811 \\(<\\) \u6839\u8282\u70b9 \\(<\\) \u53f3\u5b50\u6811\u201d\u7684\u6027\u8d28\uff0c\u56e0\u6b64\u8fd9\u4e2a\u8282\u70b9\u53ef\u4ee5\u662f\u53f3\u5b50\u6811\u7684\u6700\u5c0f\u8282\u70b9\u6216\u5de6\u5b50\u6811\u7684\u6700\u5927\u8282\u70b9\u3002

    \u5047\u8bbe\u6211\u4eec\u9009\u62e9\u53f3\u5b50\u6811\u7684\u6700\u5c0f\u8282\u70b9\uff08\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff09\uff0c\u5219\u5220\u9664\u64cd\u4f5c\u6d41\u7a0b\u5982\u56fe 7-21 \u6240\u793a\u3002

    1. \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\u5728\u201c\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217\u201d\u4e2d\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u8bb0\u4e3a tmp \u3002
    2. \u7528 tmp \u7684\u503c\u8986\u76d6\u5f85\u5220\u9664\u8282\u70b9\u7684\u503c\uff0c\u5e76\u5728\u6811\u4e2d\u9012\u5f52\u5220\u9664\u8282\u70b9 tmp \u3002
    <1><2><3><4>

    \u56fe 7-21 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u5220\u9664\u8282\u70b9\uff08\u5ea6\u4e3a 2 \uff09

    \u5220\u9664\u8282\u70b9\u64cd\u4f5c\u540c\u6837\u4f7f\u7528 \\(O(\\log n)\\) \u65f6\u95f4\uff0c\u5176\u4e2d\u67e5\u627e\u5f85\u5220\u9664\u8282\u70b9\u9700\u8981 \\(O(\\log n)\\) \u65f6\u95f4\uff0c\u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u540e\u7ee7\u8282\u70b9\u9700\u8981 \\(O(\\log n)\\) \u65f6\u95f4\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def remove(self, num: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self._root is None:\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur.val == num:\n            break\n        pre = cur\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur is None:\n        return\n\n    # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur.left is None or cur.right is None:\n        # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        child = cur.left or cur.right\n        # \u5220\u9664\u8282\u70b9 cur\n        if cur != self._root:\n            if pre.left == cur:\n                pre.left = child\n            else:\n                pre.right = child\n        else:\n            # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            self._root = child\n    # \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else:\n        # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp: TreeNode = cur.right\n        while tmp.left is not None:\n            tmp = tmp.left\n        # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.val)\n        # \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val\n
    binary_search_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == nullptr)\n        return;\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == nullptr)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur->left == nullptr || cur->right == nullptr) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != nullptr ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre->left == cur)\n                pre->left = child;\n            else\n                pre->right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete cur;\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != nullptr) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode child = cur.left != null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode? child = cur.left ?? cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode? tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        Remove(tmp.val!.Value);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (bst *binarySearchTree) remove(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5f85\u5220\u9664\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            break\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u53f3\u5b50\u6811\u4e2d\n            cur = cur.Right\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u5de6\u5b50\u6811\u4e2d\n            cur = cur.Left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u4e3a 0 \u6216 1\n    if cur.Left == nil || cur.Right == nil {\n        var child *TreeNode = nil\n        // \u53d6\u51fa\u5f85\u5220\u9664\u8282\u70b9\u7684\u5b50\u8282\u70b9\n        if cur.Left != nil {\n            child = cur.Left\n        } else {\n            child = cur.Right\n        }\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur != bst.root {\n            if pre.Left == cur {\n                pre.Left = child\n            } else {\n                pre.Right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            bst.root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u4e3a 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d\u5f85\u5220\u9664\u8282\u70b9 cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp := cur.Right\n        for tmp.Left != nil {\n            tmp = tmp.Left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        bst.remove(tmp.Val.(int))\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.Val = tmp.Val\n    }\n}\n
    binary_search_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if root == nil {\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur!.val == num {\n            break\n        }\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur?.left == nil || cur?.right == nil {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        let child = cur?.left ?? cur?.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur !== root {\n            if pre?.left === cur {\n                pre?.left = child\n            } else {\n                pre?.right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur?.right\n        while tmp?.left != nil {\n            tmp = tmp?.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(num: tmp!.val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur?.val = tmp!.val\n    }\n}\n
    binary_search_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child = cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre.left === cur) pre.left = child;\n            else pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp = cur.right;\n        while (tmp.left !== null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child: TreeNode | null =\n            cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre!.left === cur) pre!.left = child;\n            else pre!.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp: TreeNode | null = cur.right;\n        while (tmp!.left !== null) {\n            tmp = tmp!.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp!.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp!.val;\n    }\n}\n
    binary_search_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  if (_root == null) return;\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    if (cur.val == _num) break;\n    pre = cur;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n  if (cur == null) return;\n  // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if (cur.left == null || cur.right == null) {\n    // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    TreeNode? child = cur.left ?? cur.right;\n    // \u5220\u9664\u8282\u70b9 cur\n    if (cur != _root) {\n      if (pre!.left == cur)\n        pre.left = child;\n      else\n        pre.right = child;\n    } else {\n      // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      _root = child;\n    }\n  } else {\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    TreeNode? tmp = cur.right;\n    while (tmp!.left != null) {\n      tmp = tmp.left;\n    }\n    // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val);\n    // \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val;\n  }\n}\n
    binary_search_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\npub fn remove(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self.root.is_none() {\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur.is_none() {\n        return;\n    }\n    let cur = cur.unwrap();\n    let (left_child, right_child) = (cur.borrow().left.clone(), cur.borrow().right.clone());\n    match (left_child.clone(), right_child.clone()) {\n        // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n        (None, None) | (Some(_), None) | (None, Some(_)) => {\n            // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n            let child = left_child.or(right_child);\n            let pre = pre.unwrap();\n            // \u5220\u9664\u8282\u70b9 cur\n            if !Rc::ptr_eq(&cur, self.root.as_ref().unwrap()) {\n                let left = pre.borrow().left.clone();\n                if left.is_some() && Rc::ptr_eq(&left.as_ref().unwrap(), &cur) {\n                    pre.borrow_mut().left = child;\n                } else {\n                    pre.borrow_mut().right = child;\n                }\n            } else {\n                // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n                self.root = child;\n            }\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n        (Some(_), Some(_)) => {\n            // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n            let mut tmp = cur.borrow().right.clone();\n            while let Some(node) = tmp.clone() {\n                if node.borrow().left.is_some() {\n                    tmp = node.borrow().left.clone();\n                } else {\n                    break;\n                }\n            }\n            let tmpval = tmp.unwrap().borrow().val;\n            // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n            self.remove(tmpval);\n            // \u7528 tmp \u8986\u76d6 cur\n            cur.borrow_mut().val = tmpval;\n        }\n    }\n}\n
    binary_search_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (bst->root == NULL)\n        return;\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        if (cur->val < num) {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == NULL)\n        return;\n    // \u5224\u65ad\u5f85\u5220\u9664\u8282\u70b9\u662f\u5426\u5b58\u5728\u5b50\u8282\u70b9\n    if (cur->left == NULL || cur->right == NULL) {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1 */\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != NULL ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre->left == cur) {\n            pre->left = child;\n        } else {\n            pre->right = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(cur);\n    } else {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 2 */\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != NULL) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        removeItem(bst, tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur._val == num)\n            break\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        val child = if (cur.left != null)\n            cur.left\n        else\n            cur.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!!.left == cur)\n                pre.left = child\n            else\n                pre.right = child\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.right\n        while (tmp!!.left != null) {\n            tmp = tmp.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp._val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur._val = tmp._val\n    }\n}\n
    binary_search_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  return if @root.nil?\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    break if cur.val == num\n\n    pre = cur\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n  # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  return if cur.nil?\n\n  # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if cur.left.nil? || cur.right.nil?\n    # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    child = cur.left || cur.right\n    # \u5220\u9664\u8282\u70b9 cur\n    if cur != @root\n      if pre.left == cur\n        pre.left = child\n      else\n        pre.right = child\n      end\n    else\n      # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      @root = child\n    end\n  # \u5b50\u8282\u70b9\u6570\u91cf = 2\n  else\n    # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    tmp = cur.right\n    while !tmp.left.nil?\n      tmp = tmp.left\n    end\n    # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val)\n    # \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val\n  end\nend\n
    binary_search_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, num: T) void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (self.root == null) return;\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.?.val == num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.?.left == null or cur.?.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        var child = if (cur.?.left != null) cur.?.left else cur.?.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre.?.left == cur) {\n            pre.?.left = child;\n        } else {\n            pre.?.right = child;\n        }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.?.right;\n        while (tmp.?.left != null) {\n            tmp = tmp.?.left;\n        }\n        var tmp_val = tmp.?.val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.?.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.?.val = tmp_val;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_search_tree/#4","title":"4. \u00a0 \u4e2d\u5e8f\u904d\u5386\u6709\u5e8f","text":"

    \u5982\u56fe 7-22 \u6240\u793a\uff0c\u4e8c\u53c9\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u9075\u5faa\u201c\u5de6 \\(\\rightarrow\\) \u6839 \\(\\rightarrow\\) \u53f3\u201d\u7684\u904d\u5386\u987a\u5e8f\uff0c\u800c\u4e8c\u53c9\u641c\u7d22\u6811\u6ee1\u8db3\u201c\u5de6\u5b50\u8282\u70b9 \\(<\\) \u6839\u8282\u70b9 \\(<\\) \u53f3\u5b50\u8282\u70b9\u201d\u7684\u5927\u5c0f\u5173\u7cfb\u3002

    \u8fd9\u610f\u5473\u7740\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u8fdb\u884c\u4e2d\u5e8f\u904d\u5386\u65f6\uff0c\u603b\u662f\u4f1a\u4f18\u5148\u904d\u5386\u4e0b\u4e00\u4e2a\u6700\u5c0f\u8282\u70b9\uff0c\u4ece\u800c\u5f97\u51fa\u4e00\u4e2a\u91cd\u8981\u6027\u8d28\uff1a\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217\u662f\u5347\u5e8f\u7684\u3002

    \u5229\u7528\u4e2d\u5e8f\u904d\u5386\u5347\u5e8f\u7684\u6027\u8d28\uff0c\u6211\u4eec\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u83b7\u53d6\u6709\u5e8f\u6570\u636e\u4ec5\u9700 \\(O(n)\\) \u65f6\u95f4\uff0c\u65e0\u987b\u8fdb\u884c\u989d\u5916\u7684\u6392\u5e8f\u64cd\u4f5c\uff0c\u975e\u5e38\u9ad8\u6548\u3002

    \u56fe 7-22 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217

    "},{"location":"chapter_tree/binary_search_tree/#742","title":"7.4.2 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6548\u7387","text":"

    \u7ed9\u5b9a\u4e00\u7ec4\u6570\u636e\uff0c\u6211\u4eec\u8003\u8651\u4f7f\u7528\u6570\u7ec4\u6216\u4e8c\u53c9\u641c\u7d22\u6811\u5b58\u50a8\u3002\u89c2\u5bdf\u8868 7-2 \uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u5404\u9879\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f\u5bf9\u6570\u9636\uff0c\u5177\u6709\u7a33\u5b9a\u4e14\u9ad8\u6548\u7684\u6027\u80fd\u3002\u53ea\u6709\u5728\u9ad8\u9891\u6dfb\u52a0\u3001\u4f4e\u9891\u67e5\u627e\u5220\u9664\u6570\u636e\u7684\u573a\u666f\u4e0b\uff0c\u6570\u7ec4\u6bd4\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6548\u7387\u66f4\u9ad8\u3002

    \u8868 7-2 \u00a0 \u6570\u7ec4\u4e0e\u641c\u7d22\u6811\u7684\u6548\u7387\u5bf9\u6bd4

    \u65e0\u5e8f\u6570\u7ec4 \u4e8c\u53c9\u641c\u7d22\u6811 \u67e5\u627e\u5143\u7d20 \\(O(n)\\) \\(O(\\log n)\\) \u63d2\u5165\u5143\u7d20 \\(O(1)\\) \\(O(\\log n)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(\\log n)\\)

    \u5728\u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u662f\u201c\u5e73\u8861\u201d\u7684\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728 \\(\\log n\\) \u8f6e\u5faa\u73af\u5185\u67e5\u627e\u4efb\u610f\u8282\u70b9\u3002

    \u7136\u800c\uff0c\u5982\u679c\u6211\u4eec\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u4e0d\u65ad\u5730\u63d2\u5165\u548c\u5220\u9664\u8282\u70b9\uff0c\u53ef\u80fd\u5bfc\u81f4\u4e8c\u53c9\u6811\u9000\u5316\u4e3a\u56fe 7-23 \u6240\u793a\u7684\u94fe\u8868\uff0c\u8fd9\u65f6\u5404\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u4f1a\u9000\u5316\u4e3a \\(O(n)\\) \u3002

    \u56fe 7-23 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u9000\u5316

    "},{"location":"chapter_tree/binary_search_tree/#743","title":"7.4.3 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u5e38\u89c1\u5e94\u7528","text":"
    • \u7528\u4f5c\u7cfb\u7edf\u4e2d\u7684\u591a\u7ea7\u7d22\u5f15\uff0c\u5b9e\u73b0\u9ad8\u6548\u7684\u67e5\u627e\u3001\u63d2\u5165\u3001\u5220\u9664\u64cd\u4f5c\u3002
    • \u4f5c\u4e3a\u67d0\u4e9b\u641c\u7d22\u7b97\u6cd5\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u3002
    • \u7528\u4e8e\u5b58\u50a8\u6570\u636e\u6d41\uff0c\u4ee5\u4fdd\u6301\u5176\u6709\u5e8f\u72b6\u6001\u3002
    "},{"location":"chapter_tree/binary_tree/","title":"7.1 \u00a0 \u4e8c\u53c9\u6811","text":"

    \u4e8c\u53c9\u6811\uff08binary tree\uff09\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u4ee3\u8868\u201c\u7956\u5148\u201d\u4e0e\u201c\u540e\u4ee3\u201d\u4e4b\u95f4\u7684\u6d3e\u751f\u5173\u7cfb\uff0c\u4f53\u73b0\u4e86\u201c\u4e00\u5206\u4e3a\u4e8c\u201d\u7684\u5206\u6cbb\u903b\u8f91\u3002\u4e0e\u94fe\u8868\u7c7b\u4f3c\uff0c\u4e8c\u53c9\u6811\u7684\u57fa\u672c\u5355\u5143\u662f\u8282\u70b9\uff0c\u6bcf\u4e2a\u8282\u70b9\u5305\u542b\u503c\u3001\u5de6\u5b50\u8282\u70b9\u5f15\u7528\u548c\u53f3\u5b50\u8282\u70b9\u5f15\u7528\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"\u4e8c\u53c9\u6811\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # \u8282\u70b9\u503c\n        self.left: TreeNode | None = None  # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n        self.right: TreeNode | None = None # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct TreeNode {\n    int val;          // \u8282\u70b9\u503c\n    TreeNode *left;   // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    TreeNode *right;  // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n};\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    int val;         // \u8282\u70b9\u503c\n    TreeNode left;   // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    TreeNode right;  // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n    TreeNode(int x) { val = x; }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode(int? x) {\n    public int? val = x;    // \u8282\u70b9\u503c\n    public TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    public TreeNode? right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype TreeNode struct {\n    Val   int\n    Left  *TreeNode\n    Right *TreeNode\n}\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc NewTreeNode(v int) *TreeNode {\n    return &TreeNode{\n        Left:  nil, // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n        Right: nil, // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n        Val:   v,   // \u8282\u70b9\u503c\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    var val: Int // \u8282\u70b9\u503c\n    var left: TreeNode? // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    var right: TreeNode? // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n\n    init(x: Int) {\n        val = x\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val; // \u8282\u70b9\u503c\n    left; // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    right; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    constructor(val, left, right) {\n        this.val = val === undefined ? 0 : val;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val: number;\n    left: TreeNode | null;\n    right: TreeNode | null;\n\n    constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val; // \u8282\u70b9\u503c\n        this.left = left === undefined ? null : left; // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n        this.right = right === undefined ? null : right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n  int val;         // \u8282\u70b9\u503c\n  TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n  TreeNode? right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n  TreeNode(this.val, [this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct TreeNode {\n    val: i32,                               // \u8282\u70b9\u503c\n    left: Option<Rc<RefCell<TreeNode>>>,    // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    right: Option<Rc<RefCell<TreeNode>>>,   // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n\nimpl TreeNode {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct TreeNode {\n    int val;                // \u8282\u70b9\u503c\n    int height;             // \u8282\u70b9\u9ad8\u5ea6\n    struct TreeNode *left;  // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    struct TreeNode *right; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n} TreeNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode(val _val: Int) {  // \u8282\u70b9\u503c\n    val left: TreeNode? = null   // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    val right: TreeNode? = null  // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    ### \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b ###\nclass TreeNode\n  attr_accessor :val    # \u8282\u70b9\u503c\n  attr_accessor :left   # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n  attr_accessor :right  # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n\n  def initialize(val)\n    @val = val\n  end\nend\n
    \n

    \u6bcf\u4e2a\u8282\u70b9\u90fd\u6709\u4e24\u4e2a\u5f15\u7528\uff08\u6307\u9488\uff09\uff0c\u5206\u522b\u6307\u5411\u5de6\u5b50\u8282\u70b9\uff08left-child node\uff09\u548c\u53f3\u5b50\u8282\u70b9\uff08right-child node\uff09\uff0c\u8be5\u8282\u70b9\u88ab\u79f0\u4e3a\u8fd9\u4e24\u4e2a\u5b50\u8282\u70b9\u7684\u7236\u8282\u70b9\uff08parent node\uff09\u3002\u5f53\u7ed9\u5b9a\u4e00\u4e2a\u4e8c\u53c9\u6811\u7684\u8282\u70b9\u65f6\uff0c\u6211\u4eec\u5c06\u8be5\u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u53ca\u5176\u4ee5\u4e0b\u8282\u70b9\u5f62\u6210\u7684\u6811\u79f0\u4e3a\u8be5\u8282\u70b9\u7684\u5de6\u5b50\u6811\uff08left subtree\uff09\uff0c\u540c\u7406\u53ef\u5f97\u53f3\u5b50\u6811\uff08right subtree\uff09\u3002

    \u5728\u4e8c\u53c9\u6811\u4e2d\uff0c\u9664\u53f6\u8282\u70b9\u5916\uff0c\u5176\u4ed6\u6240\u6709\u8282\u70b9\u90fd\u5305\u542b\u5b50\u8282\u70b9\u548c\u975e\u7a7a\u5b50\u6811\u3002\u5982\u56fe 7-1 \u6240\u793a\uff0c\u5982\u679c\u5c06\u201c\u8282\u70b9 2\u201d\u89c6\u4e3a\u7236\u8282\u70b9\uff0c\u5219\u5176\u5de6\u5b50\u8282\u70b9\u548c\u53f3\u5b50\u8282\u70b9\u5206\u522b\u662f\u201c\u8282\u70b9 4\u201d\u548c\u201c\u8282\u70b9 5\u201d\uff0c\u5de6\u5b50\u6811\u662f\u201c\u8282\u70b9 4 \u53ca\u5176\u4ee5\u4e0b\u8282\u70b9\u5f62\u6210\u7684\u6811\u201d\uff0c\u53f3\u5b50\u6811\u662f\u201c\u8282\u70b9 5 \u53ca\u5176\u4ee5\u4e0b\u8282\u70b9\u5f62\u6210\u7684\u6811\u201d\u3002

    \u56fe 7-1 \u00a0 \u7236\u8282\u70b9\u3001\u5b50\u8282\u70b9\u3001\u5b50\u6811

    "},{"location":"chapter_tree/binary_tree/#711","title":"7.1.1 \u00a0 \u4e8c\u53c9\u6811\u5e38\u89c1\u672f\u8bed","text":"

    \u4e8c\u53c9\u6811\u7684\u5e38\u7528\u672f\u8bed\u5982\u56fe 7-2 \u6240\u793a\u3002

    • \u6839\u8282\u70b9\uff08root node\uff09\uff1a\u4f4d\u4e8e\u4e8c\u53c9\u6811\u9876\u5c42\u7684\u8282\u70b9\uff0c\u6ca1\u6709\u7236\u8282\u70b9\u3002
    • \u53f6\u8282\u70b9\uff08leaf node\uff09\uff1a\u6ca1\u6709\u5b50\u8282\u70b9\u7684\u8282\u70b9\uff0c\u5176\u4e24\u4e2a\u6307\u9488\u5747\u6307\u5411 None \u3002
    • \u8fb9\uff08edge\uff09\uff1a\u8fde\u63a5\u4e24\u4e2a\u8282\u70b9\u7684\u7ebf\u6bb5\uff0c\u5373\u8282\u70b9\u5f15\u7528\uff08\u6307\u9488\uff09\u3002
    • \u8282\u70b9\u6240\u5728\u7684\u5c42\uff08level\uff09\uff1a\u4ece\u9876\u81f3\u5e95\u9012\u589e\uff0c\u6839\u8282\u70b9\u6240\u5728\u5c42\u4e3a 1 \u3002
    • \u8282\u70b9\u7684\u5ea6\uff08degree\uff09\uff1a\u8282\u70b9\u7684\u5b50\u8282\u70b9\u7684\u6570\u91cf\u3002\u5728\u4e8c\u53c9\u6811\u4e2d\uff0c\u5ea6\u7684\u53d6\u503c\u8303\u56f4\u662f 0\u30011\u30012 \u3002
    • \u4e8c\u53c9\u6811\u7684\u9ad8\u5ea6\uff08height\uff09\uff1a\u4ece\u6839\u8282\u70b9\u5230\u6700\u8fdc\u53f6\u8282\u70b9\u6240\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u3002
    • \u8282\u70b9\u7684\u6df1\u5ea6\uff08depth\uff09\uff1a\u4ece\u6839\u8282\u70b9\u5230\u8be5\u8282\u70b9\u6240\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u3002
    • \u8282\u70b9\u7684\u9ad8\u5ea6\uff08height\uff09\uff1a\u4ece\u8ddd\u79bb\u8be5\u8282\u70b9\u6700\u8fdc\u7684\u53f6\u8282\u70b9\u5230\u8be5\u8282\u70b9\u6240\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u3002

    \u56fe 7-2 \u00a0 \u4e8c\u53c9\u6811\u7684\u5e38\u7528\u672f\u8bed

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u6211\u4eec\u901a\u5e38\u5c06\u201c\u9ad8\u5ea6\u201d\u548c\u201c\u6df1\u5ea6\u201d\u5b9a\u4e49\u4e3a\u201c\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u201d\uff0c\u4f46\u6709\u4e9b\u9898\u76ee\u6216\u6559\u6750\u53ef\u80fd\u4f1a\u5c06\u5176\u5b9a\u4e49\u4e3a\u201c\u7ecf\u8fc7\u7684\u8282\u70b9\u7684\u6570\u91cf\u201d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u9ad8\u5ea6\u548c\u6df1\u5ea6\u90fd\u9700\u8981\u52a0 1 \u3002

    "},{"location":"chapter_tree/binary_tree/#712","title":"7.1.2 \u00a0 \u4e8c\u53c9\u6811\u57fa\u672c\u64cd\u4f5c","text":""},{"location":"chapter_tree/binary_tree/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u4e8c\u53c9\u6811","text":"

    \u4e0e\u94fe\u8868\u7c7b\u4f3c\uff0c\u9996\u5148\u521d\u59cb\u5316\u8282\u70b9\uff0c\u7136\u540e\u6784\u5efa\u5f15\u7528\uff08\u6307\u9488\uff09\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # \u521d\u59cb\u5316\u4e8c\u53c9\u6811\n# \u521d\u59cb\u5316\u8282\u70b9\nn1 = TreeNode(val=1)\nn2 = TreeNode(val=2)\nn3 = TreeNode(val=3)\nn4 = TreeNode(val=4)\nn5 = TreeNode(val=5)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.cpp
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode* n1 = new TreeNode(1);\nTreeNode* n2 = new TreeNode(2);\nTreeNode* n3 = new TreeNode(3);\nTreeNode* n4 = new TreeNode(4);\nTreeNode* n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.java
    // \u521d\u59cb\u5316\u8282\u70b9\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.cs
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode n1 = new(1);\nTreeNode n2 = new(2);\nTreeNode n3 = new(3);\nTreeNode n4 = new(4);\nTreeNode n5 = new(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.go
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nn1 := NewTreeNode(1)\nn2 := NewTreeNode(2)\nn3 := NewTreeNode(3)\nn4 := NewTreeNode(4)\nn5 := NewTreeNode(5)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.Left = n2\nn1.Right = n3\nn2.Left = n4\nn2.Right = n5\n
    binary_tree.swift
    // \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = TreeNode(x: 1)\nlet n2 = TreeNode(x: 2)\nlet n3 = TreeNode(x: 3)\nlet n4 = TreeNode(x: 4)\nlet n5 = TreeNode(x: 5)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.js
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.ts
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.dart
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.rs
    // \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = TreeNode::new(1);\nlet n2 = TreeNode::new(2);\nlet n3 = TreeNode::new(3);\nlet n4 = TreeNode::new(4);\nlet n5 = TreeNode::new(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.borrow_mut().left = Some(n2.clone());\nn1.borrow_mut().right = Some(n3);\nn2.borrow_mut().left = Some(n4);\nn2.borrow_mut().right = Some(n5);\n
    binary_tree.c
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode *n1 = newTreeNode(1);\nTreeNode *n2 = newTreeNode(2);\nTreeNode *n3 = newTreeNode(3);\nTreeNode *n4 = newTreeNode(4);\nTreeNode *n5 = newTreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.kt
    // \u521d\u59cb\u5316\u8282\u70b9\nval n1 = TreeNode(1)\nval n2 = TreeNode(2)\nval n3 = TreeNode(3)\nval n4 = TreeNode(4)\nval n5 = TreeNode(5)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.rb
    # \u521d\u59cb\u5316\u4e8c\u53c9\u6811\n# \u521d\u59cb\u5316\u8282\u70b9\nn1 = TreeNode.new(1)\nn2 = TreeNode.new(2)\nn3 = TreeNode.new(3)\nn4 = TreeNode.new(4)\nn5 = TreeNode.new(5)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_tree/#2","title":"2. \u00a0 \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9","text":"

    \u4e0e\u94fe\u8868\u7c7b\u4f3c\uff0c\u5728\u4e8c\u53c9\u6811\u4e2d\u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\u53ef\u4ee5\u901a\u8fc7\u4fee\u6539\u6307\u9488\u6765\u5b9e\u73b0\u3002\u56fe 7-3 \u7ed9\u51fa\u4e86\u4e00\u4e2a\u793a\u4f8b\u3002

    \u56fe 7-3 \u00a0 \u5728\u4e8c\u53c9\u6811\u4e2d\u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\np = TreeNode(0)\n# \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = p\np.left = n2\n# \u5220\u9664\u8282\u70b9 P\nn1.left = n2\n
    binary_tree.cpp
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode* P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1->left = P;\nP->left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1->left = n2;\n
    binary_tree.java
    TreeNode P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.cs
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode P = new(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.go
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\np := NewTreeNode(0)\nn1.Left = p\np.Left = n2\n// \u5220\u9664\u8282\u70b9 P\nn1.Left = n2\n
    binary_tree.swift
    let P = TreeNode(x: 0)\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P\nP.left = n2\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2\n
    binary_tree.js
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nlet P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.ts
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nconst P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.dart
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.rs
    let p = TreeNode::new(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.borrow_mut().left = Some(p.clone());\np.borrow_mut().left = Some(n2.clone());\n// \u5220\u9664\u8282\u70b9 p\nn1.borrow_mut().left = Some(n2);\n
    binary_tree.c
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode *P = newTreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1->left = P;\nP->left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1->left = n2;\n
    binary_tree.kt
    val P = TreeNode(0)\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P\nP.left = n2\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2\n
    binary_tree.rb
    # \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\n_p = TreeNode.new(0)\n# \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 _p\nn1.left = _p\n_p.left = n2\n# \u5220\u9664\u8282\u70b9\nn1.left = n2\n
    binary_tree.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    Tip

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u63d2\u5165\u8282\u70b9\u53ef\u80fd\u4f1a\u6539\u53d8\u4e8c\u53c9\u6811\u7684\u539f\u6709\u903b\u8f91\u7ed3\u6784\uff0c\u800c\u5220\u9664\u8282\u70b9\u901a\u5e38\u610f\u5473\u7740\u5220\u9664\u8be5\u8282\u70b9\u53ca\u5176\u6240\u6709\u5b50\u6811\u3002\u56e0\u6b64\uff0c\u5728\u4e8c\u53c9\u6811\u4e2d\uff0c\u63d2\u5165\u4e0e\u5220\u9664\u901a\u5e38\u662f\u7531\u4e00\u5957\u64cd\u4f5c\u914d\u5408\u5b8c\u6210\u7684\uff0c\u4ee5\u5b9e\u73b0\u6709\u5b9e\u9645\u610f\u4e49\u7684\u64cd\u4f5c\u3002

    "},{"location":"chapter_tree/binary_tree/#713","title":"7.1.3 \u00a0 \u5e38\u89c1\u4e8c\u53c9\u6811\u7c7b\u578b","text":""},{"location":"chapter_tree/binary_tree/#1_1","title":"1. \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-4 \u6240\u793a\uff0c\u5b8c\u7f8e\u4e8c\u53c9\u6811\uff08perfect binary tree\uff09\u6240\u6709\u5c42\u7684\u8282\u70b9\u90fd\u88ab\u5b8c\u5168\u586b\u6ee1\u3002\u5728\u5b8c\u7f8e\u4e8c\u53c9\u6811\u4e2d\uff0c\u53f6\u8282\u70b9\u7684\u5ea6\u4e3a \\(0\\) \uff0c\u5176\u4f59\u6240\u6709\u8282\u70b9\u7684\u5ea6\u90fd\u4e3a \\(2\\) \uff1b\u82e5\u6811\u7684\u9ad8\u5ea6\u4e3a \\(h\\) \uff0c\u5219\u8282\u70b9\u603b\u6570\u4e3a \\(2^{h+1} - 1\\) \uff0c\u5448\u73b0\u6807\u51c6\u7684\u6307\u6570\u7ea7\u5173\u7cfb\uff0c\u53cd\u6620\u4e86\u81ea\u7136\u754c\u4e2d\u5e38\u89c1\u7684\u7ec6\u80de\u5206\u88c2\u73b0\u8c61\u3002

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u5728\u4e2d\u6587\u793e\u533a\u4e2d\uff0c\u5b8c\u7f8e\u4e8c\u53c9\u6811\u5e38\u88ab\u79f0\u4e3a\u6ee1\u4e8c\u53c9\u6811\u3002

    \u56fe 7-4 \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#2_1","title":"2. \u00a0 \u5b8c\u5168\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-5 \u6240\u793a\uff0c\u5b8c\u5168\u4e8c\u53c9\u6811\uff08complete binary tree\uff09\u53ea\u6709\u6700\u5e95\u5c42\u7684\u8282\u70b9\u672a\u88ab\u586b\u6ee1\uff0c\u4e14\u6700\u5e95\u5c42\u8282\u70b9\u5c3d\u91cf\u9760\u5de6\u586b\u5145\u3002

    \u56fe 7-5 \u00a0 \u5b8c\u5168\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#3","title":"3. \u00a0 \u5b8c\u6ee1\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-6 \u6240\u793a\uff0c\u5b8c\u6ee1\u4e8c\u53c9\u6811\uff08full binary tree\uff09\u9664\u4e86\u53f6\u8282\u70b9\u4e4b\u5916\uff0c\u5176\u4f59\u6240\u6709\u8282\u70b9\u90fd\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\u3002

    \u56fe 7-6 \u00a0 \u5b8c\u6ee1\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#4","title":"4. \u00a0 \u5e73\u8861\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-7 \u6240\u793a\uff0c\u5e73\u8861\u4e8c\u53c9\u6811\uff08balanced binary tree\uff09\u4e2d\u4efb\u610f\u8282\u70b9\u7684\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u7684\u9ad8\u5ea6\u4e4b\u5dee\u7684\u7edd\u5bf9\u503c\u4e0d\u8d85\u8fc7 1 \u3002

    \u56fe 7-7 \u00a0 \u5e73\u8861\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#714","title":"7.1.4 \u00a0 \u4e8c\u53c9\u6811\u7684\u9000\u5316","text":"

    \u56fe 7-8 \u5c55\u793a\u4e86\u4e8c\u53c9\u6811\u7684\u7406\u60f3\u7ed3\u6784\u4e0e\u9000\u5316\u7ed3\u6784\u3002\u5f53\u4e8c\u53c9\u6811\u7684\u6bcf\u5c42\u8282\u70b9\u90fd\u88ab\u586b\u6ee1\u65f6\uff0c\u8fbe\u5230\u201c\u5b8c\u7f8e\u4e8c\u53c9\u6811\u201d\uff1b\u800c\u5f53\u6240\u6709\u8282\u70b9\u90fd\u504f\u5411\u4e00\u4fa7\u65f6\uff0c\u4e8c\u53c9\u6811\u9000\u5316\u4e3a\u201c\u94fe\u8868\u201d\u3002

    • \u5b8c\u7f8e\u4e8c\u53c9\u6811\u662f\u7406\u60f3\u60c5\u51b5\uff0c\u53ef\u4ee5\u5145\u5206\u53d1\u6325\u4e8c\u53c9\u6811\u201c\u5206\u6cbb\u201d\u7684\u4f18\u52bf\u3002
    • \u94fe\u8868\u5219\u662f\u53e6\u4e00\u4e2a\u6781\u7aef\uff0c\u5404\u9879\u64cd\u4f5c\u90fd\u53d8\u4e3a\u7ebf\u6027\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u9000\u5316\u81f3 \\(O(n)\\) \u3002

    \u56fe 7-8 \u00a0 \u4e8c\u53c9\u6811\u7684\u6700\u4f73\u7ed3\u6784\u4e0e\u6700\u5dee\u7ed3\u6784

    \u5982\u8868 7-1 \u6240\u793a\uff0c\u5728\u6700\u4f73\u7ed3\u6784\u548c\u6700\u5dee\u7ed3\u6784\u4e0b\uff0c\u4e8c\u53c9\u6811\u7684\u53f6\u8282\u70b9\u6570\u91cf\u3001\u8282\u70b9\u603b\u6570\u3001\u9ad8\u5ea6\u7b49\u8fbe\u5230\u6781\u5927\u503c\u6216\u6781\u5c0f\u503c\u3002

    \u8868 7-1 \u00a0 \u4e8c\u53c9\u6811\u7684\u6700\u4f73\u7ed3\u6784\u4e0e\u6700\u5dee\u7ed3\u6784

    \u5b8c\u7f8e\u4e8c\u53c9\u6811 \u94fe\u8868 \u7b2c \\(i\\) \u5c42\u7684\u8282\u70b9\u6570\u91cf \\(2^{i-1}\\) \\(1\\) \u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u6811\u7684\u53f6\u8282\u70b9\u6570\u91cf \\(2^h\\) \\(1\\) \u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u6811\u7684\u8282\u70b9\u603b\u6570 \\(2^{h+1} - 1\\) \\(h + 1\\) \u8282\u70b9\u603b\u6570\u4e3a \\(n\\) \u7684\u6811\u7684\u9ad8\u5ea6 \\(\\log_2 (n+1) - 1\\) \\(n - 1\\)"},{"location":"chapter_tree/binary_tree_traversal/","title":"7.2 \u00a0 \u4e8c\u53c9\u6811\u904d\u5386","text":"

    \u4ece\u7269\u7406\u7ed3\u6784\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u6811\u662f\u4e00\u79cd\u57fa\u4e8e\u94fe\u8868\u7684\u6570\u636e\u7ed3\u6784\uff0c\u56e0\u6b64\u5176\u904d\u5386\u65b9\u5f0f\u662f\u901a\u8fc7\u6307\u9488\u9010\u4e2a\u8bbf\u95ee\u8282\u70b9\u3002\u7136\u800c\uff0c\u6811\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u8fd9\u4f7f\u5f97\u904d\u5386\u6811\u6bd4\u904d\u5386\u94fe\u8868\u66f4\u52a0\u590d\u6742\uff0c\u9700\u8981\u501f\u52a9\u641c\u7d22\u7b97\u6cd5\u6765\u5b9e\u73b0\u3002

    \u4e8c\u53c9\u6811\u5e38\u89c1\u7684\u904d\u5386\u65b9\u5f0f\u5305\u62ec\u5c42\u5e8f\u904d\u5386\u3001\u524d\u5e8f\u904d\u5386\u3001\u4e2d\u5e8f\u904d\u5386\u548c\u540e\u5e8f\u904d\u5386\u7b49\u3002

    "},{"location":"chapter_tree/binary_tree_traversal/#721","title":"7.2.1 \u00a0 \u5c42\u5e8f\u904d\u5386","text":"

    \u5982\u56fe 7-9 \u6240\u793a\uff0c\u5c42\u5e8f\u904d\u5386\uff08level-order traversal\uff09\u4ece\u9876\u90e8\u5230\u5e95\u90e8\u9010\u5c42\u904d\u5386\u4e8c\u53c9\u6811\uff0c\u5e76\u5728\u6bcf\u4e00\u5c42\u6309\u7167\u4ece\u5de6\u5230\u53f3\u7684\u987a\u5e8f\u8bbf\u95ee\u8282\u70b9\u3002

    \u5c42\u5e8f\u904d\u5386\u672c\u8d28\u4e0a\u5c5e\u4e8e\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\uff08breadth-first traversal\uff09\uff0c\u4e5f\u79f0\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\uff08breadth-first search, BFS\uff09\uff0c\u5b83\u4f53\u73b0\u4e86\u4e00\u79cd\u201c\u4e00\u5708\u4e00\u5708\u5411\u5916\u6269\u5c55\u201d\u7684\u9010\u5c42\u904d\u5386\u65b9\u5f0f\u3002

    \u56fe 7-9 \u00a0 \u4e8c\u53c9\u6811\u7684\u5c42\u5e8f\u904d\u5386

    "},{"location":"chapter_tree/binary_tree_traversal/#1","title":"1. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u901a\u5e38\u501f\u52a9\u201c\u961f\u5217\u201d\u6765\u5b9e\u73b0\u3002\u961f\u5217\u9075\u5faa\u201c\u5148\u8fdb\u5148\u51fa\u201d\u7684\u89c4\u5219\uff0c\u800c\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u5219\u9075\u5faa\u201c\u9010\u5c42\u63a8\u8fdb\u201d\u7684\u89c4\u5219\uff0c\u4e24\u8005\u80cc\u540e\u7684\u601d\u60f3\u662f\u4e00\u81f4\u7684\u3002\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_bfs.py
    def level_order(root: TreeNode | None) -> list[int]:\n    \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n    # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue: deque[TreeNode] = deque()\n    queue.append(root)\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    res = []\n    while queue:\n        node: TreeNode = queue.popleft()  # \u961f\u5217\u51fa\u961f\n        res.append(node.val)  # \u4fdd\u5b58\u8282\u70b9\u503c\n        if node.left is not None:\n            queue.append(node.left)  # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if node.right is not None:\n            queue.append(node.right)  # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    return res\n
    binary_tree_bfs.cpp
    /* \u5c42\u5e8f\u904d\u5386 */\nvector<int> levelOrder(TreeNode *root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue<TreeNode *> queue;\n    queue.push(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    vector<int> vec;\n    while (!queue.empty()) {\n        TreeNode *node = queue.front();\n        queue.pop();              // \u961f\u5217\u51fa\u961f\n        vec.push_back(node->val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node->left != nullptr)\n            queue.push(node->left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node->right != nullptr)\n            queue.push(node->right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return vec;\n}\n
    binary_tree_bfs.java
    /* \u5c42\u5e8f\u904d\u5386 */\nList<Integer> levelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new LinkedList<>();\n    queue.add(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<Integer> list = new ArrayList<>();\n    while (!queue.isEmpty()) {\n        TreeNode node = queue.poll(); // \u961f\u5217\u51fa\u961f\n        list.add(node.val);           // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left);   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right);  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.cs
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> LevelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new();\n    queue.Enqueue(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<int> list = [];\n    while (queue.Count != 0) {\n        TreeNode node = queue.Dequeue(); // \u961f\u5217\u51fa\u961f\n        list.Add(node.val!.Value);       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.Enqueue(node.left);    // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.Enqueue(node.right);   // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.go
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root *TreeNode) []any {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue := list.New()\n    queue.PushBack(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5207\u7247\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    nums := make([]any, 0)\n    for queue.Len() > 0 {\n        // \u961f\u5217\u51fa\u961f\n        node := queue.Remove(queue.Front()).(*TreeNode)\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        nums = append(nums, node.Val)\n        if node.Left != nil {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Left)\n        }\n        if node.Right != nil {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Right)\n        }\n    }\n    return nums\n}\n
    binary_tree_bfs.swift
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root: TreeNode) -> [Int] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    var queue: [TreeNode] = [root]\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list: [Int] = []\n    while !queue.isEmpty {\n        let node = queue.removeFirst() // \u961f\u5217\u51fa\u961f\n        list.append(node.val) // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let left = node.left {\n            queue.append(left) // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let right = node.right {\n            queue.append(right) // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list\n}\n
    binary_tree_bfs.js
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list = [];\n    while (queue.length) {\n        let node = queue.shift(); // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right) queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.ts
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root: TreeNode | null): number[] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list: number[] = [];\n    while (queue.length) {\n        let node = queue.shift() as TreeNode; // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) {\n            queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right) {\n            queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list;\n}\n
    binary_tree_bfs.dart
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> levelOrder(TreeNode? root) {\n  // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  Queue<TreeNode?> queue = Queue();\n  queue.add(root);\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  List<int> res = [];\n  while (queue.isNotEmpty) {\n    TreeNode? node = queue.removeFirst(); // \u961f\u5217\u51fa\u961f\n    res.add(node!.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n    if (node.left != null) queue.add(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    if (node.right != null) queue.add(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  }\n  return res;\n}\n
    binary_tree_bfs.rs
    /* \u5c42\u5e8f\u904d\u5386 */\nfn level_order(root: &Rc<RefCell<TreeNode>>) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    let mut que = VecDeque::new();\n    que.push_back(root.clone());\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    let mut vec = Vec::new();\n\n    while let Some(node) = que.pop_front() {\n        // \u961f\u5217\u51fa\u961f\n        vec.push(node.borrow().val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let Some(left) = node.borrow().left.as_ref() {\n            que.push_back(left.clone()); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let Some(right) = node.borrow().right.as_ref() {\n            que.push_back(right.clone()); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        };\n    }\n    vec\n}\n
    binary_tree_bfs.c
    /* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(TreeNode *root, int *size) {\n    /* \u8f85\u52a9\u961f\u5217 */\n    int front, rear;\n    int index, *arr;\n    TreeNode *node;\n    TreeNode **queue;\n\n    /* \u8f85\u52a9\u961f\u5217 */\n    queue = (TreeNode **)malloc(sizeof(TreeNode *) * MAX_SIZE);\n    // \u961f\u5217\u6307\u9488\n    front = 0, rear = 0;\n    // \u52a0\u5165\u6839\u8282\u70b9\n    queue[rear++] = root;\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    /* \u8f85\u52a9\u6570\u7ec4 */\n    arr = (int *)malloc(sizeof(int) * MAX_SIZE);\n    // \u6570\u7ec4\u6307\u9488\n    index = 0;\n    while (front < rear) {\n        // \u961f\u5217\u51fa\u961f\n        node = queue[front++];\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        arr[index++] = node->val;\n        if (node->left != NULL) {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->left;\n        }\n        if (node->right != NULL) {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->right;\n        }\n    }\n    // \u66f4\u65b0\u6570\u7ec4\u957f\u5ea6\u7684\u503c\n    *size = index;\n    arr = realloc(arr, sizeof(int) * (*size));\n\n    // \u91ca\u653e\u8f85\u52a9\u6570\u7ec4\u7a7a\u95f4\n    free(queue);\n    return arr;\n}\n
    binary_tree_bfs.kt
    /* \u5c42\u5e8f\u904d\u5386 */\nfun levelOrder(root: TreeNode?): MutableList<Int> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    val queue = LinkedList<TreeNode?>()\n    queue.add(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    val list = mutableListOf<Int>()\n    while (queue.isNotEmpty()) {\n        val node = queue.poll()      // \u961f\u5217\u51fa\u961f\n        list.add(node?._val!!)       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left)   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right)  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list\n}\n
    binary_tree_bfs.rb
    ### \u5c42\u5e8f\u904d\u5386 ###\ndef level_order(root)\n  # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  queue = [root]\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  res = []\n  while !queue.empty?\n    node = queue.shift # \u961f\u5217\u51fa\u961f\n    res << node.val # \u4fdd\u5b58\u8282\u70b9\u503c\n    queue << node.left unless node.left.nil? # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    queue << node.right unless node.right.nil? # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  end\n  res\nend\n
    binary_tree_bfs.zig
    // \u5c42\u5e8f\u904d\u5386\nfn levelOrder(comptime T: type, mem_allocator: std.mem.Allocator, root: *inc.TreeNode(T)) !std.ArrayList(T) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const L = std.TailQueue(*inc.TreeNode(T));\n    var queue = L{};\n    var root_node = try mem_allocator.create(L.Node);\n    root_node.data = root;\n    queue.append(root_node); \n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list = std.ArrayList(T).init(std.heap.page_allocator);\n    while (queue.len > 0) {\n        var queue_node = queue.popFirst().?;    // \u961f\u5217\u51fa\u961f\n        var node = queue_node.data;\n        try list.append(node.val);              // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.left.?;\n            queue.append(tmp_node);             // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.right.?;\n            queue.append(tmp_node);             // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }        \n    }\n    return list;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_tree_traversal/#2","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u6240\u6709\u8282\u70b9\u88ab\u8bbf\u95ee\u4e00\u6b21\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\uff0c\u5176\u4e2d \\(n\\) \u4e3a\u8282\u70b9\u6570\u91cf\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u5373\u6ee1\u4e8c\u53c9\u6811\u65f6\uff0c\u904d\u5386\u5230\u6700\u5e95\u5c42\u4e4b\u524d\uff0c\u961f\u5217\u4e2d\u6700\u591a\u540c\u65f6\u5b58\u5728 \\((n + 1) / 2\\) \u4e2a\u8282\u70b9\uff0c\u5360\u7528 \\(O(n)\\) \u7a7a\u95f4\u3002
    "},{"location":"chapter_tree/binary_tree_traversal/#722","title":"7.2.2 \u00a0 \u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386","text":"

    \u76f8\u5e94\u5730\uff0c\u524d\u5e8f\u3001\u4e2d\u5e8f\u548c\u540e\u5e8f\u904d\u5386\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u904d\u5386\uff08depth-first traversal\uff09\uff0c\u4e5f\u79f0\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\uff08depth-first search, DFS\uff09\uff0c\u5b83\u4f53\u73b0\u4e86\u4e00\u79cd\u201c\u5148\u8d70\u5230\u5c3d\u5934\uff0c\u518d\u56de\u6eaf\u7ee7\u7eed\u201d\u7684\u904d\u5386\u65b9\u5f0f\u3002

    \u56fe 7-10 \u5c55\u793a\u4e86\u5bf9\u4e8c\u53c9\u6811\u8fdb\u884c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u7684\u5de5\u4f5c\u539f\u7406\u3002\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u5c31\u50cf\u662f\u7ed5\u7740\u6574\u68f5\u4e8c\u53c9\u6811\u7684\u5916\u56f4\u201c\u8d70\u201d\u4e00\u5708\uff0c\u5728\u6bcf\u4e2a\u8282\u70b9\u90fd\u4f1a\u9047\u5230\u4e09\u4e2a\u4f4d\u7f6e\uff0c\u5206\u522b\u5bf9\u5e94\u524d\u5e8f\u904d\u5386\u3001\u4e2d\u5e8f\u904d\u5386\u548c\u540e\u5e8f\u904d\u5386\u3002

    \u56fe 7-10 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386

    "},{"location":"chapter_tree/binary_tree_traversal/#1_1","title":"1. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_dfs.py
    def pre_order(root: TreeNode | None):\n    \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    res.append(root.val)\n    pre_order(root=root.left)\n    pre_order(root=root.right)\n\ndef in_order(root: TreeNode | None):\n    \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    in_order(root=root.left)\n    res.append(root.val)\n    in_order(root=root.right)\n\ndef post_order(root: TreeNode | None):\n    \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    post_order(root=root.left)\n    post_order(root=root.right)\n    res.append(root.val)\n
    binary_tree_dfs.cpp
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    vec.push_back(root->val);\n    preOrder(root->left);\n    preOrder(root->right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left);\n    vec.push_back(root->val);\n    inOrder(root->right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left);\n    postOrder(root->right);\n    vec.push_back(root->val);\n}\n
    binary_tree_dfs.java
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.add(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.add(root.val);\n}\n
    binary_tree_dfs.cs
    /* \u524d\u5e8f\u904d\u5386 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.Add(root.val!.Value);\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid InOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    InOrder(root.left);\n    list.Add(root.val!.Value);\n    InOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid PostOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    PostOrder(root.left);\n    PostOrder(root.right);\n    list.Add(root.val!.Value);\n}\n
    binary_tree_dfs.go
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    nums = append(nums, node.Val)\n    preOrder(node.Left)\n    preOrder(node.Right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(node.Left)\n    nums = append(nums, node.Val)\n    inOrder(node.Right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(node.Left)\n    postOrder(node.Right)\n    nums = append(nums, node.Val)\n}\n
    binary_tree_dfs.swift
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.append(root.val)\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root: root.left)\n    list.append(root.val)\n    inOrder(root: root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root: root.left)\n    postOrder(root: root.right)\n    list.append(root.val)\n}\n
    binary_tree_dfs.js
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.ts
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.dart
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  list.add(node.val);\n  preOrder(node.left);\n  preOrder(node.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  inOrder(node.left);\n  list.add(node.val);\n  inOrder(node.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  postOrder(node.left);\n  postOrder(node.right);\n  list.add(node.val);\n}\n
    binary_tree_dfs.rs
    /* \u524d\u5e8f\u904d\u5386 */\nfn pre_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n        result.push(node.borrow().val);\n        result.extend(pre_order(node.borrow().left.as_ref()));\n        result.extend(pre_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfn in_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n        result.extend(in_order(node.borrow().left.as_ref()));\n        result.push(node.borrow().val);\n        result.extend(in_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfn post_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n        result.extend(post_order(node.borrow().left.as_ref()));\n        result.extend(post_order(node.borrow().right.as_ref()));\n        result.push(node.borrow().val);\n    }\n    result\n}\n
    binary_tree_dfs.c
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    arr[(*size)++] = root->val;\n    preOrder(root->left, size);\n    preOrder(root->right, size);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left, size);\n    arr[(*size)++] = root->val;\n    inOrder(root->right, size);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left, size);\n    postOrder(root->right, size);\n    arr[(*size)++] = root->val;\n}\n
    binary_tree_dfs.kt
    /* \u524d\u5e8f\u904d\u5386 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root._val)\n    preOrder(root.left)\n    preOrder(root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfun inOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left)\n    list.add(root._val)\n    inOrder(root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfun postOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left)\n    postOrder(root.right)\n    list.add(root._val)\n}\n
    binary_tree_dfs.rb
    ### \u524d\u5e8f\u904d\u5386 ###\ndef pre_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  $res << root.val\n  pre_order(root.left)\n  pre_order(root.right)\nend\n\n### \u4e2d\u5e8f\u904d\u5386 ###\ndef in_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  in_order(root.left)\n  $res << root.val\n  in_order(root.right)\nend\n\n### \u540e\u5e8f\u904d\u5386 ###\ndef post_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  post_order(root.left)\n  post_order(root.right)\n  $res << root.val\nend\n
    binary_tree_dfs.zig
    // \u524d\u5e8f\u904d\u5386\nfn preOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    try list.append(root.?.val);\n    try preOrder(T, root.?.left);\n    try preOrder(T, root.?.right);\n}\n\n// \u4e2d\u5e8f\u904d\u5386\nfn inOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    try inOrder(T, root.?.left);\n    try list.append(root.?.val);\n    try inOrder(T, root.?.right);\n}\n\n// \u540e\u5e8f\u904d\u5386\nfn postOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    try postOrder(T, root.?.left);\n    try postOrder(T, root.?.right);\n    try list.append(root.?.val);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    Tip

    \u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u4e5f\u53ef\u4ee5\u57fa\u4e8e\u8fed\u4ee3\u5b9e\u73b0\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u7814\u7a76\u3002

    \u56fe 7-11 \u5c55\u793a\u4e86\u524d\u5e8f\u904d\u5386\u4e8c\u53c9\u6811\u7684\u9012\u5f52\u8fc7\u7a0b\uff0c\u5176\u53ef\u5206\u4e3a\u201c\u9012\u201d\u548c\u201c\u5f52\u201d\u4e24\u4e2a\u9006\u5411\u7684\u90e8\u5206\u3002

    1. \u201c\u9012\u201d\u8868\u793a\u5f00\u542f\u65b0\u65b9\u6cd5\uff0c\u7a0b\u5e8f\u5728\u6b64\u8fc7\u7a0b\u4e2d\u8bbf\u95ee\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002
    2. \u201c\u5f52\u201d\u8868\u793a\u51fd\u6570\u8fd4\u56de\uff0c\u4ee3\u8868\u5f53\u524d\u8282\u70b9\u5df2\u7ecf\u8bbf\u95ee\u5b8c\u6bd5\u3002
    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 7-11 \u00a0 \u524d\u5e8f\u904d\u5386\u7684\u9012\u5f52\u8fc7\u7a0b

    "},{"location":"chapter_tree/binary_tree_traversal/#2_1","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u6240\u6709\u8282\u70b9\u88ab\u8bbf\u95ee\u4e00\u6b21\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u5373\u6811\u9000\u5316\u4e3a\u94fe\u8868\u65f6\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230 \\(n\\) \uff0c\u7cfb\u7edf\u5360\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002
    "},{"location":"chapter_tree/summary/","title":"7.6 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_tree/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u4e8c\u53c9\u6811\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u4f53\u73b0\u201c\u4e00\u5206\u4e3a\u4e8c\u201d\u7684\u5206\u6cbb\u903b\u8f91\u3002\u6bcf\u4e2a\u4e8c\u53c9\u6811\u8282\u70b9\u5305\u542b\u4e00\u4e2a\u503c\u4ee5\u53ca\u4e24\u4e2a\u6307\u9488\uff0c\u5206\u522b\u6307\u5411\u5176\u5de6\u5b50\u8282\u70b9\u548c\u53f3\u5b50\u8282\u70b9\u3002
    • \u5bf9\u4e8e\u4e8c\u53c9\u6811\u4e2d\u7684\u67d0\u4e2a\u8282\u70b9\uff0c\u5176\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\u53ca\u5176\u4ee5\u4e0b\u5f62\u6210\u7684\u6811\u88ab\u79f0\u4e3a\u8be5\u8282\u70b9\u7684\u5de6\uff08\u53f3\uff09\u5b50\u6811\u3002
    • \u4e8c\u53c9\u6811\u7684\u76f8\u5173\u672f\u8bed\u5305\u62ec\u6839\u8282\u70b9\u3001\u53f6\u8282\u70b9\u3001\u5c42\u3001\u5ea6\u3001\u8fb9\u3001\u9ad8\u5ea6\u548c\u6df1\u5ea6\u7b49\u3002
    • \u4e8c\u53c9\u6811\u7684\u521d\u59cb\u5316\u3001\u8282\u70b9\u63d2\u5165\u548c\u8282\u70b9\u5220\u9664\u64cd\u4f5c\u4e0e\u94fe\u8868\u64cd\u4f5c\u65b9\u6cd5\u7c7b\u4f3c\u3002
    • \u5e38\u89c1\u7684\u4e8c\u53c9\u6811\u7c7b\u578b\u6709\u5b8c\u7f8e\u4e8c\u53c9\u6811\u3001\u5b8c\u5168\u4e8c\u53c9\u6811\u3001\u5b8c\u6ee1\u4e8c\u53c9\u6811\u548c\u5e73\u8861\u4e8c\u53c9\u6811\u3002\u5b8c\u7f8e\u4e8c\u53c9\u6811\u662f\u6700\u7406\u60f3\u7684\u72b6\u6001\uff0c\u800c\u94fe\u8868\u662f\u9000\u5316\u540e\u7684\u6700\u5dee\u72b6\u6001\u3002
    • \u4e8c\u53c9\u6811\u53ef\u4ee5\u7528\u6570\u7ec4\u8868\u793a\uff0c\u65b9\u6cd5\u662f\u5c06\u8282\u70b9\u503c\u548c\u7a7a\u4f4d\u6309\u5c42\u5e8f\u904d\u5386\u987a\u5e8f\u6392\u5217\uff0c\u5e76\u6839\u636e\u7236\u8282\u70b9\u4e0e\u5b50\u8282\u70b9\u4e4b\u95f4\u7684\u7d22\u5f15\u6620\u5c04\u5173\u7cfb\u6765\u5b9e\u73b0\u6307\u9488\u3002
    • \u4e8c\u53c9\u6811\u7684\u5c42\u5e8f\u904d\u5386\u662f\u4e00\u79cd\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u65b9\u6cd5\uff0c\u5b83\u4f53\u73b0\u4e86\u201c\u4e00\u5708\u4e00\u5708\u5411\u5916\u6269\u5c55\u201d\u7684\u9010\u5c42\u904d\u5386\u65b9\u5f0f\uff0c\u901a\u5e38\u901a\u8fc7\u961f\u5217\u6765\u5b9e\u73b0\u3002
    • \u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386\u7686\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\uff0c\u5b83\u4eec\u4f53\u73b0\u4e86\u201c\u5148\u8d70\u5230\u5c3d\u5934\uff0c\u518d\u56de\u6eaf\u7ee7\u7eed\u201d\u7684\u904d\u5386\u65b9\u5f0f\uff0c\u901a\u5e38\u4f7f\u7528\u9012\u5f52\u6765\u5b9e\u73b0\u3002
    • \u4e8c\u53c9\u641c\u7d22\u6811\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u5143\u7d20\u67e5\u627e\u6570\u636e\u7ed3\u6784\uff0c\u5176\u67e5\u627e\u3001\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(\\log n)\\) \u3002\u5f53\u4e8c\u53c9\u641c\u7d22\u6811\u9000\u5316\u4e3a\u94fe\u8868\u65f6\uff0c\u5404\u9879\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u52a3\u5316\u81f3 \\(O(n)\\) \u3002
    • AVL \u6811\uff0c\u4e5f\u79f0\u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811\uff0c\u5b83\u901a\u8fc7\u65cb\u8f6c\u64cd\u4f5c\u786e\u4fdd\u5728\u4e0d\u65ad\u63d2\u5165\u548c\u5220\u9664\u8282\u70b9\u540e\u6811\u4ecd\u7136\u4fdd\u6301\u5e73\u8861\u3002
    • AVL \u6811\u7684\u65cb\u8f6c\u64cd\u4f5c\u5305\u62ec\u53f3\u65cb\u3001\u5de6\u65cb\u3001\u5148\u53f3\u65cb\u518d\u5de6\u65cb\u3001\u5148\u5de6\u65cb\u518d\u53f3\u65cb\u3002\u5728\u63d2\u5165\u6216\u5220\u9664\u8282\u70b9\u540e\uff0cAVL \u6811\u4f1a\u4ece\u5e95\u5411\u9876\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\u3002
    "},{"location":"chapter_tree/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u5bf9\u4e8e\u53ea\u6709\u4e00\u4e2a\u8282\u70b9\u7684\u4e8c\u53c9\u6811\uff0c\u6811\u7684\u9ad8\u5ea6\u548c\u6839\u8282\u70b9\u7684\u6df1\u5ea6\u90fd\u662f \\(0\\) \u5417\uff1f

    \u662f\u7684\uff0c\u56e0\u4e3a\u9ad8\u5ea6\u548c\u6df1\u5ea6\u901a\u5e38\u5b9a\u4e49\u4e3a\u201c\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u201d\u3002

    Q\uff1a\u4e8c\u53c9\u6811\u4e2d\u7684\u63d2\u5165\u4e0e\u5220\u9664\u4e00\u822c\u7531\u4e00\u5957\u64cd\u4f5c\u914d\u5408\u5b8c\u6210\uff0c\u8fd9\u91cc\u7684\u201c\u4e00\u5957\u64cd\u4f5c\u201d\u6307\u4ec0\u4e48\u5462\uff1f\u53ef\u4ee5\u7406\u89e3\u4e3a\u8d44\u6e90\u7684\u5b50\u8282\u70b9\u7684\u8d44\u6e90\u91ca\u653e\u5417\uff1f

    \u62ff\u4e8c\u53c9\u641c\u7d22\u6811\u6765\u4e3e\u4f8b\uff0c\u5220\u9664\u8282\u70b9\u64cd\u4f5c\u8981\u5206\u4e09\u79cd\u60c5\u51b5\u5904\u7406\uff0c\u5176\u4e2d\u6bcf\u79cd\u60c5\u51b5\u90fd\u9700\u8981\u8fdb\u884c\u591a\u4e2a\u6b65\u9aa4\u7684\u8282\u70b9\u64cd\u4f5c\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48 DFS \u904d\u5386\u4e8c\u53c9\u6811\u6709\u524d\u3001\u4e2d\u3001\u540e\u4e09\u79cd\u987a\u5e8f\uff0c\u5206\u522b\u6709\u4ec0\u4e48\u7528\u5462\uff1f

    \u4e0e\u987a\u5e8f\u548c\u9006\u5e8f\u904d\u5386\u6570\u7ec4\u7c7b\u4f3c\uff0c\u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386\u662f\u4e09\u79cd\u4e8c\u53c9\u6811\u904d\u5386\u65b9\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5b83\u4eec\u5f97\u5230\u4e00\u4e2a\u7279\u5b9a\u987a\u5e8f\u7684\u904d\u5386\u7ed3\u679c\u3002\u4f8b\u5982\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\uff0c\u7531\u4e8e\u8282\u70b9\u5927\u5c0f\u6ee1\u8db3 \u5de6\u5b50\u8282\u70b9\u503c < \u6839\u8282\u70b9\u503c < \u53f3\u5b50\u8282\u70b9\u503c \uff0c\u56e0\u6b64\u6211\u4eec\u53ea\u8981\u6309\u7167\u201c\u5de6 \\(\\rightarrow\\) \u6839 \\(\\rightarrow\\) \u53f3\u201d\u7684\u4f18\u5148\u7ea7\u904d\u5386\u6811\uff0c\u5c31\u53ef\u4ee5\u83b7\u5f97\u6709\u5e8f\u7684\u8282\u70b9\u5e8f\u5217\u3002

    Q\uff1a\u53f3\u65cb\u64cd\u4f5c\u662f\u5904\u7406\u5931\u8861\u8282\u70b9 node\u3001child\u3001grand_child \u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u90a3 node \u7684\u7236\u8282\u70b9\u548c node \u539f\u6765\u7684\u8fde\u63a5\u4e0d\u9700\u8981\u7ef4\u62a4\u5417\uff1f\u53f3\u65cb\u64cd\u4f5c\u540e\u5c82\u4e0d\u662f\u65ad\u6389\u4e86\uff1f

    \u6211\u4eec\u9700\u8981\u4ece\u9012\u5f52\u7684\u89c6\u89d2\u6765\u770b\u8fd9\u4e2a\u95ee\u9898\u3002\u53f3\u65cb\u64cd\u4f5c right_rotate(root) \u4f20\u5165\u7684\u662f\u5b50\u6811\u7684\u6839\u8282\u70b9\uff0c\u6700\u7ec8 return child \u8fd4\u56de\u65cb\u8f6c\u4e4b\u540e\u7684\u5b50\u6811\u7684\u6839\u8282\u70b9\u3002\u5b50\u6811\u7684\u6839\u8282\u70b9\u548c\u5176\u7236\u8282\u70b9\u7684\u8fde\u63a5\u662f\u5728\u8be5\u51fd\u6570\u8fd4\u56de\u540e\u5b8c\u6210\u7684\uff0c\u4e0d\u5c5e\u4e8e\u53f3\u65cb\u64cd\u4f5c\u7684\u7ef4\u62a4\u8303\u56f4\u3002

    Q\uff1a\u5728 C++ \u4e2d\uff0c\u51fd\u6570\u88ab\u5212\u5206\u5230 private \u548c public \u4e2d\uff0c\u8fd9\u65b9\u9762\u6709\u4ec0\u4e48\u8003\u91cf\u5417\uff1f\u4e3a\u4ec0\u4e48\u8981\u5c06 height() \u51fd\u6570\u548c updateHeight() \u51fd\u6570\u5206\u522b\u653e\u5728 public \u548c private \u4e2d\u5462\uff1f

    \u4e3b\u8981\u770b\u65b9\u6cd5\u7684\u4f7f\u7528\u8303\u56f4\uff0c\u5982\u679c\u65b9\u6cd5\u53ea\u5728\u7c7b\u5185\u90e8\u4f7f\u7528\uff0c\u90a3\u4e48\u5c31\u8bbe\u8ba1\u4e3a private \u3002\u4f8b\u5982\uff0c\u7528\u6237\u5355\u72ec\u8c03\u7528 updateHeight() \u662f\u6ca1\u6709\u610f\u4e49\u7684\uff0c\u5b83\u53ea\u662f\u63d2\u5165\u3001\u5220\u9664\u64cd\u4f5c\u4e2d\u7684\u4e00\u6b65\u3002\u800c height() \u662f\u8bbf\u95ee\u8282\u70b9\u9ad8\u5ea6\uff0c\u7c7b\u4f3c\u4e8e vector.size() \uff0c\u56e0\u6b64\u8bbe\u7f6e\u6210 public \u4ee5\u4fbf\u4f7f\u7528\u3002

    Q\uff1a\u5982\u4f55\u4ece\u4e00\u7ec4\u8f93\u5165\u6570\u636e\u6784\u5efa\u4e00\u68f5\u4e8c\u53c9\u641c\u7d22\u6811\uff1f\u6839\u8282\u70b9\u7684\u9009\u62e9\u662f\u4e0d\u662f\u5f88\u91cd\u8981\uff1f

    \u662f\u7684\uff0c\u6784\u5efa\u6811\u7684\u65b9\u6cd5\u5df2\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4ee3\u7801\u4e2d\u7684 build_tree() \u65b9\u6cd5\u4e2d\u7ed9\u51fa\u3002\u81f3\u4e8e\u6839\u8282\u70b9\u7684\u9009\u62e9\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5c06\u8f93\u5165\u6570\u636e\u6392\u5e8f\uff0c\u7136\u540e\u5c06\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u6839\u8282\u70b9\uff0c\u518d\u9012\u5f52\u5730\u6784\u5efa\u5de6\u53f3\u5b50\u6811\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u6700\u5927\u7a0b\u5ea6\u4fdd\u8bc1\u6811\u7684\u5e73\u8861\u6027\u3002

    Q\uff1a\u5728 Java \u4e2d\uff0c\u5b57\u7b26\u4e32\u5bf9\u6bd4\u662f\u5426\u4e00\u5b9a\u8981\u7528 equals() \u65b9\u6cd5\uff1f

    \u5728 Java \u4e2d\uff0c\u5bf9\u4e8e\u57fa\u672c\u6570\u636e\u7c7b\u578b\uff0c== \u7528\u4e8e\u5bf9\u6bd4\u4e24\u4e2a\u53d8\u91cf\u7684\u503c\u662f\u5426\u76f8\u7b49\u3002\u5bf9\u4e8e\u5f15\u7528\u7c7b\u578b\uff0c\u4e24\u79cd\u7b26\u53f7\u7684\u5de5\u4f5c\u539f\u7406\u662f\u4e0d\u540c\u7684\u3002

    • == \uff1a\u7528\u6765\u6bd4\u8f83\u4e24\u4e2a\u53d8\u91cf\u662f\u5426\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5373\u5b83\u4eec\u5728\u5185\u5b58\u4e2d\u7684\u4f4d\u7f6e\u662f\u5426\u76f8\u540c\u3002
    • equals()\uff1a\u7528\u6765\u5bf9\u6bd4\u4e24\u4e2a\u5bf9\u8c61\u7684\u503c\u662f\u5426\u76f8\u7b49\u3002

    \u56e0\u6b64\uff0c\u5982\u679c\u8981\u5bf9\u6bd4\u503c\uff0c\u6211\u4eec\u5e94\u8be5\u4f7f\u7528 equals() \u3002\u7136\u800c\uff0c\u901a\u8fc7 String a = \"hi\"; String b = \"hi\"; \u521d\u59cb\u5316\u7684\u5b57\u7b26\u4e32\u90fd\u5b58\u50a8\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u6c60\u4e2d\uff0c\u5b83\u4eec\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u7528 a == b \u6765\u6bd4\u8f83\u4e24\u4e2a\u5b57\u7b26\u4e32\u7684\u5185\u5bb9\u3002

    Q\uff1a\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u5230\u6700\u5e95\u5c42\u4e4b\u524d\uff0c\u961f\u5217\u4e2d\u7684\u8282\u70b9\u6570\u91cf\u662f \\(2^h\\) \u5417\uff1f

    \u662f\u7684\uff0c\u4f8b\u5982\u9ad8\u5ea6 \\(h = 2\\) \u7684\u6ee1\u4e8c\u53c9\u6811\uff0c\u5176\u8282\u70b9\u603b\u6570 \\(n = 7\\) \uff0c\u5219\u5e95\u5c42\u8282\u70b9\u6570\u91cf \\(4 = 2^h = (n + 1) / 2\\) \u3002

    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\u200b\\u3000\\-\u3001\u3002\uff0c\uff0e\uff1f\uff01\uff1b]+","pipeline":["stemmer"]},"docs":[{"location":"chapter_appendix/","title":"\u7b2c 16 \u7ae0 \u00a0 \u9644\u5f55","text":""},{"location":"chapter_appendix/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 16.1 \u00a0 \u7f16\u7a0b\u73af\u5883\u5b89\u88c5
    • 16.2 \u00a0 \u4e00\u8d77\u53c2\u4e0e\u521b\u4f5c
    • 16.3 \u00a0 \u672f\u8bed\u8868
    "},{"location":"chapter_appendix/contribution/","title":"16.2 \u00a0 \u4e00\u8d77\u53c2\u4e0e\u521b\u4f5c","text":"

    \u7531\u4e8e\u7b14\u8005\u80fd\u529b\u6709\u9650\uff0c\u4e66\u4e2d\u96be\u514d\u5b58\u5728\u4e00\u4e9b\u9057\u6f0f\u548c\u9519\u8bef\uff0c\u8bf7\u60a8\u8c05\u89e3\u3002\u5982\u679c\u60a8\u53d1\u73b0\u4e86\u7b14\u8bef\u3001\u94fe\u63a5\u5931\u6548\u3001\u5185\u5bb9\u7f3a\u5931\u3001\u6587\u5b57\u6b67\u4e49\u3001\u89e3\u91ca\u4e0d\u6e05\u6670\u6216\u884c\u6587\u7ed3\u6784\u4e0d\u5408\u7406\u7b49\u95ee\u9898\uff0c\u8bf7\u534f\u52a9\u6211\u4eec\u8fdb\u884c\u4fee\u6b63\uff0c\u4ee5\u7ed9\u8bfb\u8005\u63d0\u4f9b\u66f4\u4f18\u8d28\u7684\u5b66\u4e60\u8d44\u6e90\u3002

    \u6240\u6709\u64b0\u7a3f\u4eba\u7684 GitHub ID \u5c06\u5728\u672c\u4e66\u4ed3\u5e93\u3001\u7f51\u9875\u7248\u548c PDF \u7248\u7684\u4e3b\u9875\u4e0a\u8fdb\u884c\u5c55\u793a\uff0c\u4ee5\u611f\u8c22\u4ed6\u4eec\u5bf9\u5f00\u6e90\u793e\u533a\u7684\u65e0\u79c1\u5949\u732e\u3002

    \u5f00\u6e90\u7684\u9b45\u529b

    \u7eb8\u8d28\u56fe\u4e66\u7684\u4e24\u6b21\u5370\u5237\u7684\u95f4\u9694\u65f6\u95f4\u5f80\u5f80\u8f83\u4e45\uff0c\u5185\u5bb9\u66f4\u65b0\u975e\u5e38\u4e0d\u65b9\u4fbf\u3002

    \u800c\u5728\u672c\u5f00\u6e90\u4e66\u4e2d\uff0c\u5185\u5bb9\u66f4\u8fed\u7684\u65f6\u95f4\u88ab\u7f29\u77ed\u81f3\u6570\u65e5\u751a\u81f3\u51e0\u4e2a\u5c0f\u65f6\u3002

    "},{"location":"chapter_appendix/contribution/#1","title":"1. \u00a0 \u5185\u5bb9\u5fae\u8c03","text":"

    \u5982\u56fe 16-3 \u6240\u793a\uff0c\u6bcf\u4e2a\u9875\u9762\u7684\u53f3\u4e0a\u89d2\u90fd\u6709\u201c\u7f16\u8f91\u56fe\u6807\u201d\u3002\u60a8\u53ef\u4ee5\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u4fee\u6539\u6587\u672c\u6216\u4ee3\u7801\u3002

    1. \u70b9\u51fb\u201c\u7f16\u8f91\u56fe\u6807\u201d\uff0c\u5982\u679c\u9047\u5230\u201c\u9700\u8981 Fork \u6b64\u4ed3\u5e93\u201d\u7684\u63d0\u793a\uff0c\u8bf7\u540c\u610f\u8be5\u64cd\u4f5c\u3002
    2. \u4fee\u6539 Markdown \u6e90\u6587\u4ef6\u5185\u5bb9\uff0c\u68c0\u67e5\u5185\u5bb9\u7684\u6b63\u786e\u6027\uff0c\u5e76\u5c3d\u91cf\u4fdd\u6301\u6392\u7248\u683c\u5f0f\u7684\u7edf\u4e00\u3002
    3. \u5728\u9875\u9762\u5e95\u90e8\u586b\u5199\u4fee\u6539\u8bf4\u660e\uff0c\u7136\u540e\u70b9\u51fb\u201cPropose file change\u201d\u6309\u94ae\u3002\u9875\u9762\u8df3\u8f6c\u540e\uff0c\u70b9\u51fb\u201cCreate pull request\u201d\u6309\u94ae\u5373\u53ef\u53d1\u8d77\u62c9\u53d6\u8bf7\u6c42\u3002

    \u56fe 16-3 \u00a0 \u9875\u9762\u7f16\u8f91\u6309\u952e

    \u56fe\u7247\u65e0\u6cd5\u76f4\u63a5\u4fee\u6539\uff0c\u9700\u8981\u901a\u8fc7\u65b0\u5efa Issue \u6216\u8bc4\u8bba\u7559\u8a00\u6765\u63cf\u8ff0\u95ee\u9898\uff0c\u6211\u4eec\u4f1a\u5c3d\u5feb\u91cd\u65b0\u7ed8\u5236\u5e76\u66ff\u6362\u56fe\u7247\u3002

    "},{"location":"chapter_appendix/contribution/#2","title":"2. \u00a0 \u5185\u5bb9\u521b\u4f5c","text":"

    \u5982\u679c\u60a8\u6709\u5174\u8da3\u53c2\u4e0e\u6b64\u5f00\u6e90\u9879\u76ee\uff0c\u5305\u62ec\u5c06\u4ee3\u7801\u7ffb\u8bd1\u6210\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u3001\u6269\u5c55\u6587\u7ae0\u5185\u5bb9\u7b49\uff0c\u90a3\u4e48\u9700\u8981\u5b9e\u65bd\u4ee5\u4e0b Pull Request \u5de5\u4f5c\u6d41\u7a0b\u3002

    1. \u767b\u5f55 GitHub \uff0c\u5c06\u672c\u4e66\u7684\u4ee3\u7801\u4ed3\u5e93 Fork \u5230\u4e2a\u4eba\u8d26\u53f7\u4e0b\u3002
    2. \u8fdb\u5165\u60a8\u7684 Fork \u4ed3\u5e93\u7f51\u9875\uff0c\u4f7f\u7528 git clone \u547d\u4ee4\u5c06\u4ed3\u5e93\u514b\u9686\u81f3\u672c\u5730\u3002
    3. \u5728\u672c\u5730\u8fdb\u884c\u5185\u5bb9\u521b\u4f5c\uff0c\u5e76\u8fdb\u884c\u5b8c\u6574\u6d4b\u8bd5\uff0c\u9a8c\u8bc1\u4ee3\u7801\u7684\u6b63\u786e\u6027\u3002
    4. \u5c06\u672c\u5730\u6240\u505a\u66f4\u6539 Commit \uff0c\u7136\u540e Push \u81f3\u8fdc\u7a0b\u4ed3\u5e93\u3002
    5. \u5237\u65b0\u4ed3\u5e93\u7f51\u9875\uff0c\u70b9\u51fb\u201cCreate pull request\u201d\u6309\u94ae\u5373\u53ef\u53d1\u8d77\u62c9\u53d6\u8bf7\u6c42\u3002
    "},{"location":"chapter_appendix/contribution/#3-docker","title":"3. \u00a0 Docker \u90e8\u7f72","text":"

    \u5728 hello-algo \u6839\u76ee\u5f55\u4e0b\uff0c\u6267\u884c\u4ee5\u4e0b Docker \u811a\u672c\uff0c\u5373\u53ef\u5728 http://localhost:8000 \u8bbf\u95ee\u672c\u9879\u76ee\uff1a

    docker-compose up -d\n

    \u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u5373\u53ef\u5220\u9664\u90e8\u7f72\uff1a

    docker-compose down\n
    "},{"location":"chapter_appendix/installation/","title":"16.1 \u00a0 \u7f16\u7a0b\u73af\u5883\u5b89\u88c5","text":""},{"location":"chapter_appendix/installation/#1611-ide","title":"16.1.1 \u00a0 \u5b89\u88c5 IDE","text":"

    \u63a8\u8350\u4f7f\u7528\u5f00\u6e90\u3001\u8f7b\u91cf\u7684 VS Code \u4f5c\u4e3a\u672c\u5730\u96c6\u6210\u5f00\u53d1\u73af\u5883\uff08IDE\uff09\u3002\u8bbf\u95ee VS Code \u5b98\u7f51\uff0c\u6839\u636e\u64cd\u4f5c\u7cfb\u7edf\u9009\u62e9\u76f8\u5e94\u7248\u672c\u7684 VS Code \u8fdb\u884c\u4e0b\u8f7d\u548c\u5b89\u88c5\u3002

    \u56fe 16-1 \u00a0 \u4ece\u5b98\u7f51\u4e0b\u8f7d VS Code

    VS Code \u62e5\u6709\u5f3a\u5927\u7684\u6269\u5c55\u5305\u751f\u6001\u7cfb\u7edf\uff0c\u652f\u6301\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u7684\u8fd0\u884c\u548c\u8c03\u8bd5\u3002\u4ee5 Python \u4e3a\u4f8b\uff0c\u5b89\u88c5\u201cPython Extension Pack\u201d\u6269\u5c55\u5305\u4e4b\u540e\uff0c\u5373\u53ef\u8fdb\u884c Python \u4ee3\u7801\u8c03\u8bd5\u3002\u5b89\u88c5\u6b65\u9aa4\u5982\u56fe 16-2 \u6240\u793a\u3002

    \u56fe 16-2 \u00a0 \u5b89\u88c5 VS Code \u6269\u5c55\u5305

    "},{"location":"chapter_appendix/installation/#1612","title":"16.1.2 \u00a0 \u5b89\u88c5\u8bed\u8a00\u73af\u5883","text":""},{"location":"chapter_appendix/installation/#1-python","title":"1. \u00a0 Python \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Miniconda3 \uff0c\u9700\u8981 Python 3.10 \u6216\u66f4\u65b0\u7248\u672c\u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 python \uff0c\u5b89\u88c5 Python Extension Pack \u3002
    3. \uff08\u53ef\u9009\uff09\u5728\u547d\u4ee4\u884c\u8f93\u5165 pip install black \uff0c\u5b89\u88c5\u4ee3\u7801\u683c\u5f0f\u5316\u5de5\u5177\u3002
    "},{"location":"chapter_appendix/installation/#2-cc","title":"2. \u00a0 C/C++ \u73af\u5883","text":"
    1. Windows \u7cfb\u7edf\u9700\u8981\u5b89\u88c5 MinGW\uff08\u914d\u7f6e\u6559\u7a0b\uff09\uff1bMacOS \u81ea\u5e26 Clang \uff0c\u65e0\u987b\u5b89\u88c5\u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 c++ \uff0c\u5b89\u88c5 C/C++ Extension Pack \u3002
    3. \uff08\u53ef\u9009\uff09\u6253\u5f00 Settings \u9875\u9762\uff0c\u641c\u7d22 Clang_format_fallback Style \u4ee3\u7801\u683c\u5f0f\u5316\u9009\u9879\uff0c\u8bbe\u7f6e\u4e3a { BasedOnStyle: Microsoft, BreakBeforeBraces: Attach } \u3002
    "},{"location":"chapter_appendix/installation/#3-java","title":"3. \u00a0 Java \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 OpenJDK\uff08\u7248\u672c\u9700\u6ee1\u8db3 > JDK 9\uff09\u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 java \uff0c\u5b89\u88c5 Extension Pack for Java \u3002
    "},{"location":"chapter_appendix/installation/#4-c","title":"4. \u00a0 C# \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 .Net 8.0 \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 C# Dev Kit \uff0c\u5b89\u88c5 C# Dev Kit \uff08\u914d\u7f6e\u6559\u7a0b\uff09\u3002
    3. \u4e5f\u53ef\u4f7f\u7528 Visual Studio\uff08\u5b89\u88c5\u6559\u7a0b\uff09\u3002
    "},{"location":"chapter_appendix/installation/#5-go","title":"5. \u00a0 Go \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 go \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 go \uff0c\u5b89\u88c5 Go \u3002
    3. \u6309\u5feb\u6377\u952e Ctrl + Shift + P \u547c\u51fa\u547d\u4ee4\u680f\uff0c\u8f93\u5165 go \uff0c\u9009\u62e9 Go: Install/Update Tools \uff0c\u5168\u90e8\u52fe\u9009\u5e76\u5b89\u88c5\u5373\u53ef\u3002
    "},{"location":"chapter_appendix/installation/#6-swift","title":"6. \u00a0 Swift \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Swift \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 swift \uff0c\u5b89\u88c5 Swift for Visual Studio Code \u3002
    "},{"location":"chapter_appendix/installation/#7-javascript","title":"7. \u00a0 JavaScript \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Node.js \u3002
    2. \uff08\u53ef\u9009\uff09\u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 Prettier \uff0c\u5b89\u88c5\u4ee3\u7801\u683c\u5f0f\u5316\u5de5\u5177\u3002
    "},{"location":"chapter_appendix/installation/#8-typescript","title":"8. \u00a0 TypeScript \u73af\u5883","text":"
    1. \u540c JavaScript \u73af\u5883\u5b89\u88c5\u6b65\u9aa4\u3002
    2. \u5b89\u88c5 TypeScript Execute (tsx) \u3002
    3. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 typescript \uff0c\u5b89\u88c5 Pretty TypeScript Errors \u3002
    "},{"location":"chapter_appendix/installation/#9-dart","title":"9. \u00a0 Dart \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Dart \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 dart \uff0c\u5b89\u88c5 Dart \u3002
    "},{"location":"chapter_appendix/installation/#10-rust","title":"10. \u00a0 Rust \u73af\u5883","text":"
    1. \u4e0b\u8f7d\u5e76\u5b89\u88c5 Rust \u3002
    2. \u5728 VS Code \u7684\u63d2\u4ef6\u5e02\u573a\u4e2d\u641c\u7d22 rust \uff0c\u5b89\u88c5 rust-analyzer \u3002
    "},{"location":"chapter_appendix/terminology/","title":"16.3 \u00a0 \u672f\u8bed\u8868","text":"

    \u8868 16-1 \u5217\u51fa\u4e86\u4e66\u4e2d\u51fa\u73b0\u7684\u91cd\u8981\u672f\u8bed\uff0c\u503c\u5f97\u6ce8\u610f\u4ee5\u4e0b\u51e0\u70b9\u3002

    • \u5efa\u8bae\u8bb0\u4f4f\u540d\u8bcd\u7684\u82f1\u6587\u53eb\u6cd5\uff0c\u4ee5\u4fbf\u9605\u8bfb\u82f1\u6587\u6587\u732e\u3002
    • \u90e8\u5206\u540d\u8bcd\u5728\u7b80\u4f53\u4e2d\u6587\u548c\u7e41\u4f53\u4e2d\u6587\u4e0b\u7684\u53eb\u6cd5\u4e0d\u540c\u3002

    \u8868 16-1 \u00a0 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u91cd\u8981\u540d\u8bcd

    English \u7b80\u4f53\u4e2d\u6587 \u7e41\u4f53\u4e2d\u6587 algorithm \u7b97\u6cd5 \u6f14\u7b97\u6cd5 data structure \u6570\u636e\u7ed3\u6784 \u8cc7\u6599\u7d50\u69cb code \u4ee3\u7801 \u7a0b\u5f0f\u78bc file \u6587\u4ef6 \u6a94\u6848 function \u51fd\u6570 \u51fd\u5f0f method \u65b9\u6cd5 \u65b9\u6cd5 variable \u53d8\u91cf \u8b8a\u6578 asymptotic complexity analysis \u6e10\u8fd1\u590d\u6742\u5ea6\u5206\u6790 \u6f38\u8fd1\u8907\u96dc\u5ea6\u5206\u6790 time complexity \u65f6\u95f4\u590d\u6742\u5ea6 \u6642\u9593\u8907\u96dc\u5ea6 space complexity \u7a7a\u95f4\u590d\u6742\u5ea6 \u7a7a\u9593\u8907\u96dc\u5ea6 loop \u5faa\u73af \u8ff4\u5708 iteration \u8fed\u4ee3 \u8fed\u4ee3 recursion \u9012\u5f52 \u905e\u8ff4 tail recursion \u5c3e\u9012\u5f52 \u5c3e\u905e\u8ff4 recursion tree \u9012\u5f52\u6811 \u905e\u8ff4\u6a39 big-\\(O\\) notation \u5927 \\(O\\) \u8bb0\u53f7 \u5927 \\(O\\) \u8a18\u865f asymptotic upper bound \u6e10\u8fd1\u4e0a\u754c \u6f38\u8fd1\u4e0a\u754c sign-magnitude \u539f\u7801 \u539f\u78bc 1\u2019s complement \u53cd\u7801 \u4e00\u88dc\u6578 2\u2019s complement \u8865\u7801 \u4e8c\u88dc\u6578 array \u6570\u7ec4 \u9663\u5217 index \u7d22\u5f15 \u7d22\u5f15 linked list \u94fe\u8868 \u93c8\u7d50\u4e32\u5217 linked list node, list node \u94fe\u8868\u8282\u70b9 \u93c8\u7d50\u4e32\u5217\u7bc0\u9ede head node \u5934\u8282\u70b9 \u982d\u7bc0\u9ede tail node \u5c3e\u8282\u70b9 \u5c3e\u7bc0\u9ede list \u5217\u8868 \u4e32\u5217 dynamic array \u52a8\u6001\u6570\u7ec4 \u52d5\u614b\u9663\u5217 hard disk \u786c\u76d8 \u786c\u789f random-access memory (RAM) \u5185\u5b58 \u8a18\u61b6\u9ad4 cache memory \u7f13\u5b58 \u5feb\u53d6 cache miss \u7f13\u5b58\u672a\u547d\u4e2d \u5feb\u53d6\u672a\u547d\u4e2d cache hit rate \u7f13\u5b58\u547d\u4e2d\u7387 \u5feb\u53d6\u547d\u4e2d\u7387 stack \u6808 \u5806\u758a top of the stack \u6808\u9876 \u5806\u758a\u9802 bottom of the stack \u6808\u5e95 \u5806\u758a\u5e95 queue \u961f\u5217 \u4f47\u5217 double-ended queue \u53cc\u5411\u961f\u5217 \u96d9\u5411\u4f47\u5217 front of the queue \u961f\u9996 \u4f47\u5217\u9996 rear of the queue \u961f\u5c3e \u4f47\u5217\u5c3e hash table \u54c8\u5e0c\u8868 \u96dc\u6e4a\u8868 hash set \u54c8\u5e0c\u96c6\u5408 \u96dc\u6e4a\u96c6\u5408 bucket \u6876 \u6876 hash function \u54c8\u5e0c\u51fd\u6570 \u96dc\u6e4a\u51fd\u5f0f hash collision \u54c8\u5e0c\u51b2\u7a81 \u96dc\u6e4a\u885d\u7a81 load factor \u8d1f\u8f7d\u56e0\u5b50 \u8ca0\u8f09\u56e0\u5b50 separate chaining \u94fe\u5f0f\u5730\u5740 \u93c8\u7d50\u4f4d\u5740 open addressing \u5f00\u653e\u5bfb\u5740 \u958b\u653e\u5b9a\u5740 linear probing \u7ebf\u6027\u63a2\u6d4b \u7dda\u6027\u63a2\u67e5 lazy deletion \u61d2\u5220\u9664 \u61f6\u522a\u9664 binary tree \u4e8c\u53c9\u6811 \u4e8c\u5143\u6a39 tree node \u6811\u8282\u70b9 \u6a39\u7bc0\u9ede left-child node \u5de6\u5b50\u8282\u70b9 \u5de6\u5b50\u7bc0\u9ede right-child node \u53f3\u5b50\u8282\u70b9 \u53f3\u5b50\u7bc0\u9ede parent node \u7236\u8282\u70b9 \u7236\u7bc0\u9ede left subtree \u5de6\u5b50\u6811 \u5de6\u5b50\u6a39 right subtree \u53f3\u5b50\u6811 \u53f3\u5b50\u6a39 root node \u6839\u8282\u70b9 \u6839\u7bc0\u9ede leaf node \u53f6\u8282\u70b9 \u8449\u7bc0\u9ede edge \u8fb9 \u908a level \u5c42 \u5c64 degree \u5ea6 \u5ea6 height \u9ad8\u5ea6 \u9ad8\u5ea6 depth \u6df1\u5ea6 \u6df1\u5ea6 perfect binary tree \u5b8c\u7f8e\u4e8c\u53c9\u6811 \u5b8c\u7f8e\u4e8c\u5143\u6a39 complete binary tree \u5b8c\u5168\u4e8c\u53c9\u6811 \u5b8c\u5168\u4e8c\u5143\u6a39 full binary tree \u5b8c\u6ee1\u4e8c\u53c9\u6811 \u5b8c\u6eff\u4e8c\u5143\u6a39 balanced binary tree \u5e73\u8861\u4e8c\u53c9\u6811 \u5e73\u8861\u4e8c\u5143\u6a39 binary search tree \u4e8c\u53c9\u641c\u7d22\u6811 \u4e8c\u5143\u641c\u5c0b\u6a39 AVL tree AVL \u6811 AVL \u6a39 red-black tree \u7ea2\u9ed1\u6811 \u7d05\u9ed1\u6a39 level-order traversal \u5c42\u5e8f\u904d\u5386 \u5c64\u5e8f\u8d70\u8a2a breadth-first traversal \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 \u5ee3\u5ea6\u512a\u5148\u8d70\u8a2a depth-first traversal \u6df1\u5ea6\u4f18\u5148\u904d\u5386 \u6df1\u5ea6\u512a\u5148\u8d70\u8a2a binary search tree \u4e8c\u53c9\u641c\u7d22\u6811 \u4e8c\u5143\u641c\u5c0b\u6a39 balanced binary search tree \u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811 \u5e73\u8861\u4e8c\u5143\u641c\u5c0b\u6a39 balance factor \u5e73\u8861\u56e0\u5b50 \u5e73\u8861\u56e0\u5b50 heap \u5806 \u5806\u7a4d max heap \u5927\u9876\u5806 \u5927\u9802\u5806\u7a4d min heap \u5c0f\u9876\u5806 \u5c0f\u9802\u5806\u7a4d priority queue \u4f18\u5148\u961f\u5217 \u512a\u5148\u4f47\u5217 heapify \u5806\u5316 \u5806\u7a4d\u5316 top-\\(k\\) problem Top-\\(k\\) \u95ee\u9898 Top-\\(k\\) \u554f\u984c graph \u56fe \u5716 vertex \u9876\u70b9 \u9802\u9ede undirected graph \u65e0\u5411\u56fe \u7121\u5411\u5716 directed graph \u6709\u5411\u56fe \u6709\u5411\u5716 connected graph \u8fde\u901a\u56fe \u9023\u901a\u5716 disconnected graph \u975e\u8fde\u901a\u56fe \u975e\u9023\u901a\u5716 weighted graph \u6709\u6743\u56fe \u6709\u6b0a\u5716 adjacency \u90bb\u63a5 \u9130\u63a5 path \u8def\u5f84 \u8def\u5f91 in-degree \u5165\u5ea6 \u5165\u5ea6 out-degree \u51fa\u5ea6 \u51fa\u5ea6 adjacency matrix \u90bb\u63a5\u77e9\u9635 \u9130\u63a5\u77e9\u9663 adjacency list \u90bb\u63a5\u8868 \u9130\u63a5\u8868 breadth-first search \u5e7f\u5ea6\u4f18\u5148\u641c\u7d22 \u5ee3\u5ea6\u512a\u5148\u641c\u5c0b depth-first search \u6df1\u5ea6\u4f18\u5148\u641c\u7d22 \u6df1\u5ea6\u512a\u5148\u641c\u5c0b binary search \u4e8c\u5206\u67e5\u627e \u4e8c\u5206\u641c\u5c0b searching algorithm \u641c\u7d22\u7b97\u6cd5 \u641c\u5c0b\u6f14\u7b97\u6cd5 sorting algorithm \u6392\u5e8f\u7b97\u6cd5 \u6392\u5e8f\u6f14\u7b97\u6cd5 selection sort \u9009\u62e9\u6392\u5e8f \u9078\u64c7\u6392\u5e8f bubble sort \u5192\u6ce1\u6392\u5e8f \u6ce1\u6cab\u6392\u5e8f insertion sort \u63d2\u5165\u6392\u5e8f \u63d2\u5165\u6392\u5e8f quick sort \u5feb\u901f\u6392\u5e8f \u5feb\u901f\u6392\u5e8f merge sort \u5f52\u5e76\u6392\u5e8f \u5408\u4f75\u6392\u5e8f heap sort \u5806\u6392\u5e8f \u5806\u7a4d\u6392\u5e8f bucket sort \u6876\u6392\u5e8f \u6876\u6392\u5e8f counting sort \u8ba1\u6570\u6392\u5e8f \u8a08\u6578\u6392\u5e8f radix sort \u57fa\u6570\u6392\u5e8f \u57fa\u6578\u6392\u5e8f divide and conquer \u5206\u6cbb \u5206\u6cbb hanota problem \u6c49\u8bfa\u5854\u95ee\u9898 \u6cb3\u5167\u5854\u554f\u984c backtracking algorithm \u56de\u6eaf\u7b97\u6cd5 \u56de\u6eaf\u6f14\u7b97\u6cd5 constraint \u7ea6\u675f \u7d04\u675f solution \u89e3 \u89e3 state \u72b6\u6001 \u72c0\u614b pruning \u526a\u679d \u526a\u679d permutations problem \u5168\u6392\u5217\u95ee\u9898 \u5168\u6392\u5217\u554f\u984c subset-sum problem \u5b50\u96c6\u548c\u95ee\u9898 \u5b50\u96c6\u5408\u554f\u984c \\(n\\)-queens problem \\(n\\) \u7687\u540e\u95ee\u9898 \\(n\\) \u7687\u540e\u554f\u984c dynamic programming \u52a8\u6001\u89c4\u5212 \u52d5\u614b\u898f\u5283 initial state \u521d\u59cb\u72b6\u6001 \u521d\u59cb\u72c0\u614b state-transition equation \u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b \u72c0\u614b\u8f49\u79fb\u65b9\u7a0b knapsack problem \u80cc\u5305\u95ee\u9898 \u80cc\u5305\u554f\u984c edit distance problem \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898 \u7de8\u8f2f\u8ddd\u96e2\u554f\u984c greedy algorithm \u8d2a\u5fc3\u7b97\u6cd5 \u8caa\u5a6a\u6f14\u7b97\u6cd5"},{"location":"chapter_array_and_linkedlist/","title":"\u7b2c 4 \u7ae0 \u00a0 \u6570\u7ec4\u4e0e\u94fe\u8868","text":"

    Abstract

    \u6570\u636e\u7ed3\u6784\u7684\u4e16\u754c\u5982\u540c\u4e00\u5835\u539a\u5b9e\u7684\u7816\u5899\u3002

    \u6570\u7ec4\u7684\u7816\u5757\u6574\u9f50\u6392\u5217\uff0c\u9010\u4e2a\u7d27\u8d34\u3002\u94fe\u8868\u7684\u7816\u5757\u5206\u6563\u5404\u5904\uff0c\u8fde\u63a5\u7684\u85e4\u8513\u81ea\u7531\u5730\u7a7f\u68ad\u4e8e\u7816\u7f1d\u4e4b\u95f4\u3002

    "},{"location":"chapter_array_and_linkedlist/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 4.1 \u00a0 \u6570\u7ec4
    • 4.2 \u00a0 \u94fe\u8868
    • 4.3 \u00a0 \u5217\u8868
    • 4.4 \u00a0 \u5185\u5b58\u4e0e\u7f13\u5b58 *
    • 4.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_array_and_linkedlist/array/","title":"4.1 \u00a0 \u6570\u7ec4","text":"

    \u6570\u7ec4\uff08array\uff09\u662f\u4e00\u79cd\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u5176\u5c06\u76f8\u540c\u7c7b\u578b\u7684\u5143\u7d20\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\u3002\u6211\u4eec\u5c06\u5143\u7d20\u5728\u6570\u7ec4\u4e2d\u7684\u4f4d\u7f6e\u79f0\u4e3a\u8be5\u5143\u7d20\u7684\u7d22\u5f15\uff08index\uff09\u3002\u56fe 4-1 \u5c55\u793a\u4e86\u6570\u7ec4\u7684\u4e3b\u8981\u6982\u5ff5\u548c\u5b58\u50a8\u65b9\u5f0f\u3002

    \u56fe 4-1 \u00a0 \u6570\u7ec4\u5b9a\u4e49\u4e0e\u5b58\u50a8\u65b9\u5f0f

    "},{"location":"chapter_array_and_linkedlist/array/#411","title":"4.1.1 \u00a0 \u6570\u7ec4\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_array_and_linkedlist/array/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u6570\u7ec4","text":"

    \u6211\u4eec\u53ef\u4ee5\u6839\u636e\u9700\u6c42\u9009\u7528\u6570\u7ec4\u7684\u4e24\u79cd\u521d\u59cb\u5316\u65b9\u5f0f\uff1a\u65e0\u521d\u59cb\u503c\u3001\u7ed9\u5b9a\u521d\u59cb\u503c\u3002\u5728\u672a\u6307\u5b9a\u521d\u59cb\u503c\u7684\u60c5\u51b5\u4e0b\uff0c\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4f1a\u5c06\u6570\u7ec4\u5143\u7d20\u521d\u59cb\u5316\u4e3a \\(0\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    # \u521d\u59cb\u5316\u6570\u7ec4\narr: list[int] = [0] * 5  # [ 0, 0, 0, 0, 0 ]\nnums: list[int] = [1, 3, 2, 5, 4]  \n
    array.cpp
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\n// \u5b58\u50a8\u5728\u6808\u4e0a\nint arr[5];\nint nums[5] = { 1, 3, 2, 5, 4 };\n// \u5b58\u50a8\u5728\u5806\u4e0a\uff08\u9700\u8981\u624b\u52a8\u91ca\u653e\u7a7a\u95f4\uff09\nint* arr1 = new int[5];\nint* nums1 = new int[5] { 1, 3, 2, 5, 4 };\n
    array.java
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nint[] arr = new int[5]; // { 0, 0, 0, 0, 0 }\nint[] nums = { 1, 3, 2, 5, 4 };\n
    array.cs
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nint[] arr = new int[5]; // [ 0, 0, 0, 0, 0 ]\nint[] nums = [1, 3, 2, 5, 4];\n
    array.go
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nvar arr [5]int\n// \u5728 Go \u4e2d\uff0c\u6307\u5b9a\u957f\u5ea6\u65f6\uff08[5]int\uff09\u4e3a\u6570\u7ec4\uff0c\u4e0d\u6307\u5b9a\u957f\u5ea6\u65f6\uff08[]int\uff09\u4e3a\u5207\u7247\n// \u7531\u4e8e Go \u7684\u6570\u7ec4\u88ab\u8bbe\u8ba1\u4e3a\u5728\u7f16\u8bd1\u671f\u786e\u5b9a\u957f\u5ea6\uff0c\u56e0\u6b64\u53ea\u80fd\u4f7f\u7528\u5e38\u91cf\u6765\u6307\u5b9a\u957f\u5ea6\n// \u4e3a\u4e86\u65b9\u4fbf\u5b9e\u73b0\u6269\u5bb9 extend() \u65b9\u6cd5\uff0c\u4ee5\u4e0b\u5c06\u5207\u7247\uff08Slice\uff09\u770b\u4f5c\u6570\u7ec4\uff08Array\uff09\nnums := []int{1, 3, 2, 5, 4}\n
    array.swift
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nlet arr = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]\nlet nums = [1, 3, 2, 5, 4]\n
    array.js
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nvar arr = new Array(5).fill(0);\nvar nums = [1, 3, 2, 5, 4];\n
    array.ts
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nlet arr: number[] = new Array(5).fill(0);\nlet nums: number[] = [1, 3, 2, 5, 4];\n
    array.dart
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nList<int> arr = List.filled(5, 0); // [0, 0, 0, 0, 0]\nList<int> nums = [1, 3, 2, 5, 4];\n
    array.rs
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nlet arr: Vec<i32> = vec![0; 5]; // [0, 0, 0, 0, 0]\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    array.c
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nint arr[5] = { 0 }; // { 0, 0, 0, 0, 0 }\nint nums[5] = { 1, 3, 2, 5, 4 };\n
    array.kt
    /* \u521d\u59cb\u5316\u6570\u7ec4 */\nvar arr = IntArray(5) // { 0, 0, 0, 0, 0 }\nvar nums = intArrayOf(1, 3, 2, 5, 4)\n
    array.rb
    # \u521d\u59cb\u5316\u6570\u7ec4\narr = Array.new(5, 0)\nnums = [1, 3, 2, 5, 4]\n
    array.zig
    // \u521d\u59cb\u5316\u6570\u7ec4\nvar arr = [_]i32{0} ** 5; // { 0, 0, 0, 0, 0 }\nvar nums = [_]i32{ 1, 3, 2, 5, 4 };\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#2","title":"2. \u00a0 \u8bbf\u95ee\u5143\u7d20","text":"

    \u6570\u7ec4\u5143\u7d20\u88ab\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\uff0c\u8fd9\u610f\u5473\u7740\u8ba1\u7b97\u6570\u7ec4\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u975e\u5e38\u5bb9\u6613\u3002\u7ed9\u5b9a\u6570\u7ec4\u5185\u5b58\u5730\u5740\uff08\u9996\u5143\u7d20\u5185\u5b58\u5730\u5740\uff09\u548c\u67d0\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u56fe 4-2 \u6240\u793a\u7684\u516c\u5f0f\u8ba1\u7b97\u5f97\u5230\u8be5\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\uff0c\u4ece\u800c\u76f4\u63a5\u8bbf\u95ee\u8be5\u5143\u7d20\u3002

    \u56fe 4-2 \u00a0 \u6570\u7ec4\u5143\u7d20\u7684\u5185\u5b58\u5730\u5740\u8ba1\u7b97

    \u89c2\u5bdf\u56fe 4-2 \uff0c\u6211\u4eec\u53d1\u73b0\u6570\u7ec4\u9996\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u4e3a \\(0\\) \uff0c\u8fd9\u4f3c\u4e4e\u6709\u4e9b\u53cd\u76f4\u89c9\uff0c\u56e0\u4e3a\u4ece \\(1\\) \u5f00\u59cb\u8ba1\u6570\u4f1a\u66f4\u81ea\u7136\u3002\u4f46\u4ece\u5730\u5740\u8ba1\u7b97\u516c\u5f0f\u7684\u89d2\u5ea6\u770b\uff0c\u7d22\u5f15\u672c\u8d28\u4e0a\u662f\u5185\u5b58\u5730\u5740\u7684\u504f\u79fb\u91cf\u3002\u9996\u4e2a\u5143\u7d20\u7684\u5730\u5740\u504f\u79fb\u91cf\u662f \\(0\\) \uff0c\u56e0\u6b64\u5b83\u7684\u7d22\u5f15\u4e3a \\(0\\) \u662f\u5408\u7406\u7684\u3002

    \u5728\u6570\u7ec4\u4e2d\u8bbf\u95ee\u5143\u7d20\u975e\u5e38\u9ad8\u6548\uff0c\u6211\u4eec\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u968f\u673a\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u4e00\u4e2a\u5143\u7d20\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def random_access(nums: list[int]) -> int:\n    \"\"\"\u968f\u673a\u8bbf\u95ee\u5143\u7d20\"\"\"\n    # \u5728\u533a\u95f4 [0, len(nums)-1] \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    random_index = random.randint(0, len(nums) - 1)\n    # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    random_num = nums[random_index]\n    return random_num\n
    array.cpp
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.java
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int[] nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = ThreadLocalRandom.current().nextInt(0, nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.cs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint RandomAccess(int[] nums) {\n    Random random = new();\n    // \u5728\u533a\u95f4 [0, nums.Length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = random.Next(nums.Length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.go
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums []int) (randomNum int) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    randomIndex := rand.Intn(len(nums))\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    randomNum = nums[randomIndex]\n    return\n}\n
    array.swift
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunc randomAccess(nums: [Int]) -> Int {\n    // \u5728\u533a\u95f4 [0, nums.count) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let randomIndex = nums.indices.randomElement()!\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.js
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums) {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.ts
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfunction randomAccess(nums: number[]): number {\n    // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    const random_index = Math.floor(Math.random() * nums.length);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    const random_num = nums[random_index];\n    return random_num;\n}\n
    array.dart
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(List<int> nums) {\n  // \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  int randomIndex = Random().nextInt(nums.length);\n  // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  int randomNum = nums[randomIndex];\n  return randomNum;\n}\n
    array.rs
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfn random_access(nums: &[i32]) -> i32 {\n    // \u5728\u533a\u95f4 [0, nums.len()) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    let random_index = rand::thread_rng().gen_range(0..nums.len());\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    let random_num = nums[random_index];\n    random_num\n}\n
    array.c
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nint randomAccess(int *nums, int size) {\n    // \u5728\u533a\u95f4 [0, size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    int randomIndex = rand() % size;\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    int randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    array.kt
    /* \u968f\u673a\u8bbf\u95ee\u5143\u7d20 */\nfun randomAccess(nums: IntArray): Int {\n    // \u5728\u533a\u95f4 [0, nums.size) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n    val randomIndex = ThreadLocalRandom.current().nextInt(0, nums.size)\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    val randomNum = nums[randomIndex]\n    return randomNum\n}\n
    array.rb
    ### \u968f\u673a\u8bbf\u95ee\u5143\u7d20 ###\ndef random_access(nums)\n  # \u5728\u533a\u95f4 [0, nums.length) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6570\u5b57\n  random_index = Random.rand(0...nums.length)\n\n  # \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n  nums[random_index]\nend\n
    array.zig
    // \u968f\u673a\u8bbf\u95ee\u5143\u7d20\nfn randomAccess(nums: []i32) i32 {\n    // \u5728\u533a\u95f4 [0, nums.len) \u4e2d\u968f\u673a\u62bd\u53d6\u4e00\u4e2a\u6574\u6570\n    var randomIndex = std.crypto.random.intRangeLessThan(usize, 0, nums.len);\n    // \u83b7\u53d6\u5e76\u8fd4\u56de\u968f\u673a\u5143\u7d20\n    var randomNum = nums[randomIndex];\n    return randomNum;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#3","title":"3. \u00a0 \u63d2\u5165\u5143\u7d20","text":"

    \u6570\u7ec4\u5143\u7d20\u5728\u5185\u5b58\u4e2d\u662f\u201c\u7d27\u6328\u7740\u7684\u201d\uff0c\u5b83\u4eec\u4e4b\u95f4\u6ca1\u6709\u7a7a\u95f4\u518d\u5b58\u653e\u4efb\u4f55\u6570\u636e\u3002\u5982\u56fe 4-3 \u6240\u793a\uff0c\u5982\u679c\u60f3\u5728\u6570\u7ec4\u4e2d\u95f4\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff0c\u5219\u9700\u8981\u5c06\u8be5\u5143\u7d20\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u4e4b\u540e\u518d\u628a\u5143\u7d20\u8d4b\u503c\u7ed9\u8be5\u7d22\u5f15\u3002

    \u56fe 4-3 \u00a0 \u6570\u7ec4\u63d2\u5165\u5143\u7d20\u793a\u4f8b

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u7531\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\u662f\u56fa\u5b9a\u7684\uff0c\u56e0\u6b64\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\u5fc5\u5b9a\u4f1a\u5bfc\u81f4\u6570\u7ec4\u5c3e\u90e8\u5143\u7d20\u201c\u4e22\u5931\u201d\u3002\u6211\u4eec\u5c06\u8fd9\u4e2a\u95ee\u9898\u7684\u89e3\u51b3\u65b9\u6848\u7559\u5728\u201c\u5217\u8868\u201d\u7ae0\u8282\u4e2d\u8ba8\u8bba\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def insert(nums: list[int], num: int, index: int):\n    \"\"\"\u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\"\"\"\n    # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in range(len(nums) - 1, index, -1):\n        nums[i] = nums[i - 1]\n    # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n
    array.cpp
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid Insert(int[] nums, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = nums.Length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums []int, num int, index int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i := len(nums) - 1; i > index; i-- {\n        nums[i] = nums[i-1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunc insert(nums: inout [Int], num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).reversed() {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums, num, index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfunction insert(nums: number[], num: number, index: number): void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (let i = nums.length - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 _num */\nvoid insert(List<int> nums, int _num, int index) {\n  // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for (var i = nums.length - 1; i > index; i--) {\n    nums[i] = nums[i - 1];\n  }\n  // \u5c06 _num \u8d4b\u7ed9 index \u5904\u5143\u7d20\n  nums[index] = _num;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfn insert(nums: &mut Vec<i32>, num: i32, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for i in (index + 1..nums.len()).rev() {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nvoid insert(int *nums, int size, int num, int index) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (int i = size - 1; i > index; i--) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num */\nfun insert(nums: IntArray, num: Int, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (i in nums.size - 1 downTo index + 1) {\n        nums[i] = nums[i - 1]\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num ###\ndef insert(nums, num, index)\n  # \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n  for i in (nums.length - 1).downto(index + 1)\n    nums[i] = nums[i - 1]\n  end\n\n  # \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n  nums[index] = num\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u7684\u7d22\u5f15 index \u5904\u63d2\u5165\u5143\u7d20 num\nfn insert(nums: []i32, num: i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    var i = nums.len - 1;\n    while (i > index) : (i -= 1) {\n        nums[i] = nums[i - 1];\n    }\n    // \u5c06 num \u8d4b\u7ed9 index \u5904\u7684\u5143\u7d20\n    nums[index] = num;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#4","title":"4. \u00a0 \u5220\u9664\u5143\u7d20","text":"

    \u540c\u7406\uff0c\u5982\u56fe 4-4 \u6240\u793a\uff0c\u82e5\u60f3\u5220\u9664\u7d22\u5f15 \\(i\\) \u5904\u7684\u5143\u7d20\uff0c\u5219\u9700\u8981\u628a\u7d22\u5f15 \\(i\\) \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\u3002

    \u56fe 4-4 \u00a0 \u6570\u7ec4\u5220\u9664\u5143\u7d20\u793a\u4f8b

    \u8bf7\u6ce8\u610f\uff0c\u5220\u9664\u5143\u7d20\u5b8c\u6210\u540e\uff0c\u539f\u5148\u672b\u5c3e\u7684\u5143\u7d20\u53d8\u5f97\u201c\u65e0\u610f\u4e49\u201d\u4e86\uff0c\u6240\u4ee5\u6211\u4eec\u65e0\u987b\u7279\u610f\u53bb\u4fee\u6539\u5b83\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def remove(nums: list[int], index: int):\n    \"\"\"\u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\"\"\"\n    # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in range(index, len(nums) - 1):\n        nums[i] = nums[i + 1]\n
    array.cpp
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.java
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.cs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid Remove(int[] nums, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < nums.Length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.go
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums []int, index int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i := index; i < len(nums)-1; i++ {\n        nums[i] = nums[i+1]\n    }\n}\n
    array.swift
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunc remove(nums: inout [Int], index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in nums.indices.dropFirst(index).dropLast() {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.js
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums, index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.ts
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfunction remove(nums: number[], index: number): void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (let i = index; i < nums.length - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.dart
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nvoid remove(List<int> nums, int index) {\n  // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for (var i = index; i < nums.length - 1; i++) {\n    nums[i] = nums[i + 1];\n  }\n}\n
    array.rs
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfn remove(nums: &mut Vec<i32>, index: usize) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for i in index..nums.len() - 1 {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.c
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(int *nums, int size, int index) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (int i = index; i < size - 1; i++) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    array.kt
    /* \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 */\nfun remove(nums: IntArray, index: Int) {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (i in index..<nums.size - 1) {\n        nums[i] = nums[i + 1]\n    }\n}\n
    array.rb
    ### \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20 ###\ndef remove(nums, index)\n  # \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n  for i in index...(nums.length - 1)\n    nums[i] = nums[i + 1]\n  end\nend\n
    array.zig
    // \u5220\u9664\u7d22\u5f15 index \u5904\u7684\u5143\u7d20\nfn remove(nums: []i32, index: usize) void {\n    // \u628a\u7d22\u5f15 index \u4e4b\u540e\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    var i = index;\n    while (i < nums.len - 1) : (i += 1) {\n        nums[i] = nums[i + 1];\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u603b\u7684\u6765\u770b\uff0c\u6570\u7ec4\u7684\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u6709\u4ee5\u4e0b\u7f3a\u70b9\u3002

    • \u65f6\u95f4\u590d\u6742\u5ea6\u9ad8\uff1a\u6570\u7ec4\u7684\u63d2\u5165\u548c\u5220\u9664\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u6570\u7ec4\u957f\u5ea6\u3002
    • \u4e22\u5931\u5143\u7d20\uff1a\u7531\u4e8e\u6570\u7ec4\u7684\u957f\u5ea6\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u5728\u63d2\u5165\u5143\u7d20\u540e\uff0c\u8d85\u51fa\u6570\u7ec4\u957f\u5ea6\u8303\u56f4\u7684\u5143\u7d20\u4f1a\u4e22\u5931\u3002
    • \u5185\u5b58\u6d6a\u8d39\uff1a\u6211\u4eec\u53ef\u4ee5\u521d\u59cb\u5316\u4e00\u4e2a\u6bd4\u8f83\u957f\u7684\u6570\u7ec4\uff0c\u53ea\u7528\u524d\u9762\u4e00\u90e8\u5206\uff0c\u8fd9\u6837\u5728\u63d2\u5165\u6570\u636e\u65f6\uff0c\u4e22\u5931\u7684\u672b\u5c3e\u5143\u7d20\u90fd\u662f\u201c\u65e0\u610f\u4e49\u201d\u7684\uff0c\u4f46\u8fd9\u6837\u505a\u4f1a\u9020\u6210\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u3002
    "},{"location":"chapter_array_and_linkedlist/array/#5","title":"5. \u00a0 \u904d\u5386\u6570\u7ec4","text":"

    \u5728\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u6211\u4eec\u65e2\u53ef\u4ee5\u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u904d\u5386\u83b7\u53d6\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def traverse(nums: list[int]):\n    \"\"\"\u904d\u5386\u6570\u7ec4\"\"\"\n    count = 0\n    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in range(len(nums)):\n        count += nums[i]\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums:\n        count += num\n    # \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num in enumerate(nums):\n        count += nums[i]\n        count += num\n
    array.cpp
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.java
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (int num : nums) {\n        count += num;\n    }\n}\n
    array.cs
    /* \u904d\u5386\u6570\u7ec4 */\nvoid Traverse(int[] nums) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    foreach (int num in nums) {\n        count += num;\n    }\n}\n
    array.go
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums []int) {\n    count := 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i := 0; i < len(nums); i++ {\n        count += nums[i]\n    }\n    count = 0\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for _, num := range nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for i, num := range nums {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.swift
    /* \u904d\u5386\u6570\u7ec4 */\nfunc traverse(nums: [Int]) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in nums.indices {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        count += num\n    }\n    // \u540c\u65f6\u904d\u5386\u6570\u636e\u7d22\u5f15\u548c\u5143\u7d20\n    for (i, num) in nums.enumerated() {\n        count += nums[i]\n        count += num\n    }\n}\n
    array.js
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums) {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.ts
    /* \u904d\u5386\u6570\u7ec4 */\nfunction traverse(nums: number[]): void {\n    let count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (const num of nums) {\n        count += num;\n    }\n}\n
    array.dart
    /* \u904d\u5386\u6570\u7ec4\u5143\u7d20 */\nvoid traverse(List<int> nums) {\n  int count = 0;\n  // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n  }\n  // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for (int _num in nums) {\n    count += _num;\n  }\n  // \u901a\u8fc7 forEach \u65b9\u6cd5\u904d\u5386\u6570\u7ec4\n  nums.forEach((_num) {\n    count += _num;\n  });\n}\n
    array.rs
    /* \u904d\u5386\u6570\u7ec4 */\nfn traverse(nums: &[i32]) {\n    let mut _count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for i in 0..nums.len() {\n        _count += nums[i];\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for num in nums {\n        _count += num;\n    }\n}\n
    array.c
    /* \u904d\u5386\u6570\u7ec4 */\nvoid traverse(int *nums, int size) {\n    int count = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        count += nums[i];\n    }\n}\n
    array.kt
    /* \u904d\u5386\u6570\u7ec4 */\nfun traverse(nums: IntArray) {\n    var count = 0\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    for (i in nums.indices) {\n        count += nums[i]\n    }\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (j in nums) {\n        count += j\n    }\n}\n
    array.rb
    ### \u904d\u5386\u6570\u7ec4 ###\ndef traverse(nums)\n  count = 0\n\n  # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n  for i in 0...nums.length\n    count += nums[i]\n  end\n\n  # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n  for num in nums\n    count += num\n  end\nend\n
    array.zig
    // \u904d\u5386\u6570\u7ec4\nfn traverse(nums: []i32) void {\n    var count: i32 = 0;\n    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u6570\u7ec4\n    var i: i32 = 0;\n    while (i < nums.len) : (i += 1) {\n        count += nums[i];\n    }\n    count = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\u5143\u7d20\n    for (nums) |num| {\n        count += num;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#6","title":"6. \u00a0 \u67e5\u627e\u5143\u7d20","text":"

    \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\u9700\u8981\u904d\u5386\u6570\u7ec4\uff0c\u6bcf\u8f6e\u5224\u65ad\u5143\u7d20\u503c\u662f\u5426\u5339\u914d\uff0c\u82e5\u5339\u914d\u5219\u8f93\u51fa\u5bf9\u5e94\u7d22\u5f15\u3002

    \u56e0\u4e3a\u6570\u7ec4\u662f\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u6240\u4ee5\u4e0a\u8ff0\u67e5\u627e\u64cd\u4f5c\u88ab\u79f0\u4e3a\u201c\u7ebf\u6027\u67e5\u627e\u201d\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def find(nums: list[int], target: int) -> int:\n    \"\"\"\u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\"\"\"\n    for i in range(len(nums)):\n        if nums[i] == target:\n            return i\n    return -1\n
    array.cpp
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.java
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int[] nums, int target) {\n    for (int i = 0; i < nums.length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.cs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint Find(int[] nums, int target) {\n    for (int i = 0; i < nums.Length; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.go
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums []int, target int) (index int) {\n    index = -1\n    for i := 0; i < len(nums); i++ {\n        if nums[i] == target {\n            index = i\n            break\n        }\n    }\n    return\n}\n
    array.swift
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunc find(nums: [Int], target: Int) -> Int {\n    for i in nums.indices {\n        if nums[i] == target {\n            return i\n        }\n    }\n    return -1\n}\n
    array.js
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums, target) {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) return i;\n    }\n    return -1;\n}\n
    array.ts
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfunction find(nums: number[], target: number): number {\n    for (let i = 0; i < nums.length; i++) {\n        if (nums[i] === target) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    array.dart
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(List<int> nums, int target) {\n  for (var i = 0; i < nums.length; i++) {\n    if (nums[i] == target) return i;\n  }\n  return -1;\n}\n
    array.rs
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfn find(nums: &[i32], target: i32) -> Option<usize> {\n    for i in 0..nums.len() {\n        if nums[i] == target {\n            return Some(i);\n        }\n    }\n    None\n}\n
    array.c
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nint find(int *nums, int size, int target) {\n    for (int i = 0; i < size; i++) {\n        if (nums[i] == target)\n            return i;\n    }\n    return -1;\n}\n
    array.kt
    /* \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 */\nfun find(nums: IntArray, target: Int): Int {\n    for (i in nums.indices) {\n        if (nums[i] == target)\n            return i\n    }\n    return -1\n}\n
    array.rb
    ### \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20 ###\ndef find(nums, target)\n  for i in 0...nums.length\n    return i if nums[i] == target\n  end\n\n  -1\nend\n
    array.zig
    // \u5728\u6570\u7ec4\u4e2d\u67e5\u627e\u6307\u5b9a\u5143\u7d20\nfn find(nums: []i32, target: i32) i32 {\n    for (nums, 0..) |num, i| {\n        if (num == target) return @intCast(i);\n    }\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#7","title":"7. \u00a0 \u6269\u5bb9\u6570\u7ec4","text":"

    \u5728\u590d\u6742\u7684\u7cfb\u7edf\u73af\u5883\u4e2d\uff0c\u7a0b\u5e8f\u96be\u4ee5\u4fdd\u8bc1\u6570\u7ec4\u4e4b\u540e\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u53ef\u7528\u7684\uff0c\u4ece\u800c\u65e0\u6cd5\u5b89\u5168\u5730\u6269\u5c55\u6570\u7ec4\u5bb9\u91cf\u3002\u56e0\u6b64\u5728\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u6570\u7ec4\u7684\u957f\u5ea6\u662f\u4e0d\u53ef\u53d8\u7684\u3002

    \u5982\u679c\u6211\u4eec\u5e0c\u671b\u6269\u5bb9\u6570\u7ec4\uff0c\u5219\u9700\u91cd\u65b0\u5efa\u7acb\u4e00\u4e2a\u66f4\u5927\u7684\u6570\u7ec4\uff0c\u7136\u540e\u628a\u539f\u6570\u7ec4\u5143\u7d20\u4f9d\u6b21\u590d\u5236\u5230\u65b0\u6570\u7ec4\u3002\u8fd9\u662f\u4e00\u4e2a \\(O(n)\\) \u7684\u64cd\u4f5c\uff0c\u5728\u6570\u7ec4\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\u975e\u5e38\u8017\u65f6\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array.py
    def extend(nums: list[int], enlarge: int) -> list[int]:\n    \"\"\"\u6269\u5c55\u6570\u7ec4\u957f\u5ea6\"\"\"\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res = [0] * (len(nums) + enlarge)\n    # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in range(len(nums)):\n        res[i] = nums[i]\n    # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n
    array.cpp
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = new int[size + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    delete[] nums;\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.java
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.cs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint[] Extend(int[] nums, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int[] res = new int[nums.Length + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < nums.Length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.go
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums []int, enlarge int) []int {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    res := make([]int, len(nums)+enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i, num := range nums {\n        res[i] = num\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.swift
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfunc extend(nums: [Int], enlarge: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = Array(repeating: 0, count: nums.count + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for i in nums.indices {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.js
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cJavaScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums, enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.ts
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\n// \u8bf7\u6ce8\u610f\uff0cTypeScript \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n// \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\nfunction extend(nums: number[], enlarge: number): number[] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    const res = new Array(nums.length + enlarge).fill(0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (let i = 0; i < nums.length; i++) {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.dart
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nList<int> extend(List<int> nums, int enlarge) {\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  List<int> res = List.filled(nums.length + enlarge, 0);\n  // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for (var i = 0; i < nums.length; i++) {\n    res[i] = nums[i];\n  }\n  // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  return res;\n}\n
    array.rs
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfn extend(nums: Vec<i32>, enlarge: usize) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    let mut res: Vec<i32> = vec![0; nums.len() + enlarge];\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\n    for i in 0..nums.len() {\n        res[i] = nums[i];\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    res\n}\n
    array.c
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nint *extend(int *nums, int size, int enlarge) {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    int *res = (int *)malloc(sizeof(int) * (size + enlarge));\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (int i = 0; i < size; i++) {\n        res[i] = nums[i];\n    }\n    // \u521d\u59cb\u5316\u6269\u5c55\u540e\u7684\u7a7a\u95f4\n    for (int i = size; i < size + enlarge; i++) {\n        res[i] = 0;\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    array.kt
    /* \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 */\nfun extend(nums: IntArray, enlarge: Int): IntArray {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    val res = IntArray(nums.size + enlarge)\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    for (i in nums.indices) {\n        res[i] = nums[i]\n    }\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res\n}\n
    array.rb
    ### \u6269\u5c55\u6570\u7ec4\u957f\u5ea6 ###\n# \u8bf7\u6ce8\u610f\uff0cRuby \u7684 Array \u662f\u52a8\u6001\u6570\u7ec4\uff0c\u53ef\u4ee5\u76f4\u63a5\u6269\u5c55\n# \u4e3a\u4e86\u65b9\u4fbf\u5b66\u4e60\uff0c\u672c\u51fd\u6570\u5c06 Array \u770b\u4f5c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6570\u7ec4\ndef extend(nums, enlarge)\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n  res = Array.new(nums.length + enlarge, 0)\n\n  # \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n  for i in 0...nums.length\n    res[i] = nums[i]\n  end\n\n  # \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n  res\nend\n
    array.zig
    // \u6269\u5c55\u6570\u7ec4\u957f\u5ea6\nfn extend(mem_allocator: std.mem.Allocator, nums: []i32, enlarge: usize) ![]i32 {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u6269\u5c55\u957f\u5ea6\u540e\u7684\u6570\u7ec4\n    var res = try mem_allocator.alloc(i32, nums.len + enlarge);\n    @memset(res, 0);\n    // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    std.mem.copy(i32, res, nums);\n    // \u8fd4\u56de\u6269\u5c55\u540e\u7684\u65b0\u6570\u7ec4\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/array/#412","title":"4.1.2 \u00a0 \u6570\u7ec4\u7684\u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u6570\u7ec4\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u5185\uff0c\u4e14\u5143\u7d20\u7c7b\u578b\u76f8\u540c\u3002\u8fd9\u79cd\u505a\u6cd5\u5305\u542b\u4e30\u5bcc\u7684\u5148\u9a8c\u4fe1\u606f\uff0c\u7cfb\u7edf\u53ef\u4ee5\u5229\u7528\u8fd9\u4e9b\u4fe1\u606f\u6765\u4f18\u5316\u6570\u636e\u7ed3\u6784\u7684\u64cd\u4f5c\u6548\u7387\u3002

    • \u7a7a\u95f4\u6548\u7387\u9ad8\uff1a\u6570\u7ec4\u4e3a\u6570\u636e\u5206\u914d\u4e86\u8fde\u7eed\u7684\u5185\u5b58\u5757\uff0c\u65e0\u987b\u989d\u5916\u7684\u7ed3\u6784\u5f00\u9500\u3002
    • \u652f\u6301\u968f\u673a\u8bbf\u95ee\uff1a\u6570\u7ec4\u5141\u8bb8\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u8bbf\u95ee\u4efb\u4f55\u5143\u7d20\u3002
    • \u7f13\u5b58\u5c40\u90e8\u6027\uff1a\u5f53\u8bbf\u95ee\u6570\u7ec4\u5143\u7d20\u65f6\uff0c\u8ba1\u7b97\u673a\u4e0d\u4ec5\u4f1a\u52a0\u8f7d\u5b83\uff0c\u8fd8\u4f1a\u7f13\u5b58\u5176\u5468\u56f4\u7684\u5176\u4ed6\u6570\u636e\uff0c\u4ece\u800c\u501f\u52a9\u9ad8\u901f\u7f13\u5b58\u6765\u63d0\u5347\u540e\u7eed\u64cd\u4f5c\u7684\u6267\u884c\u901f\u5ea6\u3002

    \u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\u662f\u4e00\u628a\u53cc\u5203\u5251\uff0c\u5176\u5b58\u5728\u4ee5\u4e0b\u5c40\u9650\u6027\u3002

    • \u63d2\u5165\u4e0e\u5220\u9664\u6548\u7387\u4f4e\uff1a\u5f53\u6570\u7ec4\u4e2d\u5143\u7d20\u8f83\u591a\u65f6\uff0c\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u9700\u8981\u79fb\u52a8\u5927\u91cf\u7684\u5143\u7d20\u3002
    • \u957f\u5ea6\u4e0d\u53ef\u53d8\uff1a\u6570\u7ec4\u5728\u521d\u59cb\u5316\u540e\u957f\u5ea6\u5c31\u56fa\u5b9a\u4e86\uff0c\u6269\u5bb9\u6570\u7ec4\u9700\u8981\u5c06\u6240\u6709\u6570\u636e\u590d\u5236\u5230\u65b0\u6570\u7ec4\uff0c\u5f00\u9500\u5f88\u5927\u3002
    • \u7a7a\u95f4\u6d6a\u8d39\uff1a\u5982\u679c\u6570\u7ec4\u5206\u914d\u7684\u5927\u5c0f\u8d85\u8fc7\u5b9e\u9645\u6240\u9700\uff0c\u90a3\u4e48\u591a\u4f59\u7684\u7a7a\u95f4\u5c31\u88ab\u6d6a\u8d39\u4e86\u3002
    "},{"location":"chapter_array_and_linkedlist/array/#413","title":"4.1.3 \u00a0 \u6570\u7ec4\u5178\u578b\u5e94\u7528","text":"

    \u6570\u7ec4\u662f\u4e00\u79cd\u57fa\u7840\u4e14\u5e38\u89c1\u7684\u6570\u636e\u7ed3\u6784\uff0c\u65e2\u9891\u7e41\u5e94\u7528\u5728\u5404\u7c7b\u7b97\u6cd5\u4e4b\u4e2d\uff0c\u4e5f\u53ef\u7528\u4e8e\u5b9e\u73b0\u5404\u79cd\u590d\u6742\u6570\u636e\u7ed3\u6784\u3002

    • \u968f\u673a\u8bbf\u95ee\uff1a\u5982\u679c\u6211\u4eec\u60f3\u968f\u673a\u62bd\u53d6\u4e00\u4e9b\u6837\u672c\uff0c\u90a3\u4e48\u53ef\u4ee5\u7528\u6570\u7ec4\u5b58\u50a8\uff0c\u5e76\u751f\u6210\u4e00\u4e2a\u968f\u673a\u5e8f\u5217\uff0c\u6839\u636e\u7d22\u5f15\u5b9e\u73b0\u968f\u673a\u62bd\u6837\u3002
    • \u6392\u5e8f\u548c\u641c\u7d22\uff1a\u6570\u7ec4\u662f\u6392\u5e8f\u548c\u641c\u7d22\u7b97\u6cd5\u6700\u5e38\u7528\u7684\u6570\u636e\u7ed3\u6784\u3002\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u3001\u4e8c\u5206\u67e5\u627e\u7b49\u90fd\u4e3b\u8981\u5728\u6570\u7ec4\u4e0a\u8fdb\u884c\u3002
    • \u67e5\u627e\u8868\uff1a\u5f53\u9700\u8981\u5feb\u901f\u67e5\u627e\u4e00\u4e2a\u5143\u7d20\u6216\u5176\u5bf9\u5e94\u5173\u7cfb\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6570\u7ec4\u4f5c\u4e3a\u67e5\u627e\u8868\u3002\u5047\u5982\u6211\u4eec\u60f3\u5b9e\u73b0\u5b57\u7b26\u5230 ASCII \u7801\u7684\u6620\u5c04\uff0c\u5219\u53ef\u4ee5\u5c06\u5b57\u7b26\u7684 ASCII \u7801\u503c\u4f5c\u4e3a\u7d22\u5f15\uff0c\u5bf9\u5e94\u7684\u5143\u7d20\u5b58\u653e\u5728\u6570\u7ec4\u4e2d\u7684\u5bf9\u5e94\u4f4d\u7f6e\u3002
    • \u673a\u5668\u5b66\u4e60\uff1a\u795e\u7ecf\u7f51\u7edc\u4e2d\u5927\u91cf\u4f7f\u7528\u4e86\u5411\u91cf\u3001\u77e9\u9635\u3001\u5f20\u91cf\u4e4b\u95f4\u7684\u7ebf\u6027\u4ee3\u6570\u8fd0\u7b97\uff0c\u8fd9\u4e9b\u6570\u636e\u90fd\u662f\u4ee5\u6570\u7ec4\u7684\u5f62\u5f0f\u6784\u5efa\u7684\u3002\u6570\u7ec4\u662f\u795e\u7ecf\u7f51\u7edc\u7f16\u7a0b\u4e2d\u6700\u5e38\u4f7f\u7528\u7684\u6570\u636e\u7ed3\u6784\u3002
    • \u6570\u636e\u7ed3\u6784\u5b9e\u73b0\uff1a\u6570\u7ec4\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u5806\u3001\u56fe\u7b49\u6570\u636e\u7ed3\u6784\u3002\u4f8b\u5982\uff0c\u56fe\u7684\u90bb\u63a5\u77e9\u9635\u8868\u793a\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u4e8c\u7ef4\u6570\u7ec4\u3002
    "},{"location":"chapter_array_and_linkedlist/linked_list/","title":"4.2 \u00a0 \u94fe\u8868","text":"

    \u5185\u5b58\u7a7a\u95f4\u662f\u6240\u6709\u7a0b\u5e8f\u7684\u516c\u5171\u8d44\u6e90\uff0c\u5728\u4e00\u4e2a\u590d\u6742\u7684\u7cfb\u7edf\u8fd0\u884c\u73af\u5883\u4e0b\uff0c\u7a7a\u95f2\u7684\u5185\u5b58\u7a7a\u95f4\u53ef\u80fd\u6563\u843d\u5728\u5185\u5b58\u5404\u5904\u3002\u6211\u4eec\u77e5\u9053\uff0c\u5b58\u50a8\u6570\u7ec4\u7684\u5185\u5b58\u7a7a\u95f4\u5fc5\u987b\u662f\u8fde\u7eed\u7684\uff0c\u800c\u5f53\u6570\u7ec4\u975e\u5e38\u5927\u65f6\uff0c\u5185\u5b58\u53ef\u80fd\u65e0\u6cd5\u63d0\u4f9b\u5982\u6b64\u5927\u7684\u8fde\u7eed\u7a7a\u95f4\u3002\u6b64\u65f6\u94fe\u8868\u7684\u7075\u6d3b\u6027\u4f18\u52bf\u5c31\u4f53\u73b0\u51fa\u6765\u4e86\u3002

    \u94fe\u8868\uff08linked list\uff09\u662f\u4e00\u79cd\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u5176\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u8282\u70b9\u5bf9\u8c61\uff0c\u5404\u4e2a\u8282\u70b9\u901a\u8fc7\u201c\u5f15\u7528\u201d\u76f8\u8fde\u63a5\u3002\u5f15\u7528\u8bb0\u5f55\u4e86\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5185\u5b58\u5730\u5740\uff0c\u901a\u8fc7\u5b83\u53ef\u4ee5\u4ece\u5f53\u524d\u8282\u70b9\u8bbf\u95ee\u5230\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002

    \u94fe\u8868\u7684\u8bbe\u8ba1\u4f7f\u5f97\u5404\u4e2a\u8282\u70b9\u53ef\u4ee5\u5206\u6563\u5b58\u50a8\u5728\u5185\u5b58\u5404\u5904\uff0c\u5b83\u4eec\u7684\u5185\u5b58\u5730\u5740\u65e0\u987b\u8fde\u7eed\u3002

    \u56fe 4-5 \u00a0 \u94fe\u8868\u5b9a\u4e49\u4e0e\u5b58\u50a8\u65b9\u5f0f

    \u89c2\u5bdf\u56fe 4-5 \uff0c\u94fe\u8868\u7684\u7ec4\u6210\u5355\u4f4d\u662f\u8282\u70b9\uff08node\uff09\u5bf9\u8c61\u3002\u6bcf\u4e2a\u8282\u70b9\u90fd\u5305\u542b\u4e24\u9879\u6570\u636e\uff1a\u8282\u70b9\u7684\u201c\u503c\u201d\u548c\u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u201c\u5f15\u7528\u201d\u3002

    • \u94fe\u8868\u7684\u9996\u4e2a\u8282\u70b9\u88ab\u79f0\u4e3a\u201c\u5934\u8282\u70b9\u201d\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u88ab\u79f0\u4e3a\u201c\u5c3e\u8282\u70b9\u201d\u3002
    • \u5c3e\u8282\u70b9\u6307\u5411\u7684\u662f\u201c\u7a7a\u201d\uff0c\u5b83\u5728 Java\u3001C++ \u548c Python \u4e2d\u5206\u522b\u88ab\u8bb0\u4e3a null\u3001nullptr \u548c None \u3002
    • \u5728 C\u3001C++\u3001Go \u548c Rust \u7b49\u652f\u6301\u6307\u9488\u7684\u8bed\u8a00\u4e2d\uff0c\u4e0a\u8ff0\u201c\u5f15\u7528\u201d\u5e94\u88ab\u66ff\u6362\u4e3a\u201c\u6307\u9488\u201d\u3002

    \u5982\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff0c\u94fe\u8868\u8282\u70b9 ListNode \u9664\u4e86\u5305\u542b\u503c\uff0c\u8fd8\u9700\u989d\u5916\u4fdd\u5b58\u4e00\u4e2a\u5f15\u7528\uff08\u6307\u9488\uff09\u3002\u56e0\u6b64\u5728\u76f8\u540c\u6570\u636e\u91cf\u4e0b\uff0c\u94fe\u8868\u6bd4\u6570\u7ec4\u5360\u7528\u66f4\u591a\u7684\u5185\u5b58\u7a7a\u95f4\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class ListNode:\n    \"\"\"\u94fe\u8868\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val               # \u8282\u70b9\u503c\n        self.next: ListNode | None = None # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n
    /* \u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct ListNode {\n    int val;         // \u8282\u70b9\u503c\n    ListNode *next;  // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n    ListNode(int x) : val(x), next(nullptr) {}  // \u6784\u9020\u51fd\u6570\n};\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    int val;        // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    ListNode(int x) { val = x; }  // \u6784\u9020\u51fd\u6570\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode(int x) {  //\u6784\u9020\u51fd\u6570\n    int val = x;         // \u8282\u70b9\u503c\n    ListNode? next;      // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype ListNode struct {\n    Val  int       // \u8282\u70b9\u503c\n    Next *ListNode // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n}\n\n// NewListNode \u6784\u9020\u51fd\u6570\uff0c\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u94fe\u8868\nfunc NewListNode(val int) *ListNode {\n    return &ListNode{\n        Val:  val,\n        Next: nil,\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\n    init(x: Int) { // \u6784\u9020\u51fd\u6570\n        val = x\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    constructor(val, next) {\n        this.val = (val === undefined ? 0 : val);       // \u8282\u70b9\u503c\n        this.next = (next === undefined ? null : next); // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    constructor(val?: number, next?: ListNode | null) {\n        this.val = val === undefined ? 0 : val;        // \u8282\u70b9\u503c\n        this.next = next === undefined ? null : next;  // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n  int val; // \u8282\u70b9\u503c\n  ListNode? next; // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n  ListNode(this.val, [this.next]); // \u6784\u9020\u51fd\u6570\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n/* \u94fe\u8868\u8282\u70b9\u7c7b */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // \u8282\u70b9\u503c\n    next: Option<Rc<RefCell<ListNode>>>, // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct ListNode {\n    int val;               // \u8282\u70b9\u503c\n    struct ListNode *next; // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n} ListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nListNode *newListNode(int val) {\n    ListNode *node;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    return node;\n}\n
    /* \u94fe\u8868\u8282\u70b9\u7c7b */\n// \u6784\u9020\u65b9\u6cd5\nclass ListNode(x: Int) {\n    val _val: Int = x          // \u8282\u70b9\u503c\n    val next: ListNode? = null // \u6307\u5411\u4e0b\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\n}\n
    # \u94fe\u8868\u8282\u70b9\u7c7b\nclass ListNode\n  attr_accessor :val  # \u8282\u70b9\u503c\n  attr_accessor :next # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\n  def initialize(val=0, next_node=nil)\n    @val = val\n    @next = next_node\n  end\nend\n
    // \u94fe\u8868\u8282\u70b9\u7c7b\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // \u8282\u70b9\u503c\n        next: ?*Self = null, // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u6307\u9488\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n        }\n    };\n}\n
    "},{"location":"chapter_array_and_linkedlist/linked_list/#421","title":"4.2.1 \u00a0 \u94fe\u8868\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_array_and_linkedlist/linked_list/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u94fe\u8868","text":"

    \u5efa\u7acb\u94fe\u8868\u5206\u4e3a\u4e24\u6b65\uff0c\u7b2c\u4e00\u6b65\u662f\u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\u5bf9\u8c61\uff0c\u7b2c\u4e8c\u6b65\u662f\u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\u5173\u7cfb\u3002\u521d\u59cb\u5316\u5b8c\u6210\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u4ece\u94fe\u8868\u7684\u5934\u8282\u70b9\u51fa\u53d1\uff0c\u901a\u8fc7\u5f15\u7528\u6307\u5411 next \u4f9d\u6b21\u8bbf\u95ee\u6240\u6709\u8282\u70b9\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    # \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4\n# \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nn0 = ListNode(1)\nn1 = ListNode(3)\nn2 = ListNode(2)\nn3 = ListNode(5)\nn4 = ListNode(4)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.cpp
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode* n0 = new ListNode(1);\nListNode* n1 = new ListNode(3);\nListNode* n2 = new ListNode(2);\nListNode* n3 = new ListNode(5);\nListNode* n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.java
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode n0 = new ListNode(1);\nListNode n1 = new ListNode(3);\nListNode n2 = new ListNode(2);\nListNode n3 = new ListNode(5);\nListNode n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.cs
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode n0 = new(1);\nListNode n1 = new(3);\nListNode n2 = new(2);\nListNode n3 = new(5);\nListNode n4 = new(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.go
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nn0 := NewListNode(1)\nn1 := NewListNode(3)\nn2 := NewListNode(2)\nn3 := NewListNode(5)\nn4 := NewListNode(4)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.Next = n1\nn1.Next = n2\nn2.Next = n3\nn3.Next = n4\n
    linked_list.swift
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nlet n0 = ListNode(x: 1)\nlet n1 = ListNode(x: 3)\nlet n2 = ListNode(x: 2)\nlet n3 = ListNode(x: 5)\nlet n4 = ListNode(x: 4)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.js
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.ts
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nconst n0 = new ListNode(1);\nconst n1 = new ListNode(3);\nconst n2 = new ListNode(2);\nconst n3 = new ListNode(5);\nconst n4 = new ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.dart
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\\\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode n0 = ListNode(1);\nListNode n1 = ListNode(3);\nListNode n2 = ListNode(2);\nListNode n3 = ListNode(5);\nListNode n4 = ListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.rs
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nlet n0 = Rc::new(RefCell::new(ListNode { val: 1, next: None }));\nlet n1 = Rc::new(RefCell::new(ListNode { val: 3, next: None }));\nlet n2 = Rc::new(RefCell::new(ListNode { val: 2, next: None }));\nlet n3 = Rc::new(RefCell::new(ListNode { val: 5, next: None }));\nlet n4 = Rc::new(RefCell::new(ListNode { val: 4, next: None }));\n\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.borrow_mut().next = Some(n1.clone());\nn1.borrow_mut().next = Some(n2.clone());\nn2.borrow_mut().next = Some(n3.clone());\nn3.borrow_mut().next = Some(n4.clone());\n
    linked_list.c
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nListNode* n0 = newListNode(1);\nListNode* n1 = newListNode(3);\nListNode* n2 = newListNode(2);\nListNode* n3 = newListNode(5);\nListNode* n4 = newListNode(4);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0->next = n1;\nn1->next = n2;\nn2->next = n3;\nn3->next = n4;\n
    linked_list.kt
    /* \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4 */\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nval n0 = ListNode(1)\nval n1 = ListNode(3)\nval n2 = ListNode(2)\nval n3 = ListNode(5)\nval n4 = ListNode(4)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1;\nn1.next = n2;\nn2.next = n3;\nn3.next = n4;\n
    linked_list.rb
    # \u521d\u59cb\u5316\u94fe\u8868 1 -> 3 -> 2 -> 5 -> 4\n# \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nn0 = ListNode.new(1)\nn1 = ListNode.new(3)\nn2 = ListNode.new(2)\nn3 = ListNode.new(5)\nn4 = ListNode.new(4)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = n1\nn1.next = n2\nn2.next = n3\nn3.next = n4\n
    linked_list.zig
    // \u521d\u59cb\u5316\u94fe\u8868\n// \u521d\u59cb\u5316\u5404\u4e2a\u8282\u70b9\nvar n0 = inc.ListNode(i32){.val = 1};\nvar n1 = inc.ListNode(i32){.val = 3};\nvar n2 = inc.ListNode(i32){.val = 2};\nvar n3 = inc.ListNode(i32){.val = 5};\nvar n4 = inc.ListNode(i32){.val = 4};\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\nn0.next = &n1;\nn1.next = &n2;\nn2.next = &n3;\nn3.next = &n4;\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6570\u7ec4\u6574\u4f53\u662f\u4e00\u4e2a\u53d8\u91cf\uff0c\u6bd4\u5982\u6570\u7ec4 nums \u5305\u542b\u5143\u7d20 nums[0] \u548c nums[1] \u7b49\uff0c\u800c\u94fe\u8868\u662f\u7531\u591a\u4e2a\u72ec\u7acb\u7684\u8282\u70b9\u5bf9\u8c61\u7ec4\u6210\u7684\u3002\u6211\u4eec\u901a\u5e38\u5c06\u5934\u8282\u70b9\u5f53\u4f5c\u94fe\u8868\u7684\u4ee3\u79f0\uff0c\u6bd4\u5982\u4ee5\u4e0a\u4ee3\u7801\u4e2d\u7684\u94fe\u8868\u53ef\u8bb0\u4f5c\u94fe\u8868 n0 \u3002

    "},{"location":"chapter_array_and_linkedlist/linked_list/#2","title":"2. \u00a0 \u63d2\u5165\u8282\u70b9","text":"

    \u5728\u94fe\u8868\u4e2d\u63d2\u5165\u8282\u70b9\u975e\u5e38\u5bb9\u6613\u3002\u5982\u56fe 4-6 \u6240\u793a\uff0c\u5047\u8bbe\u6211\u4eec\u60f3\u5728\u76f8\u90bb\u7684\u4e24\u4e2a\u8282\u70b9 n0 \u548c n1 \u4e4b\u95f4\u63d2\u5165\u4e00\u4e2a\u65b0\u8282\u70b9 P \uff0c\u5219\u53ea\u9700\u6539\u53d8\u4e24\u4e2a\u8282\u70b9\u5f15\u7528\uff08\u6307\u9488\uff09\u5373\u53ef\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    \u76f8\u6bd4\u4e4b\u4e0b\uff0c\u5728\u6570\u7ec4\u4e2d\u63d2\u5165\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u5728\u5927\u6570\u636e\u91cf\u4e0b\u7684\u6548\u7387\u8f83\u4f4e\u3002

    \u56fe 4-6 \u00a0 \u94fe\u8868\u63d2\u5165\u8282\u70b9\u793a\u4f8b

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def insert(n0: ListNode, P: ListNode):\n    \"\"\"\u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\"\"\"\n    n1 = n0.next\n    P.next = n1\n    n0.next = P\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n    ListNode n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid Insert(ListNode n0, ListNode P) {\n    ListNode? n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insertNode(n0 *ListNode, P *ListNode) {\n    n1 := n0.Next\n    P.Next = n1\n    n0.Next = P\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunc insert(n0: ListNode, P: ListNode) {\n    let n1 = n0.next\n    P.next = n1\n    n0.next = P\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0, P) {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfunction insert(n0: ListNode, P: ListNode): void {\n    const n1 = n0.next;\n    P.next = n1;\n    n0.next = P;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode n0, ListNode P) {\n  ListNode? n1 = n0.next;\n  P.next = n1;\n  n0.next = P;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\n#[allow(non_snake_case)]\npub fn insert<T>(n0: &Rc<RefCell<ListNode<T>>>, P: Rc<RefCell<ListNode<T>>>) {\n    let n1 = n0.borrow_mut().next.take();\n    P.borrow_mut().next = n1;\n    n0.borrow_mut().next = Some(P);\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nvoid insert(ListNode *n0, ListNode *P) {\n    ListNode *n1 = n0->next;\n    P->next = n1;\n    n0->next = P;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P */\nfun insert(n0: ListNode?, p: ListNode?) {\n    val n1 = n0?.next\n    p?.next = n1\n    n0?.next = p\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 _p ###\n# Ruby \u7684 `p` \u662f\u4e00\u4e2a\u5185\u7f6e\u51fd\u6570\uff0c `P` \u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u6240\u4ee5\u53ef\u4ee5\u4f7f\u7528 `_p` \u4ee3\u66ff\ndef insert(n0, _p)\n  n1 = n0.next\n  _p.next = n1\n  n0.next = _p\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u63d2\u5165\u8282\u70b9 P\nfn insert(n0: ?*inc.ListNode(i32), P: ?*inc.ListNode(i32)) void {\n    var n1 = n0.?.next;\n    P.?.next = n1;\n    n0.?.next = P;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#3","title":"3. \u00a0 \u5220\u9664\u8282\u70b9","text":"

    \u5982\u56fe 4-7 \u6240\u793a\uff0c\u5728\u94fe\u8868\u4e2d\u5220\u9664\u8282\u70b9\u4e5f\u975e\u5e38\u65b9\u4fbf\uff0c\u53ea\u9700\u6539\u53d8\u4e00\u4e2a\u8282\u70b9\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\u5373\u53ef\u3002

    \u8bf7\u6ce8\u610f\uff0c\u5c3d\u7ba1\u5728\u5220\u9664\u64cd\u4f5c\u5b8c\u6210\u540e\u8282\u70b9 P \u4ecd\u7136\u6307\u5411 n1 \uff0c\u4f46\u5b9e\u9645\u4e0a\u904d\u5386\u6b64\u94fe\u8868\u5df2\u7ecf\u65e0\u6cd5\u8bbf\u95ee\u5230 P \uff0c\u8fd9\u610f\u5473\u7740 P \u5df2\u7ecf\u4e0d\u518d\u5c5e\u4e8e\u8be5\u94fe\u8868\u4e86\u3002

    \u56fe 4-7 \u00a0 \u94fe\u8868\u5220\u9664\u8282\u70b9

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def remove(n0: ListNode):\n    \"\"\"\u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    if not n0.next:\n        return\n    # n0 -> P -> n1\n    P = n0.next\n    n1 = P.next\n    n0.next = n1\n
    linked_list.cpp
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode *n0) {\n    if (n0->next == nullptr)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    delete P;\n}\n
    linked_list.java
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.cs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid Remove(ListNode n0) {\n    if (n0.next == null)\n        return;\n    // n0 -> P -> n1\n    ListNode P = n0.next;\n    ListNode? n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.go
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc removeItem(n0 *ListNode) {\n    if n0.Next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    P := n0.Next\n    n1 := P.Next\n    n0.Next = n1\n}\n
    linked_list.swift
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunc remove(n0: ListNode) {\n    if n0.next == nil {\n        return\n    }\n    // n0 -> P -> n1\n    let P = n0.next\n    let n1 = P?.next\n    n0.next = n1\n}\n
    linked_list.js
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0) {\n    if (!n0.next) return;\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.ts
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfunction remove(n0: ListNode): void {\n    if (!n0.next) {\n        return;\n    }\n    // n0 -> P -> n1\n    const P = n0.next;\n    const n1 = P.next;\n    n0.next = n1;\n}\n
    linked_list.dart
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nvoid remove(ListNode n0) {\n  if (n0.next == null) return;\n  // n0 -> P -> n1\n  ListNode P = n0.next!;\n  ListNode? n1 = P.next;\n  n0.next = n1;\n}\n
    linked_list.rs
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n#[allow(non_snake_case)]\npub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {\n    if n0.borrow().next.is_none() {\n        return;\n    };\n    // n0 -> P -> n1\n    let P = n0.borrow_mut().next.take();\n    if let Some(node) = P {\n        let n1 = node.borrow_mut().next.take();\n        n0.borrow_mut().next = n1;\n    }\n}\n
    linked_list.c
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nvoid removeItem(ListNode *n0) {\n    if (!n0->next)\n        return;\n    // n0 -> P -> n1\n    ListNode *P = n0->next;\n    ListNode *n1 = P->next;\n    n0->next = n1;\n    // \u91ca\u653e\u5185\u5b58\n    free(P);\n}\n
    linked_list.kt
    /* \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 */\nfun remove(n0: ListNode?) {\n    if (n0?.next == null)\n        return\n    // n0 -> P -> n1\n    val p = n0.next\n    val n1 = p?.next\n    n0.next = n1\n}\n
    linked_list.rb
    ### \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9 ###\ndef remove(n0)\n  return if n0.next.nil?\n\n  # n0 -> remove_node -> n1\n  remove_node = n0.next\n  n1 = remove_node.next\n  n0.next = n1\nend\n
    linked_list.zig
    // \u5220\u9664\u94fe\u8868\u7684\u8282\u70b9 n0 \u4e4b\u540e\u7684\u9996\u4e2a\u8282\u70b9\nfn remove(n0: ?*inc.ListNode(i32)) void {\n    if (n0.?.next == null) return;\n    // n0 -> P -> n1\n    var P = n0.?.next;\n    var n1 = P.?.next;\n    n0.?.next = n1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#4","title":"4. \u00a0 \u8bbf\u95ee\u8282\u70b9","text":"

    \u5728\u94fe\u8868\u4e2d\u8bbf\u95ee\u8282\u70b9\u7684\u6548\u7387\u8f83\u4f4e\u3002\u5982\u4e0a\u4e00\u8282\u6240\u8ff0\uff0c\u6211\u4eec\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u4e0b\u8bbf\u95ee\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u5143\u7d20\u3002\u94fe\u8868\u5219\u4e0d\u7136\uff0c\u7a0b\u5e8f\u9700\u8981\u4ece\u5934\u8282\u70b9\u51fa\u53d1\uff0c\u9010\u4e2a\u5411\u540e\u904d\u5386\uff0c\u76f4\u81f3\u627e\u5230\u76ee\u6807\u8282\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8bbf\u95ee\u94fe\u8868\u7684\u7b2c \\(i\\) \u4e2a\u8282\u70b9\u9700\u8981\u5faa\u73af \\(i - 1\\) \u8f6e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def access(head: ListNode, index: int) -> ListNode | None:\n    \"\"\"\u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\"\"\"\n    for _ in range(index):\n        if not head:\n            return None\n        head = head.next\n    return head\n
    linked_list.cpp
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == nullptr)\n            return nullptr;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.java
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode access(ListNode head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.cs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? Access(ListNode? head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == null)\n            return null;\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.go
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head *ListNode, index int) *ListNode {\n    for i := 0; i < index; i++ {\n        if head == nil {\n            return nil\n        }\n        head = head.Next\n    }\n    return head\n}\n
    linked_list.swift
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunc access(head: ListNode, index: Int) -> ListNode? {\n    var head: ListNode? = head\n    for _ in 0 ..< index {\n        if head == nil {\n            return nil\n        }\n        head = head?.next\n    }\n    return head\n}\n
    linked_list.js
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head, index) {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.ts
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfunction access(head: ListNode | null, index: number): ListNode | null {\n    for (let i = 0; i < index; i++) {\n        if (!head) {\n            return null;\n        }\n        head = head.next;\n    }\n    return head;\n}\n
    linked_list.dart
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode? access(ListNode? head, int index) {\n  for (var i = 0; i < index; i++) {\n    if (head == null) return null;\n    head = head.next;\n  }\n  return head;\n}\n
    linked_list.rs
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\npub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Rc<RefCell<ListNode<T>>> {\n    if index <= 0 {\n        return head;\n    };\n    if let Some(node) = &head.borrow().next {\n        return access(node.clone(), index - 1);\n    }\n\n    return head;\n}\n
    linked_list.c
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nListNode *access(ListNode *head, int index) {\n    for (int i = 0; i < index; i++) {\n        if (head == NULL)\n            return NULL;\n        head = head->next;\n    }\n    return head;\n}\n
    linked_list.kt
    /* \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 */\nfun access(head: ListNode?, index: Int): ListNode? {\n    var h = head\n    for (i in 0..<index) {\n        if (h == null)\n            return null\n        h = h.next\n    }\n    return h\n}\n
    linked_list.rb
    ### \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9 ###\ndef access(head, index)\n  for i in 0...index\n    return nil if head.nil?\n    head = head.next\n  end\n\n  head\nend\n
    linked_list.zig
    // \u8bbf\u95ee\u94fe\u8868\u4e2d\u7d22\u5f15\u4e3a index \u7684\u8282\u70b9\nfn access(node: ?*inc.ListNode(i32), index: i32) ?*inc.ListNode(i32) {\n    var head = node;\n    var i: i32 = 0;\n    while (i < index) : (i += 1) {\n        head = head.?.next;\n        if (head == null) return null;\n    }\n    return head;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#5","title":"5. \u00a0 \u67e5\u627e\u8282\u70b9","text":"

    \u904d\u5386\u94fe\u8868\uff0c\u67e5\u627e\u5176\u4e2d\u503c\u4e3a target \u7684\u8282\u70b9\uff0c\u8f93\u51fa\u8be5\u8282\u70b9\u5728\u94fe\u8868\u4e2d\u7684\u7d22\u5f15\u3002\u6b64\u8fc7\u7a0b\u4e5f\u5c5e\u4e8e\u7ebf\u6027\u67e5\u627e\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linked_list.py
    def find(head: ListNode, target: int) -> int:\n    \"\"\"\u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\"\"\"\n    index = 0\n    while head:\n        if head.val == target:\n            return index\n        head = head.next\n        index += 1\n    return -1\n
    linked_list.cpp
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head != nullptr) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.java
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.cs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint Find(ListNode? head, int target) {\n    int index = 0;\n    while (head != null) {\n        if (head.val == target)\n            return index;\n        head = head.next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.go
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc findNode(head *ListNode, target int) int {\n    index := 0\n    for head != nil {\n        if head.Val == target {\n            return index\n        }\n        head = head.Next\n        index++\n    }\n    return -1\n}\n
    linked_list.swift
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunc find(head: ListNode, target: Int) -> Int {\n    var head: ListNode? = head\n    var index = 0\n    while head != nil {\n        if head?.val == target {\n            return index\n        }\n        head = head?.next\n        index += 1\n    }\n    return -1\n}\n
    linked_list.js
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head, target) {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.ts
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfunction find(head: ListNode | null, target: number): number {\n    let index = 0;\n    while (head !== null) {\n        if (head.val === target) {\n            return index;\n        }\n        head = head.next;\n        index += 1;\n    }\n    return -1;\n}\n
    linked_list.dart
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode? head, int target) {\n  int index = 0;\n  while (head != null) {\n    if (head.val == target) {\n      return index;\n    }\n    head = head.next;\n    index++;\n  }\n  return -1;\n}\n
    linked_list.rs
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\npub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T, index: i32) -> i32 {\n    if head.borrow().val == target {\n        return index;\n    };\n    if let Some(node) = &head.borrow_mut().next {\n        return find(node.clone(), target, index + 1);\n    }\n    return -1;\n}\n
    linked_list.c
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nint find(ListNode *head, int target) {\n    int index = 0;\n    while (head) {\n        if (head->val == target)\n            return index;\n        head = head->next;\n        index++;\n    }\n    return -1;\n}\n
    linked_list.kt
    /* \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 */\nfun find(head: ListNode?, target: Int): Int {\n    var index = 0\n    var h = head\n    while (h != null) {\n        if (h._val == target)\n            return index\n        h = h.next\n        index++\n    }\n    return -1\n}\n
    linked_list.rb
    ### \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9 ###\ndef find(head, target)\n  index = 0\n  while head\n    return index if head.val == target\n    head = head.next\n    index += 1\n  end\n\n  -1\nend\n
    linked_list.zig
    // \u5728\u94fe\u8868\u4e2d\u67e5\u627e\u503c\u4e3a target \u7684\u9996\u4e2a\u8282\u70b9\nfn find(node: ?*inc.ListNode(i32), target: i32) i32 {\n    var head = node;\n    var index: i32 = 0;\n    while (head != null) {\n        if (head.?.val == target) return index;\n        head = head.?.next;\n        index += 1;\n    }\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/linked_list/#422-vs","title":"4.2.2 \u00a0 \u6570\u7ec4 vs. \u94fe\u8868","text":"

    \u8868 4-1 \u603b\u7ed3\u4e86\u6570\u7ec4\u548c\u94fe\u8868\u7684\u5404\u9879\u7279\u70b9\u5e76\u5bf9\u6bd4\u4e86\u64cd\u4f5c\u6548\u7387\u3002\u7531\u4e8e\u5b83\u4eec\u91c7\u7528\u4e24\u79cd\u76f8\u53cd\u7684\u5b58\u50a8\u7b56\u7565\uff0c\u56e0\u6b64\u5404\u79cd\u6027\u8d28\u548c\u64cd\u4f5c\u6548\u7387\u4e5f\u5448\u73b0\u5bf9\u7acb\u7684\u7279\u70b9\u3002

    \u8868 4-1 \u00a0 \u6570\u7ec4\u4e0e\u94fe\u8868\u7684\u6548\u7387\u5bf9\u6bd4

    \u6570\u7ec4 \u94fe\u8868 \u5b58\u50a8\u65b9\u5f0f \u8fde\u7eed\u5185\u5b58\u7a7a\u95f4 \u5206\u6563\u5185\u5b58\u7a7a\u95f4 \u5bb9\u91cf\u6269\u5c55 \u957f\u5ea6\u4e0d\u53ef\u53d8 \u53ef\u7075\u6d3b\u6269\u5c55 \u5185\u5b58\u6548\u7387 \u5143\u7d20\u5360\u7528\u5185\u5b58\u5c11\u3001\u4f46\u53ef\u80fd\u6d6a\u8d39\u7a7a\u95f4 \u5143\u7d20\u5360\u7528\u5185\u5b58\u591a \u8bbf\u95ee\u5143\u7d20 \\(O(1)\\) \\(O(n)\\) \u6dfb\u52a0\u5143\u7d20 \\(O(n)\\) \\(O(1)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(1)\\)"},{"location":"chapter_array_and_linkedlist/linked_list/#423","title":"4.2.3 \u00a0 \u5e38\u89c1\u94fe\u8868\u7c7b\u578b","text":"

    \u5982\u56fe 4-8 \u6240\u793a\uff0c\u5e38\u89c1\u7684\u94fe\u8868\u7c7b\u578b\u5305\u62ec\u4e09\u79cd\u3002

    • \u5355\u5411\u94fe\u8868\uff1a\u5373\u524d\u9762\u4ecb\u7ecd\u7684\u666e\u901a\u94fe\u8868\u3002\u5355\u5411\u94fe\u8868\u7684\u8282\u70b9\u5305\u542b\u503c\u548c\u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\u4e24\u9879\u6570\u636e\u3002\u6211\u4eec\u5c06\u9996\u4e2a\u8282\u70b9\u79f0\u4e3a\u5934\u8282\u70b9\uff0c\u5c06\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u79f0\u4e3a\u5c3e\u8282\u70b9\uff0c\u5c3e\u8282\u70b9\u6307\u5411\u7a7a None \u3002
    • \u73af\u5f62\u94fe\u8868\uff1a\u5982\u679c\u6211\u4eec\u4ee4\u5355\u5411\u94fe\u8868\u7684\u5c3e\u8282\u70b9\u6307\u5411\u5934\u8282\u70b9\uff08\u9996\u5c3e\u76f8\u63a5\uff09\uff0c\u5219\u5f97\u5230\u4e00\u4e2a\u73af\u5f62\u94fe\u8868\u3002\u5728\u73af\u5f62\u94fe\u8868\u4e2d\uff0c\u4efb\u610f\u8282\u70b9\u90fd\u53ef\u4ee5\u89c6\u4f5c\u5934\u8282\u70b9\u3002
    • \u53cc\u5411\u94fe\u8868\uff1a\u4e0e\u5355\u5411\u94fe\u8868\u76f8\u6bd4\uff0c\u53cc\u5411\u94fe\u8868\u8bb0\u5f55\u4e86\u4e24\u4e2a\u65b9\u5411\u7684\u5f15\u7528\u3002\u53cc\u5411\u94fe\u8868\u7684\u8282\u70b9\u5b9a\u4e49\u540c\u65f6\u5305\u542b\u6307\u5411\u540e\u7ee7\u8282\u70b9\uff08\u4e0b\u4e00\u4e2a\u8282\u70b9\uff09\u548c\u524d\u9a71\u8282\u70b9\uff08\u4e0a\u4e00\u4e2a\u8282\u70b9\uff09\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\u3002\u76f8\u8f83\u4e8e\u5355\u5411\u94fe\u8868\uff0c\u53cc\u5411\u94fe\u8868\u66f4\u5177\u7075\u6d3b\u6027\uff0c\u53ef\u4ee5\u671d\u4e24\u4e2a\u65b9\u5411\u904d\u5386\u94fe\u8868\uff0c\u4f46\u76f8\u5e94\u5730\u4e5f\u9700\u8981\u5360\u7528\u66f4\u591a\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class ListNode:\n    \"\"\"\u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # \u8282\u70b9\u503c\n        self.next: ListNode | None = None  # \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n        self.prev: ListNode | None = None  # \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct ListNode {\n    int val;         // \u8282\u70b9\u503c\n    ListNode *next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    ListNode *prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n    ListNode(int x) : val(x), next(nullptr), prev(nullptr) {}  // \u6784\u9020\u51fd\u6570\n};\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    int val;        // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    ListNode prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    ListNode(int x) { val = x; }  // \u6784\u9020\u51fd\u6570\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode(int x) {  // \u6784\u9020\u51fd\u6570\n    int val = x;    // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    ListNode prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype DoublyListNode struct {\n    Val  int             // \u8282\u70b9\u503c\n    Next *DoublyListNode // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    Prev *DoublyListNode // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n}\n\n// NewDoublyListNode \u521d\u59cb\u5316\nfunc NewDoublyListNode(val int) *DoublyListNode {\n    return &DoublyListNode{\n        Val:  val,\n        Next: nil,\n        Prev: nil,\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    var prev: ListNode? // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n\n    init(x: Int) { // \u6784\u9020\u51fd\u6570\n        val = x\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    constructor(val, next, prev) {\n        this.val = val  ===  undefined ? 0 : val;        // \u8282\u70b9\u503c\n        this.next = next  ===  undefined ? null : next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n        this.prev = prev  ===  undefined ? null : prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    val: number;\n    next: ListNode | null;\n    prev: ListNode | null;\n    constructor(val?: number, next?: ListNode | null, prev?: ListNode | null) {\n        this.val = val  ===  undefined ? 0 : val;        // \u8282\u70b9\u503c\n        this.next = next  ===  undefined ? null : next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n        this.prev = prev  ===  undefined ? null : prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\nclass ListNode {\n    int val;        // \u8282\u70b9\u503c\n    ListNode next;  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    ListNode prev;  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n    ListNode(this.val, [this.next, this.prev]);  // \u6784\u9020\u51fd\u6570\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\u578b */\n#[derive(Debug)]\nstruct ListNode {\n    val: i32, // \u8282\u70b9\u503c\n    next: Option<Rc<RefCell<ListNode>>>, // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    prev: Option<Rc<RefCell<ListNode>>>, // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nimpl ListNode {\n    fn new(val: i32) -> Self {\n        ListNode {\n            val,\n            next: None,\n            prev: None,\n        }\n    }\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct ListNode {\n    int val;               // \u8282\u70b9\u503c\n    struct ListNode *next; // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n    struct ListNode *prev; // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n} ListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nListNode *newListNode(int val) {\n    ListNode *node;\n    node = (ListNode *) malloc(sizeof(ListNode));\n    node->val = val;\n    node->next = NULL;\n    node->prev = NULL;\n    return node;\n}\n
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b */\n// \u6784\u9020\u65b9\u6cd5\nclass ListNode(x: Int) {\n    val _val: Int = x           // \u8282\u70b9\u503c\n    val next: ListNode? = null  // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n    val prev: ListNode? = null  // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n}\n
    # \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\nclass ListNode\n  attr_accessor :val    # \u8282\u70b9\u503c\n  attr_accessor :next   # \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u5f15\u7528\n  attr_accessor :prev   # \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u5f15\u7528\n\n  def initialize(val=0, next_node=nil, prev_node=nil)\n    @val = val\n    @next = next_node\n    @prev = prev_node\n  end\nend\n
    // \u53cc\u5411\u94fe\u8868\u8282\u70b9\u7c7b\npub fn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = 0, // \u8282\u70b9\u503c\n        next: ?*Self = null, // \u6307\u5411\u540e\u7ee7\u8282\u70b9\u7684\u6307\u9488\n        prev: ?*Self = null, // \u6307\u5411\u524d\u9a71\u8282\u70b9\u7684\u6307\u9488\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n

    \u56fe 4-8 \u00a0 \u5e38\u89c1\u94fe\u8868\u79cd\u7c7b

    "},{"location":"chapter_array_and_linkedlist/linked_list/#424","title":"4.2.4 \u00a0 \u94fe\u8868\u5178\u578b\u5e94\u7528","text":"

    \u5355\u5411\u94fe\u8868\u901a\u5e38\u7528\u4e8e\u5b9e\u73b0\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u548c\u56fe\u7b49\u6570\u636e\u7ed3\u6784\u3002

    • \u6808\u4e0e\u961f\u5217\uff1a\u5f53\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u90fd\u5728\u94fe\u8868\u7684\u4e00\u7aef\u8fdb\u884c\u65f6\uff0c\u5b83\u8868\u73b0\u7684\u7279\u6027\u4e3a\u5148\u8fdb\u540e\u51fa\uff0c\u5bf9\u5e94\u6808\uff1b\u5f53\u63d2\u5165\u64cd\u4f5c\u5728\u94fe\u8868\u7684\u4e00\u7aef\u8fdb\u884c\uff0c\u5220\u9664\u64cd\u4f5c\u5728\u94fe\u8868\u7684\u53e6\u4e00\u7aef\u8fdb\u884c\uff0c\u5b83\u8868\u73b0\u7684\u7279\u6027\u4e3a\u5148\u8fdb\u5148\u51fa\uff0c\u5bf9\u5e94\u961f\u5217\u3002
    • \u54c8\u5e0c\u8868\uff1a\u94fe\u5f0f\u5730\u5740\u662f\u89e3\u51b3\u54c8\u5e0c\u51b2\u7a81\u7684\u4e3b\u6d41\u65b9\u6848\u4e4b\u4e00\uff0c\u5728\u8be5\u65b9\u6848\u4e2d\uff0c\u6240\u6709\u51b2\u7a81\u7684\u5143\u7d20\u90fd\u4f1a\u88ab\u653e\u5230\u4e00\u4e2a\u94fe\u8868\u4e2d\u3002
    • \u56fe\uff1a\u90bb\u63a5\u8868\u662f\u8868\u793a\u56fe\u7684\u4e00\u79cd\u5e38\u7528\u65b9\u5f0f\uff0c\u5176\u4e2d\u56fe\u7684\u6bcf\u4e2a\u9876\u70b9\u90fd\u4e0e\u4e00\u4e2a\u94fe\u8868\u76f8\u5173\u8054\uff0c\u94fe\u8868\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u4ee3\u8868\u4e0e\u8be5\u9876\u70b9\u76f8\u8fde\u7684\u5176\u4ed6\u9876\u70b9\u3002

    \u53cc\u5411\u94fe\u8868\u5e38\u7528\u4e8e\u9700\u8981\u5feb\u901f\u67e5\u627e\u524d\u4e00\u4e2a\u548c\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u573a\u666f\u3002

    • \u9ad8\u7ea7\u6570\u636e\u7ed3\u6784\uff1a\u6bd4\u5982\u5728\u7ea2\u9ed1\u6811\u3001B \u6811\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u8bbf\u95ee\u8282\u70b9\u7684\u7236\u8282\u70b9\uff0c\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5728\u8282\u70b9\u4e2d\u4fdd\u5b58\u4e00\u4e2a\u6307\u5411\u7236\u8282\u70b9\u7684\u5f15\u7528\u6765\u5b9e\u73b0\uff0c\u7c7b\u4f3c\u4e8e\u53cc\u5411\u94fe\u8868\u3002
    • \u6d4f\u89c8\u5668\u5386\u53f2\uff1a\u5728\u7f51\u9875\u6d4f\u89c8\u5668\u4e2d\uff0c\u5f53\u7528\u6237\u70b9\u51fb\u524d\u8fdb\u6216\u540e\u9000\u6309\u94ae\u65f6\uff0c\u6d4f\u89c8\u5668\u9700\u8981\u77e5\u9053\u7528\u6237\u8bbf\u95ee\u8fc7\u7684\u524d\u4e00\u4e2a\u548c\u540e\u4e00\u4e2a\u7f51\u9875\u3002\u53cc\u5411\u94fe\u8868\u7684\u7279\u6027\u4f7f\u5f97\u8fd9\u79cd\u64cd\u4f5c\u53d8\u5f97\u7b80\u5355\u3002
    • LRU \u7b97\u6cd5\uff1a\u5728\u7f13\u5b58\u6dd8\u6c70\uff08LRU\uff09\u7b97\u6cd5\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u5feb\u901f\u627e\u5230\u6700\u8fd1\u6700\u5c11\u4f7f\u7528\u7684\u6570\u636e\uff0c\u4ee5\u53ca\u652f\u6301\u5feb\u901f\u6dfb\u52a0\u548c\u5220\u9664\u8282\u70b9\u3002\u8fd9\u65f6\u5019\u4f7f\u7528\u53cc\u5411\u94fe\u8868\u5c31\u975e\u5e38\u5408\u9002\u3002

    \u73af\u5f62\u94fe\u8868\u5e38\u7528\u4e8e\u9700\u8981\u5468\u671f\u6027\u64cd\u4f5c\u7684\u573a\u666f\uff0c\u6bd4\u5982\u64cd\u4f5c\u7cfb\u7edf\u7684\u8d44\u6e90\u8c03\u5ea6\u3002

    • \u65f6\u95f4\u7247\u8f6e\u8f6c\u8c03\u5ea6\u7b97\u6cd5\uff1a\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u65f6\u95f4\u7247\u8f6e\u8f6c\u8c03\u5ea6\u7b97\u6cd5\u662f\u4e00\u79cd\u5e38\u89c1\u7684 CPU \u8c03\u5ea6\u7b97\u6cd5\uff0c\u5b83\u9700\u8981\u5bf9\u4e00\u7ec4\u8fdb\u7a0b\u8fdb\u884c\u5faa\u73af\u3002\u6bcf\u4e2a\u8fdb\u7a0b\u88ab\u8d4b\u4e88\u4e00\u4e2a\u65f6\u95f4\u7247\uff0c\u5f53\u65f6\u95f4\u7247\u7528\u5b8c\u65f6\uff0cCPU \u5c06\u5207\u6362\u5230\u4e0b\u4e00\u4e2a\u8fdb\u7a0b\u3002\u8fd9\u79cd\u5faa\u73af\u64cd\u4f5c\u53ef\u4ee5\u901a\u8fc7\u73af\u5f62\u94fe\u8868\u6765\u5b9e\u73b0\u3002
    • \u6570\u636e\u7f13\u51b2\u533a\uff1a\u5728\u67d0\u4e9b\u6570\u636e\u7f13\u51b2\u533a\u7684\u5b9e\u73b0\u4e2d\uff0c\u4e5f\u53ef\u80fd\u4f1a\u4f7f\u7528\u73af\u5f62\u94fe\u8868\u3002\u6bd4\u5982\u5728\u97f3\u9891\u3001\u89c6\u9891\u64ad\u653e\u5668\u4e2d\uff0c\u6570\u636e\u6d41\u53ef\u80fd\u4f1a\u88ab\u5206\u6210\u591a\u4e2a\u7f13\u51b2\u5757\u5e76\u653e\u5165\u4e00\u4e2a\u73af\u5f62\u94fe\u8868\uff0c\u4ee5\u4fbf\u5b9e\u73b0\u65e0\u7f1d\u64ad\u653e\u3002
    "},{"location":"chapter_array_and_linkedlist/list/","title":"4.3 \u00a0 \u5217\u8868","text":"

    \u5217\u8868\uff08list\uff09\u662f\u4e00\u4e2a\u62bd\u8c61\u7684\u6570\u636e\u7ed3\u6784\u6982\u5ff5\uff0c\u5b83\u8868\u793a\u5143\u7d20\u7684\u6709\u5e8f\u96c6\u5408\uff0c\u652f\u6301\u5143\u7d20\u8bbf\u95ee\u3001\u4fee\u6539\u3001\u6dfb\u52a0\u3001\u5220\u9664\u548c\u904d\u5386\u7b49\u64cd\u4f5c\uff0c\u65e0\u987b\u4f7f\u7528\u8005\u8003\u8651\u5bb9\u91cf\u9650\u5236\u7684\u95ee\u9898\u3002\u5217\u8868\u53ef\u4ee5\u57fa\u4e8e\u94fe\u8868\u6216\u6570\u7ec4\u5b9e\u73b0\u3002

    • \u94fe\u8868\u5929\u7136\u53ef\u4ee5\u770b\u4f5c\u4e00\u4e2a\u5217\u8868\uff0c\u5176\u652f\u6301\u5143\u7d20\u589e\u5220\u67e5\u6539\u64cd\u4f5c\uff0c\u5e76\u4e14\u53ef\u4ee5\u7075\u6d3b\u52a8\u6001\u6269\u5bb9\u3002
    • \u6570\u7ec4\u4e5f\u652f\u6301\u5143\u7d20\u589e\u5220\u67e5\u6539\uff0c\u4f46\u7531\u4e8e\u5176\u957f\u5ea6\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u53ea\u80fd\u770b\u4f5c\u4e00\u4e2a\u5177\u6709\u957f\u5ea6\u9650\u5236\u7684\u5217\u8868\u3002

    \u5f53\u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\u5217\u8868\u65f6\uff0c\u957f\u5ea6\u4e0d\u53ef\u53d8\u7684\u6027\u8d28\u4f1a\u5bfc\u81f4\u5217\u8868\u7684\u5b9e\u7528\u6027\u964d\u4f4e\u3002\u8fd9\u662f\u56e0\u4e3a\u6211\u4eec\u901a\u5e38\u65e0\u6cd5\u4e8b\u5148\u786e\u5b9a\u9700\u8981\u5b58\u50a8\u591a\u5c11\u6570\u636e\uff0c\u4ece\u800c\u96be\u4ee5\u9009\u62e9\u5408\u9002\u7684\u5217\u8868\u957f\u5ea6\u3002\u82e5\u957f\u5ea6\u8fc7\u5c0f\uff0c\u5219\u5f88\u53ef\u80fd\u65e0\u6cd5\u6ee1\u8db3\u4f7f\u7528\u9700\u6c42\uff1b\u82e5\u957f\u5ea6\u8fc7\u5927\uff0c\u5219\u4f1a\u9020\u6210\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u3002

    \u4e3a\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u52a8\u6001\u6570\u7ec4\uff08dynamic array\uff09\u6765\u5b9e\u73b0\u5217\u8868\u3002\u5b83\u7ee7\u627f\u4e86\u6570\u7ec4\u7684\u5404\u9879\u4f18\u70b9\uff0c\u5e76\u4e14\u53ef\u4ee5\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u8fdb\u884c\u52a8\u6001\u6269\u5bb9\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u6807\u51c6\u5e93\u63d0\u4f9b\u7684\u5217\u8868\u662f\u57fa\u4e8e\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u7684\uff0c\u4f8b\u5982 Python \u4e2d\u7684 list \u3001Java \u4e2d\u7684 ArrayList \u3001C++ \u4e2d\u7684 vector \u548c C# \u4e2d\u7684 List \u7b49\u3002\u5728\u63a5\u4e0b\u6765\u7684\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u5c06\u628a\u201c\u5217\u8868\u201d\u548c\u201c\u52a8\u6001\u6570\u7ec4\u201d\u89c6\u4e3a\u7b49\u540c\u7684\u6982\u5ff5\u3002

    "},{"location":"chapter_array_and_linkedlist/list/#431","title":"4.3.1 \u00a0 \u5217\u8868\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_array_and_linkedlist/list/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u5217\u8868","text":"

    \u6211\u4eec\u901a\u5e38\u4f7f\u7528\u201c\u65e0\u521d\u59cb\u503c\u201d\u548c\u201c\u6709\u521d\u59cb\u503c\u201d\u8fd9\u4e24\u79cd\u521d\u59cb\u5316\u65b9\u6cd5\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u521d\u59cb\u5316\u5217\u8868\n# \u65e0\u521d\u59cb\u503c\nnums1: list[int] = []\n# \u6709\u521d\u59cb\u503c\nnums: list[int] = [1, 3, 2, 5, 4]\n
    list.cpp
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u9700\u6ce8\u610f\uff0cC++ \u4e2d vector \u5373\u662f\u672c\u6587\u63cf\u8ff0\u7684 nums\n// \u65e0\u521d\u59cb\u503c\nvector<int> nums1;\n// \u6709\u521d\u59cb\u503c\nvector<int> nums = { 1, 3, 2, 5, 4 };\n
    list.java
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nList<Integer> nums1 = new ArrayList<>();\n// \u6709\u521d\u59cb\u503c\uff08\u6ce8\u610f\u6570\u7ec4\u7684\u5143\u7d20\u7c7b\u578b\u9700\u4e3a int[] \u7684\u5305\u88c5\u7c7b Integer[]\uff09\nInteger[] numbers = new Integer[] { 1, 3, 2, 5, 4 };\nList<Integer> nums = new ArrayList<>(Arrays.asList(numbers));\n
    list.cs
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nList<int> nums1 = [];\n// \u6709\u521d\u59cb\u503c\nint[] numbers = [1, 3, 2, 5, 4];\nList<int> nums = [.. numbers];\n
    list_test.go
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nnums1 := []int{}\n// \u6709\u521d\u59cb\u503c\nnums := []int{1, 3, 2, 5, 4}\n
    list.swift
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nlet nums1: [Int] = []\n// \u6709\u521d\u59cb\u503c\nvar nums = [1, 3, 2, 5, 4]\n
    list.js
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nconst nums1 = [];\n// \u6709\u521d\u59cb\u503c\nconst nums = [1, 3, 2, 5, 4];\n
    list.ts
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nconst nums1: number[] = [];\n// \u6709\u521d\u59cb\u503c\nconst nums: number[] = [1, 3, 2, 5, 4];\n
    list.dart
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nList<int> nums1 = [];\n// \u6709\u521d\u59cb\u503c\nList<int> nums = [1, 3, 2, 5, 4];\n
    list.rs
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nlet nums1: Vec<i32> = Vec::new();\n// \u6709\u521d\u59cb\u503c\nlet nums: Vec<i32> = vec![1, 3, 2, 5, 4];\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u521d\u59cb\u5316\u5217\u8868 */\n// \u65e0\u521d\u59cb\u503c\nvar nums1 = listOf<Int>()\n// \u6709\u521d\u59cb\u503c\nvar numbers = arrayOf(1, 3, 2, 5, 4)\nvar nums = numbers.toMutableList()\n
    list.rb
    # \u521d\u59cb\u5316\u5217\u8868\n# \u65e0\u521d\u59cb\u503c\nnums1 = []\n# \u6709\u521d\u59cb\u503c\nnums = [1, 3, 2, 5, 4]\n
    list.zig
    // \u521d\u59cb\u5316\u5217\u8868\nvar nums = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums.deinit();\ntry nums.appendSlice(&[_]i32{ 1, 3, 2, 5, 4 });\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#2","title":"2. \u00a0 \u8bbf\u95ee\u5143\u7d20","text":"

    \u5217\u8868\u672c\u8d28\u4e0a\u662f\u6570\u7ec4\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u8bbf\u95ee\u548c\u66f4\u65b0\u5143\u7d20\uff0c\u6548\u7387\u5f88\u9ad8\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u8bbf\u95ee\u5143\u7d20\nnum: int = nums[1]  # \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n# \u66f4\u65b0\u5143\u7d20\nnums[1] = 0    # \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.cpp
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.java
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums.get(1);  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums.set(1, 0);  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.cs
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list_test.go
    /* \u8bbf\u95ee\u5143\u7d20 */\nnum := nums[1]  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0     // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.swift
    /* \u8bbf\u95ee\u5143\u7d20 */\nlet num = nums[1] // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0 // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.js
    /* \u8bbf\u95ee\u5143\u7d20 */\nconst num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.ts
    /* \u8bbf\u95ee\u5143\u7d20 */\nconst num: number = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.dart
    /* \u8bbf\u95ee\u5143\u7d20 */\nint num = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;  // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.rs
    /* \u8bbf\u95ee\u5143\u7d20 */\nlet num: i32 = nums[1];  // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0;             // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u8bbf\u95ee\u5143\u7d20 */\nval num = nums[1]       // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n/* \u66f4\u65b0\u5143\u7d20 */\nnums[1] = 0             // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.rb
    # \u8bbf\u95ee\u5143\u7d20\nnum = nums[1] # \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n# \u66f4\u65b0\u5143\u7d20\nnums[1] = 0 # \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    list.zig
    // \u8bbf\u95ee\u5143\u7d20\nvar num = nums.items[1]; // \u8bbf\u95ee\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\n\n// \u66f4\u65b0\u5143\u7d20\nnums.items[1] = 0; // \u5c06\u7d22\u5f15 1 \u5904\u7684\u5143\u7d20\u66f4\u65b0\u4e3a 0\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#3","title":"3. \u00a0 \u63d2\u5165\u4e0e\u5220\u9664\u5143\u7d20","text":"

    \u76f8\u8f83\u4e8e\u6570\u7ec4\uff0c\u5217\u8868\u53ef\u4ee5\u81ea\u7531\u5730\u6dfb\u52a0\u4e0e\u5220\u9664\u5143\u7d20\u3002\u5728\u5217\u8868\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff0c\u4f46\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u7684\u6548\u7387\u4ecd\u4e0e\u6570\u7ec4\u76f8\u540c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u6e05\u7a7a\u5217\u8868\nnums.clear()\n\n# \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n# \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\nnums.insert(3, 6)  # \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n# \u5220\u9664\u5143\u7d20\nnums.pop(3)        # \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.cpp
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push_back(1);\nnums.push_back(3);\nnums.push_back(2);\nnums.push_back(5);\nnums.push_back(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(nums.begin() + 3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.erase(nums.begin() + 3);      // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.java
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.add(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(3);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.cs
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.Clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.Add(1);\nnums.Add(3);\nnums.Add(2);\nnums.Add(5);\nnums.Add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.Insert(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.RemoveAt(3);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list_test.go
    /* \u6e05\u7a7a\u5217\u8868 */\nnums = nil\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums = append(nums, 1)\nnums = append(nums, 3)\nnums = append(nums, 2)\nnums = append(nums, 5)\nnums = append(nums, 4)\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums = append(nums[:3], append([]int{6}, nums[3:]...)...) // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums = append(nums[:3], nums[4:]...) // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.swift
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.removeAll()\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.append(1)\nnums.append(3)\nnums.append(2)\nnums.append(5)\nnums.append(4)\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(6, at: 3) // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(at: 3) // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.js
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.length = 0;\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.splice(3, 0, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.splice(3, 1);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.ts
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.length = 0;\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.splice(3, 0, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.splice(3, 1);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.dart
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(3, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.removeAt(3); // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.rs
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.push(1);\nnums.push(3);\nnums.push(2);\nnums.push(5);\nnums.push(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.insert(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(3);    // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u6e05\u7a7a\u5217\u8868 */\nnums.clear();\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nnums.add(1);\nnums.add(3);\nnums.add(2);\nnums.add(5);\nnums.add(4);\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nnums.add(3, 6);  // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n/* \u5220\u9664\u5143\u7d20 */\nnums.remove(3);  // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.rb
    # \u6e05\u7a7a\u5217\u8868\nnums.clear\n\n# \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\nnums << 1\nnums << 3\nnums << 2\nnums << 5\nnums << 4\n\n# \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\nnums.insert(3, 6) # \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n# \u5220\u9664\u5143\u7d20\nnums.delete_at(3) # \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    list.zig
    // \u6e05\u7a7a\u5217\u8868\nnums.clearRetainingCapacity();\n\n// \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\ntry nums.append(1);\ntry nums.append(3);\ntry nums.append(2);\ntry nums.append(5);\ntry nums.append(4);\n\n// \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\ntry nums.insert(3, 6); // \u5728\u7d22\u5f15 3 \u5904\u63d2\u5165\u6570\u5b57 6\n\n// \u5220\u9664\u5143\u7d20\n_ = nums.orderedRemove(3); // \u5220\u9664\u7d22\u5f15 3 \u5904\u7684\u5143\u7d20\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#4","title":"4. \u00a0 \u904d\u5386\u5217\u8868","text":"

    \u4e0e\u6570\u7ec4\u4e00\u6837\uff0c\u5217\u8868\u53ef\u4ee5\u6839\u636e\u7d22\u5f15\u904d\u5386\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u904d\u5386\u5404\u5143\u7d20\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\ncount = 0\nfor i in range(len(nums)):\n    count += nums[i]\n\n# \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\nfor num in nums:\n    count += num\n
    list.cpp
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (int num : nums) {\n    count += num;\n}\n
    list.java
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (int i = 0; i < nums.size(); i++) {\n    count += nums.get(i);\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\nfor (int num : nums) {\n    count += num;\n}\n
    list.cs
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (int i = 0; i < nums.Count; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nforeach (int num in nums) {\n    count += num;\n}\n
    list_test.go
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\ncount := 0\nfor i := 0; i < len(nums); i++ {\n    count += nums[i]\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0\nfor _, num := range nums {\n    count += num\n}\n
    list.swift
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nvar count = 0\nfor i in nums.indices {\n    count += nums[i]\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0\nfor num in nums {\n    count += num\n}\n
    list.js
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.ts
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nlet count = 0;\nfor (let i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (const num of nums) {\n    count += num;\n}\n
    list.dart
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nint count = 0;\nfor (var i = 0; i < nums.length; i++) {\n    count += nums[i];\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\ncount = 0;\nfor (var num in nums) {\n    count += num;\n}\n
    list.rs
    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\nlet mut _count = 0;\nfor i in 0..nums.len() {\n    _count += nums[i];\n}\n\n// \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\n_count = 0;\nfor num in &nums {\n    _count += num;\n}\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868 */\nvar count = 0\nfor (i in nums.indices) {\n    count += nums[i]\n}\n\n/* \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20 */\nfor (num in nums) {\n    count += num\n}\n
    list.rb
    # \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\ncount = 0\nfor i in 0...nums.length\n    count += nums[i]\nend\n\n# \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\ncount = 0\nfor num in nums\n    count += num\nend\n
    list.zig
    // \u901a\u8fc7\u7d22\u5f15\u904d\u5386\u5217\u8868\nvar count: i32 = 0;\nvar i: i32 = 0;\nwhile (i < nums.items.len) : (i += 1) {\n    count += nums[i];\n}\n\n// \u76f4\u63a5\u904d\u5386\u5217\u8868\u5143\u7d20\ncount = 0;\nfor (nums.items) |num| {\n    count += num;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#5","title":"5. \u00a0 \u62fc\u63a5\u5217\u8868","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u65b0\u5217\u8868 nums1 \uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5176\u62fc\u63a5\u5230\u539f\u5217\u8868\u7684\u5c3e\u90e8\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u62fc\u63a5\u4e24\u4e2a\u5217\u8868\nnums1: list[int] = [6, 8, 7, 10, 9]\nnums += nums1  # \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.cpp
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nvector<int> nums1 = { 6, 8, 7, 10, 9 };\n// \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\nnums.insert(nums.end(), nums1.begin(), nums1.end());\n
    list.java
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nList<Integer> nums1 = new ArrayList<>(Arrays.asList(new Integer[] { 6, 8, 7, 10, 9 }));\nnums.addAll(nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.cs
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.AddRange(nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list_test.go
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nnums1 := []int{6, 8, 7, 10, 9}\nnums = append(nums, nums1...)  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.swift
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nlet nums1 = [6, 8, 7, 10, 9]\nnums.append(contentsOf: nums1) // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.js
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nconst nums1 = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.ts
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nconst nums1: number[] = [6, 8, 7, 10, 9];\nnums.push(...nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.dart
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nList<int> nums1 = [6, 8, 7, 10, 9];\nnums.addAll(nums1);  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.rs
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nlet nums1: Vec<i32> = vec![6, 8, 7, 10, 9];\nnums.extend(nums1);\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u62fc\u63a5\u4e24\u4e2a\u5217\u8868 */\nval nums1 = intArrayOf(6, 8, 7, 10, 9).toMutableList()\nnums.addAll(nums1)  // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    list.rb
    # \u62fc\u63a5\u4e24\u4e2a\u5217\u8868\nnums1 = [6, 8, 7, 10, 9]\nnums += nums1\n
    list.zig
    // \u62fc\u63a5\u4e24\u4e2a\u5217\u8868\nvar nums1 = std.ArrayList(i32).init(std.heap.page_allocator);\ndefer nums1.deinit();\ntry nums1.appendSlice(&[_]i32{ 6, 8, 7, 10, 9 });\ntry nums.insertSlice(nums.items.len, nums1.items); // \u5c06\u5217\u8868 nums1 \u62fc\u63a5\u5230 nums \u4e4b\u540e\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#6","title":"6. \u00a0 \u6392\u5e8f\u5217\u8868","text":"

    \u5b8c\u6210\u5217\u8868\u6392\u5e8f\u540e\uff0c\u6211\u4eec\u4fbf\u53ef\u4ee5\u4f7f\u7528\u5728\u6570\u7ec4\u7c7b\u7b97\u6cd5\u9898\u4e2d\u7ecf\u5e38\u8003\u67e5\u7684\u201c\u4e8c\u5206\u67e5\u627e\u201d\u548c\u201c\u53cc\u6307\u9488\u201d\u7b97\u6cd5\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig list.py
    # \u6392\u5e8f\u5217\u8868\nnums.sort()  # \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.cpp
    /* \u6392\u5e8f\u5217\u8868 */\nsort(nums.begin(), nums.end());  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.java
    /* \u6392\u5e8f\u5217\u8868 */\nCollections.sort(nums);  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.cs
    /* \u6392\u5e8f\u5217\u8868 */\nnums.Sort(); // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list_test.go
    /* \u6392\u5e8f\u5217\u8868 */\nsort.Ints(nums)  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.swift
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort() // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.js
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort((a, b) => a - b);  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.ts
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort((a, b) => a - b);  // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.dart
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort(); // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.rs
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort(); // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u52a8\u6001\u6570\u7ec4\n
    list.kt
    /* \u6392\u5e8f\u5217\u8868 */\nnums.sort() // \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.rb
    # \u6392\u5e8f\u5217\u8868\nnums = nums.sort { |a, b| a <=> b } # \u6392\u5e8f\u540e\uff0c\u5217\u8868\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u6392\u5217\n
    list.zig
    // \u6392\u5e8f\u5217\u8868\nstd.sort.sort(i32, nums.items, {}, comptime std.sort.asc(i32));\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/list/#432","title":"4.3.2 \u00a0 \u5217\u8868\u5b9e\u73b0","text":"

    \u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u5185\u7f6e\u4e86\u5217\u8868\uff0c\u4f8b\u5982 Java\u3001C++\u3001Python \u7b49\u3002\u5b83\u4eec\u7684\u5b9e\u73b0\u6bd4\u8f83\u590d\u6742\uff0c\u5404\u4e2a\u53c2\u6570\u7684\u8bbe\u5b9a\u4e5f\u975e\u5e38\u8003\u7a76\uff0c\u4f8b\u5982\u521d\u59cb\u5bb9\u91cf\u3001\u6269\u5bb9\u500d\u6570\u7b49\u3002\u611f\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u67e5\u9605\u6e90\u7801\u8fdb\u884c\u5b66\u4e60\u3002

    \u4e3a\u4e86\u52a0\u6df1\u5bf9\u5217\u8868\u5de5\u4f5c\u539f\u7406\u7684\u7406\u89e3\uff0c\u6211\u4eec\u5c1d\u8bd5\u5b9e\u73b0\u4e00\u4e2a\u7b80\u6613\u7248\u5217\u8868\uff0c\u5305\u62ec\u4ee5\u4e0b\u4e09\u4e2a\u91cd\u70b9\u8bbe\u8ba1\u3002

    • \u521d\u59cb\u5bb9\u91cf\uff1a\u9009\u53d6\u4e00\u4e2a\u5408\u7406\u7684\u6570\u7ec4\u521d\u59cb\u5bb9\u91cf\u3002\u5728\u672c\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u9009\u62e9 10 \u4f5c\u4e3a\u521d\u59cb\u5bb9\u91cf\u3002
    • \u6570\u91cf\u8bb0\u5f55\uff1a\u58f0\u660e\u4e00\u4e2a\u53d8\u91cf size \uff0c\u7528\u4e8e\u8bb0\u5f55\u5217\u8868\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff0c\u5e76\u968f\u7740\u5143\u7d20\u63d2\u5165\u548c\u5220\u9664\u5b9e\u65f6\u66f4\u65b0\u3002\u6839\u636e\u6b64\u53d8\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4f4d\u5217\u8868\u5c3e\u90e8\uff0c\u4ee5\u53ca\u5224\u65ad\u662f\u5426\u9700\u8981\u6269\u5bb9\u3002
    • \u6269\u5bb9\u673a\u5236\uff1a\u82e5\u63d2\u5165\u5143\u7d20\u65f6\u5217\u8868\u5bb9\u91cf\u5df2\u6ee1\uff0c\u5219\u9700\u8981\u8fdb\u884c\u6269\u5bb9\u3002\u5148\u6839\u636e\u6269\u5bb9\u500d\u6570\u521b\u5efa\u4e00\u4e2a\u66f4\u5927\u7684\u6570\u7ec4\uff0c\u518d\u5c06\u5f53\u524d\u6570\u7ec4\u7684\u6240\u6709\u5143\u7d20\u4f9d\u6b21\u79fb\u52a8\u81f3\u65b0\u6570\u7ec4\u3002\u5728\u672c\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u89c4\u5b9a\u6bcf\u6b21\u5c06\u6570\u7ec4\u6269\u5bb9\u81f3\u4e4b\u524d\u7684 2 \u500d\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_list.py
    class MyList:\n    \"\"\"\u5217\u8868\u7c7b\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._capacity: int = 10  # \u5217\u8868\u5bb9\u91cf\n        self._arr: list[int] = [0] * self._capacity  # \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        self._size: int = 0  # \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        self._extend_ratio: int = 2  # \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\"\"\"\n        return self._size\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u5217\u8868\u5bb9\u91cf\"\"\"\n        return self._capacity\n\n    def get(self, index: int) -> int:\n        \"\"\"\u8bbf\u95ee\u5143\u7d20\"\"\"\n        # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        return self._arr[index]\n\n    def set(self, num: int, index: int):\n        \"\"\"\u66f4\u65b0\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        self._arr[index] = num\n\n    def add(self, num: int):\n        \"\"\"\u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\"\"\"\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size() == self.capacity():\n            self.extend_capacity()\n        self._arr[self._size] = num\n        self._size += 1\n\n    def insert(self, num: int, index: int):\n        \"\"\"\u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self._size == self.capacity():\n            self.extend_capacity()\n        # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in range(self._size - 1, index - 1, -1):\n            self._arr[j + 1] = self._arr[j]\n        self._arr[index] = num\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size += 1\n\n    def remove(self, index: int) -> int:\n        \"\"\"\u5220\u9664\u5143\u7d20\"\"\"\n        if index < 0 or index >= self._size:\n            raise IndexError(\"\u7d22\u5f15\u8d8a\u754c\")\n        num = self._arr[index]\n        # \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in range(index, self._size - 1):\n            self._arr[j] = self._arr[j + 1]\n        # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self._size -= 1\n        # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n\n    def extend_capacity(self):\n        \"\"\"\u5217\u8868\u6269\u5bb9\"\"\"\n        # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1)\n        # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self._capacity = len(self._arr)\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868\"\"\"\n        return self._arr[: self._size]\n
    my_list.cpp
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  private:\n    int *arr;             // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int arrCapacity = 10; // \u5217\u8868\u5bb9\u91cf\n    int arrSize = 0;      // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    int extendRatio = 2;   // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~MyList() {\n        delete[] arr;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    int size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    int capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    void set(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        arr[size()] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    void insert(int index, int num) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size() == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size() - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    int remove(int index) {\n        if (index < 0 || index >= size())\n            throw out_of_range(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size() - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n        int newCapacity = capacity() * extendRatio;\n        int *tmp = arr;\n        arr = new int[newCapacity];\n        // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            arr[i] = tmp[i];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete[] tmp;\n        arrCapacity = newCapacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Vector \u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> vec(size());\n        for (int i = 0; i < size(); i++) {\n            vec[i] = arr[i];\n        }\n        return vec;\n    }\n};\n
    my_list.java
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    private int size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private int extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[capacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    public int size() {\n        return size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int capacity() {\n        return capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void set(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        arr[size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void insert(int index, int num) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = size - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int remove(int index) {\n        if (index < 0 || index >= size)\n            throw new IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < size - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = Arrays.copyOf(arr, capacity() * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] toArray() {\n        int size = size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[size];\n        for (int i = 0; i < size; i++) {\n            arr[i] = get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.cs
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private int[] arr;           // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private int arrCapacity = 10;    // \u5217\u8868\u5bb9\u91cf\n    private int arrSize = 0;         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private readonly int extendRatio = 2;  // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public MyList() {\n        arr = new int[arrCapacity];\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public int Size() {\n        return arrSize;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public int Capacity() {\n        return arrCapacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public int Get(int index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        return arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public void Set(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public void Add(int num) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        arr[arrSize] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public void Insert(int index, int num) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (arrSize == arrCapacity)\n            ExtendCapacity();\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (int j = arrSize - 1; j >= index; j--) {\n            arr[j + 1] = arr[j];\n        }\n        arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public int Remove(int index) {\n        if (index < 0 || index >= arrSize)\n            throw new IndexOutOfRangeException(\"\u7d22\u5f15\u8d8a\u754c\");\n        int num = arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (int j = index; j < arrSize - 1; j++) {\n            arr[j] = arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        arrSize--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public void ExtendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a arrCapacity * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        Array.Resize(ref arr, arrCapacity * extendRatio);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        arrCapacity = arr.Length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] arr = new int[arrSize];\n        for (int i = 0; i < arrSize; i++) {\n            arr[i] = Get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.go
    /* \u5217\u8868\u7c7b */\ntype myList struct {\n    arrCapacity int\n    arr         []int\n    arrSize     int\n    extendRatio int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newMyList() *myList {\n    return &myList{\n        arrCapacity: 10,              // \u5217\u8868\u5bb9\u91cf\n        arr:         make([]int, 10), // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrSize:     0,               // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: 2,               // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n    }\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\nfunc (l *myList) size() int {\n    return l.arrSize\n}\n\n/*  \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nfunc (l *myList) capacity() int {\n    return l.arrCapacity\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nfunc (l *myList) get(index int) int {\n    // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    return l.arr[index]\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nfunc (l *myList) set(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    l.arr[index] = num\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nfunc (l *myList) add(num int) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    l.arr[l.arrSize] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nfunc (l *myList) insert(num, index int) {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if l.arrSize == l.arrCapacity {\n        l.extendCapacity()\n    }\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j := l.arrSize - 1; j >= index; j-- {\n        l.arr[j+1] = l.arr[j]\n    }\n    l.arr[index] = num\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize++\n}\n\n/* \u5220\u9664\u5143\u7d20 */\nfunc (l *myList) remove(index int) int {\n    if index < 0 || index >= l.arrSize {\n        panic(\"\u7d22\u5f15\u8d8a\u754c\")\n    }\n    num := l.arr[index]\n    // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j := index; j < l.arrSize-1; j++ {\n        l.arr[j] = l.arr[j+1]\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    l.arrSize--\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return num\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nfunc (l *myList) extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    l.arr = append(l.arr, make([]int, l.arrCapacity*(l.extendRatio-1))...)\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    l.arrCapacity = len(l.arr)\n}\n\n/* \u8fd4\u56de\u6709\u6548\u957f\u5ea6\u7684\u5217\u8868 */\nfunc (l *myList) toArray() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    return l.arr[:l.arrSize]\n}\n
    my_list.swift
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: [Int] // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var _capacity: Int // \u5217\u8868\u5bb9\u91cf\n    private var _size: Int // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private let extendRatio: Int // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        _capacity = 10\n        _size = 0\n        extendRatio = 2\n        arr = Array(repeating: 0, count: _capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    func size() -> Int {\n        _size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    func capacity() -> Int {\n        _capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    func get(index: Int) -> Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\u5219\u629b\u51fa\u9519\u8bef\uff0c\u4e0b\u540c\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    func set(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    func add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        arr[size()] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    func insert(index: Int, num: Int) {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if size() == capacity() {\n            extendCapacity()\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index ..< size()).reversed() {\n            arr[j + 1] = arr[j]\n        }\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size += 1\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    @discardableResult\n    func remove(index: Int) -> Int {\n        if index < 0 || index >= size() {\n            fatalError(\"\u7d22\u5f15\u8d8a\u754c\")\n        }\n        let num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in index ..< (size() - 1) {\n            arr[j] = arr[j + 1]\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        _size -= 1\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    func extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr + Array(repeating: 0, count: capacity() * (extendRatio - 1))\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        _capacity = arr.count\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        Array(arr.prefix(size()))\n    }\n}\n
    my_list.js
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    #arr = new Array(); // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    #capacity = 10; // \u5217\u8868\u5bb9\u91cf\n    #size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    #extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#arr = new Array(this.#capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    size() {\n        return this.#size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    capacity() {\n        return this.#capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    get(index) {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.#arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    set(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.#arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    add(num) {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.#arr[this.#size] = num;\n        this.#size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    insert(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this.#size - 1; j >= index; j--) {\n            this.#arr[j + 1] = this.#arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#arr[index] = num;\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    remove(index) {\n        if (index < 0 || index >= this.#size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.#arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this.#size - 1; j++) {\n            this.#arr[j] = this.#arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.#size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.#arr = this.#arr.concat(\n            new Array(this.capacity() * (this.#extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this.#capacity = this.#arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    toArray() {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.ts
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private arr: Array<number>; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private _capacity: number = 10; // \u5217\u8868\u5bb9\u91cf\n    private _size: number = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private extendRatio: number = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.arr = new Array(this._capacity);\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    public size(): number {\n        return this._size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    public capacity(): number {\n        return this._capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    public get(index: number): number {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        return this.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    public set(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        this.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    public add(num: number): void {\n        // \u5982\u679c\u957f\u5ea6\u7b49\u4e8e\u5bb9\u91cf\uff0c\u5219\u9700\u8981\u6269\u5bb9\n        if (this._size === this._capacity) this.extendCapacity();\n        // \u5c06\u65b0\u5143\u7d20\u6dfb\u52a0\u5230\u5217\u8868\u5c3e\u90e8\n        this.arr[this._size] = num;\n        this._size++;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    public insert(index: number, num: number): void {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (this._size === this._capacity) {\n            this.extendCapacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (let j = this._size - 1; j >= index; j--) {\n            this.arr[j + 1] = this.arr[j];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this.arr[index] = num;\n        this._size++;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    public remove(index: number): number {\n        if (index < 0 || index >= this._size) throw new Error('\u7d22\u5f15\u8d8a\u754c');\n        let num = this.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (let j = index; j < this._size - 1; j++) {\n            this.arr[j] = this.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        this._size--;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    public extendCapacity(): void {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        this.arr = this.arr.concat(\n            new Array(this.capacity() * (this.extendRatio - 1))\n        );\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        this._capacity = this.arr.length;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    public toArray(): number[] {\n        let size = this.size();\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(size);\n        for (let i = 0; i < size; i++) {\n            arr[i] = this.get(i);\n        }\n        return arr;\n    }\n}\n
    my_list.dart
    /* \u5217\u8868\u7c7b */\nclass MyList {\n  late List<int> _arr; // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n  int _capacity = 10; // \u5217\u8868\u5bb9\u91cf\n  int _size = 0; // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  int _extendRatio = 2; // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  MyList() {\n    _arr = List.filled(_capacity, 0);\n  }\n\n  /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n  int size() => _size;\n\n  /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n  int capacity() => _capacity;\n\n  /* \u8bbf\u95ee\u5143\u7d20 */\n  int get(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    return _arr[index];\n  }\n\n  /* \u66f4\u65b0\u5143\u7d20 */\n  void set(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    _arr[index] = _num;\n  }\n\n  /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n  void add(int _num) {\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    _arr[_size] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n  void insert(int index, int _num) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (_size == _capacity) extendCapacity();\n    // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for (var j = _size - 1; j >= index; j--) {\n      _arr[j + 1] = _arr[j];\n    }\n    _arr[index] = _num;\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size++;\n  }\n\n  /* \u5220\u9664\u5143\u7d20 */\n  int remove(int index) {\n    if (index >= _size) throw RangeError('\u7d22\u5f15\u8d8a\u754c');\n    int _num = _arr[index];\n    // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for (var j = index; j < _size - 1; j++) {\n      _arr[j] = _arr[j + 1];\n    }\n    // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    _size--;\n    // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    return _num;\n  }\n\n  /* \u5217\u8868\u6269\u5bb9 */\n  void extendCapacity() {\n    // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 _extendRatio \u500d\u7684\u65b0\u6570\u7ec4\n    final _newNums = List.filled(_capacity * _extendRatio, 0);\n    // \u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    List.copyRange(_newNums, 0, _arr);\n    // \u66f4\u65b0 _arr \u7684\u5f15\u7528\n    _arr = _newNums;\n    // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    _capacity = _arr.length;\n  }\n\n  /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n  List<int> toArray() {\n    List<int> arr = [];\n    for (var i = 0; i < _size; i++) {\n      arr.add(get(i));\n    }\n    return arr;\n  }\n}\n
    my_list.rs
    /* \u5217\u8868\u7c7b */\n#[allow(dead_code)]\nstruct MyList {\n    arr: Vec<i32>,       // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    capacity: usize,     // \u5217\u8868\u5bb9\u91cf\n    size: usize,         // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    extend_ratio: usize, // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n}\n\n#[allow(unused, unused_comparisons)]\nimpl MyList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        let mut vec = Vec::new();\n        vec.resize(capacity, 0);\n        Self {\n            arr: vec,\n            capacity,\n            size: 0,\n            extend_ratio: 2,\n        }\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09*/\n    pub fn size(&self) -> usize {\n        return self.size;\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        return self.capacity;\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    pub fn get(&self, index: usize) -> i32 {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        return self.arr[index];\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    pub fn set(&mut self, index: usize, num: i32) {\n        if index >= self.size {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        self.arr[index] = num;\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    pub fn add(&mut self, num: i32) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        self.arr[self.size] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    pub fn insert(&mut self, index: usize, num: i32) {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if self.size == self.capacity() {\n            self.extend_capacity();\n        }\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size).rev() {\n            self.arr[j + 1] = self.arr[j];\n        }\n        self.arr[index] = num;\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    pub fn remove(&mut self, index: usize) -> i32 {\n        if index >= self.size() {\n            panic!(\"\u7d22\u5f15\u8d8a\u754c\")\n        };\n        let num = self.arr[index];\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for j in (index..self.size - 1) {\n            self.arr[j] = self.arr[j + 1];\n        }\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        self.size -= 1;\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num;\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    pub fn extend_capacity(&mut self) {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        let new_capacity = self.capacity * self.extend_ratio;\n        self.arr.resize(new_capacity, 0);\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        self.capacity = new_capacity;\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    pub fn to_array(&mut self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut arr = Vec::new();\n        for i in 0..self.size {\n            arr.push(self.get(i));\n        }\n        arr\n    }\n}\n
    my_list.c
    /* \u5217\u8868\u7c7b */\ntypedef struct {\n    int *arr;        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    int capacity;    // \u5217\u8868\u5bb9\u91cf\n    int size;        // \u5217\u8868\u5927\u5c0f\n    int extendRatio; // \u5217\u8868\u6bcf\u6b21\u6269\u5bb9\u7684\u500d\u6570\n} MyList;\n\n/* \u6784\u9020\u51fd\u6570 */\nMyList *newMyList() {\n    MyList *nums = malloc(sizeof(MyList));\n    nums->capacity = 10;\n    nums->arr = malloc(sizeof(int) * nums->capacity);\n    nums->size = 0;\n    nums->extendRatio = 2;\n    return nums;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delMyList(MyList *nums) {\n    free(nums->arr);\n    free(nums);\n}\n\n/* \u83b7\u53d6\u5217\u8868\u957f\u5ea6 */\nint size(MyList *nums) {\n    return nums->size;\n}\n\n/* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\nint capacity(MyList *nums) {\n    return nums->capacity;\n}\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint get(MyList *nums, int index) {\n    assert(index >= 0 && index < nums->size);\n    return nums->arr[index];\n}\n\n/* \u66f4\u65b0\u5143\u7d20 */\nvoid set(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < nums->size);\n    nums->arr[index] = num;\n}\n\n/* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\nvoid add(MyList *nums, int num) {\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    nums->arr[size(nums)] = num;\n    nums->size++;\n}\n\n/* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\nvoid insert(MyList *nums, int index, int num) {\n    assert(index >= 0 && index < size(nums));\n    // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    if (size(nums) == capacity(nums)) {\n        extendCapacity(nums); // \u6269\u5bb9\n    }\n    for (int i = size(nums); i > index; --i) {\n        nums->arr[i] = nums->arr[i - 1];\n    }\n    nums->arr[index] = num;\n    nums->size++;\n}\n\n/* \u5220\u9664\u5143\u7d20 */\n// \u6ce8\u610f\uff1astdio.h \u5360\u7528\u4e86 remove \u5173\u952e\u8bcd\nint removeItem(MyList *nums, int index) {\n    assert(index >= 0 && index < size(nums));\n    int num = nums->arr[index];\n    for (int i = index; i < size(nums) - 1; i++) {\n        nums->arr[i] = nums->arr[i + 1];\n    }\n    nums->size--;\n    return num;\n}\n\n/* \u5217\u8868\u6269\u5bb9 */\nvoid extendCapacity(MyList *nums) {\n    // \u5148\u5206\u914d\u7a7a\u95f4\n    int newCapacity = capacity(nums) * nums->extendRatio;\n    int *extend = (int *)malloc(sizeof(int) * newCapacity);\n    int *temp = nums->arr;\n\n    // \u62f7\u8d1d\u65e7\u6570\u636e\u5230\u65b0\u6570\u636e\n    for (int i = 0; i < size(nums); i++)\n        extend[i] = nums->arr[i];\n\n    // \u91ca\u653e\u65e7\u6570\u636e\n    free(temp);\n\n    // \u66f4\u65b0\u65b0\u6570\u636e\n    nums->arr = extend;\n    nums->capacity = newCapacity;\n}\n\n/* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a Array \u7528\u4e8e\u6253\u5370 */\nint *toArray(MyList *nums) {\n    return nums->arr;\n}\n
    my_list.kt
    /* \u5217\u8868\u7c7b */\nclass MyList {\n    private var arr: IntArray = intArrayOf() // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n    private var capacity: Int = 10 // \u5217\u8868\u5bb9\u91cf\n    private var size: Int = 0 // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n    private var extendRatio: Int = 2 // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        arr = IntArray(capacity)\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09 */\n    fun size(): Int {\n        return size\n    }\n\n    /* \u83b7\u53d6\u5217\u8868\u5bb9\u91cf */\n    fun capacity(): Int {\n        return capacity\n    }\n\n    /* \u8bbf\u95ee\u5143\u7d20 */\n    fun get(index: Int): Int {\n        // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        return arr[index]\n    }\n\n    /* \u66f4\u65b0\u5143\u7d20 */\n    fun set(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        arr[index] = num\n    }\n\n    /* \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 */\n    fun add(num: Int) {\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        arr[size] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 */\n    fun insert(index: Int, num: Int) {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n        if (size == capacity())\n            extendCapacity()\n        // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        for (j in size - 1 downTo index)\n            arr[j + 1] = arr[j]\n        arr[index] = num\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size++\n    }\n\n    /* \u5220\u9664\u5143\u7d20 */\n    fun remove(index: Int): Int {\n        if (index < 0 || index >= size)\n            throw IndexOutOfBoundsException(\"\u7d22\u5f15\u8d8a\u754c\")\n        val num = arr[index]\n        // \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n        for (j in index..<size - 1)\n            arr[j] = arr[j + 1]\n        // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n        size--\n        // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n        return num\n    }\n\n    /* \u5217\u8868\u6269\u5bb9 */\n    fun extendCapacity() {\n        // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extendRatio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n        arr = arr.copyOf(capacity() * extendRatio)\n        // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n        capacity = arr.size\n    }\n\n    /* \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        val size = size()\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val arr = IntArray(size)\n        for (i in 0..<size) {\n            arr[i] = get(i)\n        }\n        return arr\n    }\n}\n
    my_list.rb
    ### \u5217\u8868\u7c7b ###\nclass MyList\n  attr_reader :size       # \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n  attr_reader :capacity   # \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @capacity = 10\n    @size = 0\n    @extend_ratio = 2\n    @arr = Array.new(capacity)\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def get(index)\n    # \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index]\n  end\n\n  ### \u8bbf\u95ee\u5143\u7d20 ###\n  def set(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    @arr[index] = num\n  end\n\n  ### \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20 ###\n  def add(num)\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n    @arr[size] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20 ###\n  def insert(index, num)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n\n    # \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n    extend_capacity if size == capacity\n\n    # \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    for j in (size - 1).downto(index)\n      @arr[j + 1] = @arr[j]\n    end\n    @arr[index] = num\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size += 1\n  end\n\n  ### \u5220\u9664\u5143\u7d20 ###\n  def remove(index)\n    raise IndexError, \"\u7d22\u5f15\u8d8a\u754c\" if index < 0 || index >= size\n    num = @arr[index]\n\n    # \u5c06\u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n    for j in index...size\n      @arr[j] = @arr[j + 1]\n    end\n\n    # \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n    @size -= 1\n\n    # \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n    num\n  end\n\n  ### \u5217\u8868\u6269\u5bb9 ###\n  def extend_capacity\n    # \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a\u539f\u6570\u7ec4 extend_ratio \u500d\u7684\u65b0\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n    arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1))\n    # \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n    @capacity = arr.length\n  end\n\n  ### \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4 ###\n  def to_array\n    sz = size\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    arr = Array.new(sz)\n    for i in 0...sz\n      arr[i] = get(i)\n    end\n    arr\n  end\nend\n
    my_list.zig
    // \u5217\u8868\u7c7b\nfn MyList(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        arr: []T = undefined,                        // \u6570\u7ec4\uff08\u5b58\u50a8\u5217\u8868\u5143\u7d20\uff09\n        arrCapacity: usize = 10,                     // \u5217\u8868\u5bb9\u91cf\n        numSize: usize = 0,                           // \u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        extendRatio: usize = 2,                       // \u6bcf\u6b21\u5217\u8868\u6269\u5bb9\u7684\u500d\u6570\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined, // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u5217\u8868\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.arr = try self.mem_allocator.alloc(T, self.arrCapacity);\n            @memset(self.arr, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u957f\u5ea6\uff08\u5f53\u524d\u5143\u7d20\u6570\u91cf\uff09\n        pub fn size(self: *Self) usize {\n            return self.numSize;\n        }\n\n        // \u83b7\u53d6\u5217\u8868\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.arrCapacity;\n        }\n\n        // \u8bbf\u95ee\u5143\u7d20\n        pub fn get(self: *Self, index: usize) T {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            return self.arr[index];\n        }  \n\n        // \u66f4\u65b0\u5143\u7d20\n        pub fn set(self: *Self, index: usize, num: T) void {\n            // \u7d22\u5f15\u5982\u679c\u8d8a\u754c\uff0c\u5219\u629b\u51fa\u5f02\u5e38\uff0c\u4e0b\u540c\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            self.arr[index] = num;\n        }  \n\n        // \u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\n        pub fn add(self: *Self, num: T) !void {\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            self.arr[self.size()] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }  \n\n        // \u5728\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\n        pub fn insert(self: *Self, index: usize, num: T) !void {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            // \u5143\u7d20\u6570\u91cf\u8d85\u51fa\u5bb9\u91cf\u65f6\uff0c\u89e6\u53d1\u6269\u5bb9\u673a\u5236\n            if (self.size() == self.capacity()) try self.extendCapacity();\n            // \u5c06\u7d22\u5f15 index \u4ee5\u53ca\u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n            var j = self.size() - 1;\n            while (j >= index) : (j -= 1) {\n                self.arr[j + 1] = self.arr[j];\n            }\n            self.arr[index] = num;\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize += 1;\n        }\n\n        // \u5220\u9664\u5143\u7d20\n        pub fn remove(self: *Self, index: usize) T {\n            if (index < 0 or index >= self.size()) @panic(\"\u7d22\u5f15\u8d8a\u754c\");\n            var num = self.arr[index];\n            // \u5c06\u7d22\u5f15 index \u4e4b\u540e\u7684\u5143\u7d20\u90fd\u5411\u524d\u79fb\u52a8\u4e00\u4f4d\n            var j = index;\n            while (j < self.size() - 1) : (j += 1) {\n                self.arr[j] = self.arr[j + 1];\n            }\n            // \u66f4\u65b0\u5143\u7d20\u6570\u91cf\n            self.numSize -= 1;\n            // \u8fd4\u56de\u88ab\u5220\u9664\u7684\u5143\u7d20\n            return num;\n        }\n\n        // \u5217\u8868\u6269\u5bb9\n        pub fn extendCapacity(self: *Self) !void {\n            // \u65b0\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a size * extendRatio \u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u539f\u6570\u7ec4\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            var newCapacity = self.capacity() * self.extendRatio;\n            var extend = try self.mem_allocator.alloc(T, newCapacity);\n            @memset(extend, @as(T, 0));\n            // \u5c06\u539f\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\u590d\u5236\u5230\u65b0\u6570\u7ec4\n            std.mem.copy(T, extend, self.arr);\n            self.arr = extend;\n            // \u66f4\u65b0\u5217\u8868\u5bb9\u91cf\n            self.arrCapacity = newCapacity;\n        }\n\n        // \u5c06\u5217\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var arr = try self.mem_allocator.alloc(T, self.size());\n           @memset(arr, @as(T, 0));\n            for (arr, 0..) |*num, i| {\n                num.* = self.get(i);\n            }\n            return arr;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/","title":"4.4 \u00a0 \u5185\u5b58\u4e0e\u7f13\u5b58 *","text":"

    \u5728\u672c\u7ae0\u7684\u524d\u4e24\u8282\u4e2d\uff0c\u6211\u4eec\u63a2\u8ba8\u4e86\u6570\u7ec4\u548c\u94fe\u8868\u8fd9\u4e24\u79cd\u57fa\u7840\u4e14\u91cd\u8981\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5b83\u4eec\u5206\u522b\u4ee3\u8868\u4e86\u201c\u8fde\u7eed\u5b58\u50a8\u201d\u548c\u201c\u5206\u6563\u5b58\u50a8\u201d\u4e24\u79cd\u7269\u7406\u7ed3\u6784\u3002

    \u5b9e\u9645\u4e0a\uff0c\u7269\u7406\u7ed3\u6784\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u51b3\u5b9a\u4e86\u7a0b\u5e8f\u5bf9\u5185\u5b58\u548c\u7f13\u5b58\u7684\u4f7f\u7528\u6548\u7387\uff0c\u8fdb\u800c\u5f71\u54cd\u7b97\u6cd5\u7a0b\u5e8f\u7684\u6574\u4f53\u6027\u80fd\u3002

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#441","title":"4.4.1 \u00a0 \u8ba1\u7b97\u673a\u5b58\u50a8\u8bbe\u5907","text":"

    \u8ba1\u7b97\u673a\u4e2d\u5305\u62ec\u4e09\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\u8bbe\u5907\uff1a\u786c\u76d8\uff08hard disk\uff09\u3001\u5185\u5b58\uff08random-access memory, RAM\uff09\u3001\u7f13\u5b58\uff08cache memory\uff09\u3002\u8868 4-2 \u5c55\u793a\u4e86\u5b83\u4eec\u5728\u8ba1\u7b97\u673a\u7cfb\u7edf\u4e2d\u7684\u4e0d\u540c\u89d2\u8272\u548c\u6027\u80fd\u7279\u70b9\u3002

    \u8868 4-2 \u00a0 \u8ba1\u7b97\u673a\u7684\u5b58\u50a8\u8bbe\u5907

    \u786c\u76d8 \u5185\u5b58 \u7f13\u5b58 \u7528\u9014 \u957f\u671f\u5b58\u50a8\u6570\u636e\uff0c\u5305\u62ec\u64cd\u4f5c\u7cfb\u7edf\u3001\u7a0b\u5e8f\u3001\u6587\u4ef6\u7b49 \u4e34\u65f6\u5b58\u50a8\u5f53\u524d\u8fd0\u884c\u7684\u7a0b\u5e8f\u548c\u6b63\u5728\u5904\u7406\u7684\u6570\u636e \u5b58\u50a8\u7ecf\u5e38\u8bbf\u95ee\u7684\u6570\u636e\u548c\u6307\u4ee4\uff0c\u51cf\u5c11 CPU \u8bbf\u95ee\u5185\u5b58\u7684\u6b21\u6570 \u6613\u5931\u6027 \u65ad\u7535\u540e\u6570\u636e\u4e0d\u4f1a\u4e22\u5931 \u65ad\u7535\u540e\u6570\u636e\u4f1a\u4e22\u5931 \u65ad\u7535\u540e\u6570\u636e\u4f1a\u4e22\u5931 \u5bb9\u91cf \u8f83\u5927\uff0cTB \u7ea7\u522b \u8f83\u5c0f\uff0cGB \u7ea7\u522b \u975e\u5e38\u5c0f\uff0cMB \u7ea7\u522b \u901f\u5ea6 \u8f83\u6162\uff0c\u51e0\u767e\u5230\u51e0\u5343 MB/s \u8f83\u5feb\uff0c\u51e0\u5341 GB/s \u975e\u5e38\u5feb\uff0c\u51e0\u5341\u5230\u51e0\u767e GB/s \u4ef7\u683c \u8f83\u4fbf\u5b9c\uff0c\u51e0\u6bdb\u5230\u51e0\u5143 / GB \u8f83\u8d35\uff0c\u51e0\u5341\u5230\u51e0\u767e\u5143 / GB \u975e\u5e38\u8d35\uff0c\u968f CPU \u6253\u5305\u8ba1\u4ef7

    \u6211\u4eec\u53ef\u4ee5\u5c06\u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf\u60f3\u8c61\u4e3a\u56fe 4-9 \u6240\u793a\u7684\u91d1\u5b57\u5854\u7ed3\u6784\u3002\u8d8a\u9760\u8fd1\u91d1\u5b57\u5854\u9876\u7aef\u7684\u5b58\u50a8\u8bbe\u5907\u7684\u901f\u5ea6\u8d8a\u5feb\u3001\u5bb9\u91cf\u8d8a\u5c0f\u3001\u6210\u672c\u8d8a\u9ad8\u3002\u8fd9\u79cd\u591a\u5c42\u7ea7\u7684\u8bbe\u8ba1\u5e76\u975e\u5076\u7136\uff0c\u800c\u662f\u8ba1\u7b97\u673a\u79d1\u5b66\u5bb6\u548c\u5de5\u7a0b\u5e08\u4eec\u7ecf\u8fc7\u6df1\u601d\u719f\u8651\u7684\u7ed3\u679c\u3002

    • \u786c\u76d8\u96be\u4ee5\u88ab\u5185\u5b58\u53d6\u4ee3\u3002\u9996\u5148\uff0c\u5185\u5b58\u4e2d\u7684\u6570\u636e\u5728\u65ad\u7535\u540e\u4f1a\u4e22\u5931\uff0c\u56e0\u6b64\u5b83\u4e0d\u9002\u5408\u957f\u671f\u5b58\u50a8\u6570\u636e\uff1b\u5176\u6b21\uff0c\u5185\u5b58\u7684\u6210\u672c\u662f\u786c\u76d8\u7684\u51e0\u5341\u500d\uff0c\u8fd9\u4f7f\u5f97\u5b83\u96be\u4ee5\u5728\u6d88\u8d39\u8005\u5e02\u573a\u666e\u53ca\u3002
    • \u7f13\u5b58\u7684\u5927\u5bb9\u91cf\u548c\u9ad8\u901f\u5ea6\u96be\u4ee5\u517c\u5f97\u3002\u968f\u7740 L1\u3001L2\u3001L3 \u7f13\u5b58\u7684\u5bb9\u91cf\u9010\u6b65\u589e\u5927\uff0c\u5176\u7269\u7406\u5c3a\u5bf8\u4f1a\u53d8\u5927\uff0c\u4e0e CPU \u6838\u5fc3\u4e4b\u95f4\u7684\u7269\u7406\u8ddd\u79bb\u4f1a\u53d8\u8fdc\uff0c\u4ece\u800c\u5bfc\u81f4\u6570\u636e\u4f20\u8f93\u65f6\u95f4\u589e\u52a0\uff0c\u5143\u7d20\u8bbf\u95ee\u5ef6\u8fdf\u53d8\u9ad8\u3002\u5728\u5f53\u524d\u6280\u672f\u4e0b\uff0c\u591a\u5c42\u7ea7\u7684\u7f13\u5b58\u7ed3\u6784\u662f\u5bb9\u91cf\u3001\u901f\u5ea6\u548c\u6210\u672c\u4e4b\u95f4\u7684\u6700\u4f73\u5e73\u8861\u70b9\u3002

    \u56fe 4-9 \u00a0 \u8ba1\u7b97\u673a\u5b58\u50a8\u7cfb\u7edf

    Tip

    \u8ba1\u7b97\u673a\u7684\u5b58\u50a8\u5c42\u6b21\u7ed3\u6784\u4f53\u73b0\u4e86\u901f\u5ea6\u3001\u5bb9\u91cf\u548c\u6210\u672c\u4e09\u8005\u4e4b\u95f4\u7684\u7cbe\u5999\u5e73\u8861\u3002\u5b9e\u9645\u4e0a\uff0c\u8fd9\u79cd\u6743\u8861\u666e\u904d\u5b58\u5728\u4e8e\u6240\u6709\u5de5\u4e1a\u9886\u57df\uff0c\u5b83\u8981\u6c42\u6211\u4eec\u5728\u4e0d\u540c\u7684\u4f18\u52bf\u548c\u9650\u5236\u4e4b\u95f4\u627e\u5230\u6700\u4f73\u5e73\u8861\u70b9\u3002

    \u603b\u7684\u6765\u8bf4\uff0c\u786c\u76d8\u7528\u4e8e\u957f\u671f\u5b58\u50a8\u5927\u91cf\u6570\u636e\uff0c\u5185\u5b58\u7528\u4e8e\u4e34\u65f6\u5b58\u50a8\u7a0b\u5e8f\u8fd0\u884c\u4e2d\u6b63\u5728\u5904\u7406\u7684\u6570\u636e\uff0c\u800c\u7f13\u5b58\u5219\u7528\u4e8e\u5b58\u50a8\u7ecf\u5e38\u8bbf\u95ee\u7684\u6570\u636e\u548c\u6307\u4ee4\uff0c\u4ee5\u63d0\u9ad8\u7a0b\u5e8f\u8fd0\u884c\u6548\u7387\u3002\u4e09\u8005\u5171\u540c\u534f\u4f5c\uff0c\u786e\u4fdd\u8ba1\u7b97\u673a\u7cfb\u7edf\u9ad8\u6548\u8fd0\u884c\u3002

    \u5982\u56fe 4-10 \u6240\u793a\uff0c\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6570\u636e\u4f1a\u4ece\u786c\u76d8\u4e2d\u88ab\u8bfb\u53d6\u5230\u5185\u5b58\u4e2d\uff0c\u4f9b CPU \u8ba1\u7b97\u4f7f\u7528\u3002\u7f13\u5b58\u53ef\u4ee5\u770b\u4f5c CPU \u7684\u4e00\u90e8\u5206\uff0c\u5b83\u901a\u8fc7\u667a\u80fd\u5730\u4ece\u5185\u5b58\u52a0\u8f7d\u6570\u636e\uff0c\u7ed9 CPU \u63d0\u4f9b\u9ad8\u901f\u7684\u6570\u636e\u8bfb\u53d6\uff0c\u4ece\u800c\u663e\u8457\u63d0\u5347\u7a0b\u5e8f\u7684\u6267\u884c\u6548\u7387\uff0c\u51cf\u5c11\u5bf9\u8f83\u6162\u7684\u5185\u5b58\u7684\u4f9d\u8d56\u3002

    \u56fe 4-10 \u00a0 \u786c\u76d8\u3001\u5185\u5b58\u548c\u7f13\u5b58\u4e4b\u95f4\u7684\u6570\u636e\u6d41\u901a

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#442","title":"4.4.2 \u00a0 \u6570\u636e\u7ed3\u6784\u7684\u5185\u5b58\u6548\u7387","text":"

    \u5728\u5185\u5b58\u7a7a\u95f4\u5229\u7528\u65b9\u9762\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u5404\u81ea\u5177\u6709\u4f18\u52bf\u548c\u5c40\u9650\u6027\u3002

    \u4e00\u65b9\u9762\uff0c\u5185\u5b58\u662f\u6709\u9650\u7684\uff0c\u4e14\u540c\u4e00\u5757\u5185\u5b58\u4e0d\u80fd\u88ab\u591a\u4e2a\u7a0b\u5e8f\u5171\u4eab\uff0c\u56e0\u6b64\u6211\u4eec\u5e0c\u671b\u6570\u636e\u7ed3\u6784\u80fd\u591f\u5c3d\u53ef\u80fd\u9ad8\u6548\u5730\u5229\u7528\u7a7a\u95f4\u3002\u6570\u7ec4\u7684\u5143\u7d20\u7d27\u5bc6\u6392\u5217\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u7a7a\u95f4\u6765\u5b58\u50a8\u94fe\u8868\u8282\u70b9\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\uff0c\u56e0\u6b64\u7a7a\u95f4\u6548\u7387\u66f4\u9ad8\u3002\u7136\u800c\uff0c\u6570\u7ec4\u9700\u8981\u4e00\u6b21\u6027\u5206\u914d\u8db3\u591f\u7684\u8fde\u7eed\u5185\u5b58\u7a7a\u95f4\uff0c\u8fd9\u53ef\u80fd\u5bfc\u81f4\u5185\u5b58\u6d6a\u8d39\uff0c\u6570\u7ec4\u6269\u5bb9\u4e5f\u9700\u8981\u989d\u5916\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u6210\u672c\u3002\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u94fe\u8868\u4ee5\u201c\u8282\u70b9\u201d\u4e3a\u5355\u4f4d\u8fdb\u884c\u52a8\u6001\u5185\u5b58\u5206\u914d\u548c\u56de\u6536\uff0c\u63d0\u4f9b\u4e86\u66f4\u5927\u7684\u7075\u6d3b\u6027\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5728\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u968f\u7740\u53cd\u590d\u7533\u8bf7\u4e0e\u91ca\u653e\u5185\u5b58\uff0c\u7a7a\u95f2\u5185\u5b58\u7684\u788e\u7247\u5316\u7a0b\u5ea6\u4f1a\u8d8a\u6765\u8d8a\u9ad8\uff0c\u4ece\u800c\u5bfc\u81f4\u5185\u5b58\u7684\u5229\u7528\u6548\u7387\u964d\u4f4e\u3002\u6570\u7ec4\u7531\u4e8e\u5176\u8fde\u7eed\u7684\u5b58\u50a8\u65b9\u5f0f\uff0c\u76f8\u5bf9\u4e0d\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\u3002\u76f8\u53cd\uff0c\u94fe\u8868\u7684\u5143\u7d20\u662f\u5206\u6563\u5b58\u50a8\u7684\uff0c\u5728\u9891\u7e41\u7684\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u4e2d\uff0c\u66f4\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\u3002

    "},{"location":"chapter_array_and_linkedlist/ram_and_cache/#443","title":"4.4.3 \u00a0 \u6570\u636e\u7ed3\u6784\u7684\u7f13\u5b58\u6548\u7387","text":"

    \u7f13\u5b58\u867d\u7136\u5728\u7a7a\u95f4\u5bb9\u91cf\u4e0a\u8fdc\u5c0f\u4e8e\u5185\u5b58\uff0c\u4f46\u5b83\u6bd4\u5185\u5b58\u5feb\u5f97\u591a\uff0c\u5728\u7a0b\u5e8f\u6267\u884c\u901f\u5ea6\u4e0a\u8d77\u7740\u81f3\u5173\u91cd\u8981\u7684\u4f5c\u7528\u3002\u7531\u4e8e\u7f13\u5b58\u7684\u5bb9\u91cf\u6709\u9650\uff0c\u53ea\u80fd\u5b58\u50a8\u4e00\u5c0f\u90e8\u5206\u9891\u7e41\u8bbf\u95ee\u7684\u6570\u636e\uff0c\u56e0\u6b64\u5f53 CPU \u5c1d\u8bd5\u8bbf\u95ee\u7684\u6570\u636e\u4e0d\u5728\u7f13\u5b58\u4e2d\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u7f13\u5b58\u672a\u547d\u4e2d\uff08cache miss\uff09\uff0c\u6b64\u65f6 CPU \u4e0d\u5f97\u4e0d\u4ece\u901f\u5ea6\u8f83\u6162\u7684\u5185\u5b58\u4e2d\u52a0\u8f7d\u6240\u9700\u6570\u636e\u3002

    \u663e\u7136\uff0c\u201c\u7f13\u5b58\u672a\u547d\u4e2d\u201d\u8d8a\u5c11\uff0cCPU \u8bfb\u5199\u6570\u636e\u7684\u6548\u7387\u5c31\u8d8a\u9ad8\uff0c\u7a0b\u5e8f\u6027\u80fd\u4e5f\u5c31\u8d8a\u597d\u3002\u6211\u4eec\u5c06 CPU \u4ece\u7f13\u5b58\u4e2d\u6210\u529f\u83b7\u53d6\u6570\u636e\u7684\u6bd4\u4f8b\u79f0\u4e3a\u7f13\u5b58\u547d\u4e2d\u7387\uff08cache hit rate\uff09\uff0c\u8fd9\u4e2a\u6307\u6807\u901a\u5e38\u7528\u6765\u8861\u91cf\u7f13\u5b58\u6548\u7387\u3002

    \u4e3a\u4e86\u5c3d\u53ef\u80fd\u8fbe\u5230\u66f4\u9ad8\u7684\u6548\u7387\uff0c\u7f13\u5b58\u4f1a\u91c7\u53d6\u4ee5\u4e0b\u6570\u636e\u52a0\u8f7d\u673a\u5236\u3002

    • \u7f13\u5b58\u884c\uff1a\u7f13\u5b58\u4e0d\u662f\u5355\u4e2a\u5b57\u8282\u5730\u5b58\u50a8\u4e0e\u52a0\u8f7d\u6570\u636e\uff0c\u800c\u662f\u4ee5\u7f13\u5b58\u884c\u4e3a\u5355\u4f4d\u3002\u76f8\u6bd4\u4e8e\u5355\u4e2a\u5b57\u8282\u7684\u4f20\u8f93\uff0c\u7f13\u5b58\u884c\u7684\u4f20\u8f93\u5f62\u5f0f\u66f4\u52a0\u9ad8\u6548\u3002
    • \u9884\u53d6\u673a\u5236\uff1a\u5904\u7406\u5668\u4f1a\u5c1d\u8bd5\u9884\u6d4b\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\uff08\u4f8b\u5982\u987a\u5e8f\u8bbf\u95ee\u3001\u56fa\u5b9a\u6b65\u957f\u8df3\u8dc3\u8bbf\u95ee\u7b49\uff09\uff0c\u5e76\u6839\u636e\u7279\u5b9a\u6a21\u5f0f\u5c06\u6570\u636e\u52a0\u8f7d\u81f3\u7f13\u5b58\u4e4b\u4e2d\uff0c\u4ece\u800c\u63d0\u5347\u547d\u4e2d\u7387\u3002
    • \u7a7a\u95f4\u5c40\u90e8\u6027\uff1a\u5982\u679c\u4e00\u4e2a\u6570\u636e\u88ab\u8bbf\u95ee\uff0c\u90a3\u4e48\u5b83\u9644\u8fd1\u7684\u6570\u636e\u53ef\u80fd\u8fd1\u671f\u4e5f\u4f1a\u88ab\u8bbf\u95ee\u3002\u56e0\u6b64\uff0c\u7f13\u5b58\u5728\u52a0\u8f7d\u67d0\u4e00\u6570\u636e\u65f6\uff0c\u4e5f\u4f1a\u52a0\u8f7d\u5176\u9644\u8fd1\u7684\u6570\u636e\uff0c\u4ee5\u63d0\u9ad8\u547d\u4e2d\u7387\u3002
    • \u65f6\u95f4\u5c40\u90e8\u6027\uff1a\u5982\u679c\u4e00\u4e2a\u6570\u636e\u88ab\u8bbf\u95ee\uff0c\u90a3\u4e48\u5b83\u5728\u4e0d\u4e45\u7684\u5c06\u6765\u5f88\u53ef\u80fd\u518d\u6b21\u88ab\u8bbf\u95ee\u3002\u7f13\u5b58\u5229\u7528\u8fd9\u4e00\u539f\u7406\uff0c\u901a\u8fc7\u4fdd\u7559\u6700\u8fd1\u8bbf\u95ee\u8fc7\u7684\u6570\u636e\u6765\u63d0\u9ad8\u547d\u4e2d\u7387\u3002

    \u5b9e\u9645\u4e0a\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u5bf9\u7f13\u5b58\u7684\u5229\u7528\u6548\u7387\u662f\u4e0d\u540c\u7684\uff0c\u4e3b\u8981\u4f53\u73b0\u5728\u4ee5\u4e0b\u51e0\u4e2a\u65b9\u9762\u3002

    • \u5360\u7528\u7a7a\u95f4\uff1a\u94fe\u8868\u5143\u7d20\u6bd4\u6570\u7ec4\u5143\u7d20\u5360\u7528\u7a7a\u95f4\u66f4\u591a\uff0c\u5bfc\u81f4\u7f13\u5b58\u4e2d\u5bb9\u7eb3\u7684\u6709\u6548\u6570\u636e\u91cf\u66f4\u5c11\u3002
    • \u7f13\u5b58\u884c\uff1a\u94fe\u8868\u6570\u636e\u5206\u6563\u5728\u5185\u5b58\u5404\u5904\uff0c\u800c\u7f13\u5b58\u662f\u201c\u6309\u884c\u52a0\u8f7d\u201d\u7684\uff0c\u56e0\u6b64\u52a0\u8f7d\u5230\u65e0\u6548\u6570\u636e\u7684\u6bd4\u4f8b\u66f4\u9ad8\u3002
    • \u9884\u53d6\u673a\u5236\uff1a\u6570\u7ec4\u6bd4\u94fe\u8868\u7684\u6570\u636e\u8bbf\u95ee\u6a21\u5f0f\u66f4\u5177\u201c\u53ef\u9884\u6d4b\u6027\u201d\uff0c\u5373\u7cfb\u7edf\u66f4\u5bb9\u6613\u731c\u51fa\u5373\u5c06\u88ab\u52a0\u8f7d\u7684\u6570\u636e\u3002
    • \u7a7a\u95f4\u5c40\u90e8\u6027\uff1a\u6570\u7ec4\u88ab\u5b58\u50a8\u5728\u96c6\u4e2d\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\uff0c\u56e0\u6b64\u88ab\u52a0\u8f7d\u6570\u636e\u9644\u8fd1\u7684\u6570\u636e\u66f4\u6709\u53ef\u80fd\u5373\u5c06\u88ab\u8bbf\u95ee\u3002

    \u603b\u4f53\u800c\u8a00\uff0c\u6570\u7ec4\u5177\u6709\u66f4\u9ad8\u7684\u7f13\u5b58\u547d\u4e2d\u7387\uff0c\u56e0\u6b64\u5b83\u5728\u64cd\u4f5c\u6548\u7387\u4e0a\u901a\u5e38\u4f18\u4e8e\u94fe\u8868\u3002\u8fd9\u4f7f\u5f97\u5728\u89e3\u51b3\u7b97\u6cd5\u95ee\u9898\u65f6\uff0c\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u5f80\u5f80\u66f4\u53d7\u6b22\u8fce\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u9ad8\u7f13\u5b58\u6548\u7387\u5e76\u4e0d\u610f\u5473\u7740\u6570\u7ec4\u5728\u6240\u6709\u60c5\u51b5\u4e0b\u90fd\u4f18\u4e8e\u94fe\u8868\u3002\u5b9e\u9645\u5e94\u7528\u4e2d\u9009\u62e9\u54ea\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u5e94\u6839\u636e\u5177\u4f53\u9700\u6c42\u6765\u51b3\u5b9a\u3002\u4f8b\u5982\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u90fd\u53ef\u4ee5\u5b9e\u73b0\u201c\u6808\u201d\u6570\u636e\u7ed3\u6784\uff08\u4e0b\u4e00\u7ae0\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\uff09\uff0c\u4f46\u5b83\u4eec\u9002\u7528\u4e8e\u4e0d\u540c\u573a\u666f\u3002

    • \u5728\u505a\u7b97\u6cd5\u9898\u65f6\uff0c\u6211\u4eec\u4f1a\u503e\u5411\u4e8e\u9009\u62e9\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\uff0c\u56e0\u4e3a\u5b83\u63d0\u4f9b\u4e86\u66f4\u9ad8\u7684\u64cd\u4f5c\u6548\u7387\u548c\u968f\u673a\u8bbf\u95ee\u7684\u80fd\u529b\uff0c\u4ee3\u4ef7\u4ec5\u662f\u9700\u8981\u9884\u5148\u4e3a\u6570\u7ec4\u5206\u914d\u4e00\u5b9a\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    • \u5982\u679c\u6570\u636e\u91cf\u975e\u5e38\u5927\u3001\u52a8\u6001\u6027\u5f88\u9ad8\u3001\u6808\u7684\u9884\u671f\u5927\u5c0f\u96be\u4ee5\u4f30\u8ba1\uff0c\u90a3\u4e48\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\u66f4\u52a0\u5408\u9002\u3002\u94fe\u8868\u80fd\u591f\u5c06\u5927\u91cf\u6570\u636e\u5206\u6563\u5b58\u50a8\u4e8e\u5185\u5b58\u7684\u4e0d\u540c\u90e8\u5206\uff0c\u5e76\u4e14\u907f\u514d\u4e86\u6570\u7ec4\u6269\u5bb9\u4ea7\u751f\u7684\u989d\u5916\u5f00\u9500\u3002
    "},{"location":"chapter_array_and_linkedlist/summary/","title":"4.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_array_and_linkedlist/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u6570\u7ec4\u548c\u94fe\u8868\u662f\u4e24\u79cd\u57fa\u672c\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5206\u522b\u4ee3\u8868\u6570\u636e\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u7684\u4e24\u79cd\u5b58\u50a8\u65b9\u5f0f\uff1a\u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\u548c\u5206\u6563\u7a7a\u95f4\u5b58\u50a8\u3002\u4e24\u8005\u7684\u7279\u70b9\u5448\u73b0\u51fa\u4e92\u8865\u7684\u7279\u6027\u3002
    • \u6570\u7ec4\u652f\u6301\u968f\u673a\u8bbf\u95ee\u3001\u5360\u7528\u5185\u5b58\u8f83\u5c11\uff1b\u4f46\u63d2\u5165\u548c\u5220\u9664\u5143\u7d20\u6548\u7387\u4f4e\uff0c\u4e14\u521d\u59cb\u5316\u540e\u957f\u5ea6\u4e0d\u53ef\u53d8\u3002
    • \u94fe\u8868\u901a\u8fc7\u66f4\u6539\u5f15\u7528\uff08\u6307\u9488\uff09\u5b9e\u73b0\u9ad8\u6548\u7684\u8282\u70b9\u63d2\u5165\u4e0e\u5220\u9664\uff0c\u4e14\u53ef\u4ee5\u7075\u6d3b\u8c03\u6574\u957f\u5ea6\uff1b\u4f46\u8282\u70b9\u8bbf\u95ee\u6548\u7387\u4f4e\u3001\u5360\u7528\u5185\u5b58\u8f83\u591a\u3002\u5e38\u89c1\u7684\u94fe\u8868\u7c7b\u578b\u5305\u62ec\u5355\u5411\u94fe\u8868\u3001\u73af\u5f62\u94fe\u8868\u3001\u53cc\u5411\u94fe\u8868\u3002
    • \u5217\u8868\u662f\u4e00\u79cd\u652f\u6301\u589e\u5220\u67e5\u6539\u7684\u5143\u7d20\u6709\u5e8f\u96c6\u5408\uff0c\u901a\u5e38\u57fa\u4e8e\u52a8\u6001\u6570\u7ec4\u5b9e\u73b0\u3002\u5b83\u4fdd\u7559\u4e86\u6570\u7ec4\u7684\u4f18\u52bf\uff0c\u540c\u65f6\u53ef\u4ee5\u7075\u6d3b\u8c03\u6574\u957f\u5ea6\u3002
    • \u5217\u8868\u7684\u51fa\u73b0\u5927\u5e45\u63d0\u9ad8\u4e86\u6570\u7ec4\u7684\u5b9e\u7528\u6027\uff0c\u4f46\u53ef\u80fd\u5bfc\u81f4\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u3002
    • \u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6570\u636e\u4e3b\u8981\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\u3002\u6570\u7ec4\u53ef\u63d0\u4f9b\u66f4\u9ad8\u7684\u5185\u5b58\u7a7a\u95f4\u6548\u7387\uff0c\u800c\u94fe\u8868\u5219\u5728\u5185\u5b58\u4f7f\u7528\u4e0a\u66f4\u52a0\u7075\u6d3b\u3002
    • \u7f13\u5b58\u901a\u8fc7\u7f13\u5b58\u884c\u3001\u9884\u53d6\u673a\u5236\u4ee5\u53ca\u7a7a\u95f4\u5c40\u90e8\u6027\u548c\u65f6\u95f4\u5c40\u90e8\u6027\u7b49\u6570\u636e\u52a0\u8f7d\u673a\u5236\uff0c\u4e3a CPU \u63d0\u4f9b\u5feb\u901f\u6570\u636e\u8bbf\u95ee\uff0c\u663e\u8457\u63d0\u5347\u7a0b\u5e8f\u7684\u6267\u884c\u6548\u7387\u3002
    • \u7531\u4e8e\u6570\u7ec4\u5177\u6709\u66f4\u9ad8\u7684\u7f13\u5b58\u547d\u4e2d\u7387\uff0c\u56e0\u6b64\u5b83\u901a\u5e38\u6bd4\u94fe\u8868\u66f4\u9ad8\u6548\u3002\u5728\u9009\u62e9\u6570\u636e\u7ed3\u6784\u65f6\uff0c\u5e94\u6839\u636e\u5177\u4f53\u9700\u6c42\u548c\u573a\u666f\u505a\u51fa\u6070\u5f53\u9009\u62e9\u3002
    "},{"location":"chapter_array_and_linkedlist/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6570\u7ec4\u5b58\u50a8\u5728\u6808\u4e0a\u548c\u5b58\u50a8\u5728\u5806\u4e0a\uff0c\u5bf9\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u662f\u5426\u6709\u5f71\u54cd\uff1f

    \u5b58\u50a8\u5728\u6808\u4e0a\u548c\u5806\u4e0a\u7684\u6570\u7ec4\u90fd\u88ab\u5b58\u50a8\u5728\u8fde\u7eed\u5185\u5b58\u7a7a\u95f4\u5185\uff0c\u6570\u636e\u64cd\u4f5c\u6548\u7387\u57fa\u672c\u4e00\u81f4\u3002\u7136\u800c\uff0c\u6808\u548c\u5806\u5177\u6709\u5404\u81ea\u7684\u7279\u70b9\uff0c\u4ece\u800c\u5bfc\u81f4\u4ee5\u4e0b\u4e0d\u540c\u70b9\u3002

    1. \u5206\u914d\u548c\u91ca\u653e\u6548\u7387\uff1a\u6808\u662f\u4e00\u5757\u8f83\u5c0f\u7684\u5185\u5b58\uff0c\u5206\u914d\u7531\u7f16\u8bd1\u5668\u81ea\u52a8\u5b8c\u6210\uff1b\u800c\u5806\u5185\u5b58\u76f8\u5bf9\u66f4\u5927\uff0c\u53ef\u4ee5\u5728\u4ee3\u7801\u4e2d\u52a8\u6001\u5206\u914d\uff0c\u66f4\u5bb9\u6613\u788e\u7247\u5316\u3002\u56e0\u6b64\uff0c\u5806\u4e0a\u7684\u5206\u914d\u548c\u91ca\u653e\u64cd\u4f5c\u901a\u5e38\u6bd4\u6808\u4e0a\u7684\u6162\u3002
    2. \u5927\u5c0f\u9650\u5236\uff1a\u6808\u5185\u5b58\u76f8\u5bf9\u8f83\u5c0f\uff0c\u5806\u7684\u5927\u5c0f\u4e00\u822c\u53d7\u9650\u4e8e\u53ef\u7528\u5185\u5b58\u3002\u56e0\u6b64\u5806\u66f4\u52a0\u9002\u5408\u5b58\u50a8\u5927\u578b\u6570\u7ec4\u3002
    3. \u7075\u6d3b\u6027\uff1a\u6808\u4e0a\u7684\u6570\u7ec4\u7684\u5927\u5c0f\u9700\u8981\u5728\u7f16\u8bd1\u65f6\u786e\u5b9a\uff0c\u800c\u5806\u4e0a\u7684\u6570\u7ec4\u7684\u5927\u5c0f\u53ef\u4ee5\u5728\u8fd0\u884c\u65f6\u52a8\u6001\u786e\u5b9a\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u6570\u7ec4\u8981\u6c42\u76f8\u540c\u7c7b\u578b\u7684\u5143\u7d20\uff0c\u800c\u5728\u94fe\u8868\u4e2d\u5374\u6ca1\u6709\u5f3a\u8c03\u76f8\u540c\u7c7b\u578b\u5462\uff1f

    \u94fe\u8868\u7531\u8282\u70b9\u7ec4\u6210\uff0c\u8282\u70b9\u4e4b\u95f4\u901a\u8fc7\u5f15\u7528\uff08\u6307\u9488\uff09\u8fde\u63a5\uff0c\u5404\u4e2a\u8282\u70b9\u53ef\u4ee5\u5b58\u50a8\u4e0d\u540c\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f8b\u5982 int\u3001double\u3001string\u3001object \u7b49\u3002

    \u76f8\u5bf9\u5730\uff0c\u6570\u7ec4\u5143\u7d20\u5219\u5fc5\u987b\u662f\u76f8\u540c\u7c7b\u578b\u7684\uff0c\u8fd9\u6837\u624d\u80fd\u901a\u8fc7\u8ba1\u7b97\u504f\u79fb\u91cf\u6765\u83b7\u53d6\u5bf9\u5e94\u5143\u7d20\u4f4d\u7f6e\u3002\u4f8b\u5982\uff0c\u6570\u7ec4\u540c\u65f6\u5305\u542b int \u548c long \u4e24\u79cd\u7c7b\u578b\uff0c\u5355\u4e2a\u5143\u7d20\u5206\u522b\u5360\u7528 4 \u5b57\u8282 \u548c 8 \u5b57\u8282 \uff0c\u6b64\u65f6\u5c31\u4e0d\u80fd\u7528\u4ee5\u4e0b\u516c\u5f0f\u8ba1\u7b97\u504f\u79fb\u91cf\u4e86\uff0c\u56e0\u4e3a\u6570\u7ec4\u4e2d\u5305\u542b\u4e86\u4e24\u79cd\u201c\u5143\u7d20\u957f\u5ea6\u201d\u3002

    # \u5143\u7d20\u5185\u5b58\u5730\u5740 = \u6570\u7ec4\u5185\u5b58\u5730\u5740\uff08\u9996\u5143\u7d20\u5185\u5b58\u5730\u5740\uff09 + \u5143\u7d20\u957f\u5ea6 * \u5143\u7d20\u7d22\u5f15\n

    Q\uff1a\u5220\u9664\u8282\u70b9 P \u540e\uff0c\u662f\u5426\u9700\u8981\u628a P.next \u8bbe\u4e3a None \u5462\uff1f

    \u4e0d\u4fee\u6539 P.next \u4e5f\u53ef\u4ee5\u3002\u4ece\u8be5\u94fe\u8868\u7684\u89d2\u5ea6\u770b\uff0c\u4ece\u5934\u8282\u70b9\u904d\u5386\u5230\u5c3e\u8282\u70b9\u5df2\u7ecf\u4e0d\u4f1a\u9047\u5230 P \u4e86\u3002\u8fd9\u610f\u5473\u7740\u8282\u70b9 P \u5df2\u7ecf\u4ece\u94fe\u8868\u4e2d\u5220\u9664\u4e86\uff0c\u6b64\u65f6\u8282\u70b9 P \u6307\u5411\u54ea\u91cc\u90fd\u4e0d\u4f1a\u5bf9\u8be5\u94fe\u8868\u4ea7\u751f\u5f71\u54cd\u3002

    \u4ece\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\uff08\u505a\u9898\uff09\u7684\u89d2\u5ea6\u770b\uff0c\u4e0d\u65ad\u5f00\u6ca1\u6709\u5173\u7cfb\uff0c\u53ea\u8981\u4fdd\u8bc1\u7a0b\u5e8f\u7684\u903b\u8f91\u662f\u6b63\u786e\u7684\u5c31\u884c\u3002\u4ece\u6807\u51c6\u5e93\u7684\u89d2\u5ea6\u770b\uff0c\u65ad\u5f00\u66f4\u52a0\u5b89\u5168\u3001\u903b\u8f91\u66f4\u52a0\u6e05\u6670\u3002\u5982\u679c\u4e0d\u65ad\u5f00\uff0c\u5047\u8bbe\u88ab\u5220\u9664\u8282\u70b9\u672a\u88ab\u6b63\u5e38\u56de\u6536\uff0c\u90a3\u4e48\u5b83\u4f1a\u5f71\u54cd\u540e\u7ee7\u8282\u70b9\u7684\u5185\u5b58\u56de\u6536\u3002

    Q\uff1a\u5728\u94fe\u8868\u4e2d\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u3002\u4f46\u662f\u589e\u5220\u4e4b\u524d\u90fd\u9700\u8981 \\(O(n)\\) \u7684\u65f6\u95f4\u67e5\u627e\u5143\u7d20\uff0c\u90a3\u4e3a\u4ec0\u4e48\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u662f \\(O(n)\\) \u5462\uff1f

    \u5982\u679c\u662f\u5148\u67e5\u627e\u5143\u7d20\u3001\u518d\u5220\u9664\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u786e\u5b9e\u662f \\(O(n)\\) \u3002\u7136\u800c\uff0c\u94fe\u8868\u7684 \\(O(1)\\) \u589e\u5220\u7684\u4f18\u52bf\u53ef\u4ee5\u5728\u5176\u4ed6\u5e94\u7528\u4e0a\u5f97\u5230\u4f53\u73b0\u3002\u4f8b\u5982\uff0c\u53cc\u5411\u961f\u5217\u9002\u5408\u4f7f\u7528\u94fe\u8868\u5b9e\u73b0\uff0c\u6211\u4eec\u7ef4\u62a4\u4e00\u4e2a\u6307\u9488\u53d8\u91cf\u59cb\u7ec8\u6307\u5411\u5934\u8282\u70b9\u3001\u5c3e\u8282\u70b9\uff0c\u6bcf\u6b21\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u90fd\u662f \\(O(1)\\) \u3002

    Q\uff1a\u56fe\u201c\u94fe\u8868\u5b9a\u4e49\u4e0e\u5b58\u50a8\u65b9\u5f0f\u201d\u4e2d\uff0c\u6d45\u84dd\u8272\u7684\u5b58\u50a8\u8282\u70b9\u6307\u9488\u662f\u5360\u7528\u4e00\u5757\u5185\u5b58\u5730\u5740\u5417\uff1f\u8fd8\u662f\u548c\u8282\u70b9\u503c\u5404\u5360\u4e00\u534a\u5462\uff1f

    \u8be5\u793a\u610f\u56fe\u53ea\u662f\u5b9a\u6027\u8868\u793a\uff0c\u5b9a\u91cf\u8868\u793a\u9700\u8981\u6839\u636e\u5177\u4f53\u60c5\u51b5\u8fdb\u884c\u5206\u6790\u3002

    • \u4e0d\u540c\u7c7b\u578b\u7684\u8282\u70b9\u503c\u5360\u7528\u7684\u7a7a\u95f4\u662f\u4e0d\u540c\u7684\uff0c\u6bd4\u5982 int\u3001long\u3001double \u548c\u5b9e\u4f8b\u5bf9\u8c61\u7b49\u3002
    • \u6307\u9488\u53d8\u91cf\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u5927\u5c0f\u6839\u636e\u6240\u4f7f\u7528\u7684\u64cd\u4f5c\u7cfb\u7edf\u53ca\u7f16\u8bd1\u73af\u5883\u800c\u5b9a\uff0c\u5927\u591a\u4e3a 8 \u5b57\u8282\u6216 4 \u5b57\u8282\u3002

    Q\uff1a\u5728\u5217\u8868\u672b\u5c3e\u6dfb\u52a0\u5143\u7d20\u662f\u5426\u65f6\u65f6\u523b\u523b\u90fd\u4e3a \\(O(1)\\) \uff1f

    \u5982\u679c\u6dfb\u52a0\u5143\u7d20\u65f6\u8d85\u51fa\u5217\u8868\u957f\u5ea6\uff0c\u5219\u9700\u8981\u5148\u6269\u5bb9\u5217\u8868\u518d\u6dfb\u52a0\u3002\u7cfb\u7edf\u4f1a\u7533\u8bf7\u4e00\u5757\u65b0\u7684\u5185\u5b58\uff0c\u5e76\u5c06\u539f\u5217\u8868\u7684\u6240\u6709\u5143\u7d20\u642c\u8fd0\u8fc7\u53bb\uff0c\u8fd9\u65f6\u5019\u65f6\u95f4\u590d\u6742\u5ea6\u5c31\u4f1a\u662f \\(O(n)\\) \u3002

    Q\uff1a\u201c\u5217\u8868\u7684\u51fa\u73b0\u6781\u5927\u5730\u63d0\u9ad8\u4e86\u6570\u7ec4\u7684\u5b9e\u7528\u6027\uff0c\u4f46\u53ef\u80fd\u5bfc\u81f4\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u6d6a\u8d39\u201d\uff0c\u8fd9\u91cc\u7684\u7a7a\u95f4\u6d6a\u8d39\u662f\u6307\u989d\u5916\u589e\u52a0\u7684\u53d8\u91cf\u5982\u5bb9\u91cf\u3001\u957f\u5ea6\u3001\u6269\u5bb9\u500d\u6570\u6240\u5360\u7684\u5185\u5b58\u5417\uff1f

    \u8fd9\u91cc\u7684\u7a7a\u95f4\u6d6a\u8d39\u4e3b\u8981\u6709\u4e24\u65b9\u9762\u542b\u4e49\uff1a\u4e00\u65b9\u9762\uff0c\u5217\u8868\u90fd\u4f1a\u8bbe\u5b9a\u4e00\u4e2a\u521d\u59cb\u957f\u5ea6\uff0c\u6211\u4eec\u4e0d\u4e00\u5b9a\u9700\u8981\u7528\u8fd9\u4e48\u591a\uff1b\u53e6\u4e00\u65b9\u9762\uff0c\u4e3a\u4e86\u9632\u6b62\u9891\u7e41\u6269\u5bb9\uff0c\u6269\u5bb9\u4e00\u822c\u4f1a\u4e58\u4ee5\u4e00\u4e2a\u7cfb\u6570\uff0c\u6bd4\u5982 \\(\\times 1.5\\) \u3002\u8fd9\u6837\u4e00\u6765\uff0c\u4e5f\u4f1a\u51fa\u73b0\u5f88\u591a\u7a7a\u4f4d\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u80fd\u5b8c\u5168\u586b\u6ee1\u5b83\u4eec\u3002

    Q\uff1a\u5728 Python \u4e2d\u521d\u59cb\u5316 n = [1, 2, 3] \u540e\uff0c\u8fd9 3 \u4e2a\u5143\u7d20\u7684\u5730\u5740\u662f\u76f8\u8fde\u7684\uff0c\u4f46\u662f\u521d\u59cb\u5316 m = [2, 1, 3] \u4f1a\u53d1\u73b0\u5b83\u4eec\u6bcf\u4e2a\u5143\u7d20\u7684 id \u5e76\u4e0d\u662f\u8fde\u7eed\u7684\uff0c\u800c\u662f\u5206\u522b\u8ddf n \u4e2d\u7684\u76f8\u540c\u3002\u8fd9\u4e9b\u5143\u7d20\u7684\u5730\u5740\u4e0d\u8fde\u7eed\uff0c\u90a3\u4e48 m \u8fd8\u662f\u6570\u7ec4\u5417\uff1f

    \u5047\u5982\u628a\u5217\u8868\u5143\u7d20\u6362\u6210\u94fe\u8868\u8282\u70b9 n = [n1, n2, n3, n4, n5] \uff0c\u901a\u5e38\u60c5\u51b5\u4e0b\u8fd9 5 \u4e2a\u8282\u70b9\u5bf9\u8c61\u4e5f\u5206\u6563\u5b58\u50a8\u5728\u5185\u5b58\u5404\u5904\u3002\u7136\u800c\uff0c\u7ed9\u5b9a\u4e00\u4e2a\u5217\u8868\u7d22\u5f15\uff0c\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u83b7\u53d6\u8282\u70b9\u5185\u5b58\u5730\u5740\uff0c\u4ece\u800c\u8bbf\u95ee\u5230\u5bf9\u5e94\u7684\u8282\u70b9\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u4e2d\u5b58\u50a8\u7684\u662f\u8282\u70b9\u7684\u5f15\u7528\uff0c\u800c\u975e\u8282\u70b9\u672c\u8eab\u3002

    \u4e0e\u8bb8\u591a\u8bed\u8a00\u4e0d\u540c\uff0cPython \u4e2d\u7684\u6570\u5b57\u4e5f\u88ab\u5305\u88c5\u4e3a\u5bf9\u8c61\uff0c\u5217\u8868\u4e2d\u5b58\u50a8\u7684\u4e0d\u662f\u6570\u5b57\u672c\u8eab\uff0c\u800c\u662f\u5bf9\u6570\u5b57\u7684\u5f15\u7528\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u4f1a\u53d1\u73b0\u4e24\u4e2a\u6570\u7ec4\u4e2d\u7684\u76f8\u540c\u6570\u5b57\u62e5\u6709\u540c\u4e00\u4e2a id \uff0c\u5e76\u4e14\u8fd9\u4e9b\u6570\u5b57\u7684\u5185\u5b58\u5730\u5740\u65e0\u987b\u8fde\u7eed\u3002

    Q\uff1aC++ STL \u91cc\u9762\u7684 std::list \u5df2\u7ecf\u5b9e\u73b0\u4e86\u53cc\u5411\u94fe\u8868\uff0c\u4f46\u597d\u50cf\u4e00\u4e9b\u7b97\u6cd5\u4e66\u4e0a\u4e0d\u600e\u4e48\u76f4\u63a5\u4f7f\u7528\u5b83\uff0c\u662f\u4e0d\u662f\u56e0\u4e3a\u6709\u4ec0\u4e48\u5c40\u9650\u6027\u5462\uff1f

    \u4e00\u65b9\u9762\uff0c\u6211\u4eec\u5f80\u5f80\u66f4\u9752\u7750\u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\u7b97\u6cd5\uff0c\u800c\u53ea\u5728\u5fc5\u8981\u65f6\u624d\u4f7f\u7528\u94fe\u8868\uff0c\u4e3b\u8981\u6709\u4e24\u4e2a\u539f\u56e0\u3002

    • \u7a7a\u95f4\u5f00\u9500\uff1a\u7531\u4e8e\u6bcf\u4e2a\u5143\u7d20\u9700\u8981\u4e24\u4e2a\u989d\u5916\u7684\u6307\u9488\uff08\u4e00\u4e2a\u7528\u4e8e\u524d\u4e00\u4e2a\u5143\u7d20\uff0c\u4e00\u4e2a\u7528\u4e8e\u540e\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u6240\u4ee5 std::list \u901a\u5e38\u6bd4 std::vector \u66f4\u5360\u7528\u7a7a\u95f4\u3002
    • \u7f13\u5b58\u4e0d\u53cb\u597d\uff1a\u7531\u4e8e\u6570\u636e\u4e0d\u662f\u8fde\u7eed\u5b58\u653e\u7684\uff0c\u56e0\u6b64 std::list \u5bf9\u7f13\u5b58\u7684\u5229\u7528\u7387\u8f83\u4f4e\u3002\u4e00\u822c\u60c5\u51b5\u4e0b\uff0cstd::vector \u7684\u6027\u80fd\u4f1a\u66f4\u597d\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5fc5\u8981\u4f7f\u7528\u94fe\u8868\u7684\u60c5\u51b5\u4e3b\u8981\u662f\u4e8c\u53c9\u6811\u548c\u56fe\u3002\u6808\u548c\u961f\u5217\u5f80\u5f80\u4f1a\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u7684 stack \u548c queue \uff0c\u800c\u975e\u94fe\u8868\u3002

    Q\uff1a\u521d\u59cb\u5316\u5217\u8868 res = [0] * self.size() \u64cd\u4f5c\uff0c\u4f1a\u5bfc\u81f4 res \u7684\u6bcf\u4e2a\u5143\u7d20\u5f15\u7528\u76f8\u540c\u7684\u5730\u5740\u5417\uff1f

    \u4e0d\u4f1a\u3002\u4f46\u4e8c\u7ef4\u6570\u7ec4\u4f1a\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u4f8b\u5982\u521d\u59cb\u5316\u4e8c\u7ef4\u5217\u8868 res = [[0] * self.size()] \uff0c\u5219\u591a\u6b21\u5f15\u7528\u4e86\u540c\u4e00\u4e2a\u5217\u8868 [0] \u3002

    "},{"location":"chapter_backtracking/","title":"\u7b2c 13 \u7ae0 \u00a0 \u56de\u6eaf","text":"

    Abstract

    \u6211\u4eec\u5982\u540c\u8ff7\u5bab\u4e2d\u7684\u63a2\u7d22\u8005\uff0c\u5728\u524d\u8fdb\u7684\u9053\u8def\u4e0a\u53ef\u80fd\u4f1a\u9047\u5230\u56f0\u96be\u3002

    \u56de\u6eaf\u7684\u529b\u91cf\u8ba9\u6211\u4eec\u80fd\u591f\u91cd\u65b0\u5f00\u59cb\uff0c\u4e0d\u65ad\u5c1d\u8bd5\uff0c\u6700\u7ec8\u627e\u5230\u901a\u5f80\u5149\u660e\u7684\u51fa\u53e3\u3002

    "},{"location":"chapter_backtracking/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 13.1 \u00a0 \u56de\u6eaf\u7b97\u6cd5
    • 13.2 \u00a0 \u5168\u6392\u5217\u95ee\u9898
    • 13.3 \u00a0 \u5b50\u96c6\u548c\u95ee\u9898
    • 13.4 \u00a0 N \u7687\u540e\u95ee\u9898
    • 13.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_backtracking/backtracking_algorithm/","title":"13.1 \u00a0 \u56de\u6eaf\u7b97\u6cd5","text":"

    \u56de\u6eaf\u7b97\u6cd5\uff08backtracking algorithm\uff09\u662f\u4e00\u79cd\u901a\u8fc7\u7a77\u4e3e\u6765\u89e3\u51b3\u95ee\u9898\u7684\u65b9\u6cd5\uff0c\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f\u4ece\u4e00\u4e2a\u521d\u59cb\u72b6\u6001\u51fa\u53d1\uff0c\u66b4\u529b\u641c\u7d22\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u5f53\u9047\u5230\u6b63\u786e\u7684\u89e3\u5219\u5c06\u5176\u8bb0\u5f55\uff0c\u76f4\u5230\u627e\u5230\u89e3\u6216\u8005\u5c1d\u8bd5\u4e86\u6240\u6709\u53ef\u80fd\u7684\u9009\u62e9\u90fd\u65e0\u6cd5\u627e\u5230\u89e3\u4e3a\u6b62\u3002

    \u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u91c7\u7528\u201c\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u201d\u6765\u904d\u5386\u89e3\u7a7a\u95f4\u3002\u5728\u201c\u4e8c\u53c9\u6811\u201d\u7ae0\u8282\u4e2d\uff0c\u6211\u4eec\u63d0\u5230\u524d\u5e8f\u3001\u4e2d\u5e8f\u548c\u540e\u5e8f\u904d\u5386\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5229\u7528\u524d\u5e8f\u904d\u5386\u6784\u9020\u4e00\u4e2a\u56de\u6eaf\u95ee\u9898\uff0c\u9010\u6b65\u4e86\u89e3\u56de\u6eaf\u7b97\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u3002

    \u4f8b\u9898\u4e00

    \u7ed9\u5b9a\u4e00\u68f5\u4e8c\u53c9\u6811\uff0c\u641c\u7d22\u5e76\u8bb0\u5f55\u6240\u6709\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\uff0c\u8bf7\u8fd4\u56de\u8282\u70b9\u5217\u8868\u3002

    \u5bf9\u4e8e\u6b64\u9898\uff0c\u6211\u4eec\u524d\u5e8f\u904d\u5386\u8fd9\u68f5\u6811\uff0c\u5e76\u5224\u65ad\u5f53\u524d\u8282\u70b9\u7684\u503c\u662f\u5426\u4e3a \\(7\\) \uff0c\u82e5\u662f\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u7684\u503c\u52a0\u5165\u7ed3\u679c\u5217\u8868 res \u4e4b\u4e2d\u3002\u76f8\u5173\u8fc7\u7a0b\u5b9e\u73b0\u5982\u56fe 13-1 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_i_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00\"\"\"\n    if root is None:\n        return\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(root)\n    pre_order(root.left)\n    pre_order(root.right)\n
    preorder_traversal_i_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr) {\n        return;\n    }\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(root);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n}\n
    preorder_traversal_i_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode root) {\n    if (root == null) {\n        return;\n    }\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(root);\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n}\n
    preorder_traversal_i_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) {\n        return;\n    }\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(root);\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n
    preorder_traversal_i_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunc preOrderI(root *TreeNode, res *[]*TreeNode) {\n    if root == nil {\n        return\n    }\n    if (root.Val).(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, root)\n    }\n    preOrderI(root.Left, res)\n    preOrderI(root.Right, res)\n}\n
    preorder_traversal_i_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(root)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n
    preorder_traversal_i_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunction preOrder(root, res) {\n    if (root === null) {\n        return;\n    }\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push(root);\n    }\n    preOrder(root.left, res);\n    preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfunction preOrder(root: TreeNode | null, res: TreeNode[]): void {\n    if (root === null) {\n        return;\n    }\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push(root);\n    }\n    preOrder(root.left, res);\n    preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode? root, List<TreeNode> res) {\n  if (root == null) {\n    return;\n  }\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(root);\n  }\n  preOrder(root.left, res);\n  preOrder(root.right, res);\n}\n
    preorder_traversal_i_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfn pre_order(res: &mut Vec<Rc<RefCell<TreeNode>>>, root: Option<Rc<RefCell<TreeNode>>>) {\n    if root.is_none() {\n        return;\n    }\n    if let Some(node) = root {\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(node.clone());\n        }\n        pre_order(res, node.borrow().left.clone());\n        pre_order(res, node.borrow().right.clone());\n    }\n}\n
    preorder_traversal_i_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nvoid preOrder(TreeNode *root) {\n    if (root == NULL) {\n        return;\n    }\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res[resSize++] = root;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n}\n
    preorder_traversal_i_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e00 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) {\n        return\n    }\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(root)\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n}\n
    preorder_traversal_i_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_i_compact.zig
    [class]{}-[func]{preOrder}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 13-1 \u00a0 \u5728\u524d\u5e8f\u904d\u5386\u4e2d\u641c\u7d22\u8282\u70b9

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1311","title":"13.1.1 \u00a0 \u5c1d\u8bd5\u4e0e\u56de\u9000","text":"

    \u4e4b\u6240\u4ee5\u79f0\u4e4b\u4e3a\u56de\u6eaf\u7b97\u6cd5\uff0c\u662f\u56e0\u4e3a\u8be5\u7b97\u6cd5\u5728\u641c\u7d22\u89e3\u7a7a\u95f4\u65f6\u4f1a\u91c7\u7528\u201c\u5c1d\u8bd5\u201d\u4e0e\u201c\u56de\u9000\u201d\u7684\u7b56\u7565\u3002\u5f53\u7b97\u6cd5\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u9047\u5230\u67d0\u4e2a\u72b6\u6001\u65e0\u6cd5\u7ee7\u7eed\u524d\u8fdb\u6216\u65e0\u6cd5\u5f97\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u89e3\u65f6\uff0c\u5b83\u4f1a\u64a4\u9500\u4e0a\u4e00\u6b65\u7684\u9009\u62e9\uff0c\u9000\u56de\u5230\u4e4b\u524d\u7684\u72b6\u6001\uff0c\u5e76\u5c1d\u8bd5\u5176\u4ed6\u53ef\u80fd\u7684\u9009\u62e9\u3002

    \u5bf9\u4e8e\u4f8b\u9898\u4e00\uff0c\u8bbf\u95ee\u6bcf\u4e2a\u8282\u70b9\u90fd\u4ee3\u8868\u4e00\u6b21\u201c\u5c1d\u8bd5\u201d\uff0c\u800c\u8d8a\u8fc7\u53f6\u8282\u70b9\u6216\u8fd4\u56de\u7236\u8282\u70b9\u7684 return \u5219\u8868\u793a\u201c\u56de\u9000\u201d\u3002

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u56de\u9000\u5e76\u4e0d\u4ec5\u4ec5\u5305\u62ec\u51fd\u6570\u8fd4\u56de\u3002\u4e3a\u89e3\u91ca\u8fd9\u4e00\u70b9\uff0c\u6211\u4eec\u5bf9\u4f8b\u9898\u4e00\u7a0d\u4f5c\u62d3\u5c55\u3002

    \u4f8b\u9898\u4e8c

    \u5728\u4e8c\u53c9\u6811\u4e2d\u641c\u7d22\u6240\u6709\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\uff0c\u8bf7\u8fd4\u56de\u6839\u8282\u70b9\u5230\u8fd9\u4e9b\u8282\u70b9\u7684\u8def\u5f84\u3002

    \u5728\u4f8b\u9898\u4e00\u4ee3\u7801\u7684\u57fa\u7840\u4e0a\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u5217\u8868 path \u8bb0\u5f55\u8bbf\u95ee\u8fc7\u7684\u8282\u70b9\u8def\u5f84\u3002\u5f53\u8bbf\u95ee\u5230\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\u65f6\uff0c\u5219\u590d\u5236 path \u5e76\u6dfb\u52a0\u8fdb\u7ed3\u679c\u5217\u8868 res \u3002\u904d\u5386\u5b8c\u6210\u540e\uff0cres \u4e2d\u4fdd\u5b58\u7684\u5c31\u662f\u6240\u6709\u7684\u89e3\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_ii_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c\"\"\"\n    if root is None:\n        return\n    # \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(list(path))\n    pre_order(root.left)\n    pre_order(root.right)\n    # \u56de\u9000\n    path.pop()\n
    preorder_traversal_ii_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push_back(root);\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(path);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    path.pop_back();\n}\n
    preorder_traversal_ii_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode root) {\n    if (root == null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(new ArrayList<>(path));\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n    // \u56de\u9000\n    path.remove(path.size() - 1);\n}\n
    preorder_traversal_ii_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.Add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(new List<TreeNode>(path));\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n    // \u56de\u9000\n    path.RemoveAt(path.Count - 1);\n}\n
    preorder_traversal_ii_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunc preOrderII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {\n    if root == nil {\n        return\n    }\n    // \u5c1d\u8bd5\n    *path = append(*path, root)\n    if root.Val.(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, append([]*TreeNode{}, *path...))\n    }\n    preOrderII(root.Left, res, path)\n    preOrderII(root.Right, res, path)\n    // \u56de\u9000\n    *path = (*path)[:len(*path)-1]\n}\n
    preorder_traversal_ii_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(path)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n    // \u56de\u9000\n    path.removeLast()\n}\n
    preorder_traversal_ii_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunction preOrder(root, path, res) {\n    if (root === null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_ii_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfunction preOrder(\n    root: TreeNode | null,\n    path: TreeNode[],\n    res: TreeNode[][]\n): void {\n    if (root === null) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_ii_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(\n  TreeNode? root,\n  List<TreeNode> path,\n  List<List<TreeNode>> res,\n) {\n  if (root == null) {\n    return;\n  }\n\n  // \u5c1d\u8bd5\n  path.add(root);\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(List.from(path));\n  }\n  preOrder(root.left, path, res);\n  preOrder(root.right, path, res);\n  // \u56de\u9000\n  path.removeLast();\n}\n
    preorder_traversal_ii_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfn pre_order(\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n    path: &mut Vec<Rc<RefCell<TreeNode>>>,\n    root: Option<Rc<RefCell<TreeNode>>>,\n) {\n    if root.is_none() {\n        return;\n    }\n    if let Some(node) = root {\n        // \u5c1d\u8bd5\n        path.push(node.clone());\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(path.clone());\n        }\n        pre_order(res, path, node.borrow().left.clone());\n        pre_order(res, path, node.borrow().right.clone());\n        // \u56de\u9000\n        path.remove(path.len() - 1);\n    }\n}\n
    preorder_traversal_ii_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nvoid preOrder(TreeNode *root) {\n    if (root == NULL) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path[pathSize++] = root;\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        for (int i = 0; i < pathSize; ++i) {\n            res[resSize][i] = path[i];\n        }\n        resSize++;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    pathSize--;\n}\n
    preorder_traversal_ii_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e8c */\nfun preOrder(root: TreeNode?) {\n    if (root == null) {\n        return\n    }\n    // \u5c1d\u8bd5\n    path!!.add(root)\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(path!!.toMutableList())\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n    // \u56de\u9000\n    path!!.removeAt(path!!.size - 1)\n}\n
    preorder_traversal_ii_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_ii_compact.zig
    [class]{}-[func]{preOrder}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5728\u6bcf\u6b21\u201c\u5c1d\u8bd5\u201d\u4e2d\uff0c\u6211\u4eec\u901a\u8fc7\u5c06\u5f53\u524d\u8282\u70b9\u6dfb\u52a0\u8fdb path \u6765\u8bb0\u5f55\u8def\u5f84\uff1b\u800c\u5728\u201c\u56de\u9000\u201d\u524d\uff0c\u6211\u4eec\u9700\u8981\u5c06\u8be5\u8282\u70b9\u4ece path \u4e2d\u5f39\u51fa\uff0c\u4ee5\u6062\u590d\u672c\u6b21\u5c1d\u8bd5\u4e4b\u524d\u7684\u72b6\u6001\u3002

    \u89c2\u5bdf\u56fe 13-2 \u6240\u793a\u7684\u8fc7\u7a0b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5c1d\u8bd5\u548c\u56de\u9000\u7406\u89e3\u4e3a\u201c\u524d\u8fdb\u201d\u4e0e\u201c\u64a4\u9500\u201d\uff0c\u4e24\u4e2a\u64cd\u4f5c\u4e92\u4e3a\u9006\u5411\u3002

    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 13-2 \u00a0 \u5c1d\u8bd5\u4e0e\u56de\u9000

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1312","title":"13.1.2 \u00a0 \u526a\u679d","text":"

    \u590d\u6742\u7684\u56de\u6eaf\u95ee\u9898\u901a\u5e38\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u7ea6\u675f\u6761\u4ef6\uff0c\u7ea6\u675f\u6761\u4ef6\u901a\u5e38\u53ef\u7528\u4e8e\u201c\u526a\u679d\u201d\u3002

    \u4f8b\u9898\u4e09

    \u5728\u4e8c\u53c9\u6811\u4e2d\u641c\u7d22\u6240\u6709\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\uff0c\u8bf7\u8fd4\u56de\u6839\u8282\u70b9\u5230\u8fd9\u4e9b\u8282\u70b9\u7684\u8def\u5f84\uff0c\u5e76\u8981\u6c42\u8def\u5f84\u4e2d\u4e0d\u5305\u542b\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\u3002

    \u4e3a\u4e86\u6ee1\u8db3\u4ee5\u4e0a\u7ea6\u675f\u6761\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u6dfb\u52a0\u526a\u679d\u64cd\u4f5c\uff1a\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u82e5\u9047\u5230\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\uff0c\u5219\u63d0\u524d\u8fd4\u56de\uff0c\u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_iii_compact.py
    def pre_order(root: TreeNode):\n    \"\"\"\u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09\"\"\"\n    # \u526a\u679d\n    if root is None or root.val == 3:\n        return\n    # \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7:\n        # \u8bb0\u5f55\u89e3\n        res.append(list(path))\n    pre_order(root.left)\n    pre_order(root.right)\n    # \u56de\u9000\n    path.pop()\n
    preorder_traversal_iii_compact.cpp
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode *root) {\n    // \u526a\u679d\n    if (root == nullptr || root->val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push_back(root);\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push_back(path);\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    path.pop_back();\n}\n
    preorder_traversal_iii_compact.java
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode root) {\n    // \u526a\u679d\n    if (root == null || root.val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.add(new ArrayList<>(path));\n    }\n    preOrder(root.left);\n    preOrder(root.right);\n    // \u56de\u9000\n    path.remove(path.size() - 1);\n}\n
    preorder_traversal_iii_compact.cs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid PreOrder(TreeNode? root) {\n    // \u526a\u679d\n    if (root == null || root.val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.Add(root);\n    if (root.val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res.Add(new List<TreeNode>(path));\n    }\n    PreOrder(root.left);\n    PreOrder(root.right);\n    // \u56de\u9000\n    path.RemoveAt(path.Count - 1);\n}\n
    preorder_traversal_iii_compact.go
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunc preOrderIII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {\n    // \u526a\u679d\n    if root == nil || root.Val == 3 {\n        return\n    }\n    // \u5c1d\u8bd5\n    *path = append(*path, root)\n    if root.Val.(int) == 7 {\n        // \u8bb0\u5f55\u89e3\n        *res = append(*res, append([]*TreeNode{}, *path...))\n    }\n    preOrderIII(root.Left, res, path)\n    preOrderIII(root.Right, res, path)\n    // \u56de\u9000\n    *path = (*path)[:len(*path)-1]\n}\n
    preorder_traversal_iii_compact.swift
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunc preOrder(root: TreeNode?) {\n    // \u526a\u679d\n    guard let root = root, root.val != 3 else {\n        return\n    }\n    // \u5c1d\u8bd5\n    path.append(root)\n    if root.val == 7 {\n        // \u8bb0\u5f55\u89e3\n        res.append(path)\n    }\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n    // \u56de\u9000\n    path.removeLast()\n}\n
    preorder_traversal_iii_compact.js
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunction preOrder(root, path, res) {\n    // \u526a\u679d\n    if (root === null || root.val === 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_iii_compact.ts
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfunction preOrder(\n    root: TreeNode | null,\n    path: TreeNode[],\n    res: TreeNode[][]\n): void {\n    // \u526a\u679d\n    if (root === null || root.val === 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path.push(root);\n    if (root.val === 7) {\n        // \u8bb0\u5f55\u89e3\n        res.push([...path]);\n    }\n    preOrder(root.left, path, res);\n    preOrder(root.right, path, res);\n    // \u56de\u9000\n    path.pop();\n}\n
    preorder_traversal_iii_compact.dart
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(\n  TreeNode? root,\n  List<TreeNode> path,\n  List<List<TreeNode>> res,\n) {\n  if (root == null || root.val == 3) {\n    return;\n  }\n\n  // \u5c1d\u8bd5\n  path.add(root);\n  if (root.val == 7) {\n    // \u8bb0\u5f55\u89e3\n    res.add(List.from(path));\n  }\n  preOrder(root.left, path, res);\n  preOrder(root.right, path, res);\n  // \u56de\u9000\n  path.removeLast();\n}\n
    preorder_traversal_iii_compact.rs
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfn pre_order(\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n    path: &mut Vec<Rc<RefCell<TreeNode>>>,\n    root: Option<Rc<RefCell<TreeNode>>>,\n) {\n    // \u526a\u679d\n    if root.is_none() || root.as_ref().unwrap().borrow().val == 3 {\n        return;\n    }\n    if let Some(node) = root {\n        // \u5c1d\u8bd5\n        path.push(node.clone());\n        if node.borrow().val == 7 {\n            // \u8bb0\u5f55\u89e3\n            res.push(path.clone());\n        }\n        pre_order(res, path, node.borrow().left.clone());\n        pre_order(res, path, node.borrow().right.clone());\n        // \u56de\u9000\n        path.remove(path.len() - 1);\n    }\n}\n
    preorder_traversal_iii_compact.c
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nvoid preOrder(TreeNode *root) {\n    // \u526a\u679d\n    if (root == NULL || root->val == 3) {\n        return;\n    }\n    // \u5c1d\u8bd5\n    path[pathSize++] = root;\n    if (root->val == 7) {\n        // \u8bb0\u5f55\u89e3\n        for (int i = 0; i < pathSize; i++) {\n            res[resSize][i] = path[i];\n        }\n        resSize++;\n    }\n    preOrder(root->left);\n    preOrder(root->right);\n    // \u56de\u9000\n    pathSize--;\n}\n
    preorder_traversal_iii_compact.kt
    /* \u524d\u5e8f\u904d\u5386\uff1a\u4f8b\u9898\u4e09 */\nfun preOrder(root: TreeNode?) {\n    // \u526a\u679d\n    if (root == null || root._val == 3) {\n        return\n    }\n    // \u5c1d\u8bd5\n    path!!.add(root)\n    if (root._val == 7) {\n        // \u8bb0\u5f55\u89e3\n        res!!.add(path!!.toMutableList())\n    }\n    preOrder(root.left)\n    preOrder(root.right)\n    // \u56de\u9000\n    path!!.removeAt(path!!.size - 1)\n}\n
    preorder_traversal_iii_compact.rb
    [class]{}-[func]{pre_order}\n
    preorder_traversal_iii_compact.zig
    [class]{}-[func]{preOrder}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u201c\u526a\u679d\u201d\u662f\u4e00\u4e2a\u975e\u5e38\u5f62\u8c61\u7684\u540d\u8bcd\u3002\u5982\u56fe 13-3 \u6240\u793a\uff0c\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u201c\u526a\u6389\u201d\u4e86\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u641c\u7d22\u5206\u652f\uff0c\u907f\u514d\u8bb8\u591a\u65e0\u610f\u4e49\u7684\u5c1d\u8bd5\uff0c\u4ece\u800c\u63d0\u9ad8\u4e86\u641c\u7d22\u6548\u7387\u3002

    \u56fe 13-3 \u00a0 \u6839\u636e\u7ea6\u675f\u6761\u4ef6\u526a\u679d

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1313","title":"13.1.3 \u00a0 \u6846\u67b6\u4ee3\u7801","text":"

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c1d\u8bd5\u5c06\u56de\u6eaf\u7684\u201c\u5c1d\u8bd5\u3001\u56de\u9000\u3001\u526a\u679d\u201d\u7684\u4e3b\u4f53\u6846\u67b6\u63d0\u70bc\u51fa\u6765\uff0c\u63d0\u5347\u4ee3\u7801\u7684\u901a\u7528\u6027\u3002

    \u5728\u4ee5\u4e0b\u6846\u67b6\u4ee3\u7801\u4e2d\uff0cstate \u8868\u793a\u95ee\u9898\u7684\u5f53\u524d\u72b6\u6001\uff0cchoices \u8868\u793a\u5f53\u524d\u72b6\u6001\u4e0b\u53ef\u4ee5\u505a\u51fa\u7684\u9009\u62e9\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def backtrack(state: State, choices: list[choice], res: list[state]):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\u6846\u67b6\"\"\"\n    # \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if is_solution(state):\n        # \u8bb0\u5f55\u89e3\n        record_solution(state, res)\n        # \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice):\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice)\n            backtrack(state, choices, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice)\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State *state, vector<Choice *> &choices, vector<State *> &res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Choice choice : choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State state, List<Choice> choices, List<State> res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Choice choice : choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid Backtrack(State state, List<Choice> choices, List<State> res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (IsSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        RecordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (Choice choice in choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (IsValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            MakeChoice(state, choice);\n            Backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            UndoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunc backtrack(state *State, choices []Choice, res *[]State) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if isSolution(state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range choices {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            backtrack(state, choices, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunc backtrack(state: inout State, choices: [Choice], res: inout [State]) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if isSolution(state: state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state: state, res: &res)\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state: state, choice: choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state: &state, choice: choice)\n            backtrack(state: &state, choices: choices, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state: &state, choice: choice)\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunction backtrack(state, choices, res) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let choice of choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfunction backtrack(state: State, choices: Choice[], res: State[]): void {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let choice of choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State state, List<Choice>, List<State> res) {\n  // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n  if (isSolution(state)) {\n    // \u8bb0\u5f55\u89e3\n    recordSolution(state, res);\n    // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (Choice choice in choices) {\n    // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n    if (isValid(state, choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      makeChoice(state, choice);\n      backtrack(state, choices, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      undoChoice(state, choice);\n    }\n  }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfn backtrack(state: &mut State, choices: &Vec<Choice>, res: &mut Vec<State>) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if is_solution(state) {\n        // \u8bb0\u5f55\u89e3\n        record_solution(state, res);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice);\n            backtrack(state, choices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nvoid backtrack(State *state, Choice *choices, int numChoices, State *res, int numRes) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res, numRes);\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < numChoices; i++) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, &choices[i])) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, &choices[i]);\n            backtrack(state, choices, numChoices, res, numRes);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, &choices[i]);\n        }\n    }\n}\n
    /* \u56de\u6eaf\u7b97\u6cd5\u6846\u67b6 */\nfun backtrack(state: State?, choices: List<Choice?>, res: List<State?>?) {\n    // \u5224\u65ad\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n        // \u4e0d\u518d\u7ee7\u7eed\u641c\u7d22\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u5224\u65ad\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            backtrack(state, choices, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    \n
    \n

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u57fa\u4e8e\u6846\u67b6\u4ee3\u7801\u6765\u89e3\u51b3\u4f8b\u9898\u4e09\u3002\u72b6\u6001 state \u4e3a\u8282\u70b9\u904d\u5386\u8def\u5f84\uff0c\u9009\u62e9 choices \u4e3a\u5f53\u524d\u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u548c\u53f3\u5b50\u8282\u70b9\uff0c\u7ed3\u679c res \u662f\u8def\u5f84\u5217\u8868\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig preorder_traversal_iii_template.py
    def is_solution(state: list[TreeNode]) -> bool:\n    \"\"\"\u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3\"\"\"\n    return state and state[-1].val == 7\n\ndef record_solution(state: list[TreeNode], res: list[list[TreeNode]]):\n    \"\"\"\u8bb0\u5f55\u89e3\"\"\"\n    res.append(list(state))\n\ndef is_valid(state: list[TreeNode], choice: TreeNode) -> bool:\n    \"\"\"\u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5\"\"\"\n    return choice is not None and choice.val != 3\n\ndef make_choice(state: list[TreeNode], choice: TreeNode):\n    \"\"\"\u66f4\u65b0\u72b6\u6001\"\"\"\n    state.append(choice)\n\ndef undo_choice(state: list[TreeNode], choice: TreeNode):\n    \"\"\"\u6062\u590d\u72b6\u6001\"\"\"\n    state.pop()\n\ndef backtrack(\n    state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09\"\"\"\n    # \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if is_solution(state):\n        # \u8bb0\u5f55\u89e3\n        record_solution(state, res)\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice):\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice)\n
    preorder_traversal_iii_template.cpp
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(vector<TreeNode *> &state) {\n    return !state.empty() && state.back()->val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(vector<TreeNode *> &state, vector<vector<TreeNode *>> &res) {\n    res.push_back(state);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(vector<TreeNode *> &state, TreeNode *choice) {\n    return choice != nullptr && choice->val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(vector<TreeNode *> &state, TreeNode *choice) {\n    state.push_back(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(vector<TreeNode *> &state, TreeNode *choice) {\n    state.pop_back();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(vector<TreeNode *> &state, vector<TreeNode *> &choices, vector<vector<TreeNode *>> &res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (TreeNode *choice : choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            vector<TreeNode *> nextChoices{choice->left, choice->right};\n            backtrack(state, nextChoices, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.java
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nboolean isSolution(List<TreeNode> state) {\n    return !state.isEmpty() && state.get(state.size() - 1).val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n    res.add(new ArrayList<>(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nboolean isValid(List<TreeNode> state, TreeNode choice) {\n    return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(List<TreeNode> state, TreeNode choice) {\n    state.add(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(List<TreeNode> state, TreeNode choice) {\n    state.remove(state.size() - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(List<TreeNode> state, List<TreeNode> choices, List<List<TreeNode>> res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (TreeNode choice : choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, Arrays.asList(choice.left, choice.right), res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.cs
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool IsSolution(List<TreeNode> state) {\n    return state.Count != 0 && state[^1].val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid RecordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n    res.Add(new List<TreeNode>(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool IsValid(List<TreeNode> state, TreeNode choice) {\n    return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid MakeChoice(List<TreeNode> state, TreeNode choice) {\n    state.Add(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid UndoChoice(List<TreeNode> state, TreeNode choice) {\n    state.RemoveAt(state.Count - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid Backtrack(List<TreeNode> state, List<TreeNode> choices, List<List<TreeNode>> res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (IsSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        RecordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (TreeNode choice in choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (IsValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            MakeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, [choice.left!, choice.right!], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            UndoChoice(state, choice);\n        }\n    }\n}\n
    preorder_traversal_iii_template.go
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunc isSolution(state *[]*TreeNode) bool {\n    return len(*state) != 0 && (*state)[len(*state)-1].Val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunc recordSolution(state *[]*TreeNode, res *[][]*TreeNode) {\n    *res = append(*res, append([]*TreeNode{}, *state...))\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunc isValid(state *[]*TreeNode, choice *TreeNode) bool {\n    return choice != nil && choice.Val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunc makeChoice(state *[]*TreeNode, choice *TreeNode) {\n    *state = append(*state, choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunc undoChoice(state *[]*TreeNode, choice *TreeNode) {\n    *state = (*state)[:len(*state)-1]\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunc backtrackIII(state *[]*TreeNode, choices *[]*TreeNode, res *[][]*TreeNode) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if isSolution(state) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range *choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state, choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            temp := make([]*TreeNode, 0)\n            temp = append(temp, choice.Left, choice.Right)\n            backtrackIII(state, &temp, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.swift
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunc isSolution(state: [TreeNode]) -> Bool {\n    !state.isEmpty && state.last!.val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunc recordSolution(state: [TreeNode], res: inout [[TreeNode]]) {\n    res.append(state)\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunc isValid(state: [TreeNode], choice: TreeNode?) -> Bool {\n    choice != nil && choice!.val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunc makeChoice(state: inout [TreeNode], choice: TreeNode) {\n    state.append(choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunc undoChoice(state: inout [TreeNode], choice: TreeNode) {\n    state.removeLast()\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunc backtrack(state: inout [TreeNode], choices: [TreeNode], res: inout [[TreeNode]]) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if isSolution(state: state) {\n        recordSolution(state: state, res: &res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if isValid(state: state, choice: choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state: &state, choice: choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: [choice.left, choice.right].compactMap { $0 }, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state: &state, choice: choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.js
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunction isSolution(state) {\n    return state && state[state.length - 1]?.val === 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunction recordSolution(state, res) {\n    res.push([...state]);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunction isValid(state, choice) {\n    return choice !== null && choice.val !== 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunction makeChoice(state, choice) {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunction undoChoice(state) {\n    state.pop();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunction backtrack(state, choices, res) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state);\n        }\n    }\n}\n
    preorder_traversal_iii_template.ts
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfunction isSolution(state: TreeNode[]): boolean {\n    return state && state[state.length - 1]?.val === 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfunction recordSolution(state: TreeNode[], res: TreeNode[][]): void {\n    res.push([...state]);\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfunction isValid(state: TreeNode[], choice: TreeNode): boolean {\n    return choice !== null && choice.val !== 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfunction makeChoice(state: TreeNode[], choice: TreeNode): void {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfunction undoChoice(state: TreeNode[]): void {\n    state.pop();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfunction backtrack(\n    state: TreeNode[],\n    choices: TreeNode[],\n    res: TreeNode[][]\n): void {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, [choice.left, choice.right], res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state);\n        }\n    }\n}\n
    preorder_traversal_iii_template.dart
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(List<TreeNode> state) {\n  return state.isNotEmpty && state.last.val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(List<TreeNode> state, List<List<TreeNode>> res) {\n  res.add(List.from(state));\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(List<TreeNode> state, TreeNode? choice) {\n  return choice != null && choice.val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(List<TreeNode> state, TreeNode? choice) {\n  state.add(choice!);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(List<TreeNode> state, TreeNode? choice) {\n  state.removeLast();\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(\n  List<TreeNode> state,\n  List<TreeNode?> choices,\n  List<List<TreeNode>> res,\n) {\n  // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n  if (isSolution(state)) {\n    // \u8bb0\u5f55\u89e3\n    recordSolution(state, res);\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (TreeNode? choice in choices) {\n    // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n    if (isValid(state, choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      makeChoice(state, choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, [choice!.left, choice.right], res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      undoChoice(state, choice);\n    }\n  }\n}\n
    preorder_traversal_iii_template.rs
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfn is_solution(state: &mut Vec<Rc<RefCell<TreeNode>>>) -> bool {\n    return !state.is_empty() && state.get(state.len() - 1).unwrap().borrow().val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfn record_solution(\n    state: &mut Vec<Rc<RefCell<TreeNode>>>,\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n) {\n    res.push(state.clone());\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfn is_valid(_: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) -> bool {\n    return choice.borrow().val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfn make_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) {\n    state.push(choice);\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfn undo_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, _: Rc<RefCell<TreeNode>>) {\n    state.remove(state.len() - 1);\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfn backtrack(\n    state: &mut Vec<Rc<RefCell<TreeNode>>>,\n    choices: &mut Vec<Rc<RefCell<TreeNode>>>,\n    res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>,\n) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if is_solution(state) {\n        // \u8bb0\u5f55\u89e3\n        record_solution(state, res);\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if is_valid(state, choice.clone()) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            make_choice(state, choice.clone());\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(\n                state,\n                &mut vec![\n                    choice.borrow().left.clone().unwrap(),\n                    choice.borrow().right.clone().unwrap(),\n                ],\n                res,\n            );\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undo_choice(state, choice.clone());\n        }\n    }\n}\n
    preorder_traversal_iii_template.c
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nbool isSolution(void) {\n    return pathSize > 0 && path[pathSize - 1]->val == 7;\n}\n\n/* \u8bb0\u5f55\u89e3 */\nvoid recordSolution(void) {\n    for (int i = 0; i < pathSize; i++) {\n        res[resSize][i] = path[i];\n    }\n    resSize++;\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nbool isValid(TreeNode *choice) {\n    return choice != NULL && choice->val != 3;\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nvoid makeChoice(TreeNode *choice) {\n    path[pathSize++] = choice;\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nvoid undoChoice(void) {\n    pathSize--;\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nvoid backtrack(TreeNode *choices[2]) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution()) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution();\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < 2; i++) {\n        TreeNode *choice = choices[i];\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            TreeNode *nextChoices[2] = {choice->left, choice->right};\n            backtrack(nextChoices);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice();\n        }\n    }\n}\n
    preorder_traversal_iii_template.kt
    /* \u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3a\u89e3 */\nfun isSolution(state: MutableList<TreeNode?>): Boolean {\n    return state.isNotEmpty() && state[state.size - 1]?._val == 7\n}\n\n/* \u8bb0\u5f55\u89e3 */\nfun recordSolution(state: MutableList<TreeNode?>?, res: MutableList<MutableList<TreeNode?>?>) {\n    res.add(state!!.toMutableList())\n}\n\n/* \u5224\u65ad\u5728\u5f53\u524d\u72b6\u6001\u4e0b\uff0c\u8be5\u9009\u62e9\u662f\u5426\u5408\u6cd5 */\nfun isValid(state: MutableList<TreeNode?>?, choice: TreeNode?): Boolean {\n    return choice != null && choice._val != 3\n}\n\n/* \u66f4\u65b0\u72b6\u6001 */\nfun makeChoice(state: MutableList<TreeNode?>, choice: TreeNode?) {\n    state.add(choice)\n}\n\n/* \u6062\u590d\u72b6\u6001 */\nfun undoChoice(state: MutableList<TreeNode?>, choice: TreeNode?) {\n    state.removeLast()\n}\n\n/* \u56de\u6eaf\u7b97\u6cd5\uff1a\u4f8b\u9898\u4e09 */\nfun backtrack(\n    state: MutableList<TreeNode?>,\n    choices: MutableList<TreeNode?>,\n    res: MutableList<MutableList<TreeNode?>?>\n) {\n    // \u68c0\u67e5\u662f\u5426\u4e3a\u89e3\n    if (isSolution(state)) {\n        // \u8bb0\u5f55\u89e3\n        recordSolution(state, res)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u68c0\u67e5\u9009\u62e9\u662f\u5426\u5408\u6cd5\n        if (isValid(state, choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            makeChoice(state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, mutableListOf(choice!!.left, choice.right), res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            undoChoice(state, choice)\n        }\n    }\n}\n
    preorder_traversal_iii_template.rb
    [class]{}-[func]{is_solution}\n\n[class]{}-[func]{record_solution}\n\n[class]{}-[func]{is_valid}\n\n[class]{}-[func]{make_choice}\n\n[class]{}-[func]{undo_choice}\n\n[class]{}-[func]{backtrack}\n
    preorder_traversal_iii_template.zig
    [class]{}-[func]{isSolution}\n\n[class]{}-[func]{recordSolution}\n\n[class]{}-[func]{isValid}\n\n[class]{}-[func]{makeChoice}\n\n[class]{}-[func]{undoChoice}\n\n[class]{}-[func]{backtrack}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6839\u636e\u9898\u610f\uff0c\u6211\u4eec\u5728\u627e\u5230\u503c\u4e3a \\(7\\) \u7684\u8282\u70b9\u540e\u5e94\u8be5\u7ee7\u7eed\u641c\u7d22\uff0c\u56e0\u6b64\u9700\u8981\u5c06\u8bb0\u5f55\u89e3\u4e4b\u540e\u7684 return \u8bed\u53e5\u5220\u9664\u3002\u56fe 13-4 \u5bf9\u6bd4\u4e86\u4fdd\u7559\u6216\u5220\u9664 return \u8bed\u53e5\u7684\u641c\u7d22\u8fc7\u7a0b\u3002

    \u56fe 13-4 \u00a0 \u4fdd\u7559\u4e0e\u5220\u9664 return \u7684\u641c\u7d22\u8fc7\u7a0b\u5bf9\u6bd4

    \u76f8\u6bd4\u57fa\u4e8e\u524d\u5e8f\u904d\u5386\u7684\u4ee3\u7801\u5b9e\u73b0\uff0c\u57fa\u4e8e\u56de\u6eaf\u7b97\u6cd5\u6846\u67b6\u7684\u4ee3\u7801\u5b9e\u73b0\u867d\u7136\u663e\u5f97\u5570\u5506\uff0c\u4f46\u901a\u7528\u6027\u66f4\u597d\u3002\u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u56de\u6eaf\u95ee\u9898\u53ef\u4ee5\u5728\u8be5\u6846\u67b6\u4e0b\u89e3\u51b3\u3002\u6211\u4eec\u53ea\u9700\u6839\u636e\u5177\u4f53\u95ee\u9898\u6765\u5b9a\u4e49 state \u548c choices \uff0c\u5e76\u5b9e\u73b0\u6846\u67b6\u4e2d\u7684\u5404\u4e2a\u65b9\u6cd5\u5373\u53ef\u3002

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1314","title":"13.1.4 \u00a0 \u5e38\u7528\u672f\u8bed","text":"

    \u4e3a\u4e86\u66f4\u6e05\u6670\u5730\u5206\u6790\u7b97\u6cd5\u95ee\u9898\uff0c\u6211\u4eec\u603b\u7ed3\u4e00\u4e0b\u56de\u6eaf\u7b97\u6cd5\u4e2d\u5e38\u7528\u672f\u8bed\u7684\u542b\u4e49\uff0c\u5e76\u5bf9\u7167\u4f8b\u9898\u4e09\u7ed9\u51fa\u5bf9\u5e94\u793a\u4f8b\uff0c\u5982\u8868 13-1 \u6240\u793a\u3002

    \u8868 13-1 \u00a0 \u5e38\u89c1\u7684\u56de\u6eaf\u7b97\u6cd5\u672f\u8bed

    \u540d\u8bcd \u5b9a\u4e49 \u4f8b\u9898\u4e09 \u89e3\uff08solution\uff09 \u89e3\u662f\u6ee1\u8db3\u95ee\u9898\u7279\u5b9a\u6761\u4ef6\u7684\u7b54\u6848\uff0c\u53ef\u80fd\u6709\u4e00\u4e2a\u6216\u591a\u4e2a \u6839\u8282\u70b9\u5230\u8282\u70b9 \\(7\\) \u7684\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u6240\u6709\u8def\u5f84 \u7ea6\u675f\u6761\u4ef6\uff08constraint\uff09 \u7ea6\u675f\u6761\u4ef6\u662f\u95ee\u9898\u4e2d\u9650\u5236\u89e3\u7684\u53ef\u884c\u6027\u7684\u6761\u4ef6\uff0c\u901a\u5e38\u7528\u4e8e\u526a\u679d \u8def\u5f84\u4e2d\u4e0d\u5305\u542b\u8282\u70b9 \\(3\\) \u72b6\u6001\uff08state\uff09 \u72b6\u6001\u8868\u793a\u95ee\u9898\u5728\u67d0\u4e00\u65f6\u523b\u7684\u60c5\u51b5\uff0c\u5305\u62ec\u5df2\u7ecf\u505a\u51fa\u7684\u9009\u62e9 \u5f53\u524d\u5df2\u8bbf\u95ee\u7684\u8282\u70b9\u8def\u5f84\uff0c\u5373 path \u8282\u70b9\u5217\u8868 \u5c1d\u8bd5\uff08attempt\uff09 \u5c1d\u8bd5\u662f\u6839\u636e\u53ef\u7528\u9009\u62e9\u6765\u63a2\u7d22\u89e3\u7a7a\u95f4\u7684\u8fc7\u7a0b\uff0c\u5305\u62ec\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\uff0c\u68c0\u67e5\u662f\u5426\u4e3a\u89e3 \u9012\u5f52\u8bbf\u95ee\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\uff0c\u5c06\u8282\u70b9\u6dfb\u52a0\u8fdb path \uff0c\u5224\u65ad\u8282\u70b9\u7684\u503c\u662f\u5426\u4e3a \\(7\\) \u56de\u9000\uff08backtracking\uff09 \u56de\u9000\u6307\u9047\u5230\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u72b6\u6001\u65f6\uff0c\u64a4\u9500\u524d\u9762\u505a\u51fa\u7684\u9009\u62e9\uff0c\u56de\u5230\u4e0a\u4e00\u4e2a\u72b6\u6001 \u5f53\u8d8a\u8fc7\u53f6\u8282\u70b9\u3001\u7ed3\u675f\u8282\u70b9\u8bbf\u95ee\u3001\u9047\u5230\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\u65f6\u7ec8\u6b62\u641c\u7d22\uff0c\u51fd\u6570\u8fd4\u56de \u526a\u679d\uff08pruning\uff09 \u526a\u679d\u662f\u6839\u636e\u95ee\u9898\u7279\u6027\u548c\u7ea6\u675f\u6761\u4ef6\u907f\u514d\u65e0\u610f\u4e49\u7684\u641c\u7d22\u8def\u5f84\u7684\u65b9\u6cd5\uff0c\u53ef\u63d0\u9ad8\u641c\u7d22\u6548\u7387 \u5f53\u9047\u5230\u503c\u4e3a \\(3\\) \u7684\u8282\u70b9\u65f6\uff0c\u5219\u4e0d\u518d\u7ee7\u7eed\u641c\u7d22

    Tip

    \u95ee\u9898\u3001\u89e3\u3001\u72b6\u6001\u7b49\u6982\u5ff5\u662f\u901a\u7528\u7684\uff0c\u5728\u5206\u6cbb\u3001\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\u3001\u8d2a\u5fc3\u7b49\u7b97\u6cd5\u4e2d\u90fd\u6709\u6d89\u53ca\u3002

    "},{"location":"chapter_backtracking/backtracking_algorithm/#1315","title":"13.1.5 \u00a0 \u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u56de\u6eaf\u7b97\u6cd5\u672c\u8d28\u4e0a\u662f\u4e00\u79cd\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u7b97\u6cd5\uff0c\u5b83\u5c1d\u8bd5\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\u76f4\u5230\u627e\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u89e3\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u4f18\u70b9\u5728\u4e8e\u80fd\u591f\u627e\u5230\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u800c\u4e14\u5728\u5408\u7406\u7684\u526a\u679d\u64cd\u4f5c\u4e0b\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u6548\u7387\u3002

    \u7136\u800c\uff0c\u5728\u5904\u7406\u5927\u89c4\u6a21\u6216\u8005\u590d\u6742\u95ee\u9898\u65f6\uff0c\u56de\u6eaf\u7b97\u6cd5\u7684\u8fd0\u884c\u6548\u7387\u53ef\u80fd\u96be\u4ee5\u63a5\u53d7\u3002

    • \u65f6\u95f4\uff1a\u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u9700\u8981\u904d\u5386\u72b6\u6001\u7a7a\u95f4\u7684\u6240\u6709\u53ef\u80fd\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u6307\u6570\u9636\u6216\u9636\u4e58\u9636\u3002
    • \u7a7a\u95f4\uff1a\u5728\u9012\u5f52\u8c03\u7528\u4e2d\u9700\u8981\u4fdd\u5b58\u5f53\u524d\u7684\u72b6\u6001\uff08\u4f8b\u5982\u8def\u5f84\u3001\u7528\u4e8e\u526a\u679d\u7684\u8f85\u52a9\u53d8\u91cf\u7b49\uff09\uff0c\u5f53\u6df1\u5ea6\u5f88\u5927\u65f6\uff0c\u7a7a\u95f4\u9700\u6c42\u53ef\u80fd\u4f1a\u53d8\u5f97\u5f88\u5927\u3002

    \u5373\u4fbf\u5982\u6b64\uff0c\u56de\u6eaf\u7b97\u6cd5\u4ecd\u7136\u662f\u67d0\u4e9b\u641c\u7d22\u95ee\u9898\u548c\u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\u7684\u6700\u4f73\u89e3\u51b3\u65b9\u6848\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u95ee\u9898\uff0c\u7531\u4e8e\u65e0\u6cd5\u9884\u6d4b\u54ea\u4e9b\u9009\u62e9\u53ef\u751f\u6210\u6709\u6548\u7684\u89e3\uff0c\u56e0\u6b64\u6211\u4eec\u5fc5\u987b\u5bf9\u6240\u6709\u53ef\u80fd\u7684\u9009\u62e9\u8fdb\u884c\u904d\u5386\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5173\u952e\u662f\u5982\u4f55\u4f18\u5316\u6548\u7387\uff0c\u5e38\u89c1\u7684\u6548\u7387\u4f18\u5316\u65b9\u6cd5\u6709\u4e24\u79cd\u3002

    • \u526a\u679d\uff1a\u907f\u514d\u641c\u7d22\u90a3\u4e9b\u80af\u5b9a\u4e0d\u4f1a\u4ea7\u751f\u89e3\u7684\u8def\u5f84\uff0c\u4ece\u800c\u8282\u7701\u65f6\u95f4\u548c\u7a7a\u95f4\u3002
    • \u542f\u53d1\u5f0f\u641c\u7d22\uff1a\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u5f15\u5165\u4e00\u4e9b\u7b56\u7565\u6216\u8005\u4f30\u8ba1\u503c\uff0c\u4ece\u800c\u4f18\u5148\u641c\u7d22\u6700\u6709\u53ef\u80fd\u4ea7\u751f\u6709\u6548\u89e3\u7684\u8def\u5f84\u3002
    "},{"location":"chapter_backtracking/backtracking_algorithm/#1316","title":"13.1.6 \u00a0 \u56de\u6eaf\u5178\u578b\u4f8b\u9898","text":"

    \u56de\u6eaf\u7b97\u6cd5\u53ef\u7528\u4e8e\u89e3\u51b3\u8bb8\u591a\u641c\u7d22\u95ee\u9898\u3001\u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\u548c\u7ec4\u5408\u4f18\u5316\u95ee\u9898\u3002

    \u641c\u7d22\u95ee\u9898\uff1a\u8fd9\u7c7b\u95ee\u9898\u7684\u76ee\u6807\u662f\u627e\u5230\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u7684\u89e3\u51b3\u65b9\u6848\u3002

    • \u5168\u6392\u5217\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u96c6\u5408\uff0c\u6c42\u51fa\u5176\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u7ec4\u5408\u3002
    • \u5b50\u96c6\u548c\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u96c6\u5408\u548c\u4e00\u4e2a\u76ee\u6807\u548c\uff0c\u627e\u5230\u96c6\u5408\u4e2d\u6240\u6709\u548c\u4e3a\u76ee\u6807\u548c\u7684\u5b50\u96c6\u3002
    • \u6c49\u8bfa\u5854\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e09\u6839\u67f1\u5b50\u548c\u4e00\u7cfb\u5217\u5927\u5c0f\u4e0d\u540c\u7684\u5706\u76d8\uff0c\u8981\u6c42\u5c06\u6240\u6709\u5706\u76d8\u4ece\u4e00\u6839\u67f1\u5b50\u79fb\u52a8\u5230\u53e6\u4e00\u6839\u67f1\u5b50\uff0c\u6bcf\u6b21\u53ea\u80fd\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\uff0c\u4e14\u4e0d\u80fd\u5c06\u5927\u5706\u76d8\u653e\u5728\u5c0f\u5706\u76d8\u4e0a\u3002

    \u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\uff1a\u8fd9\u7c7b\u95ee\u9898\u7684\u76ee\u6807\u662f\u627e\u5230\u6ee1\u8db3\u6240\u6709\u7ea6\u675f\u6761\u4ef6\u7684\u89e3\u3002

    • \\(n\\) \u7687\u540e\uff1a\u5728 \\(n \\times n\\) \u7684\u68cb\u76d8\u4e0a\u653e\u7f6e \\(n\\) \u4e2a\u7687\u540e\uff0c\u4f7f\u5f97\u5b83\u4eec\u4e92\u4e0d\u653b\u51fb\u3002
    • \u6570\u72ec\uff1a\u5728 \\(9 \\times 9\\) \u7684\u7f51\u683c\u4e2d\u586b\u5165\u6570\u5b57 \\(1\\) ~ \\(9\\) \uff0c\u4f7f\u5f97\u6bcf\u884c\u3001\u6bcf\u5217\u548c\u6bcf\u4e2a \\(3 \\times 3\\) \u5b50\u7f51\u683c\u4e2d\u7684\u6570\u5b57\u4e0d\u91cd\u590d\u3002
    • \u56fe\u7740\u8272\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u65e0\u5411\u56fe\uff0c\u7528\u6700\u5c11\u7684\u989c\u8272\u7ed9\u56fe\u7684\u6bcf\u4e2a\u9876\u70b9\u7740\u8272\uff0c\u4f7f\u5f97\u76f8\u90bb\u9876\u70b9\u989c\u8272\u4e0d\u540c\u3002

    \u7ec4\u5408\u4f18\u5316\u95ee\u9898\uff1a\u8fd9\u7c7b\u95ee\u9898\u7684\u76ee\u6807\u662f\u5728\u4e00\u4e2a\u7ec4\u5408\u7a7a\u95f4\u4e2d\u627e\u5230\u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u7684\u6700\u4f18\u89e3\u3002

    • 0-1 \u80cc\u5305\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u7269\u54c1\u548c\u4e00\u4e2a\u80cc\u5305\uff0c\u6bcf\u4e2a\u7269\u54c1\u6709\u4e00\u5b9a\u7684\u4ef7\u503c\u548c\u91cd\u91cf\uff0c\u8981\u6c42\u5728\u80cc\u5305\u5bb9\u91cf\u9650\u5236\u5185\uff0c\u9009\u62e9\u7269\u54c1\u4f7f\u5f97\u603b\u4ef7\u503c\u6700\u5927\u3002
    • \u65c5\u884c\u5546\u95ee\u9898\uff1a\u5728\u4e00\u4e2a\u56fe\u4e2d\uff0c\u4ece\u4e00\u4e2a\u70b9\u51fa\u53d1\uff0c\u8bbf\u95ee\u6240\u6709\u5176\u4ed6\u70b9\u6070\u597d\u4e00\u6b21\u540e\u8fd4\u56de\u8d77\u70b9\uff0c\u6c42\u6700\u77ed\u8def\u5f84\u3002
    • \u6700\u5927\u56e2\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u65e0\u5411\u56fe\uff0c\u627e\u5230\u6700\u5927\u7684\u5b8c\u5168\u5b50\u56fe\uff0c\u5373\u5b50\u56fe\u4e2d\u7684\u4efb\u610f\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u90fd\u6709\u8fb9\u76f8\u8fde\u3002

    \u8bf7\u6ce8\u610f\uff0c\u5bf9\u4e8e\u8bb8\u591a\u7ec4\u5408\u4f18\u5316\u95ee\u9898\uff0c\u56de\u6eaf\u4e0d\u662f\u6700\u4f18\u89e3\u51b3\u65b9\u6848\u3002

    • 0-1 \u80cc\u5305\u95ee\u9898\u901a\u5e38\u4f7f\u7528\u52a8\u6001\u89c4\u5212\u89e3\u51b3\uff0c\u4ee5\u8fbe\u5230\u66f4\u9ad8\u7684\u65f6\u95f4\u6548\u7387\u3002
    • \u65c5\u884c\u5546\u662f\u4e00\u4e2a\u8457\u540d\u7684 NP-Hard \u95ee\u9898\uff0c\u5e38\u7528\u89e3\u6cd5\u6709\u9057\u4f20\u7b97\u6cd5\u548c\u8681\u7fa4\u7b97\u6cd5\u7b49\u3002
    • \u6700\u5927\u56e2\u95ee\u9898\u662f\u56fe\u8bba\u4e2d\u7684\u4e00\u4e2a\u7ecf\u5178\u95ee\u9898\uff0c\u53ef\u7528\u8d2a\u5fc3\u7b97\u6cd5\u7b49\u542f\u53d1\u5f0f\u7b97\u6cd5\u6765\u89e3\u51b3\u3002
    "},{"location":"chapter_backtracking/n_queens_problem/","title":"13.4 \u00a0 n \u7687\u540e\u95ee\u9898","text":"

    Question

    \u6839\u636e\u56fd\u9645\u8c61\u68cb\u7684\u89c4\u5219\uff0c\u7687\u540e\u53ef\u4ee5\u653b\u51fb\u4e0e\u540c\u5904\u4e00\u884c\u3001\u4e00\u5217\u6216\u4e00\u6761\u659c\u7ebf\u4e0a\u7684\u68cb\u5b50\u3002\u7ed9\u5b9a \\(n\\) \u4e2a\u7687\u540e\u548c\u4e00\u4e2a \\(n \\times n\\) \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5bfb\u627e\u4f7f\u5f97\u6240\u6709\u7687\u540e\u4e4b\u95f4\u65e0\u6cd5\u76f8\u4e92\u653b\u51fb\u7684\u6446\u653e\u65b9\u6848\u3002

    \u5982\u56fe 13-15 \u6240\u793a\uff0c\u5f53 \\(n = 4\\) \u65f6\uff0c\u5171\u53ef\u4ee5\u627e\u5230\u4e24\u4e2a\u89e3\u3002\u4ece\u56de\u6eaf\u7b97\u6cd5\u7684\u89d2\u5ea6\u770b\uff0c\\(n \\times n\\) \u5927\u5c0f\u7684\u68cb\u76d8\u5171\u6709 \\(n^2\\) \u4e2a\u683c\u5b50\uff0c\u7ed9\u51fa\u4e86\u6240\u6709\u7684\u9009\u62e9 choices \u3002\u5728\u9010\u4e2a\u653e\u7f6e\u7687\u540e\u7684\u8fc7\u7a0b\u4e2d\uff0c\u68cb\u76d8\u72b6\u6001\u5728\u4e0d\u65ad\u5730\u53d8\u5316\uff0c\u6bcf\u4e2a\u65f6\u523b\u7684\u68cb\u76d8\u5c31\u662f\u72b6\u6001 state \u3002

    \u56fe 13-15 \u00a0 4 \u7687\u540e\u95ee\u9898\u7684\u89e3

    \u56fe 13-16 \u5c55\u793a\u4e86\u672c\u9898\u7684\u4e09\u4e2a\u7ea6\u675f\u6761\u4ef6\uff1a\u591a\u4e2a\u7687\u540e\u4e0d\u80fd\u5728\u540c\u4e00\u884c\u3001\u540c\u4e00\u5217\u3001\u540c\u4e00\u6761\u5bf9\u89d2\u7ebf\u4e0a\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u5bf9\u89d2\u7ebf\u5206\u4e3a\u4e3b\u5bf9\u89d2\u7ebf \\ \u548c\u6b21\u5bf9\u89d2\u7ebf / \u4e24\u79cd\u3002

    \u56fe 13-16 \u00a0 n \u7687\u540e\u95ee\u9898\u7684\u7ea6\u675f\u6761\u4ef6

    "},{"location":"chapter_backtracking/n_queens_problem/#1","title":"1. \u00a0 \u9010\u884c\u653e\u7f6e\u7b56\u7565","text":"

    \u7687\u540e\u7684\u6570\u91cf\u548c\u68cb\u76d8\u7684\u884c\u6570\u90fd\u4e3a \\(n\\) \uff0c\u56e0\u6b64\u6211\u4eec\u5bb9\u6613\u5f97\u5230\u4e00\u4e2a\u63a8\u8bba\uff1a\u68cb\u76d8\u6bcf\u884c\u90fd\u5141\u8bb8\u4e14\u53ea\u5141\u8bb8\u653e\u7f6e\u4e00\u4e2a\u7687\u540e\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u53d6\u9010\u884c\u653e\u7f6e\u7b56\u7565\uff1a\u4ece\u7b2c\u4e00\u884c\u5f00\u59cb\uff0c\u5728\u6bcf\u884c\u653e\u7f6e\u4e00\u4e2a\u7687\u540e\uff0c\u76f4\u81f3\u6700\u540e\u4e00\u884c\u7ed3\u675f\u3002

    \u56fe 13-17 \u6240\u793a\u4e3a \\(4\\) \u7687\u540e\u95ee\u9898\u7684\u9010\u884c\u653e\u7f6e\u8fc7\u7a0b\u3002\u53d7\u753b\u5e45\u9650\u5236\uff0c\u56fe 13-17 \u4ec5\u5c55\u5f00\u4e86\u7b2c\u4e00\u884c\u7684\u5176\u4e2d\u4e00\u4e2a\u641c\u7d22\u5206\u652f\uff0c\u5e76\u4e14\u5c06\u4e0d\u6ee1\u8db3\u5217\u7ea6\u675f\u548c\u5bf9\u89d2\u7ebf\u7ea6\u675f\u7684\u65b9\u6848\u90fd\u8fdb\u884c\u4e86\u526a\u679d\u3002

    \u56fe 13-17 \u00a0 \u9010\u884c\u653e\u7f6e\u7b56\u7565

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u9010\u884c\u653e\u7f6e\u7b56\u7565\u8d77\u5230\u4e86\u526a\u679d\u7684\u4f5c\u7528\uff0c\u5b83\u907f\u514d\u4e86\u540c\u4e00\u884c\u51fa\u73b0\u591a\u4e2a\u7687\u540e\u7684\u6240\u6709\u641c\u7d22\u5206\u652f\u3002

    "},{"location":"chapter_backtracking/n_queens_problem/#2","title":"2. \u00a0 \u5217\u4e0e\u5bf9\u89d2\u7ebf\u526a\u679d","text":"

    \u4e3a\u4e86\u6ee1\u8db3\u5217\u7ea6\u675f\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u5e03\u5c14\u578b\u6570\u7ec4 cols \u8bb0\u5f55\u6bcf\u4e00\u5217\u662f\u5426\u6709\u7687\u540e\u3002\u5728\u6bcf\u6b21\u51b3\u5b9a\u653e\u7f6e\u524d\uff0c\u6211\u4eec\u901a\u8fc7 cols \u5c06\u5df2\u6709\u7687\u540e\u7684\u5217\u8fdb\u884c\u526a\u679d\uff0c\u5e76\u5728\u56de\u6eaf\u4e2d\u52a8\u6001\u66f4\u65b0 cols \u7684\u72b6\u6001\u3002

    \u90a3\u4e48\uff0c\u5982\u4f55\u5904\u7406\u5bf9\u89d2\u7ebf\u7ea6\u675f\u5462\uff1f\u8bbe\u68cb\u76d8\u4e2d\u67d0\u4e2a\u683c\u5b50\u7684\u884c\u5217\u7d22\u5f15\u4e3a \\((row, col)\\) \uff0c\u9009\u5b9a\u77e9\u9635\u4e2d\u7684\u67d0\u6761\u4e3b\u5bf9\u89d2\u7ebf\uff0c\u6211\u4eec\u53d1\u73b0\u8be5\u5bf9\u89d2\u7ebf\u4e0a\u6240\u6709\u683c\u5b50\u7684\u884c\u7d22\u5f15\u51cf\u5217\u7d22\u5f15\u90fd\u76f8\u7b49\uff0c\u5373\u5bf9\u89d2\u7ebf\u4e0a\u6240\u6709\u683c\u5b50\u7684 \\(row - col\\) \u4e3a\u6052\u5b9a\u503c\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u4e24\u4e2a\u683c\u5b50\u6ee1\u8db3 \\(row_1 - col_1 = row_2 - col_2\\) \uff0c\u5219\u5b83\u4eec\u4e00\u5b9a\u5904\u5728\u540c\u4e00\u6761\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u3002\u5229\u7528\u8be5\u89c4\u5f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u501f\u52a9\u56fe 13-18 \u6240\u793a\u7684\u6570\u7ec4 diags1 \u8bb0\u5f55\u6bcf\u6761\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\u3002

    \u540c\u7406\uff0c\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u7684\u6240\u6709\u683c\u5b50\u7684 \\(row + col\\) \u662f\u6052\u5b9a\u503c\u3002\u6211\u4eec\u540c\u6837\u4e5f\u53ef\u4ee5\u501f\u52a9\u6570\u7ec4 diags2 \u6765\u5904\u7406\u6b21\u5bf9\u89d2\u7ebf\u7ea6\u675f\u3002

    \u56fe 13-18 \u00a0 \u5904\u7406\u5217\u7ea6\u675f\u548c\u5bf9\u89d2\u7ebf\u7ea6\u675f

    "},{"location":"chapter_backtracking/n_queens_problem/#3","title":"3. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u8bf7\u6ce8\u610f\uff0c\\(n\\) \u7ef4\u65b9\u9635\u4e2d \\(row - col\\) \u7684\u8303\u56f4\u662f \\([-n + 1, n - 1]\\) \uff0c\\(row + col\\) \u7684\u8303\u56f4\u662f \\([0, 2n - 2]\\) \uff0c\u6240\u4ee5\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\u7684\u6570\u91cf\u90fd\u4e3a \\(2n - 1\\) \uff0c\u5373\u6570\u7ec4 diags1 \u548c diags2 \u7684\u957f\u5ea6\u90fd\u4e3a \\(2n - 1\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig n_queens.py
    def backtrack(\n    row: int,\n    n: int,\n    state: list[list[str]],\n    res: list[list[list[str]]],\n    cols: list[bool],\n    diags1: list[bool],\n    diags2: list[bool],\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e\"\"\"\n    # \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n:\n        res.append([list(row) for row in state])\n        return\n    # \u904d\u5386\u6240\u6709\u5217\n    for col in range(n):\n        # \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        diag1 = row - col + n - 1\n        diag2 = row + col\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if not cols[col] and not diags1[diag1] and not diags2[diag2]:\n            # \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            cols[col] = diags1[diag1] = diags2[diag2] = True\n            # \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2)\n            # \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            cols[col] = diags1[diag1] = diags2[diag2] = False\n\ndef n_queens(n: int) -> list[list[list[str]]]:\n    \"\"\"\u6c42\u89e3 n \u7687\u540e\"\"\"\n    # \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    state = [[\"#\" for _ in range(n)] for _ in range(n)]\n    cols = [False] * n  # \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    diags1 = [False] * (2 * n - 1)  # \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    diags2 = [False] * (2 * n - 1)  # \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    res = []\n    backtrack(0, n, state, res, cols, diags1, diags2)\n\n    return res\n
    n_queens.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, vector<vector<string>> &state, vector<vector<vector<string>>> &res, vector<bool> &cols,\n               vector<bool> &diags1, vector<bool> &diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\";\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\";\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nvector<vector<vector<string>>> nQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    vector<vector<string>> state(n, vector<string>(n, \"#\"));\n    vector<bool> cols(n, false);           // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    vector<bool> diags1(2 * n - 1, false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    vector<bool> diags2(2 * n - 1, false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    vector<vector<vector<string>>> res;\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, List<List<String>> state, List<List<List<String>>> res,\n        boolean[] cols, boolean[] diags1, boolean[] diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        List<List<String>> copyState = new ArrayList<>();\n        for (List<String> sRow : state) {\n            copyState.add(new ArrayList<>(sRow));\n        }\n        res.add(copyState);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state.get(row).set(col, \"Q\");\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state.get(row).set(col, \"#\");\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<String>>> nQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    List<List<String>> state = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<String> row = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            row.add(\"#\");\n        }\n        state.add(row);\n    }\n    boolean[] cols = new boolean[n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    boolean[] diags1 = new boolean[2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    boolean[] diags2 = new boolean[2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    List<List<List<String>>> res = new ArrayList<>();\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid Backtrack(int row, int n, List<List<string>> state, List<List<List<string>>> res,\n        bool[] cols, bool[] diags1, bool[] diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        List<List<string>> copyState = [];\n        foreach (List<string> sRow in state) {\n            copyState.Add(new List<string>(sRow));\n        }\n        res.Add(copyState);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\";\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            Backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\";\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<string>>> NQueens(int n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    List<List<string>> state = [];\n    for (int i = 0; i < n; i++) {\n        List<string> row = [];\n        for (int j = 0; j < n; j++) {\n            row.Add(\"#\");\n        }\n        state.Add(row);\n    }\n    bool[] cols = new bool[n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    bool[] diags1 = new bool[2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    bool[] diags2 = new bool[2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    List<List<List<string>>> res = [];\n\n    Backtrack(0, n, state, res, cols, diags1, diags2);\n\n    return res;\n}\n
    n_queens.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunc backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        newState := make([][]string, len(*state))\n        for i, _ := range newState {\n            newState[i] = make([]string, len((*state)[0]))\n            copy(newState[i], (*state)[i])\n\n        }\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col := 0; col < n; col++ {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        diag1 := row - col + n - 1\n        diag2 := row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !(*cols)[col] && !(*diags1)[diag1] && !(*diags2)[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            (*state)[row][col] = \"Q\"\n            (*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = true, true, true\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row+1, n, state, res, cols, diags1, diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            (*state)[row][col] = \"#\"\n            (*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = false, false, false\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunc nQueens(n int) [][][]string {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    state := make([][]string, n)\n    for i := 0; i < n; i++ {\n        row := make([]string, n)\n        for i := 0; i < n; i++ {\n            row[i] = \"#\"\n        }\n        state[i] = row\n    }\n    // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    cols := make([]bool, n)\n    diags1 := make([]bool, 2*n-1)\n    diags2 := make([]bool, 2*n-1)\n    res := make([][][]string, 0)\n    backtrack(0, n, &state, &res, &cols, &diags1, &diags2)\n    return res\n}\n
    n_queens.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunc backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]], cols: inout [Bool], diags1: inout [Bool], diags2: inout [Bool]) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col in 0 ..< n {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        let diag1 = row - col + n - 1\n        let diag2 = row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !cols[col] && !diags1[diag1] && !diags2[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            cols[col] = true\n            diags1[diag1] = true\n            diags2[diag2] = true\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row: row + 1, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            cols[col] = false\n            diags1[diag1] = false\n            diags2[diag2] = false\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunc nQueens(n: Int) -> [[[String]]] {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    var state = Array(repeating: Array(repeating: \"#\", count: n), count: n)\n    var cols = Array(repeating: false, count: n) // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    var diags1 = Array(repeating: false, count: 2 * n - 1) // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    var diags2 = Array(repeating: false, count: 2 * n - 1) // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    var res: [[[String]]] = []\n\n    backtrack(row: 0, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)\n\n    return res\n}\n
    n_queens.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunction backtrack(row, n, state, res, cols, diags1, diags2) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row === n) {\n        res.push(state.map((row) => row.slice()));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (let col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        const diag1 = row - col + n - 1;\n        const diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunction nQueens(n) {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    const state = Array.from({ length: n }, () => Array(n).fill('#'));\n    const cols = Array(n).fill(false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    const diags1 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const diags2 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const res = [];\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfunction backtrack(\n    row: number,\n    n: number,\n    state: string[][],\n    res: string[][][],\n    cols: boolean[],\n    diags1: boolean[],\n    diags2: boolean[]\n): void {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row === n) {\n        res.push(state.map((row) => row.slice()));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (let col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        const diag1 = row - col + n - 1;\n        const diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfunction nQueens(n: number): string[][][] {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    const state = Array.from({ length: n }, () => Array(n).fill('#'));\n    const cols = Array(n).fill(false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    const diags1 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const diags2 = Array(2 * n - 1).fill(false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    const res: string[][][] = [];\n\n    backtrack(0, n, state, res, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(\n  int row,\n  int n,\n  List<List<String>> state,\n  List<List<List<String>>> res,\n  List<bool> cols,\n  List<bool> diags1,\n  List<bool> diags2,\n) {\n  // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (row == n) {\n    List<List<String>> copyState = [];\n    for (List<String> sRow in state) {\n      copyState.add(List.from(sRow));\n    }\n    res.add(copyState);\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u5217\n  for (int col = 0; col < n; col++) {\n    // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n    int diag1 = row - col + n - 1;\n    int diag2 = row + col;\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n    if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n      // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n      state[row][col] = \"Q\";\n      cols[col] = true;\n      diags1[diag1] = true;\n      diags2[diag2] = true;\n      // \u653e\u7f6e\u4e0b\u4e00\u884c\n      backtrack(row + 1, n, state, res, cols, diags1, diags2);\n      // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n      state[row][col] = \"#\";\n      cols[col] = false;\n      diags1[diag1] = false;\n      diags2[diag2] = false;\n    }\n  }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nList<List<List<String>>> nQueens(int n) {\n  // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n  List<List<String>> state = List.generate(n, (index) => List.filled(n, \"#\"));\n  List<bool> cols = List.filled(n, false); // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n  List<bool> diags1 = List.filled(2 * n - 1, false); // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n  List<bool> diags2 = List.filled(2 * n - 1, false); // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n  List<List<List<String>>> res = [];\n\n  backtrack(0, n, state, res, cols, diags1, diags2);\n\n  return res;\n}\n
    n_queens.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfn backtrack(\n    row: usize,\n    n: usize,\n    state: &mut Vec<Vec<String>>,\n    res: &mut Vec<Vec<Vec<String>>>,\n    cols: &mut [bool],\n    diags1: &mut [bool],\n    diags2: &mut [bool],\n) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if row == n {\n        let mut copy_state: Vec<Vec<String>> = Vec::new();\n        for s_row in state.clone() {\n            copy_state.push(s_row);\n        }\n        res.push(copy_state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for col in 0..n {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        let diag1 = row + n - 1 - col;\n        let diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if !cols[col] && !diags1[diag1] && !diags2[diag2] {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state.get_mut(row).unwrap()[col] = \"Q\".into();\n            (cols[col], diags1[diag1], diags2[diag2]) = (true, true, true);\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state.get_mut(row).unwrap()[col] = \"#\".into();\n            (cols[col], diags1[diag1], diags2[diag2]) = (false, false, false);\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    let mut state: Vec<Vec<String>> = Vec::new();\n    for _ in 0..n {\n        let mut row: Vec<String> = Vec::new();\n        for _ in 0..n {\n            row.push(\"#\".into());\n        }\n        state.push(row);\n    }\n    let mut cols = vec![false; n]; // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    let mut diags1 = vec![false; 2 * n - 1]; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    let mut diags2 = vec![false; 2 * n - 1]; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    let mut res: Vec<Vec<Vec<String>>> = Vec::new();\n\n    backtrack(\n        0,\n        n,\n        &mut state,\n        &mut res,\n        &mut cols,\n        &mut diags1,\n        &mut diags2,\n    );\n\n    res\n}\n
    n_queens.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nvoid backtrack(int row, int n, char state[MAX_SIZE][MAX_SIZE], char ***res, int *resSize, bool cols[MAX_SIZE],\n               bool diags1[2 * MAX_SIZE - 1], bool diags2[2 * MAX_SIZE - 1]) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        res[*resSize] = (char **)malloc(sizeof(char *) * n);\n        for (int i = 0; i < n; ++i) {\n            res[*resSize][i] = (char *)malloc(sizeof(char) * (n + 1));\n            strcpy(res[*resSize][i], state[i]);\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (int col = 0; col < n; col++) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        int diag1 = row - col + n - 1;\n        int diag2 = row + col;\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = 'Q';\n            cols[col] = diags1[diag1] = diags2[diag2] = true;\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, resSize, cols, diags1, diags2);\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = '#';\n            cols[col] = diags1[diag1] = diags2[diag2] = false;\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nchar ***nQueens(int n, int *returnSize) {\n    char state[MAX_SIZE][MAX_SIZE];\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            state[i][j] = '#';\n        }\n        state[i][n] = '\\0';\n    }\n    bool cols[MAX_SIZE] = {false};           // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    bool diags1[2 * MAX_SIZE - 1] = {false}; // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    bool diags2[2 * MAX_SIZE - 1] = {false}; // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n\n    char ***res = (char ***)malloc(sizeof(char **) * MAX_SIZE);\n    *returnSize = 0;\n    backtrack(0, n, state, res, returnSize, cols, diags1, diags2);\n    return res;\n}\n
    n_queens.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1an \u7687\u540e */\nfun backtrack(\n    row: Int,\n    n: Int,\n    state: MutableList<MutableList<String>>,\n    res: MutableList<MutableList<MutableList<String>>?>,\n    cols: BooleanArray,\n    diags1: BooleanArray,\n    diags2: BooleanArray\n) {\n    // \u5f53\u653e\u7f6e\u5b8c\u6240\u6709\u884c\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (row == n) {\n        val copyState = mutableListOf<MutableList<String>>()\n        for (sRow in state) {\n            copyState.add(sRow.toMutableList())\n        }\n        res.add(copyState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u5217\n    for (col in 0..<n) {\n        // \u8ba1\u7b97\u8be5\u683c\u5b50\u5bf9\u5e94\u7684\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\n        val diag1 = row - col + n - 1\n        val diag2 = row + col\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8be5\u683c\u5b50\u6240\u5728\u5217\u3001\u4e3b\u5bf9\u89d2\u7ebf\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u5b58\u5728\u7687\u540e\n        if (!cols[col] && !diags1[diag1] && !diags2[diag2]) {\n            // \u5c1d\u8bd5\uff1a\u5c06\u7687\u540e\u653e\u7f6e\u5728\u8be5\u683c\u5b50\n            state[row][col] = \"Q\"\n            diags2[diag2] = true\n            diags1[diag1] = diags2[diag2]\n            cols[col] = diags1[diag1]\n            // \u653e\u7f6e\u4e0b\u4e00\u884c\n            backtrack(row + 1, n, state, res, cols, diags1, diags2)\n            // \u56de\u9000\uff1a\u5c06\u8be5\u683c\u5b50\u6062\u590d\u4e3a\u7a7a\u4f4d\n            state[row][col] = \"#\"\n            diags2[diag2] = false\n            diags1[diag1] = diags2[diag2]\n            cols[col] = diags1[diag1]\n        }\n    }\n}\n\n/* \u6c42\u89e3 n \u7687\u540e */\nfun nQueens(n: Int): MutableList<MutableList<MutableList<String>>?> {\n    // \u521d\u59cb\u5316 n*n \u5927\u5c0f\u7684\u68cb\u76d8\uff0c\u5176\u4e2d 'Q' \u4ee3\u8868\u7687\u540e\uff0c'#' \u4ee3\u8868\u7a7a\u4f4d\n    val state = mutableListOf<MutableList<String>>()\n    for (i in 0..<n) {\n        val row = mutableListOf<String>()\n        for (j in 0..<n) {\n            row.add(\"#\")\n        }\n        state.add(row)\n    }\n    val cols = BooleanArray(n) // \u8bb0\u5f55\u5217\u662f\u5426\u6709\u7687\u540e\n    val diags1 = BooleanArray(2 * n - 1) // \u8bb0\u5f55\u4e3b\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    val diags2 = BooleanArray(2 * n - 1) // \u8bb0\u5f55\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u6709\u7687\u540e\n    val res = mutableListOf<MutableList<MutableList<String>>?>()\n\n    backtrack(0, n, state, res, cols, diags1, diags2)\n\n    return res\n}\n
    n_queens.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{n_queens}\n
    n_queens.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{nQueens}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u9010\u884c\u653e\u7f6e \\(n\\) \u6b21\uff0c\u8003\u8651\u5217\u7ea6\u675f\uff0c\u5219\u4ece\u7b2c\u4e00\u884c\u5230\u6700\u540e\u4e00\u884c\u5206\u522b\u6709 \\(n\\)\u3001\\(n-1\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \u4e2a\u9009\u62e9\uff0c\u4f7f\u7528 \\(O(n!)\\) \u65f6\u95f4\u3002\u5f53\u8bb0\u5f55\u89e3\u65f6\uff0c\u9700\u8981\u590d\u5236\u77e9\u9635 state \u5e76\u6dfb\u52a0\u8fdb res \uff0c\u590d\u5236\u64cd\u4f5c\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002\u56e0\u6b64\uff0c\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n! \\cdot n^2)\\) \u3002\u5b9e\u9645\u4e0a\uff0c\u6839\u636e\u5bf9\u89d2\u7ebf\u7ea6\u675f\u7684\u526a\u679d\u4e5f\u80fd\u591f\u5927\u5e45\u7f29\u5c0f\u641c\u7d22\u7a7a\u95f4\uff0c\u56e0\u800c\u641c\u7d22\u6548\u7387\u5f80\u5f80\u4f18\u4e8e\u4ee5\u4e0a\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    \u6570\u7ec4 state \u4f7f\u7528 \\(O(n^2)\\) \u7a7a\u95f4\uff0c\u6570\u7ec4 cols\u3001diags1 \u548c diags2 \u7686\u4f7f\u7528 \\(O(n)\\) \u7a7a\u95f4\u3002\u6700\u5927\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002\u56e0\u6b64\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_backtracking/permutations_problem/","title":"13.2 \u00a0 \u5168\u6392\u5217\u95ee\u9898","text":"

    \u5168\u6392\u5217\u95ee\u9898\u662f\u56de\u6eaf\u7b97\u6cd5\u7684\u4e00\u4e2a\u5178\u578b\u5e94\u7528\u3002\u5b83\u7684\u5b9a\u4e49\u662f\u5728\u7ed9\u5b9a\u4e00\u4e2a\u96c6\u5408\uff08\u5982\u4e00\u4e2a\u6570\u7ec4\u6216\u5b57\u7b26\u4e32\uff09\u7684\u60c5\u51b5\u4e0b\uff0c\u627e\u51fa\u5176\u4e2d\u5143\u7d20\u7684\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u3002

    \u8868 13-2 \u5217\u4e3e\u4e86\u51e0\u4e2a\u793a\u4f8b\u6570\u636e\uff0c\u5305\u62ec\u8f93\u5165\u6570\u7ec4\u548c\u5bf9\u5e94\u7684\u6240\u6709\u6392\u5217\u3002

    \u8868 13-2 \u00a0 \u5168\u6392\u5217\u793a\u4f8b

    \u8f93\u5165\u6570\u7ec4 \u6240\u6709\u6392\u5217 \\([1]\\) \\([1]\\) \\([1, 2]\\) \\([1, 2], [2, 1]\\) \\([1, 2, 3]\\) \\([1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]\\)"},{"location":"chapter_backtracking/permutations_problem/#1321","title":"13.2.1 \u00a0 \u65e0\u76f8\u7b49\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u8f93\u5165\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\uff0c\u5176\u4e2d\u4e0d\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u8fd4\u56de\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u3002

    \u4ece\u56de\u6eaf\u7b97\u6cd5\u7684\u89d2\u5ea6\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u751f\u6210\u6392\u5217\u7684\u8fc7\u7a0b\u60f3\u8c61\u6210\u4e00\u7cfb\u5217\u9009\u62e9\u7684\u7ed3\u679c\u3002\u5047\u8bbe\u8f93\u5165\u6570\u7ec4\u4e3a \\([1, 2, 3]\\) \uff0c\u5982\u679c\u6211\u4eec\u5148\u9009\u62e9 \\(1\\) \uff0c\u518d\u9009\u62e9 \\(3\\) \uff0c\u6700\u540e\u9009\u62e9 \\(2\\) \uff0c\u5219\u83b7\u5f97\u6392\u5217 \\([1, 3, 2]\\) \u3002\u56de\u9000\u8868\u793a\u64a4\u9500\u4e00\u4e2a\u9009\u62e9\uff0c\u4e4b\u540e\u7ee7\u7eed\u5c1d\u8bd5\u5176\u4ed6\u9009\u62e9\u3002

    \u4ece\u56de\u6eaf\u4ee3\u7801\u7684\u89d2\u5ea6\u770b\uff0c\u5019\u9009\u96c6\u5408 choices \u662f\u8f93\u5165\u6570\u7ec4\u4e2d\u7684\u6240\u6709\u5143\u7d20\uff0c\u72b6\u6001 state \u662f\u76f4\u81f3\u76ee\u524d\u5df2\u88ab\u9009\u62e9\u7684\u5143\u7d20\u3002\u8bf7\u6ce8\u610f\uff0c\u6bcf\u4e2a\u5143\u7d20\u53ea\u5141\u8bb8\u88ab\u9009\u62e9\u4e00\u6b21\uff0c\u56e0\u6b64 state \u4e2d\u7684\u6240\u6709\u5143\u7d20\u90fd\u5e94\u8be5\u662f\u552f\u4e00\u7684\u3002

    \u5982\u56fe 13-5 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u641c\u7d22\u8fc7\u7a0b\u5c55\u5f00\u6210\u4e00\u68f5\u9012\u5f52\u6811\uff0c\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u5f53\u524d\u72b6\u6001 state \u3002\u4ece\u6839\u8282\u70b9\u5f00\u59cb\uff0c\u7ecf\u8fc7\u4e09\u8f6e\u9009\u62e9\u540e\u5230\u8fbe\u53f6\u8282\u70b9\uff0c\u6bcf\u4e2a\u53f6\u8282\u70b9\u90fd\u5bf9\u5e94\u4e00\u4e2a\u6392\u5217\u3002

    \u56fe 13-5 \u00a0 \u5168\u6392\u5217\u7684\u9012\u5f52\u6811

    "},{"location":"chapter_backtracking/permutations_problem/#1","title":"1. \u00a0 \u91cd\u590d\u9009\u62e9\u526a\u679d","text":"

    \u4e3a\u4e86\u5b9e\u73b0\u6bcf\u4e2a\u5143\u7d20\u53ea\u88ab\u9009\u62e9\u4e00\u6b21\uff0c\u6211\u4eec\u8003\u8651\u5f15\u5165\u4e00\u4e2a\u5e03\u5c14\u578b\u6570\u7ec4 selected \uff0c\u5176\u4e2d selected[i] \u8868\u793a choices[i] \u662f\u5426\u5df2\u88ab\u9009\u62e9\uff0c\u5e76\u57fa\u4e8e\u5b83\u5b9e\u73b0\u4ee5\u4e0b\u526a\u679d\u64cd\u4f5c\u3002

    • \u5728\u505a\u51fa\u9009\u62e9 choice[i] \u540e\uff0c\u6211\u4eec\u5c31\u5c06 selected[i] \u8d4b\u503c\u4e3a \\(\\text{True}\\) \uff0c\u4ee3\u8868\u5b83\u5df2\u88ab\u9009\u62e9\u3002
    • \u904d\u5386\u9009\u62e9\u5217\u8868 choices \u65f6\uff0c\u8df3\u8fc7\u6240\u6709\u5df2\u88ab\u9009\u62e9\u7684\u8282\u70b9\uff0c\u5373\u526a\u679d\u3002

    \u5982\u56fe 13-6 \u6240\u793a\uff0c\u5047\u8bbe\u6211\u4eec\u7b2c\u4e00\u8f6e\u9009\u62e9 1 \uff0c\u7b2c\u4e8c\u8f6e\u9009\u62e9 3 \uff0c\u7b2c\u4e09\u8f6e\u9009\u62e9 2 \uff0c\u5219\u9700\u8981\u5728\u7b2c\u4e8c\u8f6e\u526a\u6389\u5143\u7d20 1 \u7684\u5206\u652f\uff0c\u5728\u7b2c\u4e09\u8f6e\u526a\u6389\u5143\u7d20 1 \u548c\u5143\u7d20 3 \u7684\u5206\u652f\u3002

    \u56fe 13-6 \u00a0 \u5168\u6392\u5217\u526a\u679d\u793a\u4f8b

    \u89c2\u5bdf\u56fe 13-6 \u53d1\u73b0\uff0c\u8be5\u526a\u679d\u64cd\u4f5c\u5c06\u641c\u7d22\u7a7a\u95f4\u5927\u5c0f\u4ece \\(O(n^n)\\) \u51cf\u5c0f\u81f3 \\(O(n!)\\) \u3002

    "},{"location":"chapter_backtracking/permutations_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u60f3\u6e05\u695a\u4ee5\u4e0a\u4fe1\u606f\u4e4b\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5728\u6846\u67b6\u4ee3\u7801\u4e2d\u505a\u201c\u5b8c\u5f62\u586b\u7a7a\u201d\u4e86\u3002\u4e3a\u4e86\u7f29\u77ed\u6574\u4f53\u4ee3\u7801\uff0c\u6211\u4eec\u4e0d\u5355\u72ec\u5b9e\u73b0\u6846\u67b6\u4ee3\u7801\u4e2d\u7684\u5404\u4e2a\u51fd\u6570\uff0c\u800c\u662f\u5c06\u5b83\u4eec\u5c55\u5f00\u5728 backtrack() \u51fd\u6570\u4e2d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig permutations_i.py
    def backtrack(\n    state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I\"\"\"\n    # \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(state) == len(choices):\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i, choice in enumerate(choices):\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if not selected[i]:\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = True\n            state.append(choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = False\n            state.pop()\n\ndef permutations_i(nums: list[int]) -> list[list[int]]:\n    \"\"\"\u5168\u6392\u5217 I\"\"\"\n    res = []\n    backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res)\n    return res\n
    permutations_i.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(vector<int> &state, const vector<int> &choices, vector<bool> &selected, vector<vector<int>> &res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.size()) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.size(); i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push_back(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop_back();\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nvector<vector<int>> permutationsI(vector<int> nums) {\n    vector<int> state;\n    vector<bool> selected(nums.size(), false);\n    vector<vector<int>> res;\n    backtrack(state, nums, selected, res);\n    return res;\n}\n
    permutations_i.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(List<Integer> state, int[] choices, boolean[] selected, List<List<Integer>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.length) {\n        res.add(new ArrayList<Integer>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.size() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<Integer>> permutationsI(int[] nums) {\n    List<List<Integer>> res = new ArrayList<List<Integer>>();\n    backtrack(new ArrayList<Integer>(), nums, new boolean[nums.length], res);\n    return res;\n}\n
    permutations_i.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid Backtrack(List<int> state, int[] choices, bool[] selected, List<List<int>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.Count == choices.Length) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.Length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.Add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.RemoveAt(state.Count - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<int>> PermutationsI(int[] nums) {\n    List<List<int>> res = [];\n    Backtrack([], nums, new bool[nums.Length], res);\n    return res;\n}\n
    permutations_i.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunc backtrackI(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(*state) == len(*choices) {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i := 0; i < len(*choices); i++ {\n        choice := (*choices)[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !(*selected)[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            (*selected)[i] = true\n            *state = append(*state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrackI(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            (*selected)[i] = false\n            *state = (*state)[:len(*state)-1]\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfunc permutationsI(nums []int) [][]int {\n    res := make([][]int, 0)\n    state := make([]int, 0)\n    selected := make([]bool, len(nums))\n    backtrackI(&state, &nums, &selected, &res)\n    return res\n}\n
    permutations_i.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunc backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.count == choices.count {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i, choice) in choices.enumerated() {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !selected[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true\n            state.append(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: choices, selected: &selected, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeLast()\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfunc permutationsI(nums: [Int]) -> [[Int]] {\n    var state: [Int] = []\n    var selected = Array(repeating: false, count: nums.count)\n    var res: [[Int]] = []\n    backtrack(state: &state, choices: nums, selected: &selected, res: &res)\n    return res\n}\n
    permutations_i.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunction backtrack(state, choices, selected, res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 I */\nfunction permutationsI(nums) {\n    const res = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_i.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfunction backtrack(\n    state: number[],\n    choices: number[],\n    selected: boolean[],\n    res: number[][]\n): void {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 I */\nfunction permutationsI(nums: number[]): number[][] {\n    const res: number[][] = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_i.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(\n  List<int> state,\n  List<int> choices,\n  List<bool> selected,\n  List<List<int>> res,\n) {\n  // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (state.length == choices.length) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int i = 0; i < choices.length; i++) {\n    int choice = choices[i];\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n    if (!selected[i]) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      selected[i] = true;\n      state.add(choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, choices, selected, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      selected[i] = false;\n      state.removeLast();\n    }\n  }\n}\n\n/* \u5168\u6392\u5217 I */\nList<List<int>> permutationsI(List<int> nums) {\n  List<List<int>> res = [];\n  backtrack([], nums, List.filled(nums.length, false), res);\n  return res;\n}\n
    permutations_i.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfn backtrack(mut state: Vec<i32>, choices: &[i32], selected: &mut [bool], res: &mut Vec<Vec<i32>>) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.len() == choices.len() {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in 0..choices.len() {\n        let choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if !selected[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state.clone(), choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.len() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfn permutations_i(nums: &mut [i32]) -> Vec<Vec<i32>> {\n    let mut res = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    backtrack(Vec::new(), nums, &mut vec![false; nums.len()], &mut res);\n    res\n}\n
    permutations_i.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nvoid backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (stateSize == choicesSize) {\n        res[*resSize] = (int *)malloc(choicesSize * sizeof(int));\n        for (int i = 0; i < choicesSize; i++) {\n            res[*resSize][i] = state[i];\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choicesSize; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true;\n            state[stateSize] = choice;\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nint **permutationsI(int *nums, int numsSize, int *returnSize) {\n    int *state = (int *)malloc(numsSize * sizeof(int));\n    bool *selected = (bool *)malloc(numsSize * sizeof(bool));\n    for (int i = 0; i < numsSize; i++) {\n        selected[i] = false;\n    }\n    int **res = (int **)malloc(MAX_SIZE * sizeof(int *));\n    *returnSize = 0;\n\n    backtrack(state, 0, nums, numsSize, selected, res, returnSize);\n\n    free(state);\n    free(selected);\n\n    return res;\n}\n
    permutations_i.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 I */\nfun backtrack(\n    state: MutableList<Int>,\n    choices: IntArray,\n    selected: BooleanArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size == choices.size) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i in choices.indices) {\n        val choice = choices[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20\n        if (!selected[i]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            selected[i] = true\n            state.add(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeAt(state.size - 1)\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 I */\nfun permutationsI(nums: IntArray): MutableList<MutableList<Int>?> {\n    val res = mutableListOf<MutableList<Int>?>()\n    backtrack(mutableListOf(), nums, BooleanArray(nums.size), res)\n    return res\n}\n
    permutations_i.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutations_i}\n
    permutations_i.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutationsI}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_backtracking/permutations_problem/#1322","title":"13.2.2 \u00a0 \u8003\u8651\u76f8\u7b49\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u8f93\u5165\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\uff0c\u6570\u7ec4\u4e2d\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u8fd4\u56de\u6240\u6709\u4e0d\u91cd\u590d\u7684\u6392\u5217\u3002

    \u5047\u8bbe\u8f93\u5165\u6570\u7ec4\u4e3a \\([1, 1, 2]\\) \u3002\u4e3a\u4e86\u65b9\u4fbf\u533a\u5206\u4e24\u4e2a\u91cd\u590d\u5143\u7d20 \\(1\\) \uff0c\u6211\u4eec\u5c06\u7b2c\u4e8c\u4e2a \\(1\\) \u8bb0\u4e3a \\(\\hat{1}\\) \u3002

    \u5982\u56fe 13-7 \u6240\u793a\uff0c\u4e0a\u8ff0\u65b9\u6cd5\u751f\u6210\u7684\u6392\u5217\u6709\u4e00\u534a\u662f\u91cd\u590d\u7684\u3002

    \u56fe 13-7 \u00a0 \u91cd\u590d\u6392\u5217

    \u90a3\u4e48\u5982\u4f55\u53bb\u9664\u91cd\u590d\u7684\u6392\u5217\u5462\uff1f\u6700\u76f4\u63a5\u5730\uff0c\u8003\u8651\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408\uff0c\u76f4\u63a5\u5bf9\u6392\u5217\u7ed3\u679c\u8fdb\u884c\u53bb\u91cd\u3002\u7136\u800c\u8fd9\u6837\u505a\u4e0d\u591f\u4f18\u96c5\uff0c\u56e0\u4e3a\u751f\u6210\u91cd\u590d\u6392\u5217\u7684\u641c\u7d22\u5206\u652f\u6ca1\u6709\u5fc5\u8981\uff0c\u5e94\u5f53\u63d0\u524d\u8bc6\u522b\u5e76\u526a\u679d\uff0c\u8fd9\u6837\u53ef\u4ee5\u8fdb\u4e00\u6b65\u63d0\u5347\u7b97\u6cd5\u6548\u7387\u3002

    "},{"location":"chapter_backtracking/permutations_problem/#1_1","title":"1. \u00a0 \u76f8\u7b49\u5143\u7d20\u526a\u679d","text":"

    \u89c2\u5bdf\u56fe 13-8 \uff0c\u5728\u7b2c\u4e00\u8f6e\u4e2d\uff0c\u9009\u62e9 \\(1\\) \u6216\u9009\u62e9 \\(\\hat{1}\\) \u662f\u7b49\u4ef7\u7684\uff0c\u5728\u8fd9\u4e24\u4e2a\u9009\u62e9\u4e4b\u4e0b\u751f\u6210\u7684\u6240\u6709\u6392\u5217\u90fd\u662f\u91cd\u590d\u7684\u3002\u56e0\u6b64\u5e94\u8be5\u628a \\(\\hat{1}\\) \u526a\u679d\u3002

    \u540c\u7406\uff0c\u5728\u7b2c\u4e00\u8f6e\u9009\u62e9 \\(2\\) \u4e4b\u540e\uff0c\u7b2c\u4e8c\u8f6e\u9009\u62e9\u4e2d\u7684 \\(1\\) \u548c \\(\\hat{1}\\) \u4e5f\u4f1a\u4ea7\u751f\u91cd\u590d\u5206\u652f\uff0c\u56e0\u6b64\u4e5f\u5e94\u5c06\u7b2c\u4e8c\u8f6e\u7684 \\(\\hat{1}\\) \u526a\u679d\u3002

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u6211\u4eec\u7684\u76ee\u6807\u662f\u5728\u67d0\u4e00\u8f6e\u9009\u62e9\u4e2d\uff0c\u4fdd\u8bc1\u591a\u4e2a\u76f8\u7b49\u7684\u5143\u7d20\u4ec5\u88ab\u9009\u62e9\u4e00\u6b21\u3002

    \u56fe 13-8 \u00a0 \u91cd\u590d\u6392\u5217\u526a\u679d

    "},{"location":"chapter_backtracking/permutations_problem/#2_1","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5728\u4e0a\u4e00\u9898\u7684\u4ee3\u7801\u7684\u57fa\u7840\u4e0a\uff0c\u6211\u4eec\u8003\u8651\u5728\u6bcf\u4e00\u8f6e\u9009\u62e9\u4e2d\u5f00\u542f\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408 duplicated \uff0c\u7528\u4e8e\u8bb0\u5f55\u8be5\u8f6e\u4e2d\u5df2\u7ecf\u5c1d\u8bd5\u8fc7\u7684\u5143\u7d20\uff0c\u5e76\u5c06\u91cd\u590d\u5143\u7d20\u526a\u679d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig permutations_ii.py
    def backtrack(\n    state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II\"\"\"\n    # \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(state) == len(choices):\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    duplicated = set[int]()\n    for i, choice in enumerate(choices):\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if not selected[i] and choice not in duplicated:\n            # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice)  # \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = True\n            state.append(choice)\n            # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = False\n            state.pop()\n\ndef permutations_ii(nums: list[int]) -> list[list[int]]:\n    \"\"\"\u5168\u6392\u5217 II\"\"\"\n    res = []\n    backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res)\n    return res\n
    permutations_ii.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(vector<int> &state, const vector<int> &choices, vector<bool> &selected, vector<vector<int>> &res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.size()) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    unordered_set<int> duplicated;\n    for (int i = 0; i < choices.size(); i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && duplicated.find(choice) == duplicated.end()) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.emplace(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push_back(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop_back();\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nvector<vector<int>> permutationsII(vector<int> nums) {\n    vector<int> state;\n    vector<bool> selected(nums.size(), false);\n    vector<vector<int>> res;\n    backtrack(state, nums, selected, res);\n    return res;\n}\n
    permutations_ii.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(List<Integer> state, int[] choices, boolean[] selected, List<List<Integer>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size() == choices.length) {\n        res.add(new ArrayList<Integer>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    Set<Integer> duplicated = new HashSet<Integer>();\n    for (int i = 0; i < choices.length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.size() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<Integer>> permutationsII(int[] nums) {\n    List<List<Integer>> res = new ArrayList<List<Integer>>();\n    backtrack(new ArrayList<Integer>(), nums, new boolean[nums.length], res);\n    return res;\n}\n
    permutations_ii.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid Backtrack(List<int> state, int[] choices, bool[] selected, List<List<int>> res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.Count == choices.Length) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    HashSet<int> duplicated = [];\n    for (int i = 0; i < choices.Length; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.Contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.Add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.Add(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            Backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.RemoveAt(state.Count - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<int>> PermutationsII(int[] nums) {\n    List<List<int>> res = [];\n    Backtrack([], nums, new bool[nums.Length], res);\n    return res;\n}\n
    permutations_ii.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunc backtrackII(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if len(*state) == len(*choices) {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    duplicated := make(map[int]struct{}, 0)\n    for i := 0; i < len(*choices); i++ {\n        choice := (*choices)[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if _, ok := duplicated[choice]; !ok && !(*selected)[i] {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            duplicated[choice] = struct{}{}\n            (*selected)[i] = true\n            *state = append(*state, choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrackII(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            (*selected)[i] = false\n            *state = (*state)[:len(*state)-1]\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfunc permutationsII(nums []int) [][]int {\n    res := make([][]int, 0)\n    state := make([]int, 0)\n    selected := make([]bool, len(nums))\n    backtrackII(&state, &nums, &selected, &res)\n    return res\n}\n
    permutations_ii.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunc backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.count == choices.count {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    var duplicated: Set<Int> = []\n    for (i, choice) in choices.enumerated() {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if !selected[i], !duplicated.contains(choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.insert(choice) // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true\n            state.append(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state: &state, choices: choices, selected: &selected, res: &res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeLast()\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfunc permutationsII(nums: [Int]) -> [[Int]] {\n    var state: [Int] = []\n    var selected = Array(repeating: false, count: nums.count)\n    var res: [[Int]] = []\n    backtrack(state: &state, choices: nums, selected: &selected, res: &res)\n    return res\n}\n
    permutations_ii.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunction backtrack(state, choices, selected, res) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    const duplicated = new Set();\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.has(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 II */\nfunction permutationsII(nums) {\n    const res = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_ii.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfunction backtrack(\n    state: number[],\n    choices: number[],\n    selected: boolean[],\n    res: number[][]\n): void {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.length === choices.length) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    const duplicated = new Set();\n    choices.forEach((choice, i) => {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.has(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.pop();\n        }\n    });\n}\n\n/* \u5168\u6392\u5217 II */\nfunction permutationsII(nums: number[]): number[][] {\n    const res: number[][] = [];\n    backtrack([], nums, Array(nums.length).fill(false), res);\n    return res;\n}\n
    permutations_ii.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(\n  List<int> state,\n  List<int> choices,\n  List<bool> selected,\n  List<List<int>> res,\n) {\n  // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (state.length == choices.length) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  Set<int> duplicated = {};\n  for (int i = 0; i < choices.length; i++) {\n    int choice = choices[i];\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n    if (!selected[i] && !duplicated.contains(choice)) {\n      // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n      duplicated.add(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n      selected[i] = true;\n      state.add(choice);\n      // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n      backtrack(state, choices, selected, res);\n      // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n      selected[i] = false;\n      state.removeLast();\n    }\n  }\n}\n\n/* \u5168\u6392\u5217 II */\nList<List<int>> permutationsII(List<int> nums) {\n  List<List<int>> res = [];\n  backtrack([], nums, List.filled(nums.length, false), res);\n  return res;\n}\n
    permutations_ii.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfn backtrack(mut state: Vec<i32>, choices: &[i32], selected: &mut [bool], res: &mut Vec<Vec<i32>>) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if state.len() == choices.len() {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    let mut duplicated = HashSet::<i32>::new();\n    for i in 0..choices.len() {\n        let choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if !selected[i] && !duplicated.contains(&choice) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.insert(choice); // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state.push(choice);\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state.clone(), choices, selected, res);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n            state.remove(state.len() - 1);\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfn permutations_ii(nums: &mut [i32]) -> Vec<Vec<i32>> {\n    let mut res = Vec::new();\n    backtrack(Vec::new(), nums, &mut vec![false; nums.len()], &mut res);\n    res\n}\n
    permutations_ii.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nvoid backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (stateSize == choicesSize) {\n        res[*resSize] = (int *)malloc(choicesSize * sizeof(int));\n        for (int i = 0; i < choicesSize; i++) {\n            res[*resSize][i] = state[i];\n        }\n        (*resSize)++;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    bool duplicated[MAX_SIZE] = {false};\n    for (int i = 0; i < choicesSize; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated[choice]) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated[choice] = true; // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true;\n            state[stateSize] = choice;\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false;\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nint **permutationsII(int *nums, int numsSize, int *returnSize) {\n    int *state = (int *)malloc(numsSize * sizeof(int));\n    bool *selected = (bool *)malloc(numsSize * sizeof(bool));\n    for (int i = 0; i < numsSize; i++) {\n        selected[i] = false;\n    }\n    int **res = (int **)malloc(MAX_SIZE * sizeof(int *));\n    *returnSize = 0;\n\n    backtrack(state, 0, nums, numsSize, selected, res, returnSize);\n\n    free(state);\n    free(selected);\n\n    return res;\n}\n
    permutations_ii.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5168\u6392\u5217 II */\nfun backtrack(\n    state: MutableList<Int>,\n    choices: IntArray,\n    selected: BooleanArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5f53\u72b6\u6001\u957f\u5ea6\u7b49\u4e8e\u5143\u7d20\u6570\u91cf\u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (state.size == choices.size) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    val duplicated = HashSet<Int>()\n    for (i in choices.indices) {\n        val choice = choices[i]\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u5143\u7d20 \u4e14 \u4e0d\u5141\u8bb8\u91cd\u590d\u9009\u62e9\u76f8\u7b49\u5143\u7d20\n        if (!selected[i] && !duplicated.contains(choice)) {\n            // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n            duplicated.add(choice) // \u8bb0\u5f55\u9009\u62e9\u8fc7\u7684\u5143\u7d20\u503c\n            selected[i] = true\n            state.add(choice)\n            // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n            backtrack(state, choices, selected, res)\n            // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n            selected[i] = false\n            state.removeAt(state.size - 1)\n        }\n    }\n}\n\n/* \u5168\u6392\u5217 II */\nfun permutationsII(nums: IntArray): MutableList<MutableList<Int>?> {\n    val res = mutableListOf<MutableList<Int>?>()\n    backtrack(mutableListOf(), nums, BooleanArray(nums.size), res)\n    return res\n}\n
    permutations_ii.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutations_ii}\n
    permutations_ii.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{permutationsII}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5047\u8bbe\u5143\u7d20\u4e24\u4e24\u4e4b\u95f4\u4e92\u4e0d\u76f8\u540c\uff0c\u5219 \\(n\\) \u4e2a\u5143\u7d20\u5171\u6709 \\(n!\\) \u79cd\u6392\u5217\uff08\u9636\u4e58\uff09\uff1b\u5728\u8bb0\u5f55\u7ed3\u679c\u65f6\uff0c\u9700\u8981\u590d\u5236\u957f\u5ea6\u4e3a \\(n\\) \u7684\u5217\u8868\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n!n)\\) \u3002

    \u6700\u5927\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002selected \u4f7f\u7528 \\(O(n)\\) \u7a7a\u95f4\u3002\u540c\u4e00\u65f6\u523b\u6700\u591a\u5171\u6709 \\(n\\) \u4e2a duplicated \uff0c\u4f7f\u7528 \\(O(n^2)\\) \u7a7a\u95f4\u3002\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_backtracking/permutations_problem/#3","title":"3. \u00a0 \u4e24\u79cd\u526a\u679d\u5bf9\u6bd4","text":"

    \u8bf7\u6ce8\u610f\uff0c\u867d\u7136 selected \u548c duplicated \u90fd\u7528\u4e8e\u526a\u679d\uff0c\u4f46\u4e24\u8005\u7684\u76ee\u6807\u4e0d\u540c\u3002

    • \u91cd\u590d\u9009\u62e9\u526a\u679d\uff1a\u6574\u4e2a\u641c\u7d22\u8fc7\u7a0b\u4e2d\u53ea\u6709\u4e00\u4e2a selected \u3002\u5b83\u8bb0\u5f55\u7684\u662f\u5f53\u524d\u72b6\u6001\u4e2d\u5305\u542b\u54ea\u4e9b\u5143\u7d20\uff0c\u5176\u4f5c\u7528\u662f\u907f\u514d\u67d0\u4e2a\u5143\u7d20\u5728 state \u4e2d\u91cd\u590d\u51fa\u73b0\u3002
    • \u76f8\u7b49\u5143\u7d20\u526a\u679d\uff1a\u6bcf\u8f6e\u9009\u62e9\uff08\u6bcf\u4e2a\u8c03\u7528\u7684 backtrack \u51fd\u6570\uff09\u90fd\u5305\u542b\u4e00\u4e2a duplicated \u3002\u5b83\u8bb0\u5f55\u7684\u662f\u5728\u672c\u8f6e\u904d\u5386\uff08for \u5faa\u73af\uff09\u4e2d\u54ea\u4e9b\u5143\u7d20\u5df2\u88ab\u9009\u62e9\u8fc7\uff0c\u5176\u4f5c\u7528\u662f\u4fdd\u8bc1\u76f8\u7b49\u5143\u7d20\u53ea\u88ab\u9009\u62e9\u4e00\u6b21\u3002

    \u56fe 13-9 \u5c55\u793a\u4e86\u4e24\u4e2a\u526a\u679d\u6761\u4ef6\u7684\u751f\u6548\u8303\u56f4\u3002\u6ce8\u610f\uff0c\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u4e00\u4e2a\u9009\u62e9\uff0c\u4ece\u6839\u8282\u70b9\u5230\u53f6\u8282\u70b9\u7684\u8def\u5f84\u4e0a\u7684\u5404\u4e2a\u8282\u70b9\u6784\u6210\u4e00\u4e2a\u6392\u5217\u3002

    \u56fe 13-9 \u00a0 \u4e24\u79cd\u526a\u679d\u6761\u4ef6\u7684\u4f5c\u7528\u8303\u56f4

    "},{"location":"chapter_backtracking/subset_sum_problem/","title":"13.3 \u00a0 \u5b50\u96c6\u548c\u95ee\u9898","text":""},{"location":"chapter_backtracking/subset_sum_problem/#1331","title":"13.3.1 \u00a0 \u65e0\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6b63\u6574\u6570\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u76ee\u6807\u6b63\u6574\u6570 target \uff0c\u8bf7\u627e\u51fa\u6240\u6709\u53ef\u80fd\u7684\u7ec4\u5408\uff0c\u4f7f\u5f97\u7ec4\u5408\u4e2d\u7684\u5143\u7d20\u548c\u7b49\u4e8e target \u3002\u7ed9\u5b9a\u6570\u7ec4\u65e0\u91cd\u590d\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u53ef\u4ee5\u88ab\u9009\u53d6\u591a\u6b21\u3002\u8bf7\u4ee5\u5217\u8868\u5f62\u5f0f\u8fd4\u56de\u8fd9\u4e9b\u7ec4\u5408\uff0c\u5217\u8868\u4e2d\u4e0d\u5e94\u5305\u542b\u91cd\u590d\u7ec4\u5408\u3002

    \u4f8b\u5982\uff0c\u8f93\u5165\u96c6\u5408 \\(\\{3, 4, 5\\}\\) \u548c\u76ee\u6807\u6574\u6570 \\(9\\) \uff0c\u89e3\u4e3a \\(\\{3, 3, 3\\}, \\{4, 5\\}\\) \u3002\u9700\u8981\u6ce8\u610f\u4ee5\u4e0b\u4e24\u70b9\u3002

    • \u8f93\u5165\u96c6\u5408\u4e2d\u7684\u5143\u7d20\u53ef\u4ee5\u88ab\u65e0\u9650\u6b21\u91cd\u590d\u9009\u53d6\u3002
    • \u5b50\u96c6\u4e0d\u533a\u5206\u5143\u7d20\u987a\u5e8f\uff0c\u6bd4\u5982 \\(\\{4, 5\\}\\) \u548c \\(\\{5, 4\\}\\) \u662f\u540c\u4e00\u4e2a\u5b50\u96c6\u3002
    "},{"location":"chapter_backtracking/subset_sum_problem/#1","title":"1. \u00a0 \u53c2\u8003\u5168\u6392\u5217\u89e3\u6cd5","text":"

    \u7c7b\u4f3c\u4e8e\u5168\u6392\u5217\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u5b50\u96c6\u7684\u751f\u6210\u8fc7\u7a0b\u60f3\u8c61\u6210\u4e00\u7cfb\u5217\u9009\u62e9\u7684\u7ed3\u679c\uff0c\u5e76\u5728\u9009\u62e9\u8fc7\u7a0b\u4e2d\u5b9e\u65f6\u66f4\u65b0\u201c\u5143\u7d20\u548c\u201d\uff0c\u5f53\u5143\u7d20\u548c\u7b49\u4e8e target \u65f6\uff0c\u5c31\u5c06\u5b50\u96c6\u8bb0\u5f55\u81f3\u7ed3\u679c\u5217\u8868\u3002

    \u800c\u4e0e\u5168\u6392\u5217\u95ee\u9898\u4e0d\u540c\u7684\u662f\uff0c\u672c\u9898\u96c6\u5408\u4e2d\u7684\u5143\u7d20\u53ef\u4ee5\u88ab\u65e0\u9650\u6b21\u9009\u53d6\uff0c\u56e0\u6b64\u65e0\u987b\u501f\u52a9 selected \u5e03\u5c14\u5217\u8868\u6765\u8bb0\u5f55\u5143\u7d20\u662f\u5426\u5df2\u88ab\u9009\u62e9\u3002\u6211\u4eec\u53ef\u4ee5\u5bf9\u5168\u6392\u5217\u4ee3\u7801\u8fdb\u884c\u5c0f\u5e45\u4fee\u6539\uff0c\u521d\u6b65\u5f97\u5230\u89e3\u9898\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_i_naive.py
    def backtrack(\n    state: list[int],\n    target: int,\n    total: int,\n    choices: list[int],\n    res: list[list[int]],\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in range(len(choices)):\n        # \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_i_naive(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    total = 0  # \u5b50\u96c6\u548c\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res)\n    return res\n
    subset_sum_i_naive.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(vector<int> &state, int target, int total, vector<int> &choices, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (size_t i = 0; i < choices.size(); i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nvector<vector<int>> subsetSumINaive(vector<int> &nums, int target) {\n    vector<int> state;       // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0;           // \u5b50\u96c6\u548c\n    vector<vector<int>> res; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(List<Integer> state, int target, int total, int[] choices, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<Integer>> subsetSumINaive(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0; // \u5b50\u96c6\u548c\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid Backtrack(List<int> state, int target, int total, int[] choices, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choices.Length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<int>> SubsetSumINaive(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    int total = 0; // \u5b50\u96c6\u548c\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrackSubsetSumINaive(total, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == total {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i := 0; i < len(*choices); i++ {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total+(*choices)[i] > target {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumINaive(total+(*choices)[i], target, state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunc subsetSumINaive(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    total := 0              // \u5b50\u96c6\u548c\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumINaive(total, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_i_naive.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrack(state: inout [Int], target: Int, total: Int, choices: [Int], res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in choices.indices {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target, total: total + choices[i], choices: choices, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunc subsetSumINaive(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let total = 0 // \u5b50\u96c6\u548c\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, total: total, choices: nums, res: &res)\n    return res\n}\n
    subset_sum_i_naive.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(state, target, total, choices, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total === target) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunction subsetSumINaive(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    const total = 0; // \u5b50\u96c6\u548c\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(\n    state: number[],\n    target: number,\n    total: number,\n    choices: number[],\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total === target) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (let i = 0; i < choices.length; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfunction subsetSumINaive(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    const total = 0; // \u5b50\u96c6\u548c\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res);\n    return res;\n}\n
    subset_sum_i_naive.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(\n  List<int> state,\n  int target,\n  int total,\n  List<int> choices,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (total == target) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int i = 0; i < choices.length; i++) {\n    // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n    if (total + choices[i] > target) {\n      continue;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target, total + choices[i], choices, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nList<List<int>> subsetSumINaive(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  int total = 0; // \u5143\u7d20\u548c\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, total, nums, res);\n  return res;\n}\n
    subset_sum_i_naive.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    total: i32,\n    choices: &[i32],\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if total == target {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for i in 0..choices.len() {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if total + choices[i] > target {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target, total + choices[i], choices, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfn subset_sum_i_naive(nums: &[i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let total = 0; // \u5b50\u96c6\u548c\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, &mut res);\n    res\n}\n
    subset_sum_i_naive.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(int target, int total, int *choices, int choicesSize) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        for (int i = 0; i < stateSize; i++) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < choicesSize; i++) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state[stateSize++] = choices[i];\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target, total + choices[i], choices, choicesSize);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nvoid subsetSumINaive(int *nums, int numsSize, int target) {\n    resSize = 0; // \u521d\u59cb\u5316\u89e3\u7684\u6570\u91cf\u4e3a0\n    backtrack(target, 0, nums, numsSize);\n}\n
    subset_sum_i_naive.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    total: Int,\n    choices: IntArray,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (total == target) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (i in choices.indices) {\n        // \u526a\u679d\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u8df3\u8fc7\u8be5\u9009\u62e9\n        if (total + choices[i] > target) {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u5143\u7d20\u548c total\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target, total + choices[i], choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I\uff08\u5305\u542b\u91cd\u590d\u5b50\u96c6\uff09 */\nfun subsetSumINaive(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    val total = 0 // \u5b50\u96c6\u548c\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, total, nums, res)\n    return res\n}\n
    subset_sum_i_naive.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_i_naive}\n
    subset_sum_i_naive.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumINaive}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5411\u4ee5\u4e0a\u4ee3\u7801\u8f93\u5165\u6570\u7ec4 \\([3, 4, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \uff0c\u8f93\u51fa\u7ed3\u679c\u4e3a \\([3, 3, 3], [4, 5], [5, 4]\\) \u3002\u867d\u7136\u6210\u529f\u627e\u51fa\u4e86\u6240\u6709\u548c\u4e3a \\(9\\) \u7684\u5b50\u96c6\uff0c\u4f46\u5176\u4e2d\u5b58\u5728\u91cd\u590d\u7684\u5b50\u96c6 \\([4, 5]\\) \u548c \\([5, 4]\\) \u3002

    \u8fd9\u662f\u56e0\u4e3a\u641c\u7d22\u8fc7\u7a0b\u662f\u533a\u5206\u9009\u62e9\u987a\u5e8f\u7684\uff0c\u7136\u800c\u5b50\u96c6\u4e0d\u533a\u5206\u9009\u62e9\u987a\u5e8f\u3002\u5982\u56fe 13-10 \u6240\u793a\uff0c\u5148\u9009 \\(4\\) \u540e\u9009 \\(5\\) \u4e0e\u5148\u9009 \\(5\\) \u540e\u9009 \\(4\\) \u662f\u4e0d\u540c\u7684\u5206\u652f\uff0c\u4f46\u5bf9\u5e94\u540c\u4e00\u4e2a\u5b50\u96c6\u3002

    \u56fe 13-10 \u00a0 \u5b50\u96c6\u641c\u7d22\u4e0e\u8d8a\u754c\u526a\u679d

    \u4e3a\u4e86\u53bb\u9664\u91cd\u590d\u5b50\u96c6\uff0c\u4e00\u79cd\u76f4\u63a5\u7684\u601d\u8def\u662f\u5bf9\u7ed3\u679c\u5217\u8868\u8fdb\u884c\u53bb\u91cd\u3002\u4f46\u8fd9\u4e2a\u65b9\u6cd5\u6548\u7387\u5f88\u4f4e\uff0c\u6709\u4e24\u65b9\u9762\u539f\u56e0\u3002

    • \u5f53\u6570\u7ec4\u5143\u7d20\u8f83\u591a\uff0c\u5c24\u5176\u662f\u5f53 target \u8f83\u5927\u65f6\uff0c\u641c\u7d22\u8fc7\u7a0b\u4f1a\u4ea7\u751f\u5927\u91cf\u7684\u91cd\u590d\u5b50\u96c6\u3002
    • \u6bd4\u8f83\u5b50\u96c6\uff08\u6570\u7ec4\uff09\u7684\u5f02\u540c\u975e\u5e38\u8017\u65f6\uff0c\u9700\u8981\u5148\u6392\u5e8f\u6570\u7ec4\uff0c\u518d\u6bd4\u8f83\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u5143\u7d20\u7684\u5f02\u540c\u3002
    "},{"location":"chapter_backtracking/subset_sum_problem/#2","title":"2. \u00a0 \u91cd\u590d\u5b50\u96c6\u526a\u679d","text":"

    \u6211\u4eec\u8003\u8651\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u901a\u8fc7\u526a\u679d\u8fdb\u884c\u53bb\u91cd\u3002\u89c2\u5bdf\u56fe 13-11 \uff0c\u91cd\u590d\u5b50\u96c6\u662f\u5728\u4ee5\u4e0d\u540c\u987a\u5e8f\u9009\u62e9\u6570\u7ec4\u5143\u7d20\u65f6\u4ea7\u751f\u7684\uff0c\u4f8b\u5982\u4ee5\u4e0b\u60c5\u51b5\u3002

    1. \u5f53\u7b2c\u4e00\u8f6e\u548c\u7b2c\u4e8c\u8f6e\u5206\u522b\u9009\u62e9 \\(3\\) \u548c \\(4\\) \u65f6\uff0c\u4f1a\u751f\u6210\u5305\u542b\u8fd9\u4e24\u4e2a\u5143\u7d20\u7684\u6240\u6709\u5b50\u96c6\uff0c\u8bb0\u4e3a \\([3, 4, \\dots]\\) \u3002
    2. \u4e4b\u540e\uff0c\u5f53\u7b2c\u4e00\u8f6e\u9009\u62e9 \\(4\\) \u65f6\uff0c\u5219\u7b2c\u4e8c\u8f6e\u5e94\u8be5\u8df3\u8fc7 \\(3\\) \uff0c\u56e0\u4e3a\u8be5\u9009\u62e9\u4ea7\u751f\u7684\u5b50\u96c6 \\([4, 3, \\dots]\\) \u548c\u7b2c 1. \u6b65\u4e2d\u751f\u6210\u7684\u5b50\u96c6\u5b8c\u5168\u91cd\u590d\u3002

    \u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u4e00\u5c42\u7684\u9009\u62e9\u90fd\u662f\u4ece\u5de6\u5230\u53f3\u88ab\u9010\u4e2a\u5c1d\u8bd5\u7684\uff0c\u56e0\u6b64\u8d8a\u9760\u53f3\u7684\u5206\u652f\u88ab\u526a\u6389\u7684\u8d8a\u591a\u3002

    1. \u524d\u4e24\u8f6e\u9009\u62e9 \\(3\\) \u548c \\(5\\) \uff0c\u751f\u6210\u5b50\u96c6 \\([3, 5, \\dots]\\) \u3002
    2. \u524d\u4e24\u8f6e\u9009\u62e9 \\(4\\) \u548c \\(5\\) \uff0c\u751f\u6210\u5b50\u96c6 \\([4, 5, \\dots]\\) \u3002
    3. \u82e5\u7b2c\u4e00\u8f6e\u9009\u62e9 \\(5\\) \uff0c\u5219\u7b2c\u4e8c\u8f6e\u5e94\u8be5\u8df3\u8fc7 \\(3\\) \u548c \\(4\\) \uff0c\u56e0\u4e3a\u5b50\u96c6 \\([5, 3, \\dots]\\) \u548c \\([5, 4, \\dots]\\) \u4e0e\u7b2c 1. \u6b65\u548c\u7b2c 2. \u6b65\u4e2d\u63cf\u8ff0\u7684\u5b50\u96c6\u5b8c\u5168\u91cd\u590d\u3002

    \u56fe 13-11 \u00a0 \u4e0d\u540c\u9009\u62e9\u987a\u5e8f\u5bfc\u81f4\u7684\u91cd\u590d\u5b50\u96c6

    \u603b\u7ed3\u6765\u770b\uff0c\u7ed9\u5b9a\u8f93\u5165\u6570\u7ec4 \\([x_1, x_2, \\dots, x_n]\\) \uff0c\u8bbe\u641c\u7d22\u8fc7\u7a0b\u4e2d\u7684\u9009\u62e9\u5e8f\u5217\u4e3a \\([x_{i_1}, x_{i_2}, \\dots, x_{i_m}]\\) \uff0c\u5219\u8be5\u9009\u62e9\u5e8f\u5217\u9700\u8981\u6ee1\u8db3 \\(i_1 \\leq i_2 \\leq \\dots \\leq i_m\\) \uff0c\u4e0d\u6ee1\u8db3\u8be5\u6761\u4ef6\u7684\u9009\u62e9\u5e8f\u5217\u90fd\u4f1a\u9020\u6210\u91cd\u590d\uff0c\u5e94\u5f53\u526a\u679d\u3002

    "},{"location":"chapter_backtracking/subset_sum_problem/#3","title":"3. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u4e3a\u5b9e\u73b0\u8be5\u526a\u679d\uff0c\u6211\u4eec\u521d\u59cb\u5316\u53d8\u91cf start \uff0c\u7528\u4e8e\u6307\u793a\u904d\u5386\u8d77\u59cb\u70b9\u3002\u5f53\u505a\u51fa\u9009\u62e9 \\(x_{i}\\) \u540e\uff0c\u8bbe\u5b9a\u4e0b\u4e00\u8f6e\u4ece\u7d22\u5f15 \\(i\\) \u5f00\u59cb\u904d\u5386\u3002\u8fd9\u6837\u505a\u5c31\u53ef\u4ee5\u8ba9\u9009\u62e9\u5e8f\u5217\u6ee1\u8db3 \\(i_1 \\leq i_2 \\leq \\dots \\leq i_m\\) \uff0c\u4ece\u800c\u4fdd\u8bc1\u5b50\u96c6\u552f\u4e00\u3002

    \u9664\u6b64\u4e4b\u5916\uff0c\u6211\u4eec\u8fd8\u5bf9\u4ee3\u7801\u8fdb\u884c\u4e86\u4ee5\u4e0b\u4e24\u9879\u4f18\u5316\u3002

    • \u5728\u5f00\u542f\u641c\u7d22\u524d\uff0c\u5148\u5c06\u6570\u7ec4 nums \u6392\u5e8f\u3002\u5728\u904d\u5386\u6240\u6709\u9009\u62e9\u65f6\uff0c\u5f53\u5b50\u96c6\u548c\u8d85\u8fc7 target \u65f6\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\uff0c\u56e0\u4e3a\u540e\u8fb9\u7684\u5143\u7d20\u66f4\u5927\uff0c\u5176\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target \u3002
    • \u7701\u53bb\u5143\u7d20\u548c\u53d8\u91cf total \uff0c\u901a\u8fc7\u5728 target \u4e0a\u6267\u884c\u51cf\u6cd5\u6765\u7edf\u8ba1\u5143\u7d20\u548c\uff0c\u5f53 target \u7b49\u4e8e \\(0\\) \u65f6\u8bb0\u5f55\u89e3\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_i.py
    def backtrack(\n    state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    # \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in range(start, len(choices)):\n        # \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        # \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0:\n            break\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_i(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c I\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort()  # \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start = 0  # \u904d\u5386\u8d77\u59cb\u70b9\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n
    subset_sum_i.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(vector<int> &state, int target, vector<int> &choices, int start, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.size(); i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nvector<vector<int>> subsetSumI(vector<int> &nums, int target) {\n    vector<int> state;              // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort(nums.begin(), nums.end()); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                  // \u904d\u5386\u8d77\u59cb\u70b9\n    vector<vector<int>> res;        // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(List<Integer> state, int target, int[] choices, int start, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<Integer>> subsetSumI(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Arrays.sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid Backtrack(List<int> state, int target, int[] choices, int start, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choices.Length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<int>> SubsetSumI(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Array.Sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrackSubsetSumI(start, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i := start; i < len(*choices); i++ {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target-(*choices)[i] < 0 {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumI(i, target-(*choices)[i], state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunc subsetSumI(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort.Ints(nums)         // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start := 0              // \u904d\u5386\u8d77\u59cb\u70b9\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumI(start, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_i.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunc backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in choices.indices.dropFirst(start) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target - choices[i], choices: choices, start: i, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunc subsetSumI(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let nums = nums.sorted() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, choices: nums, start: start, res: &res)\n    return res\n}\n
    subset_sum_i.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(state, target, choices, start, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunction subsetSumI(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfunction backtrack(\n    state: number[],\n    target: number,\n    choices: number[],\n    start: number,\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfunction subsetSumI(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_i.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(\n  List<int> state,\n  int target,\n  List<int> choices,\n  int start,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (target == 0) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n  for (int i = start; i < choices.length; i++) {\n    // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n    // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n    if (target - choices[i] < 0) {\n      break;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target - choices[i], choices, i, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nList<List<int>> subsetSumI(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n  int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, nums, start, res);\n  return res;\n}\n
    subset_sum_i.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    choices: &[i32],\n    start: usize,\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for i in start..choices.len() {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfn subset_sum_i(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, &mut res);\n    res\n}\n
    subset_sum_i.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nvoid backtrack(int target, int *choices, int choicesSize, int start) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        for (int i = 0; i < stateSize; ++i) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (int i = start; i < choicesSize; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state[stateSize] = choices[i];\n        stateSize++;\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target - choices[i], choices, choicesSize, i);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nvoid subsetSumI(int *nums, int numsSize, int target) {\n    qsort(nums, numsSize, sizeof(int), cmp); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                           // \u904d\u5386\u8d77\u59cb\u70b9\n    backtrack(target, nums, numsSize, start);\n}\n
    subset_sum_i.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c I */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    choices: IntArray,\n    start: Int,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    for (i in start..<choices.size) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c I */\nfun subsetSumI(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    val start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n}\n
    subset_sum_i.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_i}\n
    subset_sum_i.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumI}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 13-12 \u6240\u793a\u4e3a\u5c06\u6570\u7ec4 \\([3, 4, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \u8f93\u5165\u4ee5\u4e0a\u4ee3\u7801\u540e\u7684\u6574\u4f53\u56de\u6eaf\u8fc7\u7a0b\u3002

    \u56fe 13-12 \u00a0 \u5b50\u96c6\u548c I \u56de\u6eaf\u8fc7\u7a0b

    "},{"location":"chapter_backtracking/subset_sum_problem/#1332","title":"13.3.2 \u00a0 \u8003\u8651\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6b63\u6574\u6570\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u76ee\u6807\u6b63\u6574\u6570 target \uff0c\u8bf7\u627e\u51fa\u6240\u6709\u53ef\u80fd\u7684\u7ec4\u5408\uff0c\u4f7f\u5f97\u7ec4\u5408\u4e2d\u7684\u5143\u7d20\u548c\u7b49\u4e8e target \u3002\u7ed9\u5b9a\u6570\u7ec4\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u6bcf\u4e2a\u5143\u7d20\u53ea\u53ef\u88ab\u9009\u62e9\u4e00\u6b21\u3002\u8bf7\u4ee5\u5217\u8868\u5f62\u5f0f\u8fd4\u56de\u8fd9\u4e9b\u7ec4\u5408\uff0c\u5217\u8868\u4e2d\u4e0d\u5e94\u5305\u542b\u91cd\u590d\u7ec4\u5408\u3002

    \u76f8\u6bd4\u4e8e\u4e0a\u9898\uff0c\u672c\u9898\u7684\u8f93\u5165\u6570\u7ec4\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u8fd9\u5f15\u5165\u4e86\u65b0\u7684\u95ee\u9898\u3002\u4f8b\u5982\uff0c\u7ed9\u5b9a\u6570\u7ec4 \\([4, \\hat{4}, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \uff0c\u5219\u73b0\u6709\u4ee3\u7801\u7684\u8f93\u51fa\u7ed3\u679c\u4e3a \\([4, 5], [\\hat{4}, 5]\\) \uff0c\u51fa\u73b0\u4e86\u91cd\u590d\u5b50\u96c6\u3002

    \u9020\u6210\u8fd9\u79cd\u91cd\u590d\u7684\u539f\u56e0\u662f\u76f8\u7b49\u5143\u7d20\u5728\u67d0\u8f6e\u4e2d\u88ab\u591a\u6b21\u9009\u62e9\u3002\u5728\u56fe 13-13 \u4e2d\uff0c\u7b2c\u4e00\u8f6e\u5171\u6709\u4e09\u4e2a\u9009\u62e9\uff0c\u5176\u4e2d\u4e24\u4e2a\u90fd\u4e3a \\(4\\) \uff0c\u4f1a\u4ea7\u751f\u4e24\u4e2a\u91cd\u590d\u7684\u641c\u7d22\u5206\u652f\uff0c\u4ece\u800c\u8f93\u51fa\u91cd\u590d\u5b50\u96c6\uff1b\u540c\u7406\uff0c\u7b2c\u4e8c\u8f6e\u7684\u4e24\u4e2a \\(4\\) \u4e5f\u4f1a\u4ea7\u751f\u91cd\u590d\u5b50\u96c6\u3002

    \u56fe 13-13 \u00a0 \u76f8\u7b49\u5143\u7d20\u5bfc\u81f4\u7684\u91cd\u590d\u5b50\u96c6

    "},{"location":"chapter_backtracking/subset_sum_problem/#1_1","title":"1. \u00a0 \u76f8\u7b49\u5143\u7d20\u526a\u679d","text":"

    \u4e3a\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u9700\u8981\u9650\u5236\u76f8\u7b49\u5143\u7d20\u5728\u6bcf\u4e00\u8f6e\u4e2d\u53ea\u80fd\u88ab\u9009\u62e9\u4e00\u6b21\u3002\u5b9e\u73b0\u65b9\u5f0f\u6bd4\u8f83\u5de7\u5999\uff1a\u7531\u4e8e\u6570\u7ec4\u662f\u5df2\u6392\u5e8f\u7684\uff0c\u56e0\u6b64\u76f8\u7b49\u5143\u7d20\u90fd\u662f\u76f8\u90bb\u7684\u3002\u8fd9\u610f\u5473\u7740\u5728\u67d0\u8f6e\u9009\u62e9\u4e2d\uff0c\u82e5\u5f53\u524d\u5143\u7d20\u4e0e\u5176\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u5219\u8bf4\u660e\u5b83\u5df2\u7ecf\u88ab\u9009\u62e9\u8fc7\uff0c\u56e0\u6b64\u76f4\u63a5\u8df3\u8fc7\u5f53\u524d\u5143\u7d20\u3002

    \u4e0e\u6b64\u540c\u65f6\uff0c\u672c\u9898\u89c4\u5b9a\u6bcf\u4e2a\u6570\u7ec4\u5143\u7d20\u53ea\u80fd\u88ab\u9009\u62e9\u4e00\u6b21\u3002\u5e78\u8fd0\u7684\u662f\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u5229\u7528\u53d8\u91cf start \u6765\u6ee1\u8db3\u8be5\u7ea6\u675f\uff1a\u5f53\u505a\u51fa\u9009\u62e9 \\(x_{i}\\) \u540e\uff0c\u8bbe\u5b9a\u4e0b\u4e00\u8f6e\u4ece\u7d22\u5f15 \\(i + 1\\) \u5f00\u59cb\u5411\u540e\u904d\u5386\u3002\u8fd9\u6837\u65e2\u80fd\u53bb\u9664\u91cd\u590d\u5b50\u96c6\uff0c\u4e5f\u80fd\u907f\u514d\u91cd\u590d\u9009\u62e9\u5143\u7d20\u3002

    "},{"location":"chapter_backtracking/subset_sum_problem/#2_1","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig subset_sum_ii.py
    def backtrack(\n    state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]\n):\n    \"\"\"\u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II\"\"\"\n    # \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0:\n        res.append(list(state))\n        return\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    # \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    # \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in range(start, len(choices)):\n        # \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        # \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0:\n            break\n        # \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start and choices[i] == choices[i - 1]:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        # \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res)\n        # \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop()\n\ndef subset_sum_ii(nums: list[int], target: int) -> list[list[int]]:\n    \"\"\"\u6c42\u89e3\u5b50\u96c6\u548c II\"\"\"\n    state = []  # \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort()  # \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start = 0  # \u904d\u5386\u8d77\u59cb\u70b9\n    res = []  # \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n
    subset_sum_ii.cpp
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(vector<int> &state, int target, vector<int> &choices, int start, vector<vector<int>> &res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.push_back(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.size(); i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push_back(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop_back();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nvector<vector<int>> subsetSumII(vector<int> &nums, int target) {\n    vector<int> state;              // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort(nums.begin(), nums.end()); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0;                  // \u904d\u5386\u8d77\u59cb\u70b9\n    vector<vector<int>> res;        // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.java
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(List<Integer> state, int target, int[] choices, int start, List<List<Integer>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(new ArrayList<>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.remove(state.size() - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<Integer>> subsetSumII(int[] nums, int target) {\n    List<Integer> state = new ArrayList<>(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Arrays.sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<Integer>> res = new ArrayList<>(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.cs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid Backtrack(List<int> state, int target, int[] choices, int start, List<List<int>> res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.Add(new List<int>(state));\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choices.Length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.Add(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        Backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.RemoveAt(state.Count - 1);\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<int>> SubsetSumII(int[] nums, int target) {\n    List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    Array.Sort(nums); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    Backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.go
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunc backtrackSubsetSumII(start, target int, state, choices *[]int, res *[][]int) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        newState := append([]int{}, *state...)\n        *res = append(*res, newState)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i := start; i < len(*choices); i++ {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target-(*choices)[i] < 0 {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start && (*choices)[i] == (*choices)[i-1] {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        *state = append(*state, (*choices)[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrackSubsetSumII(i+1, target-(*choices)[i], state, choices, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        *state = (*state)[:len(*state)-1]\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunc subsetSumII(nums []int, target int) [][]int {\n    state := make([]int, 0) // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    sort.Ints(nums)         // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    start := 0              // \u904d\u5386\u8d77\u59cb\u70b9\n    res := make([][]int, 0) // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrackSubsetSumII(start, target, &state, &nums, &res)\n    return res\n}\n
    subset_sum_ii.swift
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunc backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res: inout [[Int]]) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.append(state)\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in choices.indices.dropFirst(start) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start, choices[i] == choices[i - 1] {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.append(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state: &state, target: target - choices[i], choices: choices, start: i + 1, res: &res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeLast()\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunc subsetSumII(nums: [Int], target: Int) -> [[Int]] {\n    var state: [Int] = [] // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    let nums = nums.sorted() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    var res: [[Int]] = [] // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state: &state, target: target, choices: nums, start: start, res: &res)\n    return res\n}\n
    subset_sum_ii.js
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunction backtrack(state, target, choices, start, res) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] === choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunction subsetSumII(nums, target) {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.ts
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfunction backtrack(\n    state: number[],\n    target: number,\n    choices: number[],\n    start: number,\n    res: number[][]\n): void {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target === 0) {\n        res.push([...state]);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (let i = start; i < choices.length; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] === choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfunction subsetSumII(nums: number[], target: number): number[][] {\n    const state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort((a, b) => a - b); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    const start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    const res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res);\n    return res;\n}\n
    subset_sum_ii.dart
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(\n  List<int> state,\n  int target,\n  List<int> choices,\n  int start,\n  List<List<int>> res,\n) {\n  // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n  if (target == 0) {\n    res.add(List.from(state));\n    return;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n  // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n  for (int i = start; i < choices.length; i++) {\n    // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n    // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n    if (target - choices[i] < 0) {\n      break;\n    }\n    // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n    if (i > start && choices[i] == choices[i - 1]) {\n      continue;\n    }\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n    state.add(choices[i]);\n    // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n    backtrack(state, target - choices[i], choices, i + 1, res);\n    // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n    state.removeLast();\n  }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nList<List<int>> subsetSumII(List<int> nums, int target) {\n  List<int> state = []; // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n  nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n  int start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n  List<List<int>> res = []; // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n  backtrack(state, target, nums, start, res);\n  return res;\n}\n
    subset_sum_ii.rs
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfn backtrack(\n    mut state: Vec<i32>,\n    target: i32,\n    choices: &[i32],\n    start: usize,\n    res: &mut Vec<Vec<i32>>,\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if target == 0 {\n        res.push(state);\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for i in start..choices.len() {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if target - choices[i] < 0 {\n            break;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if i > start && choices[i] == choices[i - 1] {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.push(choices[i]);\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state.clone(), target - choices[i], choices, i, res);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.pop();\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfn subset_sum_ii(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {\n    let state = Vec::new(); // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort(); // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    let start = 0; // \u904d\u5386\u8d77\u59cb\u70b9\n    let mut res = Vec::new(); // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, &mut res);\n    res\n}\n
    subset_sum_ii.c
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nvoid backtrack(int target, int *choices, int choicesSize, int start) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        for (int i = 0; i < stateSize; i++) {\n            res[resSize][i] = state[i];\n        }\n        resColSizes[resSize++] = stateSize;\n        return;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (int i = start; i < choicesSize; i++) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\n        if (target - choices[i] < 0) {\n            continue;\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state[stateSize] = choices[i];\n        stateSize++;\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(target - choices[i], choices, choicesSize, i + 1);\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        stateSize--;\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nvoid subsetSumII(int *nums, int numsSize, int target) {\n    // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    qsort(nums, numsSize, sizeof(int), cmp);\n    // \u5f00\u59cb\u56de\u6eaf\n    backtrack(target, nums, numsSize, 0);\n}\n
    subset_sum_ii.kt
    /* \u56de\u6eaf\u7b97\u6cd5\uff1a\u5b50\u96c6\u548c II */\nfun backtrack(\n    state: MutableList<Int>,\n    target: Int,\n    choices: IntArray,\n    start: Int,\n    res: MutableList<MutableList<Int>?>\n) {\n    // \u5b50\u96c6\u548c\u7b49\u4e8e target \u65f6\uff0c\u8bb0\u5f55\u89e3\n    if (target == 0) {\n        res.add(state.toMutableList())\n        return\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    // \u526a\u679d\u4e8c\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u751f\u6210\u91cd\u590d\u5b50\u96c6\n    // \u526a\u679d\u4e09\uff1a\u4ece start \u5f00\u59cb\u904d\u5386\uff0c\u907f\u514d\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\n    for (i in start..<choices.size) {\n        // \u526a\u679d\u4e00\uff1a\u82e5\u5b50\u96c6\u548c\u8d85\u8fc7 target \uff0c\u5219\u76f4\u63a5\u7ed3\u675f\u5faa\u73af\n        // \u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u5df2\u6392\u5e8f\uff0c\u540e\u8fb9\u5143\u7d20\u66f4\u5927\uff0c\u5b50\u96c6\u548c\u4e00\u5b9a\u8d85\u8fc7 target\n        if (target - choices[i] < 0) {\n            break\n        }\n        // \u526a\u679d\u56db\uff1a\u5982\u679c\u8be5\u5143\u7d20\u4e0e\u5de6\u8fb9\u5143\u7d20\u76f8\u7b49\uff0c\u8bf4\u660e\u8be5\u641c\u7d22\u5206\u652f\u91cd\u590d\uff0c\u76f4\u63a5\u8df3\u8fc7\n        if (i > start && choices[i] == choices[i - 1]) {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0 target, start\n        state.add(choices[i])\n        // \u8fdb\u884c\u4e0b\u4e00\u8f6e\u9009\u62e9\n        backtrack(state, target - choices[i], choices, i + 1, res)\n        // \u56de\u9000\uff1a\u64a4\u9500\u9009\u62e9\uff0c\u6062\u590d\u5230\u4e4b\u524d\u7684\u72b6\u6001\n        state.removeAt(state.size - 1)\n    }\n}\n\n/* \u6c42\u89e3\u5b50\u96c6\u548c II */\nfun subsetSumII(nums: IntArray, target: Int): MutableList<MutableList<Int>?> {\n    val state = mutableListOf<Int>() // \u72b6\u6001\uff08\u5b50\u96c6\uff09\n    nums.sort() // \u5bf9 nums \u8fdb\u884c\u6392\u5e8f\n    val start = 0 // \u904d\u5386\u8d77\u59cb\u70b9\n    val res = mutableListOf<MutableList<Int>?>() // \u7ed3\u679c\u5217\u8868\uff08\u5b50\u96c6\u5217\u8868\uff09\n    backtrack(state, target, nums, start, res)\n    return res\n}\n
    subset_sum_ii.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subset_sum_ii}\n
    subset_sum_ii.zig
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{subsetSumII}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 13-14 \u5c55\u793a\u4e86\u6570\u7ec4 \\([4, 4, 5]\\) \u548c\u76ee\u6807\u5143\u7d20 \\(9\\) \u7684\u56de\u6eaf\u8fc7\u7a0b\uff0c\u5171\u5305\u542b\u56db\u79cd\u526a\u679d\u64cd\u4f5c\u3002\u8bf7\u4f60\u5c06\u56fe\u793a\u4e0e\u4ee3\u7801\u6ce8\u91ca\u76f8\u7ed3\u5408\uff0c\u7406\u89e3\u6574\u4e2a\u641c\u7d22\u8fc7\u7a0b\uff0c\u4ee5\u53ca\u6bcf\u79cd\u526a\u679d\u64cd\u4f5c\u662f\u5982\u4f55\u5de5\u4f5c\u7684\u3002

    \u56fe 13-14 \u00a0 \u5b50\u96c6\u548c II \u56de\u6eaf\u8fc7\u7a0b

    "},{"location":"chapter_backtracking/summary/","title":"13.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_backtracking/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u56de\u6eaf\u7b97\u6cd5\u672c\u8d28\u662f\u7a77\u4e3e\u6cd5\uff0c\u901a\u8fc7\u5bf9\u89e3\u7a7a\u95f4\u8fdb\u884c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u6765\u5bfb\u627e\u7b26\u5408\u6761\u4ef6\u7684\u89e3\u3002\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\uff0c\u9047\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u89e3\u5219\u8bb0\u5f55\uff0c\u76f4\u81f3\u627e\u5230\u6240\u6709\u89e3\u6216\u904d\u5386\u5b8c\u6210\u540e\u7ed3\u675f\u3002
    • \u56de\u6eaf\u7b97\u6cd5\u7684\u641c\u7d22\u8fc7\u7a0b\u5305\u62ec\u5c1d\u8bd5\u4e0e\u56de\u9000\u4e24\u4e2a\u90e8\u5206\u3002\u5b83\u901a\u8fc7\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u6765\u5c1d\u8bd5\u5404\u79cd\u9009\u62e9\uff0c\u5f53\u9047\u5230\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\u7684\u60c5\u51b5\u65f6\uff0c\u5219\u64a4\u9500\u4e0a\u4e00\u6b65\u7684\u9009\u62e9\uff0c\u9000\u56de\u5230\u4e4b\u524d\u7684\u72b6\u6001\uff0c\u5e76\u7ee7\u7eed\u5c1d\u8bd5\u5176\u4ed6\u9009\u62e9\u3002\u5c1d\u8bd5\u4e0e\u56de\u9000\u662f\u4e24\u4e2a\u65b9\u5411\u76f8\u53cd\u7684\u64cd\u4f5c\u3002
    • \u56de\u6eaf\u95ee\u9898\u901a\u5e38\u5305\u542b\u591a\u4e2a\u7ea6\u675f\u6761\u4ef6\uff0c\u5b83\u4eec\u53ef\u7528\u4e8e\u5b9e\u73b0\u526a\u679d\u64cd\u4f5c\u3002\u526a\u679d\u53ef\u4ee5\u63d0\u524d\u7ed3\u675f\u4e0d\u5fc5\u8981\u7684\u641c\u7d22\u5206\u652f\uff0c\u5927\u5e45\u63d0\u5347\u641c\u7d22\u6548\u7387\u3002
    • \u56de\u6eaf\u7b97\u6cd5\u4e3b\u8981\u53ef\u7528\u4e8e\u89e3\u51b3\u641c\u7d22\u95ee\u9898\u548c\u7ea6\u675f\u6ee1\u8db3\u95ee\u9898\u3002\u7ec4\u5408\u4f18\u5316\u95ee\u9898\u867d\u7136\u53ef\u4ee5\u7528\u56de\u6eaf\u7b97\u6cd5\u89e3\u51b3\uff0c\u4f46\u5f80\u5f80\u5b58\u5728\u6548\u7387\u66f4\u9ad8\u6216\u6548\u679c\u66f4\u597d\u7684\u89e3\u6cd5\u3002
    • \u5168\u6392\u5217\u95ee\u9898\u65e8\u5728\u641c\u7d22\u7ed9\u5b9a\u96c6\u5408\u5143\u7d20\u7684\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u3002\u6211\u4eec\u501f\u52a9\u4e00\u4e2a\u6570\u7ec4\u6765\u8bb0\u5f55\u6bcf\u4e2a\u5143\u7d20\u662f\u5426\u88ab\u9009\u62e9\uff0c\u526a\u6389\u91cd\u590d\u9009\u62e9\u540c\u4e00\u5143\u7d20\u7684\u641c\u7d22\u5206\u652f\uff0c\u786e\u4fdd\u6bcf\u4e2a\u5143\u7d20\u53ea\u88ab\u9009\u62e9\u4e00\u6b21\u3002
    • \u5728\u5168\u6392\u5217\u95ee\u9898\u4e2d\uff0c\u5982\u679c\u96c6\u5408\u4e2d\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff0c\u5219\u6700\u7ec8\u7ed3\u679c\u4f1a\u51fa\u73b0\u91cd\u590d\u6392\u5217\u3002\u6211\u4eec\u9700\u8981\u7ea6\u675f\u76f8\u7b49\u5143\u7d20\u5728\u6bcf\u8f6e\u4e2d\u53ea\u80fd\u88ab\u9009\u62e9\u4e00\u6b21\uff0c\u8fd9\u901a\u5e38\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408\u6765\u5b9e\u73b0\u3002
    • \u5b50\u96c6\u548c\u95ee\u9898\u7684\u76ee\u6807\u662f\u5728\u7ed9\u5b9a\u96c6\u5408\u4e2d\u627e\u5230\u548c\u4e3a\u76ee\u6807\u503c\u7684\u6240\u6709\u5b50\u96c6\u3002\u96c6\u5408\u4e0d\u533a\u5206\u5143\u7d20\u987a\u5e8f\uff0c\u800c\u641c\u7d22\u8fc7\u7a0b\u4f1a\u8f93\u51fa\u6240\u6709\u987a\u5e8f\u7684\u7ed3\u679c\uff0c\u4ea7\u751f\u91cd\u590d\u5b50\u96c6\u3002\u6211\u4eec\u5728\u56de\u6eaf\u524d\u5c06\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c\u5e76\u8bbe\u7f6e\u4e00\u4e2a\u53d8\u91cf\u6765\u6307\u793a\u6bcf\u4e00\u8f6e\u7684\u904d\u5386\u8d77\u59cb\u70b9\uff0c\u4ece\u800c\u5c06\u751f\u6210\u91cd\u590d\u5b50\u96c6\u7684\u641c\u7d22\u5206\u652f\u8fdb\u884c\u526a\u679d\u3002
    • \u5bf9\u4e8e\u5b50\u96c6\u548c\u95ee\u9898\uff0c\u6570\u7ec4\u4e2d\u7684\u76f8\u7b49\u5143\u7d20\u4f1a\u4ea7\u751f\u91cd\u590d\u96c6\u5408\u3002\u6211\u4eec\u5229\u7528\u6570\u7ec4\u5df2\u6392\u5e8f\u7684\u524d\u7f6e\u6761\u4ef6\uff0c\u901a\u8fc7\u5224\u65ad\u76f8\u90bb\u5143\u7d20\u662f\u5426\u76f8\u7b49\u5b9e\u73b0\u526a\u679d\uff0c\u4ece\u800c\u786e\u4fdd\u76f8\u7b49\u5143\u7d20\u5728\u6bcf\u8f6e\u4e2d\u53ea\u80fd\u88ab\u9009\u4e2d\u4e00\u6b21\u3002
    • \\(n\\) \u7687\u540e\u95ee\u9898\u65e8\u5728\u5bfb\u627e\u5c06 \\(n\\) \u4e2a\u7687\u540e\u653e\u7f6e\u5230 \\(n \\times n\\) \u5c3a\u5bf8\u68cb\u76d8\u4e0a\u7684\u65b9\u6848\uff0c\u8981\u6c42\u6240\u6709\u7687\u540e\u4e24\u4e24\u4e4b\u95f4\u65e0\u6cd5\u653b\u51fb\u5bf9\u65b9\u3002\u8be5\u95ee\u9898\u7684\u7ea6\u675f\u6761\u4ef6\u6709\u884c\u7ea6\u675f\u3001\u5217\u7ea6\u675f\u3001\u4e3b\u5bf9\u89d2\u7ebf\u548c\u6b21\u5bf9\u89d2\u7ebf\u7ea6\u675f\u3002\u4e3a\u6ee1\u8db3\u884c\u7ea6\u675f\uff0c\u6211\u4eec\u91c7\u7528\u6309\u884c\u653e\u7f6e\u7684\u7b56\u7565\uff0c\u4fdd\u8bc1\u6bcf\u4e00\u884c\u653e\u7f6e\u4e00\u4e2a\u7687\u540e\u3002
    • \u5217\u7ea6\u675f\u548c\u5bf9\u89d2\u7ebf\u7ea6\u675f\u7684\u5904\u7406\u65b9\u5f0f\u7c7b\u4f3c\u3002\u5bf9\u4e8e\u5217\u7ea6\u675f\uff0c\u6211\u4eec\u5229\u7528\u4e00\u4e2a\u6570\u7ec4\u6765\u8bb0\u5f55\u6bcf\u4e00\u5217\u662f\u5426\u6709\u7687\u540e\uff0c\u4ece\u800c\u6307\u793a\u9009\u4e2d\u7684\u683c\u5b50\u662f\u5426\u5408\u6cd5\u3002\u5bf9\u4e8e\u5bf9\u89d2\u7ebf\u7ea6\u675f\uff0c\u6211\u4eec\u501f\u52a9\u4e24\u4e2a\u6570\u7ec4\u6765\u5206\u522b\u8bb0\u5f55\u8be5\u4e3b\u3001\u6b21\u5bf9\u89d2\u7ebf\u4e0a\u662f\u5426\u5b58\u5728\u7687\u540e\uff1b\u96be\u70b9\u5728\u4e8e\u627e\u5904\u5728\u5230\u540c\u4e00\u4e3b\uff08\u526f\uff09\u5bf9\u89d2\u7ebf\u4e0a\u683c\u5b50\u6ee1\u8db3\u7684\u884c\u5217\u7d22\u5f15\u89c4\u5f8b\u3002
    "},{"location":"chapter_backtracking/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u600e\u4e48\u7406\u89e3\u56de\u6eaf\u548c\u9012\u5f52\u7684\u5173\u7cfb\uff1f

    \u603b\u7684\u6765\u770b\uff0c\u56de\u6eaf\u662f\u4e00\u79cd\u201c\u7b97\u6cd5\u7b56\u7565\u201d\uff0c\u800c\u9012\u5f52\u66f4\u50cf\u662f\u4e00\u4e2a\u201c\u5de5\u5177\u201d\u3002

    • \u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\u3002\u7136\u800c\uff0c\u56de\u6eaf\u662f\u9012\u5f52\u7684\u5e94\u7528\u573a\u666f\u4e4b\u4e00\uff0c\u662f\u9012\u5f52\u5728\u641c\u7d22\u95ee\u9898\u4e2d\u7684\u5e94\u7528\u3002
    • \u9012\u5f52\u7684\u7ed3\u6784\u4f53\u73b0\u4e86\u201c\u5b50\u95ee\u9898\u5206\u89e3\u201d\u7684\u89e3\u9898\u8303\u5f0f\uff0c\u5e38\u7528\u4e8e\u89e3\u51b3\u5206\u6cbb\u3001\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\uff08\u8bb0\u5fc6\u5316\u9012\u5f52\uff09\u7b49\u95ee\u9898\u3002
    "},{"location":"chapter_computational_complexity/","title":"\u7b2c 2 \u7ae0 \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    Abstract

    \u590d\u6742\u5ea6\u5206\u6790\u72b9\u5982\u6d69\u701a\u7684\u7b97\u6cd5\u5b87\u5b99\u4e2d\u7684\u65f6\u7a7a\u5411\u5bfc\u3002

    \u5b83\u5e26\u9886\u6211\u4eec\u5728\u65f6\u95f4\u4e0e\u7a7a\u95f4\u8fd9\u4e24\u4e2a\u7ef4\u5ea6\u4e0a\u6df1\u5165\u63a2\u7d22\uff0c\u5bfb\u627e\u66f4\u4f18\u96c5\u7684\u89e3\u51b3\u65b9\u6848\u3002

    "},{"location":"chapter_computational_complexity/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 2.1 \u00a0 \u7b97\u6cd5\u6548\u7387\u8bc4\u4f30
    • 2.2 \u00a0 \u8fed\u4ee3\u4e0e\u9012\u5f52
    • 2.3 \u00a0 \u65f6\u95f4\u590d\u6742\u5ea6
    • 2.4 \u00a0 \u7a7a\u95f4\u590d\u6742\u5ea6
    • 2.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/","title":"2.2 \u00a0 \u8fed\u4ee3\u4e0e\u9012\u5f52","text":"

    \u5728\u7b97\u6cd5\u4e2d\uff0c\u91cd\u590d\u6267\u884c\u67d0\u4e2a\u4efb\u52a1\u662f\u5f88\u5e38\u89c1\u7684\uff0c\u5b83\u4e0e\u590d\u6742\u5ea6\u5206\u6790\u606f\u606f\u76f8\u5173\u3002\u56e0\u6b64\uff0c\u5728\u4ecb\u7ecd\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e4b\u524d\uff0c\u6211\u4eec\u5148\u6765\u4e86\u89e3\u5982\u4f55\u5728\u7a0b\u5e8f\u4e2d\u5b9e\u73b0\u91cd\u590d\u6267\u884c\u4efb\u52a1\uff0c\u5373\u4e24\u79cd\u57fa\u672c\u7684\u7a0b\u5e8f\u63a7\u5236\u7ed3\u6784\uff1a\u8fed\u4ee3\u3001\u9012\u5f52\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#221","title":"2.2.1 \u00a0 \u8fed\u4ee3","text":"

    \u8fed\u4ee3\uff08iteration\uff09\u662f\u4e00\u79cd\u91cd\u590d\u6267\u884c\u67d0\u4e2a\u4efb\u52a1\u7684\u63a7\u5236\u7ed3\u6784\u3002\u5728\u8fed\u4ee3\u4e2d\uff0c\u7a0b\u5e8f\u4f1a\u5728\u6ee1\u8db3\u4e00\u5b9a\u7684\u6761\u4ef6\u4e0b\u91cd\u590d\u6267\u884c\u67d0\u6bb5\u4ee3\u7801\uff0c\u76f4\u5230\u8fd9\u4e2a\u6761\u4ef6\u4e0d\u518d\u6ee1\u8db3\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1-for","title":"1. \u00a0 for \u5faa\u73af","text":"

    for \u5faa\u73af\u662f\u6700\u5e38\u89c1\u7684\u8fed\u4ee3\u5f62\u5f0f\u4e4b\u4e00\uff0c\u9002\u5408\u5728\u9884\u5148\u77e5\u9053\u8fed\u4ee3\u6b21\u6570\u65f6\u4f7f\u7528\u3002

    \u4ee5\u4e0b\u51fd\u6570\u57fa\u4e8e for \u5faa\u73af\u5b9e\u73b0\u4e86\u6c42\u548c \\(1 + 2 + \\dots + n\\) \uff0c\u6c42\u548c\u7ed3\u679c\u4f7f\u7528\u53d8\u91cf res \u8bb0\u5f55\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cPython \u4e2d range(a, b) \u5bf9\u5e94\u7684\u533a\u95f4\u662f\u201c\u5de6\u95ed\u53f3\u5f00\u201d\u7684\uff0c\u5bf9\u5e94\u7684\u904d\u5386\u8303\u56f4\u4e3a \\(a, a + 1, \\dots, b-1\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def for_loop(n: int) -> int:\n    \"\"\"for \u5faa\u73af\"\"\"\n    res = 0\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        res += i\n    return res\n
    iteration.cpp
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.java
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.cs
    /* for \u5faa\u73af */\nint ForLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.go
    /* for \u5faa\u73af */\nfunc forLoop(n int) int {\n    res := 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        res += i\n    }\n    return res\n}\n
    iteration.swift
    /* for \u5faa\u73af */\nfunc forLoop(n: Int) -> Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        res += i\n    }\n    return res\n}\n
    iteration.js
    /* for \u5faa\u73af */\nfunction forLoop(n) {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.ts
    /* for \u5faa\u73af */\nfunction forLoop(n: number): number {\n    let res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.dart
    /* for \u5faa\u73af */\nint forLoop(int n) {\n  int res = 0;\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    res += i;\n  }\n  return res;\n}\n
    iteration.rs
    /* for \u5faa\u73af */\nfn for_loop(n: i32) -> i32 {\n    let mut res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i in 1..=n {\n        res += i;\n    }\n    res\n}\n
    iteration.c
    /* for \u5faa\u73af */\nint forLoop(int n) {\n    int res = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        res += i;\n    }\n    return res;\n}\n
    iteration.kt
    /* for \u5faa\u73af */\nfun forLoop(n: Int): Int {\n    var res = 0\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        res += i\n    }\n    return res\n}\n
    iteration.rb
    ### for \u5faa\u73af ###\ndef for_loop(n)\n  res = 0\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  for i in 1..n\n    res += i\n  end\n\n  res\nend\n
    iteration.zig
    // for \u5faa\u73af\nfn forLoop(n: usize) i32 {\n    var res: i32 = 0;\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        res = res + @as(i32, @intCast(i));\n    }\n    return res;\n} \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-1 \u662f\u8be5\u6c42\u548c\u51fd\u6570\u7684\u6d41\u7a0b\u6846\u56fe\u3002

    \u56fe 2-1 \u00a0 \u6c42\u548c\u51fd\u6570\u7684\u6d41\u7a0b\u6846\u56fe

    \u6b64\u6c42\u548c\u51fd\u6570\u7684\u64cd\u4f5c\u6570\u91cf\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u6210\u6b63\u6bd4\uff0c\u6216\u8005\u8bf4\u6210\u201c\u7ebf\u6027\u5173\u7cfb\u201d\u3002\u5b9e\u9645\u4e0a\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u63cf\u8ff0\u7684\u5c31\u662f\u8fd9\u4e2a\u201c\u7ebf\u6027\u5173\u7cfb\u201d\u3002\u76f8\u5173\u5185\u5bb9\u5c06\u4f1a\u5728\u4e0b\u4e00\u8282\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2-while","title":"2. \u00a0 while \u5faa\u73af","text":"

    \u4e0e for \u5faa\u73af\u7c7b\u4f3c\uff0cwhile \u5faa\u73af\u4e5f\u662f\u4e00\u79cd\u5b9e\u73b0\u8fed\u4ee3\u7684\u65b9\u6cd5\u3002\u5728 while \u5faa\u73af\u4e2d\uff0c\u7a0b\u5e8f\u6bcf\u8f6e\u90fd\u4f1a\u5148\u68c0\u67e5\u6761\u4ef6\uff0c\u5982\u679c\u6761\u4ef6\u4e3a\u771f\uff0c\u5219\u7ee7\u7eed\u6267\u884c\uff0c\u5426\u5219\u5c31\u7ed3\u675f\u5faa\u73af\u3002

    \u4e0b\u9762\u6211\u4eec\u7528 while \u5faa\u73af\u6765\u5b9e\u73b0\u6c42\u548c \\(1 + 2 + \\dots + n\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop(n: int) -> int:\n    \"\"\"while \u5faa\u73af\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n:\n        res += i\n        i += 1  # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af */\nint WhileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af */\nfunc whileLoop(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af */\nfunc whileLoop(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i\n        i += 1 // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af */\nfunction whileLoop(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af */\nfunction whileLoop(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while (i <= n) {\n    res += i;\n    i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af */\nfn while_loop(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while i <= n {\n        res += i;\n        i += 1; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af */\nint whileLoop(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i;\n        i++; // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af */\nfun whileLoop(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += i\n        i++ // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af ###\ndef while_loop(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n  while i <= n\n    res += i\n    i += 1 # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n  end\n\n  res\nend\n
    iteration.zig
    // while \u5faa\u73af\nfn whileLoop(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 2, ..., n-1, n\n    while (i <= n) {\n        res += @intCast(i);\n        i += 1;\n    }\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    while \u5faa\u73af\u6bd4 for \u5faa\u73af\u7684\u81ea\u7531\u5ea6\u66f4\u9ad8\u3002\u5728 while \u5faa\u73af\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u81ea\u7531\u5730\u8bbe\u8ba1\u6761\u4ef6\u53d8\u91cf\u7684\u521d\u59cb\u5316\u548c\u66f4\u65b0\u6b65\u9aa4\u3002

    \u4f8b\u5982\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u6761\u4ef6\u53d8\u91cf \\(i\\) \u6bcf\u8f6e\u8fdb\u884c\u4e24\u6b21\u66f4\u65b0\uff0c\u8fd9\u79cd\u60c5\u51b5\u5c31\u4e0d\u592a\u65b9\u4fbf\u7528 for \u5faa\u73af\u5b9e\u73b0\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def while_loop_ii(n: int) -> int:\n    \"\"\"while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\"\"\"\n    res = 0\n    i = 1  # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n:\n        res += i\n        # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    return res\n
    iteration.cpp
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.java
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.cs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint WhileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1; \n        i *= 2;\n    }\n    return res;\n}\n
    iteration.go
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n int) int {\n    res := 0\n    // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    i := 1\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    for i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.swift
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunc whileLoopII(n: Int) -> Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1\n        i *= 2\n    }\n    return res\n}\n
    iteration.js
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n) {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.ts
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfunction whileLoopII(n: number): number {\n    let res = 0;\n    let i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.dart
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n  int res = 0;\n  int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n  // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while (i <= n) {\n    res += i;\n    // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i++;\n    i *= 2;\n  }\n  return res;\n}\n
    iteration.rs
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfn while_loop_ii(n: i32) -> i32 {\n    let mut res = 0;\n    let mut i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while i <= n {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    res\n}\n
    iteration.c
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nint whileLoopII(int n) {\n    int res = 0;\n    int i = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i;\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++;\n        i *= 2;\n    }\n    return res;\n}\n
    iteration.kt
    /* while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09 */\nfun whileLoopII(n: Int): Int {\n    var res = 0\n    var i = 1 // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += i\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i++\n        i *= 2\n    }\n    return res\n}\n
    iteration.rb
    ### while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09###\ndef while_loop_ii(n)\n  res = 0\n  i = 1 # \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n\n  # \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n  while i <= n\n    res += i\n    # \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n    i += 1\n    i *= 2\n  end\n\n  res\nend\n
    iteration.zig
    //  while \u5faa\u73af\uff08\u4e24\u6b21\u66f4\u65b0\uff09\nfn whileLoopII(n: i32) i32 {\n    var res: i32 = 0;\n    var i: i32 = 1; // \u521d\u59cb\u5316\u6761\u4ef6\u53d8\u91cf\n    // \u5faa\u73af\u6c42\u548c 1, 4, 10, ...\n    while (i <= n) {\n        res += @intCast(i);\n        // \u66f4\u65b0\u6761\u4ef6\u53d8\u91cf\n        i += 1;\n        i *= 2;\n    }\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u603b\u7684\u6765\u8bf4\uff0cfor \u5faa\u73af\u7684\u4ee3\u7801\u66f4\u52a0\u7d27\u51d1\uff0cwhile \u5faa\u73af\u66f4\u52a0\u7075\u6d3b\uff0c\u4e24\u8005\u90fd\u53ef\u4ee5\u5b9e\u73b0\u8fed\u4ee3\u7ed3\u6784\u3002\u9009\u62e9\u4f7f\u7528\u54ea\u4e00\u4e2a\u5e94\u8be5\u6839\u636e\u7279\u5b9a\u95ee\u9898\u7684\u9700\u6c42\u6765\u51b3\u5b9a\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3","title":"3. \u00a0 \u5d4c\u5957\u5faa\u73af","text":"

    \u6211\u4eec\u53ef\u4ee5\u5728\u4e00\u4e2a\u5faa\u73af\u7ed3\u6784\u5185\u5d4c\u5957\u53e6\u4e00\u4e2a\u5faa\u73af\u7ed3\u6784\uff0c\u4e0b\u9762\u4ee5 for \u5faa\u73af\u4e3a\u4f8b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig iteration.py
    def nested_for_loop(n: int) -> str:\n    \"\"\"\u53cc\u5c42 for \u5faa\u73af\"\"\"\n    res = \"\"\n    # \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in range(1, n + 1):\n        # \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in range(1, n + 1):\n            res += f\"({i}, {j}), \"\n    return res\n
    iteration.cpp
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring nestedForLoop(int n) {\n    ostringstream res;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; ++i) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; ++j) {\n            res << \"(\" << i << \", \" << j << \"), \";\n        }\n    }\n    return res.str();\n}\n
    iteration.java
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n    StringBuilder res = new StringBuilder();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.append(\"(\" + i + \", \" + j + \"), \");\n        }\n    }\n    return res.toString();\n}\n
    iteration.cs
    /* \u53cc\u5c42 for \u5faa\u73af */\nstring NestedForLoop(int n) {\n    StringBuilder res = new();\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            res.Append($\"({i}, {j}), \");\n        }\n    }\n    return res.ToString();\n}\n
    iteration.go
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n int) string {\n    res := \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= n; j++ {\n            // \u5faa\u73af j = 1, 2, ..., n-1, n\n            res += fmt.Sprintf(\"(%d, %d), \", i, j)\n        }\n    }\n    return res\n}\n
    iteration.swift
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunc nestedForLoop(n: Int) -> String {\n    var res = \"\"\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1 ... n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1 ... n {\n            res.append(\"(\\(i), \\(j)), \")\n        }\n    }\n    return res\n}\n
    iteration.js
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n) {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.ts
    /* \u53cc\u5c42 for \u5faa\u73af */\nfunction nestedForLoop(n: number): string {\n    let res = '';\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (let i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (let j = 1; j <= n; j++) {\n            res += `(${i}, ${j}), `;\n        }\n    }\n    return res;\n}\n
    iteration.dart
    /* \u53cc\u5c42 for \u5faa\u73af */\nString nestedForLoop(int n) {\n  String res = \"\";\n  // \u5faa\u73af i = 1, 2, ..., n-1, n\n  for (int i = 1; i <= n; i++) {\n    // \u5faa\u73af j = 1, 2, ..., n-1, n\n    for (int j = 1; j <= n; j++) {\n      res += \"($i, $j), \";\n    }\n  }\n  return res;\n}\n
    iteration.rs
    /* \u53cc\u5c42 for \u5faa\u73af */\nfn nested_for_loop(n: i32) -> String {\n    let mut res = vec![];\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for i in 1..=n {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for j in 1..=n {\n            res.push(format!(\"({}, {}), \", i, j));\n        }\n    }\n    res.join(\"\")\n}\n
    iteration.c
    /* \u53cc\u5c42 for \u5faa\u73af */\nchar *nestedForLoop(int n) {\n    // n * n \u4e3a\u5bf9\u5e94\u70b9\u6570\u91cf\uff0c\"(i, j), \" \u5bf9\u5e94\u5b57\u7b26\u4e32\u957f\u6700\u5927\u4e3a 6+10*2\uff0c\u52a0\u4e0a\u6700\u540e\u4e00\u4e2a\u7a7a\u5b57\u7b26 \\0 \u7684\u989d\u5916\u7a7a\u95f4\n    int size = n * n * 26 + 1;\n    char *res = malloc(size * sizeof(char));\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (int i = 1; i <= n; i++) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (int j = 1; j <= n; j++) {\n            char tmp[26];\n            snprintf(tmp, sizeof(tmp), \"(%d, %d), \", i, j);\n            strncat(res, tmp, size - strlen(res) - 1);\n        }\n    }\n    return res;\n}\n
    iteration.kt
    /* \u53cc\u5c42 for \u5faa\u73af */\nfun nestedForLoop(n: Int): String {\n    val res = StringBuilder()\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (i in 1..n) {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (j in 1..n) {\n            res.append(\" ($i, $j), \")\n        }\n    }\n    return res.toString()\n}\n
    iteration.rb
    ### \u53cc\u5c42 for \u5faa\u73af ###\ndef nested_for_loop(n)\n  res = \"\"\n\n  # \u5faa\u73af i = 1, 2, ..., n-1, n\n  for i in 1..n\n    # \u5faa\u73af j = 1, 2, ..., n-1, n\n    for j in 1..n\n      res += \"(#{i}, #{j}), \"\n    end\n  end\n\n  res\nend\n
    iteration.zig
    // \u53cc\u5c42 for \u5faa\u73af\nfn nestedForLoop(allocator: Allocator, n: usize) ![]const u8 {\n    var res = std.ArrayList(u8).init(allocator);\n    defer res.deinit();\n    var buffer: [20]u8 = undefined;\n    // \u5faa\u73af i = 1, 2, ..., n-1, n\n    for (1..n+1) |i| {\n        // \u5faa\u73af j = 1, 2, ..., n-1, n\n        for (1..n+1) |j| {\n            var _str = try std.fmt.bufPrint(&buffer, \"({d}, {d}), \", .{i, j});\n            try res.appendSlice(_str);\n        }\n    }\n    return res.toOwnedSlice();\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-2 \u662f\u8be5\u5d4c\u5957\u5faa\u73af\u7684\u6d41\u7a0b\u6846\u56fe\u3002

    \u56fe 2-2 \u00a0 \u5d4c\u5957\u5faa\u73af\u7684\u6d41\u7a0b\u6846\u56fe

    \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u7684\u64cd\u4f5c\u6570\u91cf\u4e0e \\(n^2\\) \u6210\u6b63\u6bd4\uff0c\u6216\u8005\u8bf4\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u548c\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u6210\u201c\u5e73\u65b9\u5173\u7cfb\u201d\u3002

    \u6211\u4eec\u53ef\u4ee5\u7ee7\u7eed\u6dfb\u52a0\u5d4c\u5957\u5faa\u73af\uff0c\u6bcf\u4e00\u6b21\u5d4c\u5957\u90fd\u662f\u4e00\u6b21\u201c\u5347\u7ef4\u201d\uff0c\u5c06\u4f1a\u4f7f\u65f6\u95f4\u590d\u6742\u5ea6\u63d0\u9ad8\u81f3\u201c\u7acb\u65b9\u5173\u7cfb\u201d\u201c\u56db\u6b21\u65b9\u5173\u7cfb\u201d\uff0c\u4ee5\u6b64\u7c7b\u63a8\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#222","title":"2.2.2 \u00a0 \u9012\u5f52","text":"

    \u9012\u5f52\uff08recursion\uff09\u662f\u4e00\u79cd\u7b97\u6cd5\u7b56\u7565\uff0c\u901a\u8fc7\u51fd\u6570\u8c03\u7528\u81ea\u8eab\u6765\u89e3\u51b3\u95ee\u9898\u3002\u5b83\u4e3b\u8981\u5305\u542b\u4e24\u4e2a\u9636\u6bb5\u3002

    1. \u9012\uff1a\u7a0b\u5e8f\u4e0d\u65ad\u6df1\u5165\u5730\u8c03\u7528\u81ea\u8eab\uff0c\u901a\u5e38\u4f20\u5165\u66f4\u5c0f\u6216\u66f4\u7b80\u5316\u7684\u53c2\u6570\uff0c\u76f4\u5230\u8fbe\u5230\u201c\u7ec8\u6b62\u6761\u4ef6\u201d\u3002
    2. \u5f52\uff1a\u89e6\u53d1\u201c\u7ec8\u6b62\u6761\u4ef6\u201d\u540e\uff0c\u7a0b\u5e8f\u4ece\u6700\u6df1\u5c42\u7684\u9012\u5f52\u51fd\u6570\u5f00\u59cb\u9010\u5c42\u8fd4\u56de\uff0c\u6c47\u805a\u6bcf\u4e00\u5c42\u7684\u7ed3\u679c\u3002

    \u800c\u4ece\u5b9e\u73b0\u7684\u89d2\u5ea6\u770b\uff0c\u9012\u5f52\u4ee3\u7801\u4e3b\u8981\u5305\u542b\u4e09\u4e2a\u8981\u7d20\u3002

    1. \u7ec8\u6b62\u6761\u4ef6\uff1a\u7528\u4e8e\u51b3\u5b9a\u4ec0\u4e48\u65f6\u5019\u7531\u201c\u9012\u201d\u8f6c\u201c\u5f52\u201d\u3002
    2. \u9012\u5f52\u8c03\u7528\uff1a\u5bf9\u5e94\u201c\u9012\u201d\uff0c\u51fd\u6570\u8c03\u7528\u81ea\u8eab\uff0c\u901a\u5e38\u8f93\u5165\u66f4\u5c0f\u6216\u66f4\u7b80\u5316\u7684\u53c2\u6570\u3002
    3. \u8fd4\u56de\u7ed3\u679c\uff1a\u5bf9\u5e94\u201c\u5f52\u201d\uff0c\u5c06\u5f53\u524d\u9012\u5f52\u5c42\u7ea7\u7684\u7ed3\u679c\u8fd4\u56de\u81f3\u4e0a\u4e00\u5c42\u3002

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u6211\u4eec\u53ea\u9700\u8c03\u7528\u51fd\u6570 recur(n) \uff0c\u5c31\u53ef\u4ee5\u5b8c\u6210 \\(1 + 2 + \\dots + n\\) \u7684\u8ba1\u7b97\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def recur(n: int) -> int:\n    \"\"\"\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 1:\n        return 1\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res = recur(n - 1)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n
    recursion.cpp
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.java
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.cs
    /* \u9012\u5f52 */\nint Recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = Recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.go
    /* \u9012\u5f52 */\nfunc recur(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    res := recur(n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.swift
    /* \u9012\u5f52 */\nfunc recur(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n: n - 1)\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.js
    /* \u9012\u5f52 */\nfunction recur(n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.ts
    /* \u9012\u5f52 */\nfunction recur(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 1) return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    const res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.dart
    /* \u9012\u5f52 */\nint recur(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 1) return 1;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  int res = recur(n - 1);\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  return n + res;\n}\n
    recursion.rs
    /* \u9012\u5f52 */\nfn recur(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 1 {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    let res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    n + res\n}\n
    recursion.c
    /* \u9012\u5f52 */\nint recur(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    int res = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    recursion.kt
    /* \u9012\u5f52 */\nfun recur(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1)\n        return 1\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    val res = recur(n - 1)\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    return n + res\n}\n
    recursion.rb
    ### \u9012\u5f52 ###\ndef recur(n)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return 1 if n == 1\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  res = recur(n - 1)\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  n + res\nend\n
    recursion.zig
    // \u9012\u5f52\u51fd\u6570\nfn recur(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 1) {\n        return 1;\n    }\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var res: i32 = recur(n - 1);\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    return n + res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-3 \u5c55\u793a\u4e86\u8be5\u51fd\u6570\u7684\u9012\u5f52\u8fc7\u7a0b\u3002

    \u56fe 2-3 \u00a0 \u6c42\u548c\u51fd\u6570\u7684\u9012\u5f52\u8fc7\u7a0b

    \u867d\u7136\u4ece\u8ba1\u7b97\u89d2\u5ea6\u770b\uff0c\u8fed\u4ee3\u4e0e\u9012\u5f52\u53ef\u4ee5\u5f97\u5230\u76f8\u540c\u7684\u7ed3\u679c\uff0c\u4f46\u5b83\u4eec\u4ee3\u8868\u4e86\u4e24\u79cd\u5b8c\u5168\u4e0d\u540c\u7684\u601d\u8003\u548c\u89e3\u51b3\u95ee\u9898\u7684\u8303\u5f0f\u3002

    • \u8fed\u4ee3\uff1a\u201c\u81ea\u4e0b\u800c\u4e0a\u201d\u5730\u89e3\u51b3\u95ee\u9898\u3002\u4ece\u6700\u57fa\u7840\u7684\u6b65\u9aa4\u5f00\u59cb\uff0c\u7136\u540e\u4e0d\u65ad\u91cd\u590d\u6216\u7d2f\u52a0\u8fd9\u4e9b\u6b65\u9aa4\uff0c\u76f4\u5230\u4efb\u52a1\u5b8c\u6210\u3002
    • \u9012\u5f52\uff1a\u201c\u81ea\u4e0a\u800c\u4e0b\u201d\u5730\u89e3\u51b3\u95ee\u9898\u3002\u5c06\u539f\u95ee\u9898\u5206\u89e3\u4e3a\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u8fd9\u4e9b\u5b50\u95ee\u9898\u548c\u539f\u95ee\u9898\u5177\u6709\u76f8\u540c\u7684\u5f62\u5f0f\u3002\u63a5\u4e0b\u6765\u5c06\u5b50\u95ee\u9898\u7ee7\u7eed\u5206\u89e3\u4e3a\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u76f4\u5230\u57fa\u672c\u60c5\u51b5\u65f6\u505c\u6b62\uff08\u57fa\u672c\u60c5\u51b5\u7684\u89e3\u662f\u5df2\u77e5\u7684\uff09\u3002

    \u4ee5\u4e0a\u8ff0\u6c42\u548c\u51fd\u6570\u4e3a\u4f8b\uff0c\u8bbe\u95ee\u9898 \\(f(n) = 1 + 2 + \\dots + n\\) \u3002

    • \u8fed\u4ee3\uff1a\u5728\u5faa\u73af\u4e2d\u6a21\u62df\u6c42\u548c\u8fc7\u7a0b\uff0c\u4ece \\(1\\) \u904d\u5386\u5230 \\(n\\) \uff0c\u6bcf\u8f6e\u6267\u884c\u6c42\u548c\u64cd\u4f5c\uff0c\u5373\u53ef\u6c42\u5f97 \\(f(n)\\) \u3002
    • \u9012\u5f52\uff1a\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u5b50\u95ee\u9898 \\(f(n) = n + f(n-1)\\) \uff0c\u4e0d\u65ad\uff08\u9012\u5f52\u5730\uff09\u5206\u89e3\u4e0b\u53bb\uff0c\u76f4\u81f3\u57fa\u672c\u60c5\u51b5 \\(f(1) = 1\\) \u65f6\u7ec8\u6b62\u3002
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#1","title":"1. \u00a0 \u8c03\u7528\u6808","text":"

    \u9012\u5f52\u51fd\u6570\u6bcf\u6b21\u8c03\u7528\u81ea\u8eab\u65f6\uff0c\u7cfb\u7edf\u90fd\u4f1a\u4e3a\u65b0\u5f00\u542f\u7684\u51fd\u6570\u5206\u914d\u5185\u5b58\uff0c\u4ee5\u5b58\u50a8\u5c40\u90e8\u53d8\u91cf\u3001\u8c03\u7528\u5730\u5740\u548c\u5176\u4ed6\u4fe1\u606f\u7b49\u3002\u8fd9\u5c06\u5bfc\u81f4\u4e24\u65b9\u9762\u7684\u7ed3\u679c\u3002

    • \u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u6570\u636e\u90fd\u5b58\u50a8\u5728\u79f0\u4e3a\u201c\u6808\u5e27\u7a7a\u95f4\u201d\u7684\u5185\u5b58\u533a\u57df\u4e2d\uff0c\u76f4\u81f3\u51fd\u6570\u8fd4\u56de\u540e\u624d\u4f1a\u88ab\u91ca\u653e\u3002\u56e0\u6b64\uff0c\u9012\u5f52\u901a\u5e38\u6bd4\u8fed\u4ee3\u66f4\u52a0\u8017\u8d39\u5185\u5b58\u7a7a\u95f4\u3002
    • \u9012\u5f52\u8c03\u7528\u51fd\u6570\u4f1a\u4ea7\u751f\u989d\u5916\u7684\u5f00\u9500\u3002\u56e0\u6b64\u9012\u5f52\u901a\u5e38\u6bd4\u5faa\u73af\u7684\u65f6\u95f4\u6548\u7387\u66f4\u4f4e\u3002

    \u5982\u56fe 2-4 \u6240\u793a\uff0c\u5728\u89e6\u53d1\u7ec8\u6b62\u6761\u4ef6\u524d\uff0c\u540c\u65f6\u5b58\u5728 \\(n\\) \u4e2a\u672a\u8fd4\u56de\u7684\u9012\u5f52\u51fd\u6570\uff0c\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \u3002

    \u56fe 2-4 \u00a0 \u9012\u5f52\u8c03\u7528\u6df1\u5ea6

    \u5728\u5b9e\u9645\u4e2d\uff0c\u7f16\u7a0b\u8bed\u8a00\u5141\u8bb8\u7684\u9012\u5f52\u6df1\u5ea6\u901a\u5e38\u662f\u6709\u9650\u7684\uff0c\u8fc7\u6df1\u7684\u9012\u5f52\u53ef\u80fd\u5bfc\u81f4\u6808\u6ea2\u51fa\u9519\u8bef\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#2","title":"2. \u00a0 \u5c3e\u9012\u5f52","text":"

    \u6709\u8da3\u7684\u662f\uff0c\u5982\u679c\u51fd\u6570\u5728\u8fd4\u56de\u524d\u7684\u6700\u540e\u4e00\u6b65\u624d\u8fdb\u884c\u9012\u5f52\u8c03\u7528\uff0c\u5219\u8be5\u51fd\u6570\u53ef\u4ee5\u88ab\u7f16\u8bd1\u5668\u6216\u89e3\u91ca\u5668\u4f18\u5316\uff0c\u4f7f\u5176\u5728\u7a7a\u95f4\u6548\u7387\u4e0a\u4e0e\u8fed\u4ee3\u76f8\u5f53\u3002\u8fd9\u79cd\u60c5\u51b5\u88ab\u79f0\u4e3a\u5c3e\u9012\u5f52\uff08tail recursion\uff09\u3002

    • \u666e\u901a\u9012\u5f52\uff1a\u5f53\u51fd\u6570\u8fd4\u56de\u5230\u4e0a\u4e00\u5c42\u7ea7\u7684\u51fd\u6570\u540e\uff0c\u9700\u8981\u7ee7\u7eed\u6267\u884c\u4ee3\u7801\uff0c\u56e0\u6b64\u7cfb\u7edf\u9700\u8981\u4fdd\u5b58\u4e0a\u4e00\u5c42\u8c03\u7528\u7684\u4e0a\u4e0b\u6587\u3002
    • \u5c3e\u9012\u5f52\uff1a\u9012\u5f52\u8c03\u7528\u662f\u51fd\u6570\u8fd4\u56de\u524d\u7684\u6700\u540e\u4e00\u4e2a\u64cd\u4f5c\uff0c\u8fd9\u610f\u5473\u7740\u51fd\u6570\u8fd4\u56de\u5230\u4e0a\u4e00\u5c42\u7ea7\u540e\uff0c\u65e0\u987b\u7ee7\u7eed\u6267\u884c\u5176\u4ed6\u64cd\u4f5c\uff0c\u56e0\u6b64\u7cfb\u7edf\u65e0\u987b\u4fdd\u5b58\u4e0a\u4e00\u5c42\u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u3002

    \u4ee5\u8ba1\u7b97 \\(1 + 2 + \\dots + n\\) \u4e3a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u7ed3\u679c\u53d8\u91cf res \u8bbe\u4e3a\u51fd\u6570\u53c2\u6570\uff0c\u4ece\u800c\u5b9e\u73b0\u5c3e\u9012\u5f52\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def tail_recur(n, res):\n    \"\"\"\u5c3e\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if n == 0:\n        return res\n    # \u5c3e\u9012\u5f52\u8c03\u7528\n    return tail_recur(n - 1, res + n)\n
    recursion.cpp
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.java
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.cs
    /* \u5c3e\u9012\u5f52 */\nint TailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return TailRecur(n - 1, res + n);\n}\n
    recursion.go
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n int, res int) int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n-1, res+n)\n}\n
    recursion.swift
    /* \u5c3e\u9012\u5f52 */\nfunc tailRecur(n: Int, res: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n: n - 1, res: res + n)\n}\n
    recursion.js
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n, res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.ts
    /* \u5c3e\u9012\u5f52 */\nfunction tailRecur(n: number, res: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n === 0) return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.dart
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (n == 0) return res;\n  // \u5c3e\u9012\u5f52\u8c03\u7528\n  return tailRecur(n - 1, res + n);\n}\n
    recursion.rs
    /* \u5c3e\u9012\u5f52 */\nfn tail_recur(n: i32, res: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if n == 0 {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    tail_recur(n - 1, res + n)\n}\n
    recursion.c
    /* \u5c3e\u9012\u5f52 */\nint tailRecur(int n, int res) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res;\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    recursion.kt
    /* \u5c3e\u9012\u5f52 */\ntailrec fun tailRecur(n: Int, res: Int): Int {\n    // \u6dfb\u52a0 tailrec \u5173\u952e\u8bcd\uff0c\u4ee5\u5f00\u542f\u5c3e\u9012\u5f52\u4f18\u5316\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0)\n        return res\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n)\n}\n
    recursion.rb
    ### \u5c3e\u9012\u5f52 ###\ndef tail_recur(n, res)\n  # \u7ec8\u6b62\u6761\u4ef6\n  return res if n == 0\n  # \u5c3e\u9012\u5f52\u8c03\u7528\n  tail_recur(n - 1, res + n)\nend\n
    recursion.zig
    // \u5c3e\u9012\u5f52\u51fd\u6570\nfn tailRecur(n: i32, res: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (n == 0) {\n        return res;\n    }\n    // \u5c3e\u9012\u5f52\u8c03\u7528\n    return tailRecur(n - 1, res + n);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5c3e\u9012\u5f52\u7684\u6267\u884c\u8fc7\u7a0b\u5982\u56fe 2-5 \u6240\u793a\u3002\u5bf9\u6bd4\u666e\u901a\u9012\u5f52\u548c\u5c3e\u9012\u5f52\uff0c\u4e24\u8005\u7684\u6c42\u548c\u64cd\u4f5c\u7684\u6267\u884c\u70b9\u662f\u4e0d\u540c\u7684\u3002

    • \u666e\u901a\u9012\u5f52\uff1a\u6c42\u548c\u64cd\u4f5c\u662f\u5728\u201c\u5f52\u201d\u7684\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\uff0c\u6bcf\u5c42\u8fd4\u56de\u540e\u90fd\u8981\u518d\u6267\u884c\u4e00\u6b21\u6c42\u548c\u64cd\u4f5c\u3002
    • \u5c3e\u9012\u5f52\uff1a\u6c42\u548c\u64cd\u4f5c\u662f\u5728\u201c\u9012\u201d\u7684\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\uff0c\u201c\u5f52\u201d\u7684\u8fc7\u7a0b\u53ea\u9700\u5c42\u5c42\u8fd4\u56de\u3002

    \u56fe 2-5 \u00a0 \u5c3e\u9012\u5f52\u8fc7\u7a0b

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u8bb8\u591a\u7f16\u8bd1\u5668\u6216\u89e3\u91ca\u5668\u5e76\u4e0d\u652f\u6301\u5c3e\u9012\u5f52\u4f18\u5316\u3002\u4f8b\u5982\uff0cPython \u9ed8\u8ba4\u4e0d\u652f\u6301\u5c3e\u9012\u5f52\u4f18\u5316\uff0c\u56e0\u6b64\u5373\u4f7f\u51fd\u6570\u662f\u5c3e\u9012\u5f52\u5f62\u5f0f\uff0c\u4ecd\u7136\u53ef\u80fd\u4f1a\u9047\u5230\u6808\u6ea2\u51fa\u95ee\u9898\u3002

    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#3_1","title":"3. \u00a0 \u9012\u5f52\u6811","text":"

    \u5f53\u5904\u7406\u4e0e\u201c\u5206\u6cbb\u201d\u76f8\u5173\u7684\u7b97\u6cd5\u95ee\u9898\u65f6\uff0c\u9012\u5f52\u5f80\u5f80\u6bd4\u8fed\u4ee3\u7684\u601d\u8def\u66f4\u52a0\u76f4\u89c2\u3001\u4ee3\u7801\u66f4\u52a0\u6613\u8bfb\u3002\u4ee5\u201c\u6590\u6ce2\u90a3\u5951\u6570\u5217\u201d\u4e3a\u4f8b\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6590\u6ce2\u90a3\u5951\u6570\u5217 \\(0, 1, 1, 2, 3, 5, 8, 13, \\dots\\) \uff0c\u6c42\u8be5\u6570\u5217\u7684\u7b2c \\(n\\) \u4e2a\u6570\u5b57\u3002

    \u8bbe\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u7b2c \\(n\\) \u4e2a\u6570\u5b57\u4e3a \\(f(n)\\) \uff0c\u6613\u5f97\u4e24\u4e2a\u7ed3\u8bba\u3002

    • \u6570\u5217\u7684\u524d\u4e24\u4e2a\u6570\u5b57\u4e3a \\(f(1) = 0\\) \u548c \\(f(2) = 1\\) \u3002
    • \u6570\u5217\u4e2d\u7684\u6bcf\u4e2a\u6570\u5b57\u662f\u524d\u4e24\u4e2a\u6570\u5b57\u7684\u548c\uff0c\u5373 \\(f(n) = f(n - 1) + f(n - 2)\\) \u3002

    \u6309\u7167\u9012\u63a8\u5173\u7cfb\u8fdb\u884c\u9012\u5f52\u8c03\u7528\uff0c\u5c06\u524d\u4e24\u4e2a\u6570\u5b57\u4f5c\u4e3a\u7ec8\u6b62\u6761\u4ef6\uff0c\u4fbf\u53ef\u5199\u51fa\u9012\u5f52\u4ee3\u7801\u3002\u8c03\u7528 fib(n) \u5373\u53ef\u5f97\u5230\u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u7b2c \\(n\\) \u4e2a\u6570\u5b57\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def fib(n: int) -> int:\n    \"\"\"\u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 or n == 2:\n        return n - 1\n    # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res = fib(n - 1) + fib(n - 2)\n    # \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n
    recursion.cpp
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.java
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.cs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint Fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = Fib(n - 1) + Fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.go
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n int) int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    res := fib(n-1) + fib(n-2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.swift
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunc fib(n: Int) -> Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n: n - 1) + fib(n: n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.js
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.ts
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfunction fib(n: number): number {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n === 1 || n === 2) return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    const res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.dart
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n  // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  if (n == 1 || n == 2) return n - 1;\n  // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  int res = fib(n - 1) + fib(n - 2);\n  // \u8fd4\u56de\u7ed3\u679c f(n)\n  return res;\n}\n
    recursion.rs
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfn fib(n: i32) -> i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if n == 1 || n == 2 {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    let res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c\n    res\n}\n
    recursion.c
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nint fib(int n) {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1;\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    int res = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    recursion.kt
    /* \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 */\nfun fib(n: Int): Int {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 || n == 2)\n        return n - 1\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    val res = fib(n - 1) + fib(n - 2)\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res\n}\n
    recursion.rb
    ### \u6590\u6ce2\u90a3\u5951\u6570\u5217\uff1a\u9012\u5f52 ###\ndef fib(n)\n  # \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n  return n - 1 if n == 1 || n == 2\n  # \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n  res = fib(n - 1) + fib(n - 2)\n  # \u8fd4\u56de\u7ed3\u679c f(n)\n  res\nend\n
    recursion.zig
    // \u6590\u6ce2\u90a3\u5951\u6570\u5217\nfn fib(n: i32) i32 {\n    // \u7ec8\u6b62\u6761\u4ef6 f(1) = 0, f(2) = 1\n    if (n == 1 or n == 2) {\n        return n - 1;\n    }\n    // \u9012\u5f52\u8c03\u7528 f(n) = f(n-1) + f(n-2)\n    var res: i32 = fib(n - 1) + fib(n - 2);\n    // \u8fd4\u56de\u7ed3\u679c f(n)\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u4ee5\u4e0a\u4ee3\u7801\uff0c\u6211\u4eec\u5728\u51fd\u6570\u5185\u9012\u5f52\u8c03\u7528\u4e86\u4e24\u4e2a\u51fd\u6570\uff0c\u8fd9\u610f\u5473\u7740\u4ece\u4e00\u4e2a\u8c03\u7528\u4ea7\u751f\u4e86\u4e24\u4e2a\u8c03\u7528\u5206\u652f\u3002\u5982\u56fe 2-6 \u6240\u793a\uff0c\u8fd9\u6837\u4e0d\u65ad\u9012\u5f52\u8c03\u7528\u4e0b\u53bb\uff0c\u6700\u7ec8\u5c06\u4ea7\u751f\u4e00\u68f5\u5c42\u6570\u4e3a \\(n\\) \u7684\u9012\u5f52\u6811\uff08recursion tree\uff09\u3002

    \u56fe 2-6 \u00a0 \u6590\u6ce2\u90a3\u5951\u6570\u5217\u7684\u9012\u5f52\u6811

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u9012\u5f52\u4f53\u73b0\u4e86\u201c\u5c06\u95ee\u9898\u5206\u89e3\u4e3a\u66f4\u5c0f\u5b50\u95ee\u9898\u201d\u7684\u601d\u7ef4\u8303\u5f0f\uff0c\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u81f3\u5173\u91cd\u8981\u3002

    • \u4ece\u7b97\u6cd5\u89d2\u5ea6\u770b\uff0c\u641c\u7d22\u3001\u6392\u5e8f\u3001\u56de\u6eaf\u3001\u5206\u6cbb\u3001\u52a8\u6001\u89c4\u5212\u7b49\u8bb8\u591a\u91cd\u8981\u7b97\u6cd5\u7b56\u7565\u76f4\u63a5\u6216\u95f4\u63a5\u5730\u5e94\u7528\u4e86\u8fd9\u79cd\u601d\u7ef4\u65b9\u5f0f\u3002
    • \u4ece\u6570\u636e\u7ed3\u6784\u89d2\u5ea6\u770b\uff0c\u9012\u5f52\u5929\u7136\u9002\u5408\u5904\u7406\u94fe\u8868\u3001\u6811\u548c\u56fe\u7684\u76f8\u5173\u95ee\u9898\uff0c\u56e0\u4e3a\u5b83\u4eec\u975e\u5e38\u9002\u5408\u7528\u5206\u6cbb\u601d\u60f3\u8fdb\u884c\u5206\u6790\u3002
    "},{"location":"chapter_computational_complexity/iteration_and_recursion/#223","title":"2.2.3 \u00a0 \u4e24\u8005\u5bf9\u6bd4","text":"

    \u603b\u7ed3\u4ee5\u4e0a\u5185\u5bb9\uff0c\u5982\u8868 2-1 \u6240\u793a\uff0c\u8fed\u4ee3\u548c\u9012\u5f52\u5728\u5b9e\u73b0\u3001\u6027\u80fd\u548c\u9002\u7528\u6027\u4e0a\u6709\u6240\u4e0d\u540c\u3002

    \u8868 2-1 \u00a0 \u8fed\u4ee3\u4e0e\u9012\u5f52\u7279\u70b9\u5bf9\u6bd4

    \u8fed\u4ee3 \u9012\u5f52 \u5b9e\u73b0\u65b9\u5f0f \u5faa\u73af\u7ed3\u6784 \u51fd\u6570\u8c03\u7528\u81ea\u8eab \u65f6\u95f4\u6548\u7387 \u6548\u7387\u901a\u5e38\u8f83\u9ad8\uff0c\u65e0\u51fd\u6570\u8c03\u7528\u5f00\u9500 \u6bcf\u6b21\u51fd\u6570\u8c03\u7528\u90fd\u4f1a\u4ea7\u751f\u5f00\u9500 \u5185\u5b58\u4f7f\u7528 \u901a\u5e38\u4f7f\u7528\u56fa\u5b9a\u5927\u5c0f\u7684\u5185\u5b58\u7a7a\u95f4 \u7d2f\u79ef\u51fd\u6570\u8c03\u7528\u53ef\u80fd\u4f7f\u7528\u5927\u91cf\u7684\u6808\u5e27\u7a7a\u95f4 \u9002\u7528\u95ee\u9898 \u9002\u7528\u4e8e\u7b80\u5355\u5faa\u73af\u4efb\u52a1\uff0c\u4ee3\u7801\u76f4\u89c2\u3001\u53ef\u8bfb\u6027\u597d \u9002\u7528\u4e8e\u5b50\u95ee\u9898\u5206\u89e3\uff0c\u5982\u6811\u3001\u56fe\u3001\u5206\u6cbb\u3001\u56de\u6eaf\u7b49\uff0c\u4ee3\u7801\u7ed3\u6784\u7b80\u6d01\u3001\u6e05\u6670

    Tip

    \u5982\u679c\u611f\u89c9\u4ee5\u4e0b\u5185\u5bb9\u7406\u89e3\u56f0\u96be\uff0c\u53ef\u4ee5\u5728\u8bfb\u5b8c\u201c\u6808\u201d\u7ae0\u8282\u540e\u518d\u6765\u590d\u4e60\u3002

    \u90a3\u4e48\uff0c\u8fed\u4ee3\u548c\u9012\u5f52\u5177\u6709\u4ec0\u4e48\u5185\u5728\u8054\u7cfb\u5462\uff1f\u4ee5\u4e0a\u8ff0\u9012\u5f52\u51fd\u6570\u4e3a\u4f8b\uff0c\u6c42\u548c\u64cd\u4f5c\u5728\u9012\u5f52\u7684\u201c\u5f52\u201d\u9636\u6bb5\u8fdb\u884c\u3002\u8fd9\u610f\u5473\u7740\u6700\u521d\u88ab\u8c03\u7528\u7684\u51fd\u6570\u5b9e\u9645\u4e0a\u662f\u6700\u540e\u5b8c\u6210\u5176\u6c42\u548c\u64cd\u4f5c\u7684\uff0c\u8fd9\u79cd\u5de5\u4f5c\u673a\u5236\u4e0e\u6808\u7684\u201c\u5148\u5165\u540e\u51fa\u201d\u539f\u5219\u5f02\u66f2\u540c\u5de5\u3002

    \u4e8b\u5b9e\u4e0a\uff0c\u201c\u8c03\u7528\u6808\u201d\u548c\u201c\u6808\u5e27\u7a7a\u95f4\u201d\u8fd9\u7c7b\u9012\u5f52\u672f\u8bed\u5df2\u7ecf\u6697\u793a\u4e86\u9012\u5f52\u4e0e\u6808\u4e4b\u95f4\u7684\u5bc6\u5207\u5173\u7cfb\u3002

    1. \u9012\uff1a\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u7cfb\u7edf\u4f1a\u5728\u201c\u8c03\u7528\u6808\u201d\u4e0a\u4e3a\u8be5\u51fd\u6570\u5206\u914d\u65b0\u7684\u6808\u5e27\uff0c\u7528\u4e8e\u5b58\u50a8\u51fd\u6570\u7684\u5c40\u90e8\u53d8\u91cf\u3001\u53c2\u6570\u3001\u8fd4\u56de\u5730\u5740\u7b49\u6570\u636e\u3002
    2. \u5f52\uff1a\u5f53\u51fd\u6570\u5b8c\u6210\u6267\u884c\u5e76\u8fd4\u56de\u65f6\uff0c\u5bf9\u5e94\u7684\u6808\u5e27\u4f1a\u88ab\u4ece\u201c\u8c03\u7528\u6808\u201d\u4e0a\u79fb\u9664\uff0c\u6062\u590d\u4e4b\u524d\u51fd\u6570\u7684\u6267\u884c\u73af\u5883\u3002

    \u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u8c03\u7528\u6808\u7684\u884c\u4e3a\uff0c\u4ece\u800c\u5c06\u9012\u5f52\u8f6c\u5316\u4e3a\u8fed\u4ee3\u5f62\u5f0f\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig recursion.py
    def for_loop_recur(n: int) -> int:\n    \"\"\"\u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\"\"\"\n    # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack = []\n    res = 0\n    # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in range(n, 0, -1):\n        # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while stack:\n        # \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    # res = 1+2+3+...+n\n    return res\n
    recursion.cpp
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack<int> stack;\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.empty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.top();\n        stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.java
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<Integer> stack = new Stack<>();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (!stack.isEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.cs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint ForLoopRecur(int n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    Stack<int> stack = new();\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.Push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.Count > 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.go
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n int) int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    stack := list.New()\n    res := 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i := n; i > 0; i-- {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.PushBack(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    for stack.Len() != 0 {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.Back().Value.(int)\n        stack.Remove(stack.Back())\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.swift
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunc forLoopRecur(n: Int) -> Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [Int] = []\n    var res = 0\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1 ... n).reversed() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.append(i)\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.isEmpty {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.removeLast()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.js
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n) {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    const stack = [];\n    let res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.ts
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfunction forLoopRecur(n: number): number {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808 \n    const stack: number[] = [];\n    let res: number = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (let i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (stack.length) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop();\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.dart
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n  // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  List<int> stack = [];\n  int res = 0;\n  // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for (int i = n; i > 0; i--) {\n    // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack.add(i);\n  }\n  // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while (!stack.isEmpty) {\n    // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n    res += stack.removeLast();\n  }\n  // res = 1+2+3+...+n\n  return res;\n}\n
    recursion.rs
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfn for_loop_recur(n: i32) -> i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    let mut stack = Vec::new();\n    let mut res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for i in (1..=n).rev() {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i);\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while !stack.is_empty() {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop().unwrap();\n    }\n    // res = 1+2+3+...+n\n    res\n}\n
    recursion.c
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nint forLoopRecur(int n) {\n    int stack[1000]; // \u501f\u52a9\u4e00\u4e2a\u5927\u6570\u7ec4\u6765\u6a21\u62df\u6808\n    int top = -1;    // \u6808\u9876\u7d22\u5f15\n    int res = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    for (int i = n; i > 0; i--) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack[1 + top++] = i;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    while (top >= 0) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack[top--];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    recursion.kt
    /* \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 */\nfun forLoopRecur(n: Int): Int {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    val stack = Stack<Int>()\n    var res = 0\n    // \u9012: \u9012\u5f52\u8c03\u7528\n    for (i in n downTo 0) {\n        // \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n        stack.push(i)\n    }\n    // \u5f52: \u8fd4\u56de\u7ed3\u679c\n    while (stack.isNotEmpty()) {\n        // \u901a\u8fc7\u201c\u51fa\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u5f52\u201d\n        res += stack.pop()\n    }\n    // res = 1+2+3+...+n\n    return res\n}\n
    recursion.rb
    ### \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52 ###\ndef for_loop_recur(n)\n  # \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n  stack = []\n  res = 0\n\n  # \u9012\uff1a\u9012\u5f52\u8c03\u7528\n  for i in n.downto(0)\n    # \u901a\u8fc7\u201c\u5165\u6808\u64cd\u4f5c\u201d\u6a21\u62df\u201c\u9012\u201d\n    stack << i\n  end\n  # \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n  while !stack.empty?\n    res += stack.pop\n  end\n\n  # res = 1+2+3+...+n\n  res\nend\n
    recursion.zig
    // \u4f7f\u7528\u8fed\u4ee3\u6a21\u62df\u9012\u5f52\nfn forLoopRecur(comptime n: i32) i32 {\n    // \u4f7f\u7528\u4e00\u4e2a\u663e\u5f0f\u7684\u6808\u6765\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\n    var stack: [n]i32 = undefined;\n    var res: i32 = 0;\n    // \u9012\uff1a\u9012\u5f52\u8c03\u7528\n    var i: usize = n;\n    while (i > 0) {\n        stack[i - 1] = @intCast(i);\n        i -= 1;\n    }\n    // \u5f52\uff1a\u8fd4\u56de\u7ed3\u679c\n    var index: usize = n;\n    while (index > 0) {\n        index -= 1;\n        res += stack[index];\n    }\n    // res = 1+2+3+...+n\n    return res;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u4ee5\u4e0a\u4ee3\u7801\uff0c\u5f53\u9012\u5f52\u8f6c\u5316\u4e3a\u8fed\u4ee3\u540e\uff0c\u4ee3\u7801\u53d8\u5f97\u66f4\u52a0\u590d\u6742\u4e86\u3002\u5c3d\u7ba1\u8fed\u4ee3\u548c\u9012\u5f52\u5728\u5f88\u591a\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4e92\u76f8\u8f6c\u5316\uff0c\u4f46\u4e0d\u4e00\u5b9a\u503c\u5f97\u8fd9\u6837\u505a\uff0c\u6709\u4ee5\u4e0b\u4e24\u70b9\u539f\u56e0\u3002

    • \u8f6c\u5316\u540e\u7684\u4ee3\u7801\u53ef\u80fd\u66f4\u52a0\u96be\u4ee5\u7406\u89e3\uff0c\u53ef\u8bfb\u6027\u66f4\u5dee\u3002
    • \u5bf9\u4e8e\u67d0\u4e9b\u590d\u6742\u95ee\u9898\uff0c\u6a21\u62df\u7cfb\u7edf\u8c03\u7528\u6808\u7684\u884c\u4e3a\u53ef\u80fd\u975e\u5e38\u56f0\u96be\u3002

    \u603b\u4e4b\uff0c\u9009\u62e9\u8fed\u4ee3\u8fd8\u662f\u9012\u5f52\u53d6\u51b3\u4e8e\u7279\u5b9a\u95ee\u9898\u7684\u6027\u8d28\u3002\u5728\u7f16\u7a0b\u5b9e\u8df5\u4e2d\uff0c\u6743\u8861\u4e24\u8005\u7684\u4f18\u52a3\u5e76\u6839\u636e\u60c5\u5883\u9009\u62e9\u5408\u9002\u7684\u65b9\u6cd5\u81f3\u5173\u91cd\u8981\u3002

    "},{"location":"chapter_computational_complexity/performance_evaluation/","title":"2.1 \u00a0 \u7b97\u6cd5\u6548\u7387\u8bc4\u4f30","text":"

    \u5728\u7b97\u6cd5\u8bbe\u8ba1\u4e2d\uff0c\u6211\u4eec\u5148\u540e\u8ffd\u6c42\u4ee5\u4e0b\u4e24\u4e2a\u5c42\u9762\u7684\u76ee\u6807\u3002

    1. \u627e\u5230\u95ee\u9898\u89e3\u6cd5\uff1a\u7b97\u6cd5\u9700\u8981\u5728\u89c4\u5b9a\u7684\u8f93\u5165\u8303\u56f4\u5185\u53ef\u9760\u5730\u6c42\u5f97\u95ee\u9898\u7684\u6b63\u786e\u89e3\u3002
    2. \u5bfb\u6c42\u6700\u4f18\u89e3\u6cd5\uff1a\u540c\u4e00\u4e2a\u95ee\u9898\u53ef\u80fd\u5b58\u5728\u591a\u79cd\u89e3\u6cd5\uff0c\u6211\u4eec\u5e0c\u671b\u627e\u5230\u5c3d\u53ef\u80fd\u9ad8\u6548\u7684\u7b97\u6cd5\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5728\u80fd\u591f\u89e3\u51b3\u95ee\u9898\u7684\u524d\u63d0\u4e0b\uff0c\u7b97\u6cd5\u6548\u7387\u5df2\u6210\u4e3a\u8861\u91cf\u7b97\u6cd5\u4f18\u52a3\u7684\u4e3b\u8981\u8bc4\u4ef7\u6307\u6807\uff0c\u5b83\u5305\u62ec\u4ee5\u4e0b\u4e24\u4e2a\u7ef4\u5ea6\u3002

    • \u65f6\u95f4\u6548\u7387\uff1a\u7b97\u6cd5\u8fd0\u884c\u901f\u5ea6\u7684\u5feb\u6162\u3002
    • \u7a7a\u95f4\u6548\u7387\uff1a\u7b97\u6cd5\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u7684\u5927\u5c0f\u3002

    \u7b80\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u7684\u76ee\u6807\u662f\u8bbe\u8ba1\u201c\u65e2\u5feb\u53c8\u7701\u201d\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u3002\u800c\u6709\u6548\u5730\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u81f3\u5173\u91cd\u8981\uff0c\u56e0\u4e3a\u53ea\u6709\u8fd9\u6837\uff0c\u6211\u4eec\u624d\u80fd\u5c06\u5404\u79cd\u7b97\u6cd5\u8fdb\u884c\u5bf9\u6bd4\uff0c\u8fdb\u800c\u6307\u5bfc\u7b97\u6cd5\u8bbe\u8ba1\u4e0e\u4f18\u5316\u8fc7\u7a0b\u3002

    \u6548\u7387\u8bc4\u4f30\u65b9\u6cd5\u4e3b\u8981\u5206\u4e3a\u4e24\u79cd\uff1a\u5b9e\u9645\u6d4b\u8bd5\u3001\u7406\u8bba\u4f30\u7b97\u3002

    "},{"location":"chapter_computational_complexity/performance_evaluation/#211","title":"2.1.1 \u00a0 \u5b9e\u9645\u6d4b\u8bd5","text":"

    \u5047\u8bbe\u6211\u4eec\u73b0\u5728\u6709\u7b97\u6cd5 A \u548c\u7b97\u6cd5 B \uff0c\u5b83\u4eec\u90fd\u80fd\u89e3\u51b3\u540c\u4e00\u95ee\u9898\uff0c\u73b0\u5728\u9700\u8981\u5bf9\u6bd4\u8fd9\u4e24\u4e2a\u7b97\u6cd5\u7684\u6548\u7387\u3002\u6700\u76f4\u63a5\u7684\u65b9\u6cd5\u662f\u627e\u4e00\u53f0\u8ba1\u7b97\u673a\uff0c\u8fd0\u884c\u8fd9\u4e24\u4e2a\u7b97\u6cd5\uff0c\u5e76\u76d1\u63a7\u8bb0\u5f55\u5b83\u4eec\u7684\u8fd0\u884c\u65f6\u95f4\u548c\u5185\u5b58\u5360\u7528\u60c5\u51b5\u3002\u8fd9\u79cd\u8bc4\u4f30\u65b9\u5f0f\u80fd\u591f\u53cd\u6620\u771f\u5b9e\u60c5\u51b5\uff0c\u4f46\u4e5f\u5b58\u5728\u8f83\u5927\u7684\u5c40\u9650\u6027\u3002

    \u4e00\u65b9\u9762\uff0c\u96be\u4ee5\u6392\u9664\u6d4b\u8bd5\u73af\u5883\u7684\u5e72\u6270\u56e0\u7d20\u3002\u786c\u4ef6\u914d\u7f6e\u4f1a\u5f71\u54cd\u7b97\u6cd5\u7684\u6027\u80fd\u3002\u6bd4\u5982\u5728\u67d0\u53f0\u8ba1\u7b97\u673a\u4e2d\uff0c\u7b97\u6cd5 A \u7684\u8fd0\u884c\u65f6\u95f4\u6bd4\u7b97\u6cd5 B \u77ed\uff1b\u4f46\u5728\u53e6\u4e00\u53f0\u914d\u7f6e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u4e2d\uff0c\u53ef\u80fd\u5f97\u5230\u76f8\u53cd\u7684\u6d4b\u8bd5\u7ed3\u679c\u3002\u8fd9\u610f\u5473\u7740\u6211\u4eec\u9700\u8981\u5728\u5404\u79cd\u673a\u5668\u4e0a\u8fdb\u884c\u6d4b\u8bd5\uff0c\u7edf\u8ba1\u5e73\u5747\u6548\u7387\uff0c\u800c\u8fd9\u662f\u4e0d\u73b0\u5b9e\u7684\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5c55\u5f00\u5b8c\u6574\u6d4b\u8bd5\u975e\u5e38\u8017\u8d39\u8d44\u6e90\u3002\u968f\u7740\u8f93\u5165\u6570\u636e\u91cf\u7684\u53d8\u5316\uff0c\u7b97\u6cd5\u4f1a\u8868\u73b0\u51fa\u4e0d\u540c\u7684\u6548\u7387\u3002\u4f8b\u5982\uff0c\u5728\u8f93\u5165\u6570\u636e\u91cf\u8f83\u5c0f\u65f6\uff0c\u7b97\u6cd5 A \u7684\u8fd0\u884c\u65f6\u95f4\u6bd4\u7b97\u6cd5 B \u77ed\uff1b\u800c\u5728\u8f93\u5165\u6570\u636e\u91cf\u8f83\u5927\u65f6\uff0c\u6d4b\u8bd5\u7ed3\u679c\u53ef\u80fd\u6070\u6070\u76f8\u53cd\u3002\u56e0\u6b64\uff0c\u4e3a\u4e86\u5f97\u5230\u6709\u8bf4\u670d\u529b\u7684\u7ed3\u8bba\uff0c\u6211\u4eec\u9700\u8981\u6d4b\u8bd5\u5404\u79cd\u89c4\u6a21\u7684\u8f93\u5165\u6570\u636e\uff0c\u800c\u8fd9\u9700\u8981\u8017\u8d39\u5927\u91cf\u7684\u8ba1\u7b97\u8d44\u6e90\u3002

    "},{"location":"chapter_computational_complexity/performance_evaluation/#212","title":"2.1.2 \u00a0 \u7406\u8bba\u4f30\u7b97","text":"

    \u7531\u4e8e\u5b9e\u9645\u6d4b\u8bd5\u5177\u6709\u8f83\u5927\u7684\u5c40\u9650\u6027\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u8003\u8651\u4ec5\u901a\u8fc7\u4e00\u4e9b\u8ba1\u7b97\u6765\u8bc4\u4f30\u7b97\u6cd5\u7684\u6548\u7387\u3002\u8fd9\u79cd\u4f30\u7b97\u65b9\u6cd5\u88ab\u79f0\u4e3a\u6e10\u8fd1\u590d\u6742\u5ea6\u5206\u6790\uff08asymptotic complexity analysis\uff09\uff0c\u7b80\u79f0\u590d\u6742\u5ea6\u5206\u6790\u3002

    \u590d\u6742\u5ea6\u5206\u6790\u80fd\u591f\u4f53\u73b0\u7b97\u6cd5\u8fd0\u884c\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u8d44\u6e90\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u5b83\u63cf\u8ff0\u4e86\u968f\u7740\u8f93\u5165\u6570\u636e\u5927\u5c0f\u7684\u589e\u52a0\uff0c\u7b97\u6cd5\u6267\u884c\u6240\u9700\u65f6\u95f4\u548c\u7a7a\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u3002\u8fd9\u4e2a\u5b9a\u4e49\u6709\u4e9b\u62d7\u53e3\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5176\u5206\u4e3a\u4e09\u4e2a\u91cd\u70b9\u6765\u7406\u89e3\u3002

    • \u201c\u65f6\u95f4\u548c\u7a7a\u95f4\u8d44\u6e90\u201d\u5206\u522b\u5bf9\u5e94\u65f6\u95f4\u590d\u6742\u5ea6\uff08time complexity\uff09\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\uff08space complexity\uff09\u3002
    • \u201c\u968f\u7740\u8f93\u5165\u6570\u636e\u5927\u5c0f\u7684\u589e\u52a0\u201d\u610f\u5473\u7740\u590d\u6742\u5ea6\u53cd\u6620\u4e86\u7b97\u6cd5\u8fd0\u884c\u6548\u7387\u4e0e\u8f93\u5165\u6570\u636e\u4f53\u91cf\u4e4b\u95f4\u7684\u5173\u7cfb\u3002
    • \u201c\u65f6\u95f4\u548c\u7a7a\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u201d\u8868\u793a\u590d\u6742\u5ea6\u5206\u6790\u5173\u6ce8\u7684\u4e0d\u662f\u8fd0\u884c\u65f6\u95f4\u6216\u5360\u7528\u7a7a\u95f4\u7684\u5177\u4f53\u503c\uff0c\u800c\u662f\u65f6\u95f4\u6216\u7a7a\u95f4\u589e\u957f\u7684\u201c\u5feb\u6162\u201d\u3002

    \u590d\u6742\u5ea6\u5206\u6790\u514b\u670d\u4e86\u5b9e\u9645\u6d4b\u8bd5\u65b9\u6cd5\u7684\u5f0a\u7aef\uff0c\u4f53\u73b0\u5728\u4ee5\u4e0b\u4e24\u4e2a\u65b9\u9762\u3002

    • \u5b83\u72ec\u7acb\u4e8e\u6d4b\u8bd5\u73af\u5883\uff0c\u5206\u6790\u7ed3\u679c\u9002\u7528\u4e8e\u6240\u6709\u8fd0\u884c\u5e73\u53f0\u3002
    • \u5b83\u53ef\u4ee5\u4f53\u73b0\u4e0d\u540c\u6570\u636e\u91cf\u4e0b\u7684\u7b97\u6cd5\u6548\u7387\uff0c\u5c24\u5176\u662f\u5728\u5927\u6570\u636e\u91cf\u4e0b\u7684\u7b97\u6cd5\u6027\u80fd\u3002

    Tip

    \u5982\u679c\u4f60\u4ecd\u5bf9\u590d\u6742\u5ea6\u7684\u6982\u5ff5\u611f\u5230\u56f0\u60d1\uff0c\u65e0\u987b\u62c5\u5fc3\uff0c\u6211\u4eec\u4f1a\u5728\u540e\u7eed\u7ae0\u8282\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u3002

    \u590d\u6742\u5ea6\u5206\u6790\u4e3a\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u628a\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u7684\u201c\u6807\u5c3a\u201d\uff0c\u4f7f\u6211\u4eec\u53ef\u4ee5\u8861\u91cf\u6267\u884c\u67d0\u4e2a\u7b97\u6cd5\u6240\u9700\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u8d44\u6e90\uff0c\u5bf9\u6bd4\u4e0d\u540c\u7b97\u6cd5\u4e4b\u95f4\u7684\u6548\u7387\u3002

    \u590d\u6742\u5ea6\u662f\u4e2a\u6570\u5b66\u6982\u5ff5\uff0c\u5bf9\u4e8e\u521d\u5b66\u8005\u53ef\u80fd\u6bd4\u8f83\u62bd\u8c61\uff0c\u5b66\u4e60\u96be\u5ea6\u76f8\u5bf9\u8f83\u9ad8\u3002\u4ece\u8fd9\u4e2a\u89d2\u5ea6\u770b\uff0c\u590d\u6742\u5ea6\u5206\u6790\u53ef\u80fd\u4e0d\u592a\u9002\u5408\u4f5c\u4e3a\u6700\u5148\u4ecb\u7ecd\u7684\u5185\u5bb9\u3002\u7136\u800c\uff0c\u5f53\u6211\u4eec\u8ba8\u8bba\u67d0\u4e2a\u6570\u636e\u7ed3\u6784\u6216\u7b97\u6cd5\u7684\u7279\u70b9\u65f6\uff0c\u96be\u4ee5\u907f\u514d\u8981\u5206\u6790\u5176\u8fd0\u884c\u901f\u5ea6\u548c\u7a7a\u95f4\u4f7f\u7528\u60c5\u51b5\u3002

    \u7efc\u4e0a\u6240\u8ff0\uff0c\u5efa\u8bae\u4f60\u5728\u6df1\u5165\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u4e4b\u524d\uff0c\u5148\u5bf9\u590d\u6742\u5ea6\u5206\u6790\u5efa\u7acb\u521d\u6b65\u7684\u4e86\u89e3\uff0c\u4ee5\u4fbf\u80fd\u591f\u5b8c\u6210\u7b80\u5355\u7b97\u6cd5\u7684\u590d\u6742\u5ea6\u5206\u6790\u3002

    "},{"location":"chapter_computational_complexity/space_complexity/","title":"2.4 \u00a0 \u7a7a\u95f4\u590d\u6742\u5ea6","text":"

    \u7a7a\u95f4\u590d\u6742\u5ea6\uff08space complexity\uff09\u7528\u4e8e\u8861\u91cf\u7b97\u6cd5\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u968f\u7740\u6570\u636e\u91cf\u53d8\u5927\u65f6\u7684\u589e\u957f\u8d8b\u52bf\u3002\u8fd9\u4e2a\u6982\u5ff5\u4e0e\u65f6\u95f4\u590d\u6742\u5ea6\u975e\u5e38\u7c7b\u4f3c\uff0c\u53ea\u9700\u5c06\u201c\u8fd0\u884c\u65f6\u95f4\u201d\u66ff\u6362\u4e3a\u201c\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u201d\u3002

    "},{"location":"chapter_computational_complexity/space_complexity/#241","title":"2.4.1 \u00a0 \u7b97\u6cd5\u76f8\u5173\u7a7a\u95f4","text":"

    \u7b97\u6cd5\u5728\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f7f\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u4e3b\u8981\u5305\u62ec\u4ee5\u4e0b\u51e0\u79cd\u3002

    • \u8f93\u5165\u7a7a\u95f4\uff1a\u7528\u4e8e\u5b58\u50a8\u7b97\u6cd5\u7684\u8f93\u5165\u6570\u636e\u3002
    • \u6682\u5b58\u7a7a\u95f4\uff1a\u7528\u4e8e\u5b58\u50a8\u7b97\u6cd5\u5728\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u53d8\u91cf\u3001\u5bf9\u8c61\u3001\u51fd\u6570\u4e0a\u4e0b\u6587\u7b49\u6570\u636e\u3002
    • \u8f93\u51fa\u7a7a\u95f4\uff1a\u7528\u4e8e\u5b58\u50a8\u7b97\u6cd5\u7684\u8f93\u51fa\u6570\u636e\u3002

    \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u7edf\u8ba1\u8303\u56f4\u662f\u201c\u6682\u5b58\u7a7a\u95f4\u201d\u52a0\u4e0a\u201c\u8f93\u51fa\u7a7a\u95f4\u201d\u3002

    \u6682\u5b58\u7a7a\u95f4\u53ef\u4ee5\u8fdb\u4e00\u6b65\u5212\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\u3002

    • \u6682\u5b58\u6570\u636e\uff1a\u7528\u4e8e\u4fdd\u5b58\u7b97\u6cd5\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u5404\u79cd\u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u7b49\u3002
    • \u6808\u5e27\u7a7a\u95f4\uff1a\u7528\u4e8e\u4fdd\u5b58\u8c03\u7528\u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u6570\u636e\u3002\u7cfb\u7edf\u5728\u6bcf\u6b21\u8c03\u7528\u51fd\u6570\u65f6\u90fd\u4f1a\u5728\u6808\u9876\u90e8\u521b\u5efa\u4e00\u4e2a\u6808\u5e27\uff0c\u51fd\u6570\u8fd4\u56de\u540e\uff0c\u6808\u5e27\u7a7a\u95f4\u4f1a\u88ab\u91ca\u653e\u3002
    • \u6307\u4ee4\u7a7a\u95f4\uff1a\u7528\u4e8e\u4fdd\u5b58\u7f16\u8bd1\u540e\u7684\u7a0b\u5e8f\u6307\u4ee4\uff0c\u5728\u5b9e\u9645\u7edf\u8ba1\u4e2d\u901a\u5e38\u5ffd\u7565\u4e0d\u8ba1\u3002

    \u5728\u5206\u6790\u4e00\u6bb5\u7a0b\u5e8f\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u7edf\u8ba1\u6682\u5b58\u6570\u636e\u3001\u6808\u5e27\u7a7a\u95f4\u548c\u8f93\u51fa\u6570\u636e\u4e09\u90e8\u5206\uff0c\u5982\u56fe 2-15 \u6240\u793a\u3002

    \u56fe 2-15 \u00a0 \u7b97\u6cd5\u4f7f\u7528\u7684\u76f8\u5173\u7a7a\u95f4

    \u76f8\u5173\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class Node:\n    \"\"\"\u7c7b\"\"\"\n    def __init__(self, x: int):\n        self.val: int = x              # \u8282\u70b9\u503c\n        self.next: Node | None = None  # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\ndef function() -> int:\n    \"\"\"\u51fd\u6570\"\"\"\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n\ndef algorithm(n) -> int:  # \u8f93\u5165\u6570\u636e\n    A = 0                 # \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff0c\u4e00\u822c\u7528\u5927\u5199\u5b57\u6bcd\u8868\u793a\uff09\n    b = 0                 # \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    node = Node(0)        # \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    c = function()        # \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return A + b + c      # \u8f93\u51fa\u6570\u636e\n
    /* \u7ed3\u6784\u4f53 */\nstruct Node {\n    int val;\n    Node *next;\n    Node(int x) : val(x), next(nullptr) {}\n};\n\n/* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint algorithm(int n) {        // \u8f93\u5165\u6570\u636e\n    const int a = 0;          // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    Node* node = new Node(0); // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    int c = func();           // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    int val;\n    Node next;\n    Node(int x) { val = x; }\n}\n\n/* \u51fd\u6570 */\nint function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint algorithm(int n) {        // \u8f93\u5165\u6570\u636e\n    final int a = 0;          // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    Node node = new Node(0);  // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    int c = function();       // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node(int x) {\n    int val = x;\n    Node next;\n}\n\n/* \u51fd\u6570 */\nint Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint Algorithm(int n) {        // \u8f93\u5165\u6570\u636e\n    const int a = 0;          // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    Node node = new(0);       // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    int c = Function();       // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7ed3\u6784\u4f53 */\ntype node struct {\n    val  int\n    next *node\n}\n\n/* \u521b\u5efa node \u7ed3\u6784\u4f53  */\nfunc newNode(val int) *node {\n    return &node{val: val}\n}\n\n/* \u51fd\u6570 */\nfunc function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\nfunc algorithm(n int) int { // \u8f93\u5165\u6570\u636e\n    const a = 0             // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    b := 0                  // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    newNode(0)              // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    c := function()         // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c        // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    var val: Int\n    var next: Node?\n\n    init(x: Int) {\n        val = x\n    }\n}\n\n/* \u51fd\u6570 */\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\nfunc algorithm(n: Int) -> Int { // \u8f93\u5165\u6570\u636e\n    let a = 0             // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    var b = 0             // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    let node = Node(x: 0) // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    let c = function()    // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c      // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    val;\n    next;\n    constructor(val) {\n        this.val = val === undefined ? 0 : val; // \u8282\u70b9\u503c\n        this.next = null;                       // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n\n/* \u51fd\u6570 */\nfunction constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\nfunction algorithm(n) {       // \u8f93\u5165\u6570\u636e\n    const a = 0;              // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    let b = 0;                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    const node = new Node(0); // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    const c = constFunc();    // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;         // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n    val: number;\n    next: Node | null;\n    constructor(val?: number) {\n        this.val = val === undefined ? 0 : val; // \u8282\u70b9\u503c\n        this.next = null;                       // \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n    }\n}\n\n/* \u51fd\u6570 */\nfunction constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\nfunction algorithm(n: number): number { // \u8f93\u5165\u6570\u636e\n    const a = 0;                        // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    let b = 0;                          // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    const node = new Node(0);           // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    const c = constFunc();              // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;                   // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node {\n  int val;\n  Node next;\n  Node(this.val, [this.next]);\n}\n\n/* \u51fd\u6570 */\nint function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n  return 0;\n}\n\nint algorithm(int n) {  // \u8f93\u5165\u6570\u636e\n  const int a = 0;      // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n  int b = 0;            // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n  Node node = Node(0);  // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n  int c = function();   // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n  return a + b + c;     // \u8f93\u51fa\u6570\u636e\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* \u7ed3\u6784\u4f53 */\nstruct Node {\n    val: i32,\n    next: Option<Rc<RefCell<Node>>>,\n}\n\n/* \u521b\u5efa Node \u7ed3\u6784\u4f53 */\nimpl Node {\n    fn new(val: i32) -> Self {\n        Self { val: val, next: None }\n    }\n}\n\n/* \u51fd\u6570 */\nfn function() -> i32 {      \n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nfn algorithm(n: i32) -> i32 {       // \u8f93\u5165\u6570\u636e\n    const a: i32 = 0;               // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    let mut b = 0;                  // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    let node = Node::new(0);        // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    let c = function();             // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;               // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0;\n}\n\nint algorithm(int n) { // \u8f93\u5165\u6570\u636e\n    const int a = 0;   // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    int b = 0;         // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    int c = func();    // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c;  // \u8f93\u51fa\u6570\u636e\n}\n
    /* \u7c7b */\nclass Node(var _val: Int) {\n    var next: Node? = null\n}\n\n/* \u51fd\u6570 */\nfun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\nfun algorithm(n: Int): Int { // \u8f93\u5165\u6570\u636e\n    val a = 0                // \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    var b = 0                // \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    val node = Node(0)       // \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    val c = function()       // \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    return a + b + c         // \u8f93\u51fa\u6570\u636e\n}\n
    ### \u7c7b ###\nclass Node\n    attr_accessor :val      # \u8282\u70b9\u503c\n    attr_accessor :next     # \u6307\u5411\u4e0b\u4e00\u8282\u70b9\u7684\u5f15\u7528\n\n    def initialize(x)\n        @val = x\n    end\nend\n\n### \u51fd\u6570 ###\ndef function\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    0\nend\n\n### \u7b97\u6cd5 ###\ndef algorithm(n)        # \u8f93\u5165\u6570\u636e\n    a = 0               # \u6682\u5b58\u6570\u636e\uff08\u5e38\u91cf\uff09\n    b = 0               # \u6682\u5b58\u6570\u636e\uff08\u53d8\u91cf\uff09\n    node = Node.new(0)  # \u6682\u5b58\u6570\u636e\uff08\u5bf9\u8c61\uff09\n    c = function        # \u6808\u5e27\u7a7a\u95f4\uff08\u8c03\u7528\u51fd\u6570\uff09\n    a + b + c           # \u8f93\u51fa\u6570\u636e\nend\n
    \n
    "},{"location":"chapter_computational_complexity/space_complexity/#242","title":"2.4.2 \u00a0 \u63a8\u7b97\u65b9\u6cd5","text":"

    \u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u63a8\u7b97\u65b9\u6cd5\u4e0e\u65f6\u95f4\u590d\u6742\u5ea6\u5927\u81f4\u76f8\u540c\uff0c\u53ea\u9700\u5c06\u7edf\u8ba1\u5bf9\u8c61\u4ece\u201c\u64cd\u4f5c\u6570\u91cf\u201d\u8f6c\u4e3a\u201c\u4f7f\u7528\u7a7a\u95f4\u5927\u5c0f\u201d\u3002

    \u800c\u4e0e\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u540c\u7684\u662f\uff0c\u6211\u4eec\u901a\u5e38\u53ea\u5173\u6ce8\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u3002\u8fd9\u662f\u56e0\u4e3a\u5185\u5b58\u7a7a\u95f4\u662f\u4e00\u9879\u786c\u6027\u8981\u6c42\uff0c\u6211\u4eec\u5fc5\u987b\u786e\u4fdd\u5728\u6240\u6709\u8f93\u5165\u6570\u636e\u4e0b\u90fd\u6709\u8db3\u591f\u7684\u5185\u5b58\u7a7a\u95f4\u9884\u7559\u3002

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4e2d\u7684\u201c\u6700\u5dee\u201d\u6709\u4e24\u5c42\u542b\u4e49\u3002

    1. \u4ee5\u6700\u5dee\u8f93\u5165\u6570\u636e\u4e3a\u51c6\uff1a\u5f53 \\(n < 10\\) \u65f6\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff1b\u4f46\u5f53 \\(n > 10\\) \u65f6\uff0c\u521d\u59cb\u5316\u7684\u6570\u7ec4 nums \u5360\u7528 \\(O(n)\\) \u7a7a\u95f4\uff0c\u56e0\u6b64\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002
    2. \u4ee5\u7b97\u6cd5\u8fd0\u884c\u4e2d\u7684\u5cf0\u503c\u5185\u5b58\u4e3a\u51c6\uff1a\u4f8b\u5982\uff0c\u7a0b\u5e8f\u5728\u6267\u884c\u6700\u540e\u4e00\u884c\u4e4b\u524d\uff0c\u5360\u7528 \\(O(1)\\) \u7a7a\u95f4\uff1b\u5f53\u521d\u59cb\u5316\u6570\u7ec4 nums \u65f6\uff0c\u7a0b\u5e8f\u5360\u7528 \\(O(n)\\) \u7a7a\u95f4\uff0c\u56e0\u6b64\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def algorithm(n: int):\n    a = 0               # O(1)\n    b = [0] * 10000     # O(1)\n    if n > 10:\n        nums = [0] * n  # O(n)\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    vector<int> b(10000);    // O(1)\n    if (n > 10)\n        vector<int> nums(n); // O(n)\n}\n
    void algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10)\n        int[] nums = new int[n]; // O(n)\n}\n
    void Algorithm(int n) {\n    int a = 0;                   // O(1)\n    int[] b = new int[10000];    // O(1)\n    if (n > 10) {\n        int[] nums = new int[n]; // O(n)\n    }\n}\n
    func algorithm(n int) {\n    a := 0                      // O(1)\n    b := make([]int, 10000)     // O(1)\n    var nums []int\n    if n > 10 {\n        nums := make([]int, n)  // O(n)\n    }\n    fmt.Println(a, b, nums)\n}\n
    func algorithm(n: Int) {\n    let a = 0 // O(1)\n    let b = Array(repeating: 0, count: 10000) // O(1)\n    if n > 10 {\n        let nums = Array(repeating: 0, count: n) // O(n)\n    }\n}\n
    function algorithm(n) {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    function algorithm(n: number): void {\n    const a = 0;                   // O(1)\n    const b = new Array(10000);    // O(1)\n    if (n > 10) {\n        const nums = new Array(n); // O(n)\n    }\n}\n
    void algorithm(int n) {\n  int a = 0;                            // O(1)\n  List<int> b = List.filled(10000, 0);  // O(1)\n  if (n > 10) {\n    List<int> nums = List.filled(n, 0); // O(n)\n  }\n}\n
    fn algorithm(n: i32) {\n    let a = 0;                              // O(1)\n    let b = [0; 10000];                     // O(1)\n    if n > 10 {\n        let nums = vec![0; n as usize];     // O(n)\n    }\n}\n
    void algorithm(int n) {\n    int a = 0;               // O(1)\n    int b[10000];            // O(1)\n    if (n > 10)\n        int nums[n] = {0};   // O(n)\n}\n
    fun algorithm(n: Int) {\n    val a = 0                    // O(1)\n    val b = IntArray(10000)      // O(1)\n    if (n > 10) {\n        val nums = IntArray(n)   // O(n)\n    }\n}\n
    def algorithm(n)\n    a = 0                           # O(1)\n    b = Array.new(10000)            # O(1)\n    nums = Array.new(n) if n > 10   # O(n)\nend\n
    \n

    \u5728\u9012\u5f52\u51fd\u6570\u4e2d\uff0c\u9700\u8981\u6ce8\u610f\u7edf\u8ba1\u6808\u5e27\u7a7a\u95f4\u3002\u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def function() -> int:\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n\ndef loop(n: int):\n    \"\"\"\u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1)\"\"\"\n    for _ in range(n):\n        function()\n\ndef recur(n: int):\n    \"\"\"\u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\"\"\"\n    if n == 1:\n        return\n    return recur(n - 1)\n
    int func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    int Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid Loop(int n) {\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nint Recur(int n) {\n    if (n == 1) return 1;\n    return Recur(n - 1);\n}\n
    func function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunc loop(n int) {\n    for i := 0; i < n; i++ {\n        function()\n    }\n}\n\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunc recur(n int) {\n    if n == 1 {\n        return\n    }\n    recur(n - 1)\n}\n
    @discardableResult\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunc loop(n: Int) {\n    for _ in 0 ..< n {\n        function()\n    }\n}\n\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunc recur(n: Int) {\n    if n == 1 {\n        return\n    }\n    recur(n: n - 1)\n}\n
    function constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunction loop(n) {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunction recur(n) {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    function constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfunction loop(n: number): void {\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfunction recur(n: number): void {\n    if (n === 1) return;\n    return recur(n - 1);\n}\n
    int function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n  for (int i = 0; i < n; i++) {\n    function();\n  }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n  if (n == 1) return;\n  return recur(n - 1);\n}\n
    fn function() -> i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfn loop(n: i32) {\n    for i in 0..n {\n        function();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfn recur(n: i32) {\n    if n == 1 {\n        return;\n    }\n    recur(n - 1);\n}\n
    int func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nvoid loop(int n) {\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nvoid recur(int n) {\n    if (n == 1) return;\n    return recur(n - 1);\n}\n
    fun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n/* \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) */\nfun loop(n: Int) {\n    for (i in 0..<n) {\n        function()\n    }\n}\n/* \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) */\nfun recur(n: Int) {\n    if (n == 1) return\n    return recur(n - 1)\n}\n
    def function\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    0\nend\n\n### \u5faa\u73af\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(1) ###\ndef loop(n)\n    (0...n).each { function }\nend\n\n### \u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n) ###\ndef recur(n)\n    return if n == 1\n    recur(n - 1)\nend\n
    \n

    \u51fd\u6570 loop() \u548c recur() \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n)\\) \uff0c\u4f46\u7a7a\u95f4\u590d\u6742\u5ea6\u4e0d\u540c\u3002

    • \u51fd\u6570 loop() \u5728\u5faa\u73af\u4e2d\u8c03\u7528\u4e86 \\(n\\) \u6b21 function() \uff0c\u6bcf\u8f6e\u4e2d\u7684 function() \u90fd\u8fd4\u56de\u5e76\u91ca\u653e\u4e86\u6808\u5e27\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(1)\\) \u3002
    • \u9012\u5f52\u51fd\u6570 recur() \u5728\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u540c\u65f6\u5b58\u5728 \\(n\\) \u4e2a\u672a\u8fd4\u56de\u7684 recur() \uff0c\u4ece\u800c\u5360\u7528 \\(O(n)\\) \u7684\u6808\u5e27\u7a7a\u95f4\u3002
    "},{"location":"chapter_computational_complexity/space_complexity/#243","title":"2.4.3 \u00a0 \u5e38\u89c1\u7c7b\u578b","text":"

    \u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u56fe 2-16 \u5c55\u793a\u4e86\u5e38\u89c1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u7c7b\u578b\uff08\u4ece\u4f4e\u5230\u9ad8\u6392\u5217\uff09\u3002

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n^2) < O(2^n) \\newline \\text{\u5e38\u6570\u9636} < \\text{\u5bf9\u6570\u9636} < \\text{\u7ebf\u6027\u9636} < \\text{\u5e73\u65b9\u9636} < \\text{\u6307\u6570\u9636} \\end{aligned} \\]

    \u56fe 2-16 \u00a0 \u5e38\u89c1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u7c7b\u578b

    "},{"location":"chapter_computational_complexity/space_complexity/#1-o1","title":"1. \u00a0 \u5e38\u6570\u9636 \\(O(1)\\)","text":"

    \u5e38\u6570\u9636\u5e38\u89c1\u4e8e\u6570\u91cf\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\u7684\u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728\u5faa\u73af\u4e2d\u521d\u59cb\u5316\u53d8\u91cf\u6216\u8c03\u7528\u51fd\u6570\u800c\u5360\u7528\u7684\u5185\u5b58\uff0c\u5728\u8fdb\u5165\u4e0b\u4e00\u5faa\u73af\u540e\u5c31\u4f1a\u88ab\u91ca\u653e\uff0c\u56e0\u6b64\u4e0d\u4f1a\u7d2f\u79ef\u5360\u7528\u7a7a\u95f4\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(1)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def function() -> int:\n    \"\"\"\u51fd\u6570\"\"\"\n    # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n\ndef constant(n: int):\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    a = 0\n    nums = [0] * 10000\n    node = ListNode(0)\n    # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        c = 0\n    # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in range(n):\n        function()\n
    space_complexity.cpp
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    vector<int> nums(10000);\n    ListNode node(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.java
    /* \u51fd\u6570 */\nint function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    final int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        function();\n    }\n}\n
    space_complexity.cs
    /* \u51fd\u6570 */\nint Function() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid Constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    int a = 0;\n    int b = 0;\n    int[] nums = new int[10000];\n    ListNode node = new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        Function();\n    }\n}\n
    space_complexity.go
    /* \u51fd\u6570 */\nfunc function() int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c...\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc spaceConstant(n int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0\n    b := 0\n    nums := make([]int, 10000)\n    node := newNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    var c int\n    for i := 0; i < n; i++ {\n        c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i := 0; i < n; i++ {\n        function()\n    }\n    b += 0\n    c += 0\n    nums[0] = 0\n    node.val = 0\n}\n
    space_complexity.swift
    /* \u51fd\u6570 */\n@discardableResult\nfunc function() -> Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfunc constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    let a = 0\n    var b = 0\n    let nums = Array(repeating: 0, count: 10000)\n    let node = ListNode(x: 0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        let c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for _ in 0 ..< n {\n        function()\n    }\n}\n
    space_complexity.js
    /* \u51fd\u6570 */\nfunction constFunc() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.ts
    /* \u51fd\u6570 */\nfunction constFunc(): number {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nfunction constant(n: number): void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a = 0;\n    const b = 0;\n    const nums = new Array(10000);\n    const node = new ListNode(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        const c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (let i = 0; i < n; i++) {\n        constFunc();\n    }\n}\n
    space_complexity.dart
    /* \u51fd\u6570 */\nint function() {\n  // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n  // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  final int a = 0;\n  int b = 0;\n  List<int> nums = List.filled(10000, 0);\n  ListNode node = ListNode(0);\n  // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    int c = 0;\n  }\n  // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  for (var i = 0; i < n; i++) {\n    function();\n  }\n}\n
    space_complexity.rs
    /* \u51fd\u6570 */\nfn function() -> i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\n#[allow(unused)]\nfn constant(n: i32) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const A: i32 = 0;\n    let b = 0;\n    let nums = vec![0; 10000];\n    let node = ListNode::new(0);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        let c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for i in 0..n {\n        function();\n    }\n}\n
    space_complexity.c
    /* \u51fd\u6570 */\nint func() {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n/* \u5e38\u6570\u9636 */\nvoid constant(int n) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const int a = 0;\n    int b = 0;\n    int nums[1000];\n    ListNode *node = newListNode(0);\n    free(node);\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        int c = 0;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (int i = 0; i < n; i++) {\n        func();\n    }\n}\n
    space_complexity.kt
    /* \u51fd\u6570 */\nfun function(): Int {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0\n}\n\n/* \u5e38\u6570\u9636 */\nfun constant(n: Int) {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    val a = 0\n    var b = 0\n    val nums = Array(10000) { 0 }\n    val node = ListNode(0)\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        val c = 0\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    for (i in 0..<n) {\n        function()\n    }\n}\n
    space_complexity.rb
    ### \u51fd\u6570 ###\ndef function\n  # \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n  0\nend\n\n### \u5e38\u6570\u9636 ###\ndef constant(n)\n  # \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n  a = 0\n  nums = [0] * 10000\n  node = ListNode.new\n\n  # \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { c = 0 }\n  # \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n  (0...n).each { function }\nend\n
    space_complexity.zig
    // \u51fd\u6570\nfn function() i32 {\n    // \u6267\u884c\u67d0\u4e9b\u64cd\u4f5c\n    return 0;\n}\n\n// \u5e38\u6570\u9636\nfn constant(n: i32) void {\n    // \u5e38\u91cf\u3001\u53d8\u91cf\u3001\u5bf9\u8c61\u5360\u7528 O(1) \u7a7a\u95f4\n    const a: i32 = 0;\n    var b: i32 = 0;\n    var nums = [_]i32{0}**10000;\n    var node = inc.ListNode(i32){.val = 0};\n    var i: i32 = 0;\n    // \u5faa\u73af\u4e2d\u7684\u53d8\u91cf\u5360\u7528 O(1) \u7a7a\u95f4\n    while (i < n) : (i += 1) {\n        var c: i32 = 0;\n        _ = c;\n    }\n    // \u5faa\u73af\u4e2d\u7684\u51fd\u6570\u5360\u7528 O(1) \u7a7a\u95f4\n    i = 0;\n    while (i < n) : (i += 1) {\n        _ = function();\n    }\n    _ = a;\n    _ = b;\n    _ = nums;\n    _ = node;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_computational_complexity/space_complexity/#2-on","title":"2. \u00a0 \u7ebf\u6027\u9636 \\(O(n)\\)","text":"

    \u7ebf\u6027\u9636\u5e38\u89c1\u4e8e\u5143\u7d20\u6570\u91cf\u4e0e \\(n\\) \u6210\u6b63\u6bd4\u7684\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u7b49\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear(n: int):\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    nums = [0] * n\n    # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    hmap = dict[int, str]()\n    for i in range(n):\n        hmap[i] = str(i)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<int> nums(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    vector<ListNode> nodes;\n    for (int i = 0; i < n; i++) {\n        nodes.push_back(ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    unordered_map<int, string> map;\n    for (int i = 0; i < n; i++) {\n        map[i] = to_string(i);\n    }\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        nodes.add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Map<Integer, String> map = new HashMap<>();\n    for (int i = 0; i < n; i++) {\n        map.put(i, String.valueOf(i));\n    }\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636 */\nvoid Linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int[] nums = new int[n];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    List<ListNode> nodes = [];\n    for (int i = 0; i < n; i++) {\n        nodes.Add(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    Dictionary<int, string> map = [];\n    for (int i = 0; i < n; i++) {\n        map.Add(i, i.ToString());\n    }\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc spaceLinear(n int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    _ = make([]int, n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes []*node\n    for i := 0; i < n; i++ {\n        nodes = append(nodes, newNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    m := make(map[int]string, n)\n    for i := 0; i < n; i++ {\n        m[i] = strconv.Itoa(i)\n    }\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let nums = Array(repeating: 0, count: n)\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let nodes = (0 ..< n).map { ListNode(x: $0) }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let map = Dictionary(uniqueKeysWithValues: (0 ..< n).map { ($0, \"\\($0)\") })\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    const nums = new Array(n);\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const nodes: ListNode[] = [];\n    for (let i = 0; i < n; i++) {\n        nodes.push(new ListNode(i));\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    const map = new Map();\n    for (let i = 0; i < n; i++) {\n        map.set(i, i.toString());\n    }\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n  // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n  List<int> nums = List.filled(n, 0);\n  // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  List<ListNode> nodes = [];\n  for (var i = 0; i < n; i++) {\n    nodes.add(ListNode(i));\n  }\n  // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  Map<int, String> map = HashMap();\n  for (var i = 0; i < n; i++) {\n    map.putIfAbsent(i, () => i.toString());\n  }\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636 */\n#[allow(unused)]\nfn linear(n: i32) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nums = vec![0; n as usize];\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut nodes = Vec::new();\n    for i in 0..n {\n        nodes.push(ListNode::new(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    let mut map = HashMap::new();\n    for i in 0..n {\n        map.insert(i, i.to_string());\n    }\n}\n
    space_complexity.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u7ebf\u6027\u9636 */\nvoid linear(int n) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    int *nums = malloc(sizeof(int) * n);\n    free(nums);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    ListNode **nodes = malloc(sizeof(ListNode *) * n);\n    for (int i = 0; i < n; i++) {\n        nodes[i] = newListNode(i);\n    }\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(nodes[i]);\n    }\n    free(nodes);\n\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    HashTable *h = NULL;\n    for (int i = 0; i < n; i++) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = i;\n        tmp->val = i;\n        HASH_ADD_INT(h, key, tmp);\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    HashTable *curr, *tmp;\n    HASH_ITER(hh, h, curr, tmp) {\n        HASH_DEL(h, curr);\n        free(curr);\n    }\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int) {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    val nums = Array(n) { 0 }\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val nodes = mutableListOf<ListNode>()\n    for (i in 0..<n) {\n        nodes.add(ListNode(i))\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    val map = mutableMapOf<Int, String>()\n    for (i in 0..<n) {\n        map[i] = i.toString()\n    }\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  # \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  nums = Array.new(n, 0)\n\n  # \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n  hmap = {}\n  for i in 0...n\n    hmap[i] = i.to_s\n  end\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(comptime n: i32) !void {\n    // \u957f\u5ea6\u4e3a n \u7684\u6570\u7ec4\u5360\u7528 O(n) \u7a7a\u95f4\n    var nums = [_]i32{0}**n;\n    // \u957f\u5ea6\u4e3a n \u7684\u5217\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var nodes = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        try nodes.append(i);\n    }\n    // \u957f\u5ea6\u4e3a n \u7684\u54c8\u5e0c\u8868\u5360\u7528 O(n) \u7a7a\u95f4\n    var map = std.AutoArrayHashMap(i32, []const u8).init(std.heap.page_allocator);\n    defer map.deinit();\n    var j: i32 = 0;\n    while (j < n) : (j += 1) {\n        const string = try std.fmt.allocPrint(std.heap.page_allocator, \"{d}\", .{j});\n        defer std.heap.page_allocator.free(string);\n        try map.put(i, string);\n    }\n    _ = nums;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 2-17 \u6240\u793a\uff0c\u6b64\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u5373\u540c\u65f6\u5b58\u5728 \\(n\\) \u4e2a\u672a\u8fd4\u56de\u7684 linear_recur() \u51fd\u6570\uff0c\u4f7f\u7528 \\(O(n)\\) \u5927\u5c0f\u7684\u6808\u5e27\u7a7a\u95f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def linear_recur(n: int):\n    \"\"\"\u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    print(\"\u9012\u5f52 n =\", n)\n    if n == 1:\n        return\n    linear_recur(n - 1)\n
    space_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    cout << \"\u9012\u5f52 n = \" << n << endl;\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    System.out.println(\"\u9012\u5f52 n = \" + n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid LinearRecur(int n) {\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n);\n    if (n == 1) return;\n    LinearRecur(n - 1);\n}\n
    space_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceLinearRecur(n int) {\n    fmt.Println(\"\u9012\u5f52 n =\", n)\n    if n == 1 {\n        return\n    }\n    spaceLinearRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc linearRecur(n: Int) {\n    print(\"\u9012\u5f52 n = \\(n)\")\n    if n == 1 {\n        return\n    }\n    linearRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n) {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction linearRecur(n: number): void {\n    console.log(`\u9012\u5f52 n = ${n}`);\n    if (n === 1) return;\n    linearRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n  print('\u9012\u5f52 n = $n');\n  if (n == 1) return;\n  linearRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn linear_recur(n: i32) {\n    println!(\"\u9012\u5f52 n = {}\", n);\n    if n == 1 {\n        return;\n    };\n    linear_recur(n - 1);\n}\n
    space_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nvoid linearRecur(int n) {\n    printf(\"\u9012\u5f52 n = %d\\r\\n\", n);\n    if (n == 1)\n        return;\n    linearRecur(n - 1);\n}\n
    space_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun linearRecur(n: Int) {\n    println(\"\u9012\u5f52 n = $n\")\n    if (n == 1)\n        return\n    linearRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef linear_recur(n)\n  puts \"\u9012\u5f52 n = #{n}\"\n  return if n == 1\n  linear_recur(n - 1)\nend\n
    space_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn linearRecur(comptime n: i32) void {\n    std.debug.print(\"\u9012\u5f52 n = {}\\n\", .{n});\n    if (n == 1) return;\n    linearRecur(n - 1);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-17 \u00a0 \u9012\u5f52\u51fd\u6570\u4ea7\u751f\u7684\u7ebf\u6027\u9636\u7a7a\u95f4\u590d\u6742\u5ea6

    "},{"location":"chapter_computational_complexity/space_complexity/#3-on2","title":"3. \u00a0 \u5e73\u65b9\u9636 \\(O(n^2)\\)","text":"

    \u5e73\u65b9\u9636\u5e38\u89c1\u4e8e\u77e9\u9635\u548c\u56fe\uff0c\u5143\u7d20\u6570\u91cf\u4e0e \\(n\\) \u6210\u5e73\u65b9\u5173\u7cfb\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic(n: int):\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    num_matrix = [[0] * n for _ in range(n)]\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    vector<vector<int>> numMatrix;\n    for (int i = 0; i < n; i++) {\n        vector<int> tmp;\n        for (int j = 0; j < n; j++) {\n            tmp.push_back(0);\n        }\n        numMatrix.push_back(tmp);\n    }\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[][] numMatrix = new int[n][n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<Integer>> numList = new ArrayList<>();\n    for (int i = 0; i < n; i++) {\n        List<Integer> tmp = new ArrayList<>();\n        for (int j = 0; j < n; j++) {\n            tmp.add(0);\n        }\n        numList.add(tmp);\n    }\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636 */\nvoid Quadratic(int n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int[,] numMatrix = new int[n, n];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    List<List<int>> numList = [];\n    for (int i = 0; i < n; i++) {\n        List<int> tmp = [];\n        for (int j = 0; j < n; j++) {\n            tmp.Add(0);\n        }\n        numList.Add(tmp);\n    }\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc spaceQuadratic(n int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    numMatrix := make([][]int, n)\n    for i := 0; i < n; i++ {\n        numMatrix[i] = make([]int, n)\n    }\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let numList = Array(repeating: Array(repeating: 0, count: n), count: n)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): void {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numMatrix = Array(n)\n        .fill(null)\n        .map(() => Array(n).fill(null));\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    const numList = [];\n    for (let i = 0; i < n; i++) {\n        const tmp = [];\n        for (let j = 0; j < n; j++) {\n            tmp.push(0);\n        }\n        numList.push(tmp);\n    }\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n  // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numMatrix = List.generate(n, (_) => List.filled(n, 0));\n  // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  List<List<int>> numList = [];\n  for (var i = 0; i < n; i++) {\n    List<int> tmp = [];\n    for (int j = 0; j < n; j++) {\n      tmp.add(0);\n    }\n    numList.add(tmp);\n  }\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636 */\n#[allow(unused)]\nfn quadratic(n: i32) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let num_matrix = vec![vec![0; n as usize]; n as usize];\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    let mut num_list = Vec::new();\n    for i in 0..n {\n        let mut tmp = Vec::new();\n        for j in 0..n {\n            tmp.push(0);\n        }\n        num_list.push(tmp);\n    }\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636 */\nvoid quadratic(int n) {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    int **numMatrix = malloc(sizeof(int *) * n);\n    for (int i = 0; i < n; i++) {\n        int *tmp = malloc(sizeof(int) * n);\n        for (int j = 0; j < n; j++) {\n            tmp[j] = 0;\n        }\n        numMatrix[i] = tmp;\n    }\n\n    // \u5185\u5b58\u91ca\u653e\n    for (int i = 0; i < n; i++) {\n        free(numMatrix[i]);\n    }\n    free(numMatrix);\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int) {\n    // \u77e9\u9635\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numMatrix = arrayOfNulls<Array<Int>?>(n)\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    val numList = mutableListOf<MutableList<Int>>()\n    for (i in 0..<n) {\n        val tmp = mutableListOf<Int>()\n        for (j in 0..<n) {\n            tmp.add(0)\n        }\n        numList.add(tmp)\n    }\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  # \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n  Array.new(n) { Array.new(n, 0) }\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) !void {\n    // \u4e8c\u7ef4\u5217\u8868\u5360\u7528 O(n^2) \u7a7a\u95f4\n    var nodes = std.ArrayList(std.ArrayList(i32)).init(std.heap.page_allocator);\n    defer nodes.deinit();\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        var tmp = std.ArrayList(i32).init(std.heap.page_allocator);\n        defer tmp.deinit();\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            try tmp.append(0);\n        }\n        try nodes.append(tmp);\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 2-18 \u6240\u793a\uff0c\u8be5\u51fd\u6570\u7684\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u5728\u6bcf\u4e2a\u9012\u5f52\u51fd\u6570\u4e2d\u90fd\u521d\u59cb\u5316\u4e86\u4e00\u4e2a\u6570\u7ec4\uff0c\u957f\u5ea6\u5206\u522b\u4e3a \\(n\\)\u3001\\(n-1\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \uff0c\u5e73\u5747\u957f\u5ea6\u4e3a \\(n / 2\\) \uff0c\u56e0\u6b64\u603b\u4f53\u5360\u7528 \\(O(n^2)\\) \u7a7a\u95f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def quadratic_recur(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 0:\n        return 0\n    # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    nums = [0] * n\n    return quadratic_recur(n - 1)\n
    space_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    vector<int> nums(n);\n    cout << \"\u9012\u5f52 n = \" << n << \" \u4e2d\u7684 nums \u957f\u5ea6 = \" << nums.size() << endl;\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    int[] nums = new int[n];\n    System.out.println(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.length);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint QuadraticRecur(int n) {\n    if (n <= 0) return 0;\n    int[] nums = new int[n];\n    Console.WriteLine(\"\u9012\u5f52 n = \" + n + \" \u4e2d\u7684 nums \u957f\u5ea6 = \" + nums.Length);\n    return QuadraticRecur(n - 1);\n}\n
    space_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc spaceQuadraticRecur(n int) int {\n    if n <= 0 {\n        return 0\n    }\n    nums := make([]int, n)\n    fmt.Printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d \\n\", n, len(nums))\n    return spaceQuadraticRecur(n - 1)\n}\n
    space_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\n@discardableResult\nfunc quadraticRecur(n: Int) -> Int {\n    if n <= 0 {\n        return 0\n    }\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = Array(repeating: 0, count: n)\n    print(\"\u9012\u5f52 n = \\(n) \u4e2d\u7684 nums \u957f\u5ea6 = \\(nums.count)\")\n    return quadraticRecur(n: n - 1)\n}\n
    space_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n) {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction quadraticRecur(n: number): number {\n    if (n <= 0) return 0;\n    const nums = new Array(n);\n    console.log(`\u9012\u5f52 n = ${n} \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}`);\n    return quadraticRecur(n - 1);\n}\n
    space_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n  if (n <= 0) return 0;\n  List<int> nums = List.filled(n, 0);\n  print('\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.length}');\n  return quadraticRecur(n - 1);\n}\n
    space_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn quadratic_recur(n: i32) -> i32 {\n    if n <= 0 {\n        return 0;\n    };\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    let nums = vec![0; n as usize];\n    println!(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\", n, nums.len());\n    return quadratic_recur(n - 1);\n}\n
    space_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint quadraticRecur(int n) {\n    if (n <= 0)\n        return 0;\n    int *nums = malloc(sizeof(int) * n);\n    printf(\"\u9012\u5f52 n = %d \u4e2d\u7684 nums \u957f\u5ea6 = %d\\r\\n\", n, n);\n    int res = quadraticRecur(n - 1);\n    free(nums);\n    return res;\n}\n
    space_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\ntailrec fun quadraticRecur(n: Int): Int {\n    if (n <= 0)\n        return 0\n    // \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n    val nums = Array(n) { 0 }\n    println(\"\u9012\u5f52 n = $n \u4e2d\u7684 nums \u957f\u5ea6 = ${nums.size}\")\n    return quadraticRecur(n - 1)\n}\n
    space_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef quadratic_recur(n)\n  return 0 unless n > 0\n\n  # \u6570\u7ec4 nums \u957f\u5ea6\u4e3a n, n-1, ..., 2, 1\n  nums = Array.new(n, 0)\n  quadratic_recur(n - 1)\nend\n
    space_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn quadraticRecur(comptime n: i32) i32 {\n    if (n <= 0) return 0;\n    var nums = [_]i32{0}**n;\n    std.debug.print(\"\u9012\u5f52 n = {} \u4e2d\u7684 nums \u957f\u5ea6 = {}\\n\", .{n, nums.len});\n    return quadraticRecur(n - 1);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-18 \u00a0 \u9012\u5f52\u51fd\u6570\u4ea7\u751f\u7684\u5e73\u65b9\u9636\u7a7a\u95f4\u590d\u6742\u5ea6

    "},{"location":"chapter_computational_complexity/space_complexity/#4-o2n","title":"4. \u00a0 \u6307\u6570\u9636 \\(O(2^n)\\)","text":"

    \u6307\u6570\u9636\u5e38\u89c1\u4e8e\u4e8c\u53c9\u6811\u3002\u89c2\u5bdf\u56fe 2-19 \uff0c\u5c42\u6570\u4e3a \\(n\\) \u7684\u201c\u6ee1\u4e8c\u53c9\u6811\u201d\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(2^n - 1\\) \uff0c\u5360\u7528 \\(O(2^n)\\) \u7a7a\u95f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig space_complexity.py
    def build_tree(n: int) -> TreeNode | None:\n    \"\"\"\u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\"\"\"\n    if n == 0:\n        return None\n    root = TreeNode(0)\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n    return root\n
    space_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return nullptr;\n    TreeNode *root = new TreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.java
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode buildTree(int n) {\n    if (n == 0)\n        return null;\n    TreeNode root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? BuildTree(int n) {\n    if (n == 0) return null;\n    TreeNode root = new(0) {\n        left = BuildTree(n - 1),\n        right = BuildTree(n - 1)\n    };\n    return root;\n}\n
    space_complexity.go
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n int) *TreeNode {\n    if n == 0 {\n        return nil\n    }\n    root := NewTreeNode(0)\n    root.Left = buildTree(n - 1)\n    root.Right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunc buildTree(n: Int) -> TreeNode? {\n    if n == 0 {\n        return nil\n    }\n    let root = TreeNode(x: 0)\n    root.left = buildTree(n: n - 1)\n    root.right = buildTree(n: n - 1)\n    return root\n}\n
    space_complexity.js
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n) {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfunction buildTree(n: number): TreeNode | null {\n    if (n === 0) return null;\n    const root = new TreeNode(0);\n    root.left = buildTree(n - 1);\n    root.right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode? buildTree(int n) {\n  if (n == 0) return null;\n  TreeNode root = TreeNode(0);\n  root.left = buildTree(n - 1);\n  root.right = buildTree(n - 1);\n  return root;\n}\n
    space_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfn build_tree(n: i32) -> Option<Rc<RefCell<TreeNode>>> {\n    if n == 0 {\n        return None;\n    };\n    let root = TreeNode::new(0);\n    root.borrow_mut().left = build_tree(n - 1);\n    root.borrow_mut().right = build_tree(n - 1);\n    return Some(root);\n}\n
    space_complexity.c
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nTreeNode *buildTree(int n) {\n    if (n == 0)\n        return NULL;\n    TreeNode *root = newTreeNode(0);\n    root->left = buildTree(n - 1);\n    root->right = buildTree(n - 1);\n    return root;\n}\n
    space_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09 */\nfun buildTree(n: Int): TreeNode? {\n    if (n == 0)\n        return null\n    val root = TreeNode(0)\n    root.left = buildTree(n - 1)\n    root.right = buildTree(n - 1)\n    return root\n}\n
    space_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09###\ndef build_tree(n)\n  return if n == 0\n\n  TreeNode.new.tap do |root|\n    root.left = build_tree(n - 1)\n    root.right = build_tree(n - 1)\n  end\nend\n
    space_complexity.zig
    // \u6307\u6570\u9636\uff08\u5efa\u7acb\u6ee1\u4e8c\u53c9\u6811\uff09\nfn buildTree(mem_allocator: std.mem.Allocator, n: i32) !?*inc.TreeNode(i32) {\n    if (n == 0) return null;\n    const root = try mem_allocator.create(inc.TreeNode(i32));\n    root.init(0);\n    root.left = try buildTree(mem_allocator, n - 1);\n    root.right = try buildTree(mem_allocator, n - 1);\n    return root;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-19 \u00a0 \u6ee1\u4e8c\u53c9\u6811\u4ea7\u751f\u7684\u6307\u6570\u9636\u7a7a\u95f4\u590d\u6742\u5ea6

    "},{"location":"chapter_computational_complexity/space_complexity/#5-olog-n","title":"5. \u00a0 \u5bf9\u6570\u9636 \\(O(\\log n)\\)","text":"

    \u5bf9\u6570\u9636\u5e38\u89c1\u4e8e\u5206\u6cbb\u7b97\u6cd5\u3002\u4f8b\u5982\u5f52\u5e76\u6392\u5e8f\uff0c\u8f93\u5165\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\uff0c\u6bcf\u8f6e\u9012\u5f52\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5904\u5212\u5206\u4e3a\u4e24\u534a\uff0c\u5f62\u6210\u9ad8\u5ea6\u4e3a \\(\\log n\\) \u7684\u9012\u5f52\u6811\uff0c\u4f7f\u7528 \\(O(\\log n)\\) \u6808\u5e27\u7a7a\u95f4\u3002

    \u518d\u4f8b\u5982\u5c06\u6570\u5b57\u8f6c\u5316\u4e3a\u5b57\u7b26\u4e32\uff0c\u8f93\u5165\u4e00\u4e2a\u6b63\u6574\u6570 \\(n\\) \uff0c\u5b83\u7684\u4f4d\u6570\u4e3a \\(\\lfloor \\log_{10} n \\rfloor + 1\\) \uff0c\u5373\u5bf9\u5e94\u5b57\u7b26\u4e32\u957f\u5ea6\u4e3a \\(\\lfloor \\log_{10} n \\rfloor + 1\\) \uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log_{10} n + 1) = O(\\log n)\\) \u3002

    "},{"location":"chapter_computational_complexity/space_complexity/#244","title":"2.4.4 \u00a0 \u6743\u8861\u65f6\u95f4\u4e0e\u7a7a\u95f4","text":"

    \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5e0c\u671b\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u80fd\u8fbe\u5230\u6700\u4f18\u3002\u7136\u800c\u5728\u5b9e\u9645\u60c5\u51b5\u4e2d\uff0c\u540c\u65f6\u4f18\u5316\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u975e\u5e38\u56f0\u96be\u3002

    \u964d\u4f4e\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u9700\u8981\u4ee5\u63d0\u5347\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a\u4ee3\u4ef7\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002\u6211\u4eec\u5c06\u727a\u7272\u5185\u5b58\u7a7a\u95f4\u6765\u63d0\u5347\u7b97\u6cd5\u8fd0\u884c\u901f\u5ea6\u7684\u601d\u8def\u79f0\u4e3a\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\uff1b\u53cd\u4e4b\uff0c\u5219\u79f0\u4e3a\u201c\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4\u201d\u3002

    \u9009\u62e9\u54ea\u79cd\u601d\u8def\u53d6\u51b3\u4e8e\u6211\u4eec\u66f4\u770b\u91cd\u54ea\u4e2a\u65b9\u9762\u3002\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u65f6\u95f4\u6bd4\u7a7a\u95f4\u66f4\u5b9d\u8d35\uff0c\u56e0\u6b64\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\u901a\u5e38\u662f\u66f4\u5e38\u7528\u7684\u7b56\u7565\u3002\u5f53\u7136\uff0c\u5728\u6570\u636e\u91cf\u5f88\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u63a7\u5236\u7a7a\u95f4\u590d\u6742\u5ea6\u4e5f\u975e\u5e38\u91cd\u8981\u3002

    "},{"location":"chapter_computational_complexity/summary/","title":"2.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_computational_complexity/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"

    \u7b97\u6cd5\u6548\u7387\u8bc4\u4f30

    • \u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u662f\u8861\u91cf\u7b97\u6cd5\u4f18\u52a3\u7684\u4e24\u4e2a\u4e3b\u8981\u8bc4\u4ef7\u6307\u6807\u3002
    • \u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5b9e\u9645\u6d4b\u8bd5\u6765\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\uff0c\u4f46\u96be\u4ee5\u6d88\u9664\u6d4b\u8bd5\u73af\u5883\u7684\u5f71\u54cd\uff0c\u4e14\u4f1a\u8017\u8d39\u5927\u91cf\u8ba1\u7b97\u8d44\u6e90\u3002
    • \u590d\u6742\u5ea6\u5206\u6790\u53ef\u4ee5\u6d88\u9664\u5b9e\u9645\u6d4b\u8bd5\u7684\u5f0a\u7aef\uff0c\u5206\u6790\u7ed3\u679c\u9002\u7528\u4e8e\u6240\u6709\u8fd0\u884c\u5e73\u53f0\uff0c\u5e76\u4e14\u80fd\u591f\u63ed\u793a\u7b97\u6cd5\u5728\u4e0d\u540c\u6570\u636e\u89c4\u6a21\u4e0b\u7684\u6548\u7387\u3002

    \u65f6\u95f4\u590d\u6742\u5ea6

    • \u65f6\u95f4\u590d\u6742\u5ea6\u7528\u4e8e\u8861\u91cf\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u968f\u6570\u636e\u91cf\u589e\u957f\u7684\u8d8b\u52bf\uff0c\u53ef\u4ee5\u6709\u6548\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\u53ef\u80fd\u5931\u6548\uff0c\u5982\u5728\u8f93\u5165\u7684\u6570\u636e\u91cf\u8f83\u5c0f\u6216\u65f6\u95f4\u590d\u6742\u5ea6\u76f8\u540c\u65f6\uff0c\u65e0\u6cd5\u7cbe\u786e\u5bf9\u6bd4\u7b97\u6cd5\u6548\u7387\u7684\u4f18\u52a3\u3002
    • \u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4f7f\u7528\u5927 \\(O\\) \u7b26\u53f7\u8868\u793a\uff0c\u5bf9\u5e94\u51fd\u6570\u6e10\u8fd1\u4e0a\u754c\uff0c\u53cd\u6620\u5f53 \\(n\\) \u8d8b\u5411\u6b63\u65e0\u7a77\u65f6\uff0c\u64cd\u4f5c\u6570\u91cf \\(T(n)\\) \u7684\u589e\u957f\u7ea7\u522b\u3002
    • \u63a8\u7b97\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u4e3a\u4e24\u6b65\uff0c\u9996\u5148\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf\uff0c\u7136\u540e\u5224\u65ad\u6e10\u8fd1\u4e0a\u754c\u3002
    • \u5e38\u89c1\u65f6\u95f4\u590d\u6742\u5ea6\u4ece\u4f4e\u5230\u9ad8\u6392\u5217\u6709 \\(O(1)\\)\u3001\\(O(\\log n)\\)\u3001\\(O(n)\\)\u3001\\(O(n \\log n)\\)\u3001\\(O(n^2)\\)\u3001\\(O(2^n)\\) \u548c \\(O(n!)\\) \u7b49\u3002
    • \u67d0\u4e9b\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u975e\u56fa\u5b9a\uff0c\u800c\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u6709\u5173\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u4e3a\u6700\u5dee\u3001\u6700\u4f73\u3001\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u51e0\u4e4e\u4e0d\u7528\uff0c\u56e0\u4e3a\u8f93\u5165\u6570\u636e\u4e00\u822c\u9700\u8981\u6ee1\u8db3\u4e25\u683c\u6761\u4ef6\u624d\u80fd\u8fbe\u5230\u6700\u4f73\u60c5\u51b5\u3002
    • \u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u53cd\u6620\u7b97\u6cd5\u5728\u968f\u673a\u6570\u636e\u8f93\u5165\u4e0b\u7684\u8fd0\u884c\u6548\u7387\uff0c\u6700\u63a5\u8fd1\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u7b97\u6cd5\u6027\u80fd\u3002\u8ba1\u7b97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u9700\u8981\u7edf\u8ba1\u8f93\u5165\u6570\u636e\u5206\u5e03\u4ee5\u53ca\u7efc\u5408\u540e\u7684\u6570\u5b66\u671f\u671b\u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6

    • \u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u4f5c\u7528\u7c7b\u4f3c\u4e8e\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u7528\u4e8e\u8861\u91cf\u7b97\u6cd5\u5360\u7528\u5185\u5b58\u7a7a\u95f4\u968f\u6570\u636e\u91cf\u589e\u957f\u7684\u8d8b\u52bf\u3002
    • \u7b97\u6cd5\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u76f8\u5173\u5185\u5b58\u7a7a\u95f4\u53ef\u5206\u4e3a\u8f93\u5165\u7a7a\u95f4\u3001\u6682\u5b58\u7a7a\u95f4\u3001\u8f93\u51fa\u7a7a\u95f4\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u8f93\u5165\u7a7a\u95f4\u4e0d\u7eb3\u5165\u7a7a\u95f4\u590d\u6742\u5ea6\u8ba1\u7b97\u3002\u6682\u5b58\u7a7a\u95f4\u53ef\u5206\u4e3a\u6682\u5b58\u6570\u636e\u3001\u6808\u5e27\u7a7a\u95f4\u548c\u6307\u4ee4\u7a7a\u95f4\uff0c\u5176\u4e2d\u6808\u5e27\u7a7a\u95f4\u901a\u5e38\u4ec5\u5728\u9012\u5f52\u51fd\u6570\u4e2d\u5f71\u54cd\u7a7a\u95f4\u590d\u6742\u5ea6\u3002
    • \u6211\u4eec\u901a\u5e38\u53ea\u5173\u6ce8\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5373\u7edf\u8ba1\u7b97\u6cd5\u5728\u6700\u5dee\u8f93\u5165\u6570\u636e\u548c\u6700\u5dee\u8fd0\u884c\u65f6\u523b\u4e0b\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u3002
    • \u5e38\u89c1\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece\u4f4e\u5230\u9ad8\u6392\u5217\u6709 \\(O(1)\\)\u3001\\(O(\\log n)\\)\u3001\\(O(n)\\)\u3001\\(O(n^2)\\) \u548c \\(O(2^n)\\) \u7b49\u3002
    "},{"location":"chapter_computational_complexity/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u5c3e\u9012\u5f52\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u5417\uff1f

    \u7406\u8bba\u4e0a\uff0c\u5c3e\u9012\u5f52\u51fd\u6570\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f18\u5316\u81f3 \\(O(1)\\) \u3002\u4e0d\u8fc7\u7edd\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\uff08\u4f8b\u5982 Java\u3001Python\u3001C++\u3001Go\u3001C# \u7b49\uff09\u4e0d\u652f\u6301\u81ea\u52a8\u4f18\u5316\u5c3e\u9012\u5f52\uff0c\u56e0\u6b64\u901a\u5e38\u8ba4\u4e3a\u7a7a\u95f4\u590d\u6742\u5ea6\u662f \\(O(n)\\) \u3002

    Q\uff1a\u51fd\u6570\u548c\u65b9\u6cd5\u8fd9\u4e24\u4e2a\u672f\u8bed\u7684\u533a\u522b\u662f\u4ec0\u4e48\uff1f

    \u51fd\u6570\uff08function\uff09\u53ef\u4ee5\u88ab\u72ec\u7acb\u6267\u884c\uff0c\u6240\u6709\u53c2\u6570\u90fd\u4ee5\u663e\u5f0f\u4f20\u9012\u3002\u65b9\u6cd5\uff08method\uff09\u4e0e\u4e00\u4e2a\u5bf9\u8c61\u5173\u8054\uff0c\u88ab\u9690\u5f0f\u4f20\u9012\u7ed9\u8c03\u7528\u5b83\u7684\u5bf9\u8c61\uff0c\u80fd\u591f\u5bf9\u7c7b\u7684\u5b9e\u4f8b\u4e2d\u5305\u542b\u7684\u6570\u636e\u8fdb\u884c\u64cd\u4f5c\u3002

    \u4e0b\u9762\u4ee5\u51e0\u79cd\u5e38\u89c1\u7684\u7f16\u7a0b\u8bed\u8a00\u4e3a\u4f8b\u6765\u8bf4\u660e\u3002

    • C \u8bed\u8a00\u662f\u8fc7\u7a0b\u5f0f\u7f16\u7a0b\u8bed\u8a00\uff0c\u6ca1\u6709\u9762\u5411\u5bf9\u8c61\u7684\u6982\u5ff5\uff0c\u6240\u4ee5\u53ea\u6709\u51fd\u6570\u3002\u4f46\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa\u7ed3\u6784\u4f53\uff08struct\uff09\u6765\u6a21\u62df\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff0c\u4e0e\u7ed3\u6784\u4f53\u76f8\u5173\u8054\u7684\u51fd\u6570\u5c31\u76f8\u5f53\u4e8e\u5176\u4ed6\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u65b9\u6cd5\u3002
    • Java \u548c C# \u662f\u9762\u5411\u5bf9\u8c61\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u4ee3\u7801\u5757\uff08\u65b9\u6cd5\uff09\u901a\u5e38\u4f5c\u4e3a\u67d0\u4e2a\u7c7b\u7684\u4e00\u90e8\u5206\u3002\u9759\u6001\u65b9\u6cd5\u7684\u884c\u4e3a\u7c7b\u4f3c\u4e8e\u51fd\u6570\uff0c\u56e0\u4e3a\u5b83\u88ab\u7ed1\u5b9a\u5728\u7c7b\u4e0a\uff0c\u4e0d\u80fd\u8bbf\u95ee\u7279\u5b9a\u7684\u5b9e\u4f8b\u53d8\u91cf\u3002
    • C++ \u548c Python \u65e2\u652f\u6301\u8fc7\u7a0b\u5f0f\u7f16\u7a0b\uff08\u51fd\u6570\uff09\uff0c\u4e5f\u652f\u6301\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08\u65b9\u6cd5\uff09\u3002

    Q\uff1a\u56fe\u89e3\u201c\u5e38\u89c1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u7c7b\u578b\u201d\u53cd\u6620\u7684\u662f\u5426\u662f\u5360\u7528\u7a7a\u95f4\u7684\u7edd\u5bf9\u5927\u5c0f\uff1f

    \u4e0d\u662f\uff0c\u8be5\u56fe\u5c55\u793a\u7684\u662f\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5176\u53cd\u6620\u7684\u662f\u589e\u957f\u8d8b\u52bf\uff0c\u800c\u4e0d\u662f\u5360\u7528\u7a7a\u95f4\u7684\u7edd\u5bf9\u5927\u5c0f\u3002

    \u5047\u8bbe\u53d6 \\(n = 8\\) \uff0c\u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0\u6bcf\u6761\u66f2\u7ebf\u7684\u503c\u4e0e\u51fd\u6570\u5bf9\u5e94\u4e0d\u4e0a\u3002\u8fd9\u662f\u56e0\u4e3a\u6bcf\u6761\u66f2\u7ebf\u90fd\u5305\u542b\u4e00\u4e2a\u5e38\u6570\u9879\uff0c\u7528\u4e8e\u5c06\u53d6\u503c\u8303\u56f4\u538b\u7f29\u5230\u4e00\u4e2a\u89c6\u89c9\u8212\u9002\u7684\u8303\u56f4\u5185\u3002

    \u5728\u5b9e\u9645\u4e2d\uff0c\u56e0\u4e3a\u6211\u4eec\u901a\u5e38\u4e0d\u77e5\u9053\u6bcf\u4e2a\u65b9\u6cd5\u7684\u201c\u5e38\u6570\u9879\u201d\u590d\u6742\u5ea6\u662f\u591a\u5c11\uff0c\u6240\u4ee5\u4e00\u822c\u65e0\u6cd5\u4ec5\u51ed\u590d\u6742\u5ea6\u6765\u9009\u62e9 \\(n = 8\\) \u4e4b\u4e0b\u7684\u6700\u4f18\u89e3\u6cd5\u3002\u4f46\u5bf9\u4e8e \\(n = 8^5\\) \u5c31\u5f88\u597d\u9009\u4e86\uff0c\u8fd9\u65f6\u589e\u957f\u8d8b\u52bf\u5df2\u7ecf\u5360\u4e3b\u5bfc\u4e86\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/","title":"2.3 \u00a0 \u65f6\u95f4\u590d\u6742\u5ea6","text":"

    \u8fd0\u884c\u65f6\u95f4\u53ef\u4ee5\u76f4\u89c2\u4e14\u51c6\u786e\u5730\u53cd\u6620\u7b97\u6cd5\u7684\u6548\u7387\u3002\u5982\u679c\u6211\u4eec\u60f3\u51c6\u786e\u9884\u4f30\u4e00\u6bb5\u4ee3\u7801\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u5e94\u8be5\u5982\u4f55\u64cd\u4f5c\u5462\uff1f

    1. \u786e\u5b9a\u8fd0\u884c\u5e73\u53f0\uff0c\u5305\u62ec\u786c\u4ef6\u914d\u7f6e\u3001\u7f16\u7a0b\u8bed\u8a00\u3001\u7cfb\u7edf\u73af\u5883\u7b49\uff0c\u8fd9\u4e9b\u56e0\u7d20\u90fd\u4f1a\u5f71\u54cd\u4ee3\u7801\u7684\u8fd0\u884c\u6548\u7387\u3002
    2. \u8bc4\u4f30\u5404\u79cd\u8ba1\u7b97\u64cd\u4f5c\u6240\u9700\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u4f8b\u5982\u52a0\u6cd5\u64cd\u4f5c + \u9700\u8981 1 ns \uff0c\u4e58\u6cd5\u64cd\u4f5c * \u9700\u8981 10 ns \uff0c\u6253\u5370\u64cd\u4f5c print() \u9700\u8981 5 ns \u7b49\u3002
    3. \u7edf\u8ba1\u4ee3\u7801\u4e2d\u6240\u6709\u7684\u8ba1\u7b97\u64cd\u4f5c\uff0c\u5e76\u5c06\u6240\u6709\u64cd\u4f5c\u7684\u6267\u884c\u65f6\u95f4\u6c42\u548c\uff0c\u4ece\u800c\u5f97\u5230\u8fd0\u884c\u65f6\u95f4\u3002

    \u4f8b\u5982\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\ndef algorithm(n: int):\n    a = 2      # 1 ns\n    a = a + 1  # 1 ns\n    a = a * 2  # 10 ns\n    # \u5faa\u73af n \u6b21\n    for _ in range(n):  # 1 ns\n        print(0)        # 5 ns\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        cout << 0 << endl;         // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        System.out.println(0);     // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid Algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        Console.WriteLine(0);      // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunc algorithm(n int) {\n    a := 2     // 1 ns\n    a = a + 1  // 1 ns\n    a = a * 2  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for i := 0; i < n; i++ {  // 1 ns\n        fmt.Println(a)        // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunc algorithm(n: Int) {\n    var a = 2 // 1 ns\n    a = a + 1 // 1 ns\n    a = a * 2 // 10 ns\n    // \u5faa\u73af n \u6b21\n    for _ in 0 ..< n { // 1 ns\n        print(0) // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunction algorithm(n) {\n    var a = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++) { // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        console.log(0); // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfunction algorithm(n: number): void {\n    var a: number = 2; // 1 ns\n    a = a + 1; // 1 ns\n    a = a * 2; // 10 ns\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++) { // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        console.log(0); // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n  int a = 2; // 1 ns\n  a = a + 1; // 1 ns\n  a = a * 2; // 10 ns\n  // \u5faa\u73af n \u6b21\n  for (int i = 0; i < n; i++) { // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n    print(0); // 5 ns\n  }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfn algorithm(n: i32) {\n    let mut a = 2;      // 1 ns\n    a = a + 1;          // 1 ns\n    a = a * 2;          // 10 ns\n    // \u5faa\u73af n \u6b21\n    for _ in 0..n {     // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        println!(\"{}\", 0);  // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nvoid algorithm(int n) {\n    int a = 2;  // 1 ns\n    a = a + 1;  // 1 ns\n    a = a * 2;  // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {   // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        printf(\"%d\", 0);            // 5 ns\n    }\n}\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfun algorithm(n: Int) {\n    var a = 2 // 1 ns\n    a = a + 1 // 1 ns\n    a = a * 2 // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (i in 0..<n) {  // 1 ns \uff0c\u6bcf\u8f6e\u90fd\u8981\u6267\u884c i++\n        println(0)      // 5 ns\n    }\n}\n
    # \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\ndef algorithm(n)\n    a = 2       # 1 ns\n    a = a + 1   # 1 ns\n    a = a * 2   # 10 ns\n    # \u5faa\u73af n \u6b21\n    (0...n).each do # 1 ns\n        puts 0      # 5 ns\n    end\nend\n
    // \u5728\u67d0\u8fd0\u884c\u5e73\u53f0\u4e0b\nfn algorithm(n: usize) void {\n    var a: i32 = 2; // 1 ns\n    a += 1; // 1 ns\n    a *= 2; // 10 ns\n    // \u5faa\u73af n \u6b21\n    for (0..n) |_| { // 1 ns\n        std.debug.print(\"{}\\n\", .{0}); // 5 ns\n    }\n}\n

    \u6839\u636e\u4ee5\u4e0a\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5f97\u5230\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u95f4\u4e3a \\((6n + 12)\\) ns \uff1a

    \\[ 1 + 1 + 10 + (1 + 5) \\times n = 6n + 12 \\]

    \u4f46\u5b9e\u9645\u4e0a\uff0c\u7edf\u8ba1\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u95f4\u65e2\u4e0d\u5408\u7406\u4e5f\u4e0d\u73b0\u5b9e\u3002\u9996\u5148\uff0c\u6211\u4eec\u4e0d\u5e0c\u671b\u5c06\u9884\u4f30\u65f6\u95f4\u548c\u8fd0\u884c\u5e73\u53f0\u7ed1\u5b9a\uff0c\u56e0\u4e3a\u7b97\u6cd5\u9700\u8981\u5728\u5404\u79cd\u4e0d\u540c\u7684\u5e73\u53f0\u4e0a\u8fd0\u884c\u3002\u5176\u6b21\uff0c\u6211\u4eec\u5f88\u96be\u83b7\u77e5\u6bcf\u79cd\u64cd\u4f5c\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u8fd9\u7ed9\u9884\u4f30\u8fc7\u7a0b\u5e26\u6765\u4e86\u6781\u5927\u7684\u96be\u5ea6\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#231","title":"2.3.1 \u00a0 \u7edf\u8ba1\u65f6\u95f4\u589e\u957f\u8d8b\u52bf","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u7edf\u8ba1\u7684\u4e0d\u662f\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\uff0c\u800c\u662f\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u968f\u7740\u6570\u636e\u91cf\u53d8\u5927\u65f6\u7684\u589e\u957f\u8d8b\u52bf\u3002

    \u201c\u65f6\u95f4\u589e\u957f\u8d8b\u52bf\u201d\u8fd9\u4e2a\u6982\u5ff5\u6bd4\u8f83\u62bd\u8c61\uff0c\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u4f8b\u5b50\u6765\u52a0\u4ee5\u7406\u89e3\u3002\u5047\u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u7ed9\u5b9a\u4e09\u4e2a\u7b97\u6cd5 A\u3001B \u548c C \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_A(n: int):\n    print(0)\n# \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\ndef algorithm_B(n: int):\n    for _ in range(n):\n        print(0)\n# \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_C(n: int):\n    for _ in range(1000000):\n        print(0)\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_A(int n) {\n    cout << 0 << endl;\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        cout << 0 << endl;\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        cout << 0 << endl;\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_A(int n) {\n    System.out.println(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        System.out.println(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        System.out.println(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid AlgorithmA(int n) {\n    Console.WriteLine(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid AlgorithmB(int n) {\n    for (int i = 0; i < n; i++) {\n        Console.WriteLine(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid AlgorithmC(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        Console.WriteLine(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithm_A(n int) {\n    fmt.Println(0)\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunc algorithm_B(n int) {\n    for i := 0; i < n; i++ {\n        fmt.Println(0)\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithm_C(n int) {\n    for i := 0; i < 1000000; i++ {\n        fmt.Println(0)\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithmA(n: Int) {\n    print(0)\n}\n\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunc algorithmB(n: Int) {\n    for _ in 0 ..< n {\n        print(0)\n    }\n}\n\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunc algorithmC(n: Int) {\n    for _ in 0 ..< 1_000_000 {\n        print(0)\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_A(n) {\n    console.log(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunction algorithm_B(n) {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_C(n) {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_A(n: number): void {\n    console.log(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfunction algorithm_B(n: number): void {\n    for (let i = 0; i < n; i++) {\n        console.log(0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfunction algorithm_C(n: number): void {\n    for (let i = 0; i < 1000000; i++) {\n        console.log(0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithmA(int n) {\n  print(0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithmB(int n) {\n  for (int i = 0; i < n; i++) {\n    print(0);\n  }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithmC(int n) {\n  for (int i = 0; i < 1000000; i++) {\n    print(0);\n  }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_A(n: i32) {\n    println!(\"{}\", 0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfn algorithm_B(n: i32) {\n    for _ in 0..n {\n        println!(\"{}\", 0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_C(n: i32) {\n    for _ in 0..1000000 {\n        println!(\"{}\", 0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_A(int n) {\n    printf(\"%d\", 0);\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nvoid algorithm_B(int n) {\n    for (int i = 0; i < n; i++) {\n        printf(\"%d\", 0);\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nvoid algorithm_C(int n) {\n    for (int i = 0; i < 1000000; i++) {\n        printf(\"%d\", 0);\n    }\n}\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfun algoritm_A(n: Int) {\n    println(0)\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfun algorithm_B(n: Int) {\n    for (i in 0..<n){\n        println(0)\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfun algorithm_C(n: Int) {\n    for (i in 0..<1000000) {\n        println(0)\n    }\n}\n
    # \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_A(n)\n    puts 0\nend\n\n# \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\ndef algorithm_B(n)\n    (0...n).each { puts 0 }\nend\n\n# \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\ndef algorithm_C(n)\n    (0...1_000_000).each { puts 0 }\nend\n
    // \u7b97\u6cd5 A \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_A(n: usize) void {\n    _ = n;\n    std.debug.print(\"{}\\n\", .{0});\n}\n// \u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u7ebf\u6027\u9636\nfn algorithm_B(n: i32) void {\n    for (0..n) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n// \u7b97\u6cd5 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u5e38\u6570\u9636\nfn algorithm_C(n: i32) void {\n    _ = n;\n    for (0..1000000) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n}\n

    \u56fe 2-7 \u5c55\u793a\u4e86\u4ee5\u4e0a\u4e09\u4e2a\u7b97\u6cd5\u51fd\u6570\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    • \u7b97\u6cd5 A \u53ea\u6709 \\(1\\) \u4e2a\u6253\u5370\u64cd\u4f5c\uff0c\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u4e0d\u968f\u7740 \\(n\\) \u589e\u5927\u800c\u589e\u957f\u3002\u6211\u4eec\u79f0\u6b64\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\u201c\u5e38\u6570\u9636\u201d\u3002
    • \u7b97\u6cd5 B \u4e2d\u7684\u6253\u5370\u64cd\u4f5c\u9700\u8981\u5faa\u73af \\(n\\) \u6b21\uff0c\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u968f\u7740 \\(n\\) \u589e\u5927\u5448\u7ebf\u6027\u589e\u957f\u3002\u6b64\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u88ab\u79f0\u4e3a\u201c\u7ebf\u6027\u9636\u201d\u3002
    • \u7b97\u6cd5 C \u4e2d\u7684\u6253\u5370\u64cd\u4f5c\u9700\u8981\u5faa\u73af \\(1000000\\) \u6b21\uff0c\u867d\u7136\u8fd0\u884c\u65f6\u95f4\u5f88\u957f\uff0c\u4f46\u5b83\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\u3002\u56e0\u6b64 C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u548c A \u76f8\u540c\uff0c\u4ecd\u4e3a\u201c\u5e38\u6570\u9636\u201d\u3002

    \u56fe 2-7 \u00a0 \u7b97\u6cd5 A\u3001B \u548c C \u7684\u65f6\u95f4\u589e\u957f\u8d8b\u52bf

    \u76f8\u8f83\u4e8e\u76f4\u63a5\u7edf\u8ba1\u7b97\u6cd5\u7684\u8fd0\u884c\u65f6\u95f4\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u6709\u54ea\u4e9b\u7279\u70b9\u5462\uff1f

    • \u65f6\u95f4\u590d\u6742\u5ea6\u80fd\u591f\u6709\u6548\u8bc4\u4f30\u7b97\u6cd5\u6548\u7387\u3002\u4f8b\u5982\uff0c\u7b97\u6cd5 B \u7684\u8fd0\u884c\u65f6\u95f4\u5448\u7ebf\u6027\u589e\u957f\uff0c\u5728 \\(n > 1\\) \u65f6\u6bd4\u7b97\u6cd5 A \u66f4\u6162\uff0c\u5728 \\(n > 1000000\\) \u65f6\u6bd4\u7b97\u6cd5 C \u66f4\u6162\u3002\u4e8b\u5b9e\u4e0a\uff0c\u53ea\u8981\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u8db3\u591f\u5927\uff0c\u590d\u6742\u5ea6\u4e3a\u201c\u5e38\u6570\u9636\u201d\u7684\u7b97\u6cd5\u4e00\u5b9a\u4f18\u4e8e\u201c\u7ebf\u6027\u9636\u201d\u7684\u7b97\u6cd5\uff0c\u8fd9\u6b63\u662f\u65f6\u95f4\u589e\u957f\u8d8b\u52bf\u7684\u542b\u4e49\u3002
    • \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u63a8\u7b97\u65b9\u6cd5\u66f4\u7b80\u4fbf\u3002\u663e\u7136\uff0c\u8fd0\u884c\u5e73\u53f0\u548c\u8ba1\u7b97\u64cd\u4f5c\u7c7b\u578b\u90fd\u4e0e\u7b97\u6cd5\u8fd0\u884c\u65f6\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u65e0\u5173\u3002\u56e0\u6b64\u5728\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5355\u5730\u5c06\u6240\u6709\u8ba1\u7b97\u64cd\u4f5c\u7684\u6267\u884c\u65f6\u95f4\u89c6\u4e3a\u76f8\u540c\u7684\u201c\u5355\u4f4d\u65f6\u95f4\u201d\uff0c\u4ece\u800c\u5c06\u201c\u8ba1\u7b97\u64cd\u4f5c\u8fd0\u884c\u65f6\u95f4\u7edf\u8ba1\u201d\u7b80\u5316\u4e3a\u201c\u8ba1\u7b97\u64cd\u4f5c\u6570\u91cf\u7edf\u8ba1\u201d\uff0c\u8fd9\u6837\u4e00\u6765\u4f30\u7b97\u96be\u5ea6\u5c31\u5927\u5927\u964d\u4f4e\u4e86\u3002
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u5b58\u5728\u4e00\u5b9a\u7684\u5c40\u9650\u6027\u3002\u4f8b\u5982\uff0c\u5c3d\u7ba1\u7b97\u6cd5 A \u548c C \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u76f8\u540c\uff0c\u4f46\u5b9e\u9645\u8fd0\u884c\u65f6\u95f4\u5dee\u522b\u5f88\u5927\u3002\u540c\u6837\uff0c\u5c3d\u7ba1\u7b97\u6cd5 B \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u6bd4 C \u9ad8\uff0c\u4f46\u5728\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u8f83\u5c0f\u65f6\uff0c\u7b97\u6cd5 B \u660e\u663e\u4f18\u4e8e\u7b97\u6cd5 C \u3002\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5f88\u96be\u4ec5\u51ed\u65f6\u95f4\u590d\u6742\u5ea6\u5224\u65ad\u7b97\u6cd5\u6548\u7387\u7684\u9ad8\u4f4e\u3002\u5f53\u7136\uff0c\u5c3d\u7ba1\u5b58\u5728\u4e0a\u8ff0\u95ee\u9898\uff0c\u590d\u6742\u5ea6\u5206\u6790\u4ecd\u7136\u662f\u8bc4\u5224\u7b97\u6cd5\u6548\u7387\u6700\u6709\u6548\u4e14\u5e38\u7528\u7684\u65b9\u6cd5\u3002
    "},{"location":"chapter_computational_complexity/time_complexity/#232","title":"2.3.2 \u00a0 \u51fd\u6570\u6e10\u8fd1\u4e0a\u754c","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u8f93\u5165\u5927\u5c0f\u4e3a \\(n\\) \u7684\u51fd\u6570\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def algorithm(n: int):\n    a = 1      # +1\n    a = a + 1  # +1\n    a = a * 2  # +1\n    # \u5faa\u73af n \u6b21\n    for i in range(n):  # +1\n        print(0)        # +1\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        cout << 0 << endl;    // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        System.out.println(0);    // +1\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {   // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        Console.WriteLine(0);   // +1\n    }\n}\n
    func algorithm(n int) {\n    a := 1      // +1\n    a = a + 1   // +1\n    a = a * 2   // +1\n    // \u5faa\u73af n \u6b21\n    for i := 0; i < n; i++ {   // +1\n        fmt.Println(a)         // +1\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +1\n    a = a + 1 // +1\n    a = a * 2 // +1\n    // \u5faa\u73af n \u6b21\n    for _ in 0 ..< n { // +1\n        print(0) // +1\n    }\n}\n
    function algorithm(n) {\n    var a = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++){ // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        console.log(0); // +1\n    }\n}\n
    function algorithm(n: number): void{\n    var a: number = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // \u5faa\u73af n \u6b21\n    for(let i = 0; i < n; i++){ // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        console.log(0); // +1\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +1\n  a = a + 1; // +1\n  a = a * 2; // +1\n  // \u5faa\u73af n \u6b21\n  for (int i = 0; i < n; i++) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n    print(0); // +1\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;   // +1\n    a = a + 1;      // +1\n    a = a * 2;      // +1\n\n    // \u5faa\u73af n \u6b21\n    for _ in 0..n { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        println!(\"{}\", 0); // +1\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +1\n    a = a + 1;  // +1\n    a = a * 2;  // +1\n    // \u5faa\u73af n \u6b21\n    for (int i = 0; i < n; i++) {   // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        printf(\"%d\", 0);            // +1\n    }\n}\n
    fun algorithm(n: Int) {\n    var a = 1 // +1\n    a = a + 1 // +1\n    a = a * 2 // +1\n    // \u5faa\u73af n \u6b21\n    for (i in 0..<n) { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        println(0) // +1\n    }\n}\n
    def algorithm(n)\n    a = 1       # +1\n    a = a + 1   # +1\n    a = a * 2   # +1\n    # \u5faa\u73af n \u6b21\n    (0...n).each do # +1\n        puts 0      # +1\n    end\nend\n
    fn algorithm(n: usize) void {\n    var a: i32 = 1; // +1\n    a += 1; // +1\n    a *= 2; // +1\n    // \u5faa\u73af n \u6b21\n    for (0..n) |_| { // +1\uff08\u6bcf\u8f6e\u90fd\u6267\u884c i ++\uff09\n        std.debug.print(\"{}\\n\", .{0}); // +1\n    }\n}\n

    \u8bbe\u7b97\u6cd5\u7684\u64cd\u4f5c\u6570\u91cf\u662f\u4e00\u4e2a\u5173\u4e8e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u7684\u51fd\u6570\uff0c\u8bb0\u4e3a \\(T(n)\\) \uff0c\u5219\u4ee5\u4e0a\u51fd\u6570\u7684\u64cd\u4f5c\u6570\u91cf\u4e3a\uff1a

    \\[ T(n) = 3 + 2n \\]

    \\(T(n)\\) \u662f\u4e00\u6b21\u51fd\u6570\uff0c\u8bf4\u660e\u5176\u8fd0\u884c\u65f6\u95f4\u7684\u589e\u957f\u8d8b\u52bf\u662f\u7ebf\u6027\u7684\uff0c\u56e0\u6b64\u5b83\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u7ebf\u6027\u9636\u3002

    \u6211\u4eec\u5c06\u7ebf\u6027\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u8bb0\u4e3a \\(O(n)\\) \uff0c\u8fd9\u4e2a\u6570\u5b66\u7b26\u53f7\u79f0\u4e3a\u5927 \\(O\\) \u8bb0\u53f7\uff08big-\\(O\\) notation\uff09\uff0c\u8868\u793a\u51fd\u6570 \\(T(n)\\) \u7684\u6e10\u8fd1\u4e0a\u754c\uff08asymptotic upper bound\uff09\u3002

    \u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790\u672c\u8d28\u4e0a\u662f\u8ba1\u7b97\u201c\u64cd\u4f5c\u6570\u91cf \\(T(n)\\)\u201d\u7684\u6e10\u8fd1\u4e0a\u754c\uff0c\u5b83\u5177\u6709\u660e\u786e\u7684\u6570\u5b66\u5b9a\u4e49\u3002

    \u51fd\u6570\u6e10\u8fd1\u4e0a\u754c

    \u82e5\u5b58\u5728\u6b63\u5b9e\u6570 \\(c\\) \u548c\u5b9e\u6570 \\(n_0\\) \uff0c\u4f7f\u5f97\u5bf9\u4e8e\u6240\u6709\u7684 \\(n > n_0\\) \uff0c\u5747\u6709 \\(T(n) \\leq c \\cdot f(n)\\) \uff0c\u5219\u53ef\u8ba4\u4e3a \\(f(n)\\) \u7ed9\u51fa\u4e86 \\(T(n)\\) \u7684\u4e00\u4e2a\u6e10\u8fd1\u4e0a\u754c\uff0c\u8bb0\u4e3a \\(T(n) = O(f(n))\\) \u3002

    \u5982\u56fe 2-8 \u6240\u793a\uff0c\u8ba1\u7b97\u6e10\u8fd1\u4e0a\u754c\u5c31\u662f\u5bfb\u627e\u4e00\u4e2a\u51fd\u6570 \\(f(n)\\) \uff0c\u4f7f\u5f97\u5f53 \\(n\\) \u8d8b\u5411\u4e8e\u65e0\u7a77\u5927\u65f6\uff0c\\(T(n)\\) \u548c \\(f(n)\\) \u5904\u4e8e\u76f8\u540c\u7684\u589e\u957f\u7ea7\u522b\uff0c\u4ec5\u76f8\u5dee\u4e00\u4e2a\u5e38\u6570\u9879 \\(c\\) \u7684\u500d\u6570\u3002

    \u56fe 2-8 \u00a0 \u51fd\u6570\u7684\u6e10\u8fd1\u4e0a\u754c

    "},{"location":"chapter_computational_complexity/time_complexity/#233","title":"2.3.3 \u00a0 \u63a8\u7b97\u65b9\u6cd5","text":"

    \u6e10\u8fd1\u4e0a\u754c\u7684\u6570\u5b66\u5473\u513f\u6709\u70b9\u91cd\uff0c\u5982\u679c\u4f60\u611f\u89c9\u6ca1\u6709\u5b8c\u5168\u7406\u89e3\uff0c\u4e5f\u65e0\u987b\u62c5\u5fc3\u3002\u6211\u4eec\u53ef\u4ee5\u5148\u638c\u63e1\u63a8\u7b97\u65b9\u6cd5\uff0c\u5728\u4e0d\u65ad\u7684\u5b9e\u8df5\u4e2d\uff0c\u5c31\u53ef\u4ee5\u9010\u6e10\u9886\u609f\u5176\u6570\u5b66\u610f\u4e49\u3002

    \u6839\u636e\u5b9a\u4e49\uff0c\u786e\u5b9a \\(f(n)\\) \u4e4b\u540e\uff0c\u6211\u4eec\u4fbf\u53ef\u5f97\u5230\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(f(n))\\) \u3002\u90a3\u4e48\u5982\u4f55\u786e\u5b9a\u6e10\u8fd1\u4e0a\u754c \\(f(n)\\) \u5462\uff1f\u603b\u4f53\u5206\u4e3a\u4e24\u6b65\uff1a\u9996\u5148\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf\uff0c\u7136\u540e\u5224\u65ad\u6e10\u8fd1\u4e0a\u754c\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#1","title":"1. \u00a0 \u7b2c\u4e00\u6b65\uff1a\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf","text":"

    \u9488\u5bf9\u4ee3\u7801\uff0c\u9010\u884c\u4ece\u4e0a\u5230\u4e0b\u8ba1\u7b97\u5373\u53ef\u3002\u7136\u800c\uff0c\u7531\u4e8e\u4e0a\u8ff0 \\(c \\cdot f(n)\\) \u4e2d\u7684\u5e38\u6570\u9879 \\(c\\) \u53ef\u4ee5\u53d6\u4efb\u610f\u5927\u5c0f\uff0c\u56e0\u6b64\u64cd\u4f5c\u6570\u91cf \\(T(n)\\) \u4e2d\u7684\u5404\u79cd\u7cfb\u6570\u3001\u5e38\u6570\u9879\u90fd\u53ef\u4ee5\u5ffd\u7565\u3002\u6839\u636e\u6b64\u539f\u5219\uff0c\u53ef\u4ee5\u603b\u7ed3\u51fa\u4ee5\u4e0b\u8ba1\u6570\u7b80\u5316\u6280\u5de7\u3002

    1. \u5ffd\u7565 \\(T(n)\\) \u4e2d\u7684\u5e38\u6570\u9879\u3002\u56e0\u4e3a\u5b83\u4eec\u90fd\u4e0e \\(n\\) \u65e0\u5173\uff0c\u6240\u4ee5\u5bf9\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u4ea7\u751f\u5f71\u54cd\u3002
    2. \u7701\u7565\u6240\u6709\u7cfb\u6570\u3002\u4f8b\u5982\uff0c\u5faa\u73af \\(2n\\) \u6b21\u3001\\(5n + 1\\) \u6b21\u7b49\uff0c\u90fd\u53ef\u4ee5\u7b80\u5316\u8bb0\u4e3a \\(n\\) \u6b21\uff0c\u56e0\u4e3a \\(n\\) \u524d\u9762\u7684\u7cfb\u6570\u5bf9\u65f6\u95f4\u590d\u6742\u5ea6\u6ca1\u6709\u5f71\u54cd\u3002
    3. \u5faa\u73af\u5d4c\u5957\u65f6\u4f7f\u7528\u4e58\u6cd5\u3002\u603b\u64cd\u4f5c\u6570\u91cf\u7b49\u4e8e\u5916\u5c42\u5faa\u73af\u548c\u5185\u5c42\u5faa\u73af\u64cd\u4f5c\u6570\u91cf\u4e4b\u79ef\uff0c\u6bcf\u4e00\u5c42\u5faa\u73af\u4f9d\u7136\u53ef\u4ee5\u5206\u522b\u5957\u7528\u7b2c 1. \u70b9\u548c\u7b2c 2. \u70b9\u7684\u6280\u5de7\u3002

    \u7ed9\u5b9a\u4e00\u4e2a\u51fd\u6570\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u4e0a\u8ff0\u6280\u5de7\u6765\u7edf\u8ba1\u64cd\u4f5c\u6570\u91cf\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    def algorithm(n: int):\n    a = 1      # +0\uff08\u6280\u5de7 1\uff09\n    a = a + n  # +0\uff08\u6280\u5de7 1\uff09\n    # +n\uff08\u6280\u5de7 2\uff09\n    for i in range(5 * n + 1):\n        print(0)\n    # +n*n\uff08\u6280\u5de7 3\uff09\n    for i in range(2 * n):\n        for j in range(n + 1):\n            print(0)\n
    void algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        cout << 0 << endl;\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            cout << 0 << endl;\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        System.out.println(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            System.out.println(0);\n        }\n    }\n}\n
    void Algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        Console.WriteLine(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            Console.WriteLine(0);\n        }\n    }\n}\n
    func algorithm(n int) {\n    a := 1     // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for i := 0; i < 5 * n + 1; i++ {\n        fmt.Println(0)\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for i := 0; i < 2 * n; i++ {\n        for j := 0; j < n + 1; j++ {\n            fmt.Println(0)\n        }\n    }\n}\n
    func algorithm(n: Int) {\n    var a = 1 // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for _ in 0 ..< (5 * n + 1) {\n        print(0)\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for _ in 0 ..< (2 * n) {\n        for _ in 0 ..< (n + 1) {\n            print(0)\n        }\n    }\n}\n
    function algorithm(n) {\n    let a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    function algorithm(n: number): void {\n    let a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (let i = 0; i < 5 * n + 1; i++) {\n        console.log(0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (let i = 0; i < 2 * n; i++) {\n        for (let j = 0; j < n + 1; j++) {\n            console.log(0);\n        }\n    }\n}\n
    void algorithm(int n) {\n  int a = 1; // +0\uff08\u6280\u5de7 1\uff09\n  a = a + n; // +0\uff08\u6280\u5de7 1\uff09\n  // +n\uff08\u6280\u5de7 2\uff09\n  for (int i = 0; i < 5 * n + 1; i++) {\n    print(0);\n  }\n  // +n*n\uff08\u6280\u5de7 3\uff09\n  for (int i = 0; i < 2 * n; i++) {\n    for (int j = 0; j < n + 1; j++) {\n      print(0);\n    }\n  }\n}\n
    fn algorithm(n: i32) {\n    let mut a = 1;     // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;        // +0\uff08\u6280\u5de7 1\uff09\n\n    // +n\uff08\u6280\u5de7 2\uff09\n    for i in 0..(5 * n + 1) {\n        println!(\"{}\", 0);\n    }\n\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for i in 0..(2 * n) {\n        for j in 0..(n + 1) {\n            println!(\"{}\", 0);\n        }\n    }\n}\n
    void algorithm(int n) {\n    int a = 1;  // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n;  // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (int i = 0; i < 5 * n + 1; i++) {\n        printf(\"%d\", 0);\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (int i = 0; i < 2 * n; i++) {\n        for (int j = 0; j < n + 1; j++) {\n            printf(\"%d\", 0);\n        }\n    }\n}\n
    fun algorithm(n: Int) {\n    var a = 1   // +0\uff08\u6280\u5de7 1\uff09\n    a = a + n   // +0\uff08\u6280\u5de7 1\uff09\n    // +n\uff08\u6280\u5de7 2\uff09\n    for (i in 0..<5 * n + 1) {\n        println(0)\n    }\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for (i in 0..<2 * n) {\n        for (j in 0..<n + 1) {\n            println(0)\n        }\n    }\n}\n
    def algorithm(n)\n    a = 1       # +0\uff08\u6280\u5de7 1\uff09\n    a = a + n   # +0\uff08\u6280\u5de7 1\uff09\n    # +n\uff08\u6280\u5de7 2\uff09\n    (0...(5 * n + 1)).each do { puts 0 }\n    # +n*n\uff08\u6280\u5de7 3\uff09\n    (0...(2 * n)).each do\n        (0...(n + 1)).each do { puts 0 }\n    end\nend\n
    fn algorithm(n: usize) void {\n    var a: i32 = 1;     // +0\uff08\u6280\u5de7 1\uff09\n    a = a + @as(i32, @intCast(n));        // +0\uff08\u6280\u5de7 1\uff09\n\n    // +n\uff08\u6280\u5de7 2\uff09\n    for(0..(5 * n + 1)) |_| {\n        std.debug.print(\"{}\\n\", .{0});\n    }\n\n    // +n*n\uff08\u6280\u5de7 3\uff09\n    for(0..(2 * n)) |_| {\n        for(0..(n + 1)) |_| {\n            std.debug.print(\"{}\\n\", .{0});\n        }\n    }\n}\n

    \u4ee5\u4e0b\u516c\u5f0f\u5c55\u793a\u4e86\u4f7f\u7528\u4e0a\u8ff0\u6280\u5de7\u524d\u540e\u7684\u7edf\u8ba1\u7ed3\u679c\uff0c\u4e24\u8005\u63a8\u7b97\u51fa\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n^2)\\) \u3002

    \\[ \\begin{aligned} T(n) & = 2n(n + 1) + (5n + 1) + 2 & \\text{\u5b8c\u6574\u7edf\u8ba1 (-.-|||)} \\newline & = 2n^2 + 7n + 3 \\newline T(n) & = n^2 + n & \\text{\u5077\u61d2\u7edf\u8ba1 (o.O)} \\end{aligned} \\]"},{"location":"chapter_computational_complexity/time_complexity/#2","title":"2. \u00a0 \u7b2c\u4e8c\u6b65\uff1a\u5224\u65ad\u6e10\u8fd1\u4e0a\u754c","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\u7531 \\(T(n)\\) \u4e2d\u6700\u9ad8\u9636\u7684\u9879\u6765\u51b3\u5b9a\u3002\u8fd9\u662f\u56e0\u4e3a\u5728 \\(n\\) \u8d8b\u4e8e\u65e0\u7a77\u5927\u65f6\uff0c\u6700\u9ad8\u9636\u7684\u9879\u5c06\u53d1\u6325\u4e3b\u5bfc\u4f5c\u7528\uff0c\u5176\u4ed6\u9879\u7684\u5f71\u54cd\u90fd\u53ef\u4ee5\u5ffd\u7565\u3002

    \u8868 2-2 \u5c55\u793a\u4e86\u4e00\u4e9b\u4f8b\u5b50\uff0c\u5176\u4e2d\u4e00\u4e9b\u5938\u5f20\u7684\u503c\u662f\u4e3a\u4e86\u5f3a\u8c03\u201c\u7cfb\u6570\u65e0\u6cd5\u64bc\u52a8\u9636\u6570\u201d\u8fd9\u4e00\u7ed3\u8bba\u3002\u5f53 \\(n\\) \u8d8b\u4e8e\u65e0\u7a77\u5927\u65f6\uff0c\u8fd9\u4e9b\u5e38\u6570\u53d8\u5f97\u65e0\u8db3\u8f7b\u91cd\u3002

    \u8868 2-2 \u00a0 \u4e0d\u540c\u64cd\u4f5c\u6570\u91cf\u5bf9\u5e94\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u64cd\u4f5c\u6570\u91cf \\(T(n)\\) \u65f6\u95f4\u590d\u6742\u5ea6 \\(O(f(n))\\) \\(100000\\) \\(O(1)\\) \\(3n + 2\\) \\(O(n)\\) \\(2n^2 + 3n + 2\\) \\(O(n^2)\\) \\(n^3 + 10000n^2\\) \\(O(n^3)\\) \\(2^n + 10000n^{10000}\\) \\(O(2^n)\\)"},{"location":"chapter_computational_complexity/time_complexity/#234","title":"2.3.4 \u00a0 \u5e38\u89c1\u7c7b\u578b","text":"

    \u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u5e38\u89c1\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7c7b\u578b\u5982\u56fe 2-9 \u6240\u793a\uff08\u6309\u7167\u4ece\u4f4e\u5230\u9ad8\u7684\u987a\u5e8f\u6392\u5217\uff09\u3002

    \\[ \\begin{aligned} O(1) < O(\\log n) < O(n) < O(n \\log n) < O(n^2) < O(2^n) < O(n!) \\newline \\text{\u5e38\u6570\u9636} < \\text{\u5bf9\u6570\u9636} < \\text{\u7ebf\u6027\u9636} < \\text{\u7ebf\u6027\u5bf9\u6570\u9636} < \\text{\u5e73\u65b9\u9636} < \\text{\u6307\u6570\u9636} < \\text{\u9636\u4e58\u9636} \\end{aligned} \\]

    \u56fe 2-9 \u00a0 \u5e38\u89c1\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7c7b\u578b

    "},{"location":"chapter_computational_complexity/time_complexity/#1-o1","title":"1. \u00a0 \u5e38\u6570\u9636 \\(O(1)\\)","text":"

    \u5e38\u6570\u9636\u7684\u64cd\u4f5c\u6570\u91cf\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\uff0c\u5373\u4e0d\u968f\u7740 \\(n\\) \u7684\u53d8\u5316\u800c\u53d8\u5316\u3002

    \u5728\u4ee5\u4e0b\u51fd\u6570\u4e2d\uff0c\u5c3d\u7ba1\u64cd\u4f5c\u6570\u91cf size \u53ef\u80fd\u5f88\u5927\uff0c\u4f46\u7531\u4e8e\u5176\u4e0e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u65e0\u5173\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(1)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def constant(n: int) -> int:\n    \"\"\"\u5e38\u6570\u9636\"\"\"\n    count = 0\n    size = 100000\n    for _ in range(size):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u5e38\u6570\u9636 */\nint Constant(int n) {\n    int count = 0;\n    int size = 100000;\n    for (int i = 0; i < size; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u5e38\u6570\u9636 */\nfunc constant(n int) int {\n    count := 0\n    size := 100000\n    for i := 0; i < size; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e38\u6570\u9636 */\nfunc constant(n: Int) -> Int {\n    var count = 0\n    let size = 100_000\n    for _ in 0 ..< size {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e38\u6570\u9636 */\nfunction constant(n) {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u5e38\u6570\u9636 */\nfunction constant(n: number): number {\n    let count = 0;\n    const size = 100000;\n    for (let i = 0; i < size; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n  int count = 0;\n  int size = 100000;\n  for (var i = 0; i < size; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e38\u6570\u9636 */\nfn constant(n: i32) -> i32 {\n    _ = n;\n    let mut count = 0;\n    let size = 100_000;\n    for _ in 0..size {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e38\u6570\u9636 */\nint constant(int n) {\n    int count = 0;\n    int size = 100000;\n    int i = 0;\n    for (int i = 0; i < size; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e38\u6570\u9636 */\nfun constant(n: Int): Int {\n    var count = 0\n    val size = 100000\n    for (i in 0..<size)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u5e38\u6570\u9636 ###\ndef constant(n)\n  count = 0\n  size = 100000\n\n  (0...size).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u5e38\u6570\u9636\nfn constant(n: i32) i32 {\n    _ = n;\n    var count: i32 = 0;\n    const size: i32 = 100_000;\n    var i: i32 = 0;\n    while(i<size) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_computational_complexity/time_complexity/#2-on","title":"2. \u00a0 \u7ebf\u6027\u9636 \\(O(n)\\)","text":"

    \u7ebf\u6027\u9636\u7684\u64cd\u4f5c\u6570\u91cf\u76f8\u5bf9\u4e8e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u4ee5\u7ebf\u6027\u7ea7\u522b\u589e\u957f\u3002\u7ebf\u6027\u9636\u901a\u5e38\u51fa\u73b0\u5728\u5355\u5c42\u5faa\u73af\u4e2d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u9636\"\"\"\n    count = 0\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636 */\nint Linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++)\n        count++;\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636 */\nfunc linear(n int) int {\n    count := 0\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636 */\nfunc linear(n: Int) -> Int {\n    var count = 0\n    for _ in 0 ..< n {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636 */\nfunction linear(n) {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636 */\nfunction linear(n: number): number {\n    let count = 0;\n    for (let i = 0; i < n; i++) count++;\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n  int count = 0;\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636 */\nfn linear(n: i32) -> i32 {\n    let mut count = 0;\n    for _ in 0..n {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636 */\nint linear(int n) {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636 */\nfun linear(n: Int): Int {\n    var count = 0\n    for (i in 0..<n)\n        count++\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636 ###\ndef linear(n)\n  count = 0\n  (0...n).each { count += 1 }\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\nfn linear(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u904d\u5386\u6570\u7ec4\u548c\u904d\u5386\u94fe\u8868\u7b49\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u6570\u7ec4\u6216\u94fe\u8868\u7684\u957f\u5ea6\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def array_traversal(nums: list[int]) -> int:\n    \"\"\"\u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for num in nums:\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(vector<int> &nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int num : nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint ArrayTraversal(int[] nums) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    foreach (int num in nums) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums []int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for range nums {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunc arrayTraversal(nums: [Int]) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfunction arrayTraversal(nums: number[]): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (let i = 0; i < nums.length; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(List<int> nums) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for (var _num in nums) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfn array_traversal(nums: &[i32]) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for _ in nums {\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nint arrayTraversal(int *nums, int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09 */\nfun arrayTraversal(nums: IntArray): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (num in nums) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09###\ndef array_traversal(nums)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n  for num in nums\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u9636\uff08\u904d\u5386\u6570\u7ec4\uff09\nfn arrayTraversal(nums: []i32) i32 {\n    var count: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u7ec4\u957f\u5ea6\u6210\u6b63\u6bd4\n    for (nums) |_| {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u9700\u6839\u636e\u8f93\u5165\u6570\u636e\u7684\u7c7b\u578b\u6765\u5177\u4f53\u786e\u5b9a\u3002\u6bd4\u5982\u5728\u7b2c\u4e00\u4e2a\u793a\u4f8b\u4e2d\uff0c\u53d8\u91cf \\(n\\) \u4e3a\u8f93\u5165\u6570\u636e\u5927\u5c0f\uff1b\u5728\u7b2c\u4e8c\u4e2a\u793a\u4f8b\u4e2d\uff0c\u6570\u7ec4\u957f\u5ea6 \\(n\\) \u4e3a\u6570\u636e\u5927\u5c0f\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#3-on2","title":"3. \u00a0 \u5e73\u65b9\u9636 \\(O(n^2)\\)","text":"

    \u5e73\u65b9\u9636\u7684\u64cd\u4f5c\u6570\u91cf\u76f8\u5bf9\u4e8e\u8f93\u5165\u6570\u636e\u5927\u5c0f \\(n\\) \u4ee5\u5e73\u65b9\u7ea7\u522b\u589e\u957f\u3002\u5e73\u65b9\u9636\u901a\u5e38\u51fa\u73b0\u5728\u5d4c\u5957\u5faa\u73af\u4e2d\uff0c\u5916\u5c42\u5faa\u73af\u548c\u5185\u5c42\u5faa\u73af\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n)\\) \uff0c\u56e0\u6b64\u603b\u4f53\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def quadratic(n: int) -> int:\n    \"\"\"\u5e73\u65b9\u9636\"\"\"\n    count = 0\n    # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i in range(n):\n        for j in range(n):\n            count += 1\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636 */\nint Quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n int) int {\n    count := 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for i := 0; i < n; i++ {\n        for j := 0; j < n; j++ {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636 */\nfunc quadratic(n: Int) -> Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0 ..< n {\n        for _ in 0 ..< n {\n            count += 1\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n) {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636 */\nfunction quadratic(n: number): number {\n    let count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n  int count = 0;\n  // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for (int i = 0; i < n; i++) {\n    for (int j = 0; j < n; j++) {\n      count++;\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636 */\nfn quadratic(n: i32) -> i32 {\n    let mut count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for _ in 0..n {\n        for _ in 0..n {\n            count += 1;\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636 */\nint quadratic(int n) {\n    int count = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            count++;\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636 */\nfun quadratic(n: Int): Int {\n    var count = 0\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    for (i in 0..<n) {\n        for (j in 0..<n) {\n            count++\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636 ###\ndef quadratic(n)\n  count = 0\n\n  # \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n  for i in 0...n\n    for j in 0...n\n      count += 1\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\nfn quadratic(n: i32) i32 {\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u5faa\u73af\u6b21\u6570\u4e0e\u6570\u636e\u5927\u5c0f n \u6210\u5e73\u65b9\u5173\u7cfb\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < n) : (j += 1) {\n            count += 1;\n        }\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-10 \u5bf9\u6bd4\u4e86\u5e38\u6570\u9636\u3001\u7ebf\u6027\u9636\u548c\u5e73\u65b9\u9636\u4e09\u79cd\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    \u56fe 2-10 \u00a0 \u5e38\u6570\u9636\u3001\u7ebf\u6027\u9636\u548c\u5e73\u65b9\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u4ee5\u5192\u6ce1\u6392\u5e8f\u4e3a\u4f8b\uff0c\u5916\u5c42\u5faa\u73af\u6267\u884c \\(n - 1\\) \u6b21\uff0c\u5185\u5c42\u5faa\u73af\u6267\u884c \\(n-1\\)\u3001\\(n-2\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \u6b21\uff0c\u5e73\u5747\u4e3a \\(n / 2\\) \u6b21\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O((n - 1) n / 2) = O(n^2)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def bubble_sort(nums: list[int]) -> int:\n    \"\"\"\u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\"\"\"\n    count = 0  # \u8ba1\u6570\u5668\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(len(nums) - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp: int = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3  # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n    return count\n
    time_complexity.cpp
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(vector<int> &nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int[] nums) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint BubbleSort(int[] nums) {\n    int count = 0;  // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums []int) int {\n    count := 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                tmp := nums[j]\n                nums[j] = nums[j+1]\n                nums[j+1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunc bubbleSort(nums: inout [Int]) -> Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = tmp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums) {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfunction bubbleSort(nums: number[]): number {\n    let count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(List<int> nums) {\n  int count = 0; // \u8ba1\u6570\u5668\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (var i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (var j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      }\n    }\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfn bubble_sort(nums: &mut [i32]) -> i32 {\n    let mut count = 0; // \u8ba1\u6570\u5668\n\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    count\n}\n
    time_complexity.c
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nint bubbleSort(int *nums, int n) {\n    int count = 0; // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = n - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3; // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09 */\nfun bubbleSort(nums: IntArray): Int {\n    var count = 0 // \u8ba1\u6570\u5668\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                count += 3 // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09###\ndef bubble_sort(nums)\n  count = 0  # \u8ba1\u6570\u5668\n\n  # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for i in (nums.length - 1).downto(0)\n    # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for j in 0...i\n      if nums[j] > nums[j + 1]\n        # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        tmp = nums[j]\n        nums[j] = nums[j + 1]\n        nums[j + 1] = tmp\n        count += 3 # \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n      end\n    end\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5e73\u65b9\u9636\uff08\u5192\u6ce1\u6392\u5e8f\uff09\nfn bubbleSort(nums: []i32) i32 {\n    var count: i32 = 0;  // \u8ba1\u6570\u5668 \n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: i32 = @as(i32, @intCast(nums.len)) - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                count += 3;  // \u5143\u7d20\u4ea4\u6362\u5305\u542b 3 \u4e2a\u5355\u5143\u64cd\u4f5c\n            }\n        }\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_computational_complexity/time_complexity/#4-o2n","title":"4. \u00a0 \u6307\u6570\u9636 \\(O(2^n)\\)","text":"

    \u751f\u7269\u5b66\u7684\u201c\u7ec6\u80de\u5206\u88c2\u201d\u662f\u6307\u6570\u9636\u589e\u957f\u7684\u5178\u578b\u4f8b\u5b50\uff1a\u521d\u59cb\u72b6\u6001\u4e3a \\(1\\) \u4e2a\u7ec6\u80de\uff0c\u5206\u88c2\u4e00\u8f6e\u540e\u53d8\u4e3a \\(2\\) \u4e2a\uff0c\u5206\u88c2\u4e24\u8f6e\u540e\u53d8\u4e3a \\(4\\) \u4e2a\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u5206\u88c2 \\(n\\) \u8f6e\u540e\u6709 \\(2^n\\) \u4e2a\u7ec6\u80de\u3002

    \u56fe 2-11 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6a21\u62df\u4e86\u7ec6\u80de\u5206\u88c2\u7684\u8fc7\u7a0b\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exponential(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    base = 1\n    # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in range(n):\n        for _ in range(base):\n            count += 1\n        base *= 2\n    # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0, base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Exponential(int n) {\n    int count = 0, bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc exponential(n int) int {\n    count, base := 0, 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for i := 0; i < n; i++ {\n        for j := 0; j < base; j++ {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc exponential(n: Int) -> Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0 ..< n {\n        for _ in 0 ..< base {\n            count += 1\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n) {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction exponential(n: number): number {\n    let count = 0,\n        base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < base; j++) {\n            count++;\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n  int count = 0, base = 1;\n  // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  for (var i = 0; i < n; i++) {\n    for (var j = 0; j < base; j++) {\n      count++;\n    }\n    base *= 2;\n  }\n  // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  return count;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn exponential(n: i32) -> i32 {\n    let mut count = 0;\n    let mut base = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for _ in 0..n {\n        for _ in 0..base {\n            count += 1\n        }\n        base *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    count\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint exponential(int n) {\n    int count = 0;\n    int bas = 1;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < bas; j++) {\n            count++;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun exponential(n: Int): Int {\n    var count = 0\n    var base = 1\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    for (i in 0..<n) {\n        for (j in 0..<base) {\n            count++\n        }\n        base *= 2\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef exponential(n)\n  count, base = 0, 1\n\n  # \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n  (0...n).each do\n    (0...base).each { count += 1 }\n    base *= 2\n  end\n\n  # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n  count\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn exponential(n: i32) i32 {\n    var count: i32 = 0;\n    var bas: i32 = 1;\n    var i: i32 = 0;\n    // \u7ec6\u80de\u6bcf\u8f6e\u4e00\u5206\u4e3a\u4e8c\uff0c\u5f62\u6210\u6570\u5217 1, 2, 4, 8, ..., 2^(n-1)\n    while (i < n) : (i += 1) {\n        var j: i32 = 0;\n        while (j < bas) : (j += 1) {\n            count += 1;\n        }\n        bas *= 2;\n    }\n    // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-11 \u00a0 \u6307\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u5728\u5b9e\u9645\u7b97\u6cd5\u4e2d\uff0c\u6307\u6570\u9636\u5e38\u51fa\u73b0\u4e8e\u9012\u5f52\u51fd\u6570\u4e2d\u3002\u4f8b\u5982\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u5176\u9012\u5f52\u5730\u4e00\u5206\u4e3a\u4e8c\uff0c\u7ecf\u8fc7 \\(n\\) \u6b21\u5206\u88c2\u540e\u505c\u6b62\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def exp_recur(n: int) -> int:\n    \"\"\"\u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 1:\n        return 1\n    return exp_recur(n - 1) + exp_recur(n - 1) + 1\n
    time_complexity.cpp
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.java
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.cs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint ExpRecur(int n) {\n    if (n == 1) return 1;\n    return ExpRecur(n - 1) + ExpRecur(n - 1) + 1;\n}\n
    time_complexity.go
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc expRecur(n int) int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n-1) + expRecur(n-1) + 1\n}\n
    time_complexity.swift
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc expRecur(n: Int) -> Int {\n    if n == 1 {\n        return 1\n    }\n    return expRecur(n: n - 1) + expRecur(n: n - 1) + 1\n}\n
    time_complexity.js
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n) {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.ts
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction expRecur(n: number): number {\n    if (n === 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.dart
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n  if (n == 1) return 1;\n  return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.rs
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn exp_recur(n: i32) -> i32 {\n    if n == 1 {\n        return 1;\n    }\n    exp_recur(n - 1) + exp_recur(n - 1) + 1\n}\n
    time_complexity.c
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint expRecur(int n) {\n    if (n == 1)\n        return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    time_complexity.kt
    /* \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun expRecur(n: Int): Int {\n    if (n == 1) {\n        return 1\n    }\n    return expRecur(n - 1) + expRecur(n - 1) + 1\n}\n
    time_complexity.rb
    ### \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef exp_recur(n)\n  return 1 if n == 1\n  exp_recur(n - 1) + exp_recur(n - 1) + 1\nend\n
    time_complexity.zig
    // \u6307\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn expRecur(n: i32) i32 {\n    if (n == 1) return 1;\n    return expRecur(n - 1) + expRecur(n - 1) + 1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6307\u6570\u9636\u589e\u957f\u975e\u5e38\u8fc5\u901f\uff0c\u5728\u7a77\u4e3e\u6cd5\uff08\u66b4\u529b\u641c\u7d22\u3001\u56de\u6eaf\u7b49\uff09\u4e2d\u6bd4\u8f83\u5e38\u89c1\u3002\u5bf9\u4e8e\u6570\u636e\u89c4\u6a21\u8f83\u5927\u7684\u95ee\u9898\uff0c\u6307\u6570\u9636\u662f\u4e0d\u53ef\u63a5\u53d7\u7684\uff0c\u901a\u5e38\u9700\u8981\u4f7f\u7528\u52a8\u6001\u89c4\u5212\u6216\u8d2a\u5fc3\u7b97\u6cd5\u7b49\u6765\u89e3\u51b3\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#5-olog-n","title":"5. \u00a0 \u5bf9\u6570\u9636 \\(O(\\log n)\\)","text":"

    \u4e0e\u6307\u6570\u9636\u76f8\u53cd\uff0c\u5bf9\u6570\u9636\u53cd\u6620\u4e86\u201c\u6bcf\u8f6e\u7f29\u51cf\u5230\u4e00\u534a\u201d\u7684\u60c5\u51b5\u3002\u8bbe\u8f93\u5165\u6570\u636e\u5927\u5c0f\u4e3a \\(n\\) \uff0c\u7531\u4e8e\u6bcf\u8f6e\u7f29\u51cf\u5230\u4e00\u534a\uff0c\u56e0\u6b64\u5faa\u73af\u6b21\u6570\u662f \\(\\log_2 n\\) \uff0c\u5373 \\(2^n\\) \u7684\u53cd\u51fd\u6570\u3002

    \u56fe 2-12 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6a21\u62df\u4e86\u201c\u6bcf\u8f6e\u7f29\u51cf\u5230\u4e00\u534a\u201d\u7684\u8fc7\u7a0b\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log_2 n)\\) \uff0c\u7b80\u8bb0\u4e3a \\(O(\\log n)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def logarithmic(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\"\"\"\n    count = 0\n    while n > 1:\n        n = n / 2\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint Logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n /= 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09*/\nfunc logarithmic(n int) int {\n    count := 0\n    for n > 1 {\n        n = n / 2\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunc logarithmic(n: Int) -> Int {\n    var count = 0\n    var n = n\n    while n > 1 {\n        n = n / 2\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n) {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfunction logarithmic(n: number): number {\n    let count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n  int count = 0;\n  while (n > 1) {\n    n = n ~/ 2;\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfn logarithmic(mut n: i32) -> i32 {\n    let mut count = 0;\n    while n > 1 {\n        n = n / 2;\n        count += 1;\n    }\n    count\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nint logarithmic(int n) {\n    int count = 0;\n    while (n > 1) {\n        n = n / 2;\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09 */\nfun logarithmic(n: Int): Int {\n    var n1 = n\n    var count = 0\n    while (n1 > 1) {\n        n1 /= 2\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09###\ndef logarithmic(n)\n  count = 0\n\n  while n > 1\n    n /= 2\n    count += 1\n  end\n\n  count\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u5faa\u73af\u5b9e\u73b0\uff09\nfn logarithmic(n: i32) i32 {\n    var count: i32 = 0;\n    var n_var = n;\n    while (n_var > 1)\n    {\n        n_var = n_var / 2;\n        count +=1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-12 \u00a0 \u5bf9\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u4e0e\u6307\u6570\u9636\u7c7b\u4f3c\uff0c\u5bf9\u6570\u9636\u4e5f\u5e38\u51fa\u73b0\u4e8e\u9012\u5f52\u51fd\u6570\u4e2d\u3002\u4ee5\u4e0b\u4ee3\u7801\u5f62\u6210\u4e86\u4e00\u68f5\u9ad8\u5ea6\u4e3a \\(\\log_2 n\\) \u7684\u9012\u5f52\u6811\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def log_recur(n: int) -> int:\n    \"\"\"\u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n <= 1:\n        return 0\n    return log_recur(n / 2) + 1\n
    time_complexity.cpp
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.java
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.cs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint LogRecur(int n) {\n    if (n <= 1) return 0;\n    return LogRecur(n / 2) + 1;\n}\n
    time_complexity.go
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09*/\nfunc logRecur(n int) int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n/2) + 1\n}\n
    time_complexity.swift
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc logRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 0\n    }\n    return logRecur(n: n / 2) + 1\n}\n
    time_complexity.js
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n) {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.ts
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction logRecur(n: number): number {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.dart
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n  if (n <= 1) return 0;\n  return logRecur(n ~/ 2) + 1;\n}\n
    time_complexity.rs
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 0;\n    }\n    log_recur(n / 2) + 1\n}\n
    time_complexity.c
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint logRecur(int n) {\n    if (n <= 1)\n        return 0;\n    return logRecur(n / 2) + 1;\n}\n
    time_complexity.kt
    /* \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun logRecur(n: Int): Int {\n    if (n <= 1)\n        return 0\n    return logRecur(n / 2) + 1\n}\n
    time_complexity.rb
    ### \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef log_recur(n)\n  return 0 unless n > 1\n  log_recur(n / 2) + 1\nend\n
    time_complexity.zig
    // \u5bf9\u6570\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn logRecur(n: i32) i32 {\n    if (n <= 1) return 0;\n    return logRecur(n / 2) + 1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5bf9\u6570\u9636\u5e38\u51fa\u73b0\u4e8e\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u7b97\u6cd5\u4e2d\uff0c\u4f53\u73b0\u4e86\u201c\u4e00\u5206\u4e3a\u591a\u201d\u548c\u201c\u5316\u7e41\u4e3a\u7b80\u201d\u7684\u7b97\u6cd5\u601d\u60f3\u3002\u5b83\u589e\u957f\u7f13\u6162\uff0c\u662f\u4ec5\u6b21\u4e8e\u5e38\u6570\u9636\u7684\u7406\u60f3\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    \\(O(\\log n)\\) \u7684\u5e95\u6570\u662f\u591a\u5c11\uff1f

    \u51c6\u786e\u6765\u8bf4\uff0c\u201c\u4e00\u5206\u4e3a \\(m\\)\u201d\u5bf9\u5e94\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(\\log_m n)\\) \u3002\u800c\u901a\u8fc7\u5bf9\u6570\u6362\u5e95\u516c\u5f0f\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5177\u6709\u4e0d\u540c\u5e95\u6570\u3001\u76f8\u7b49\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a

    \\[ O(\\log_m n) = O(\\log_k n / \\log_k m) = O(\\log_k n) \\]

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5e95\u6570 \\(m\\) \u53ef\u4ee5\u5728\u4e0d\u5f71\u54cd\u590d\u6742\u5ea6\u7684\u524d\u63d0\u4e0b\u8f6c\u6362\u3002\u56e0\u6b64\u6211\u4eec\u901a\u5e38\u4f1a\u7701\u7565\u5e95\u6570 \\(m\\) \uff0c\u5c06\u5bf9\u6570\u9636\u76f4\u63a5\u8bb0\u4e3a \\(O(\\log n)\\) \u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#6-on-log-n","title":"6. \u00a0 \u7ebf\u6027\u5bf9\u6570\u9636 \\(O(n \\log n)\\)","text":"

    \u7ebf\u6027\u5bf9\u6570\u9636\u5e38\u51fa\u73b0\u4e8e\u5d4c\u5957\u5faa\u73af\u4e2d\uff0c\u4e24\u5c42\u5faa\u73af\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5206\u522b\u4e3a \\(O(\\log n)\\) \u548c \\(O(n)\\) \u3002\u76f8\u5173\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def linear_log_recur(n: int) -> int:\n    \"\"\"\u7ebf\u6027\u5bf9\u6570\u9636\"\"\"\n    if n <= 1:\n        return 1\n    count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2)\n    for _ in range(n):\n        count += 1\n    return count\n
    time_complexity.cpp
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint LinearLogRecur(int n) {\n    if (n <= 1) return 1;\n    int count = LinearLogRecur(n / 2) + LinearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n int) int {\n    if n <= 1 {\n        return 1\n    }\n    count := linearLogRecur(n/2) + linearLogRecur(n/2)\n    for i := 0; i < n; i++ {\n        count++\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunc linearLogRecur(n: Int) -> Int {\n    if n <= 1 {\n        return 1\n    }\n    var count = linearLogRecur(n: n / 2) + linearLogRecur(n: n / 2)\n    for _ in stride(from: 0, to: n, by: 1) {\n        count += 1\n    }\n    return count\n}\n
    time_complexity.js
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n) {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfunction linearLogRecur(n: number): number {\n    if (n <= 1) return 1;\n    let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (let i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n  if (n <= 1) return 1;\n  int count = linearLogRecur(n ~/ 2) + linearLogRecur(n ~/ 2);\n  for (var i = 0; i < n; i++) {\n    count++;\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfn linear_log_recur(n: i32) -> i32 {\n    if n <= 1 {\n        return 1;\n    }\n    let mut count = linear_log_recur(n / 2) + linear_log_recur(n / 2);\n    for _ in 0..n as i32 {\n        count += 1;\n    }\n    return count;\n}\n
    time_complexity.c
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nint linearLogRecur(int n) {\n    if (n <= 1)\n        return 1;\n    int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    for (int i = 0; i < n; i++) {\n        count++;\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u7ebf\u6027\u5bf9\u6570\u9636 */\nfun linearLogRecur(n: Int): Int {\n    if (n <= 1)\n        return 1\n    var count = linearLogRecur(n / 2) + linearLogRecur(n / 2)\n    for (i in 0..<n) {\n        count++\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u7ebf\u6027\u5bf9\u6570\u9636 ###\ndef linear_log_recur(n)\n  return 1 unless n > 1\n\n  count = linear_log_recur(n / 2) + linear_log_recur(n / 2)\n  (0...n).each { count += 1 }\n\n  count\nend\n
    time_complexity.zig
    // \u7ebf\u6027\u5bf9\u6570\u9636\nfn linearLogRecur(n: i32) i32 {\n    if (n <= 1) return 1;\n    var count: i32 = linearLogRecur(n / 2) + linearLogRecur(n / 2);\n    var i: i32 = 0;\n    while (i < n) : (i += 1) {\n        count += 1;\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-13 \u5c55\u793a\u4e86\u7ebf\u6027\u5bf9\u6570\u9636\u7684\u751f\u6210\u65b9\u5f0f\u3002\u4e8c\u53c9\u6811\u7684\u6bcf\u4e00\u5c42\u7684\u64cd\u4f5c\u603b\u6570\u90fd\u4e3a \\(n\\) \uff0c\u6811\u5171\u6709 \\(\\log_2 n + 1\\) \u5c42\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    \u56fe 2-13 \u00a0 \u7ebf\u6027\u5bf9\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u4e3b\u6d41\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u4e3a \\(O(n \\log n)\\) \uff0c\u4f8b\u5982\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u3001\u5806\u6392\u5e8f\u7b49\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#7-on","title":"7. \u00a0 \u9636\u4e58\u9636 \\(O(n!)\\)","text":"

    \u9636\u4e58\u9636\u5bf9\u5e94\u6570\u5b66\u4e0a\u7684\u201c\u5168\u6392\u5217\u201d\u95ee\u9898\u3002\u7ed9\u5b9a \\(n\\) \u4e2a\u4e92\u4e0d\u91cd\u590d\u7684\u5143\u7d20\uff0c\u6c42\u5176\u6240\u6709\u53ef\u80fd\u7684\u6392\u5217\u65b9\u6848\uff0c\u65b9\u6848\u6570\u91cf\u4e3a\uff1a

    \\[ n! = n \\times (n - 1) \\times (n - 2) \\times \\dots \\times 2 \\times 1 \\]

    \u9636\u4e58\u901a\u5e38\u4f7f\u7528\u9012\u5f52\u5b9e\u73b0\u3002\u5982\u56fe 2-14 \u548c\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff0c\u7b2c\u4e00\u5c42\u5206\u88c2\u51fa \\(n\\) \u4e2a\uff0c\u7b2c\u4e8c\u5c42\u5206\u88c2\u51fa \\(n - 1\\) \u4e2a\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u7b2c \\(n\\) \u5c42\u65f6\u505c\u6b62\u5206\u88c2\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig time_complexity.py
    def factorial_recur(n: int) -> int:\n    \"\"\"\u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\"\"\"\n    if n == 0:\n        return 1\n    count = 0\n    # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in range(n):\n        count += factorial_recur(n - 1)\n    return count\n
    time_complexity.cpp
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.java
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.cs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint FactorialRecur(int n) {\n    if (n == 0) return 1;\n    int count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (int i = 0; i < n; i++) {\n        count += FactorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.go
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n int) int {\n    if n == 0 {\n        return 1\n    }\n    count := 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for i := 0; i < n; i++ {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.swift
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunc factorialRecur(n: Int) -> Int {\n    if n == 0 {\n        return 1\n    }\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0 ..< n {\n        count += factorialRecur(n: n - 1)\n    }\n    return count\n}\n
    time_complexity.js
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n) {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.ts
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfunction factorialRecur(n: number): number {\n    if (n === 0) return 1;\n    let count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (let i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.dart
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n  if (n == 0) return 1;\n  int count = 0;\n  // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  for (var i = 0; i < n; i++) {\n    count += factorialRecur(n - 1);\n  }\n  return count;\n}\n
    time_complexity.rs
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfn factorial_recur(n: i32) -> i32 {\n    if n == 0 {\n        return 1;\n    }\n    let mut count = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for _ in 0..n {\n        count += factorial_recur(n - 1);\n    }\n    count\n}\n
    time_complexity.c
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nint factorialRecur(int n) {\n    if (n == 0)\n        return 1;\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    time_complexity.kt
    /* \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09 */\nfun factorialRecur(n: Int): Int {\n    if (n == 0)\n        return 1\n    var count = 0\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    for (i in 0..<n) {\n        count += factorialRecur(n - 1)\n    }\n    return count\n}\n
    time_complexity.rb
    ### \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09###\ndef factorial_recur(n)\n  return 1 if n == 0\n\n  count = 0\n  # \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n  (0...n).each { count += factorial_recur(n - 1) }\n\n  count\nend\n
    time_complexity.zig
    // \u9636\u4e58\u9636\uff08\u9012\u5f52\u5b9e\u73b0\uff09\nfn factorialRecur(n: i32) i32 {\n    if (n == 0) return 1;\n    var count: i32 = 0;\n    var i: i32 = 0;\n    // \u4ece 1 \u4e2a\u5206\u88c2\u51fa n \u4e2a\n    while (i < n) : (i += 1) {\n        count += factorialRecur(n - 1);\n    }\n    return count;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 2-14 \u00a0 \u9636\u4e58\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6

    \u8bf7\u6ce8\u610f\uff0c\u56e0\u4e3a\u5f53 \\(n \\geq 4\\) \u65f6\u6052\u6709 \\(n! > 2^n\\) \uff0c\u6240\u4ee5\u9636\u4e58\u9636\u6bd4\u6307\u6570\u9636\u589e\u957f\u5f97\u66f4\u5feb\uff0c\u5728 \\(n\\) \u8f83\u5927\u65f6\u4e5f\u662f\u4e0d\u53ef\u63a5\u53d7\u7684\u3002

    "},{"location":"chapter_computational_complexity/time_complexity/#235","title":"2.3.5 \u00a0 \u6700\u5dee\u3001\u6700\u4f73\u3001\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6","text":"

    \u7b97\u6cd5\u7684\u65f6\u95f4\u6548\u7387\u5f80\u5f80\u4e0d\u662f\u56fa\u5b9a\u7684\uff0c\u800c\u662f\u4e0e\u8f93\u5165\u6570\u636e\u7684\u5206\u5e03\u6709\u5173\u3002\u5047\u8bbe\u8f93\u5165\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4 nums \uff0c\u5176\u4e2d nums \u7531\u4ece \\(1\\) \u81f3 \\(n\\) \u7684\u6570\u5b57\u7ec4\u6210\uff0c\u6bcf\u4e2a\u6570\u5b57\u53ea\u51fa\u73b0\u4e00\u6b21\uff1b\u4f46\u5143\u7d20\u987a\u5e8f\u662f\u968f\u673a\u6253\u4e71\u7684\uff0c\u4efb\u52a1\u76ee\u6807\u662f\u8fd4\u56de\u5143\u7d20 \\(1\\) \u7684\u7d22\u5f15\u3002\u6211\u4eec\u53ef\u4ee5\u5f97\u51fa\u4ee5\u4e0b\u7ed3\u8bba\u3002

    • \u5f53 nums = [?, ?, ..., 1] \uff0c\u5373\u5f53\u672b\u5c3e\u5143\u7d20\u662f \\(1\\) \u65f6\uff0c\u9700\u8981\u5b8c\u6574\u904d\u5386\u6570\u7ec4\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u3002
    • \u5f53 nums = [1, ?, ?, ...] \uff0c\u5373\u5f53\u9996\u4e2a\u5143\u7d20\u4e3a \\(1\\) \u65f6\uff0c\u65e0\u8bba\u6570\u7ec4\u591a\u957f\u90fd\u4e0d\u9700\u8981\u7ee7\u7eed\u904d\u5386\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 \\(\\Omega(1)\\) \u3002

    \u201c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u201d\u5bf9\u5e94\u51fd\u6570\u6e10\u8fd1\u4e0a\u754c\uff0c\u4f7f\u7528\u5927 \\(O\\) \u8bb0\u53f7\u8868\u793a\u3002\u76f8\u5e94\u5730\uff0c\u201c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u201d\u5bf9\u5e94\u51fd\u6570\u6e10\u8fd1\u4e0b\u754c\uff0c\u7528 \\(\\Omega\\) \u8bb0\u53f7\u8868\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig worst_best_time_complexity.py
    def random_numbers(n: int) -> list[int]:\n    \"\"\"\u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71\"\"\"\n    # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n    nums = [i for i in range(1, n + 1)]\n    # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    random.shuffle(nums)\n    return nums\n\ndef find_one(nums: list[int]) -> int:\n    \"\"\"\u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\"\"\"\n    for i in range(len(nums)):\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1:\n            return i\n    return -1\n
    worst_best_time_complexity.cpp
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nvector<int> randomNumbers(int n) {\n    vector<int> nums(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u4f7f\u7528\u7cfb\u7edf\u65f6\u95f4\u751f\u6210\u968f\u673a\u79cd\u5b50\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    shuffle(nums.begin(), nums.end(), default_random_engine(seed));\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(vector<int> &nums) {\n    for (int i = 0; i < nums.size(); i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.java
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] randomNumbers(int n) {\n    Integer[] nums = new Integer[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    Collections.shuffle(Arrays.asList(nums));\n    // Integer[] -> int[]\n    int[] res = new int[n];\n    for (int i = 0; i < n; i++) {\n        res[i] = nums[i];\n    }\n    return res;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int[] nums) {\n    for (int i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.cs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint[] RandomNumbers(int n) {\n    int[] nums = new int[n];\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = 0; i < nums.Length; i++) {\n        int index = new Random().Next(i, nums.Length);\n        (nums[i], nums[index]) = (nums[index], nums[i]);\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint FindOne(int[] nums) {\n    for (int i = 0; i < nums.Length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.go
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n int) []int {\n    nums := make([]int, n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for i := 0; i < n; i++ {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    rand.Shuffle(len(nums), func(i, j int) {\n        nums[i], nums[j] = nums[j], nums[i]\n    })\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums []int) int {\n    for i := 0; i < len(nums); i++ {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.swift
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunc randomNumbers(n: Int) -> [Int] {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    var nums = Array(1 ... n)\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    return nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunc findOne(nums: [Int]) -> Int {\n    for i in nums.indices {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return i\n        }\n    }\n    return -1\n}\n
    worst_best_time_complexity.js
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n) {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums) {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.ts
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfunction randomNumbers(n: number): number[] {\n    const nums = Array(n);\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (let i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (let i = 0; i < n; i++) {\n        const r = Math.floor(Math.random() * (i + 1));\n        const temp = nums[i];\n        nums[i] = nums[r];\n        nums[r] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfunction findOne(nums: number[]): number {\n    for (let i = 0; i < nums.length; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] === 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n
    worst_best_time_complexity.dart
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nList<int> randomNumbers(int n) {\n  final nums = List.filled(n, 0);\n  // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n  for (var i = 0; i < n; i++) {\n    nums[i] = i + 1;\n  }\n  // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle();\n\n  return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(List<int> nums) {\n  for (var i = 0; i < nums.length; i++) {\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    if (nums[i] == 1) return i;\n  }\n\n  return -1;\n}\n
    worst_best_time_complexity.rs
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfn random_numbers(n: i32) -> Vec<i32> {\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    let mut nums = (1..=n).collect::<Vec<i32>>();\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle(&mut thread_rng());\n    nums\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfn find_one(nums: &[i32]) -> Option<usize> {\n    for i in 0..nums.len() {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if nums[i] == 1 {\n            return Some(i);\n        }\n    }\n    None\n}\n
    worst_best_time_complexity.c
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nint *randomNumbers(int n) {\n    // \u5206\u914d\u5806\u533a\u5185\u5b58\uff08\u521b\u5efa\u4e00\u7ef4\u53ef\u53d8\u957f\u6570\u7ec4\uff1a\u6570\u7ec4\u4e2d\u5143\u7d20\u6570\u91cf\u4e3a n \uff0c\u5143\u7d20\u7c7b\u578b\u4e3a int \uff09\n    int *nums = (int *)malloc(n * sizeof(int));\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (int i = 0; i < n; i++) {\n        nums[i] = i + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    for (int i = n - 1; i > 0; i--) {\n        int j = rand() % (i + 1);\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n    return nums;\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nint findOne(int *nums, int n) {\n    for (int i = 0; i < n; i++) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i;\n    }\n    return -1;\n}\n
    worst_best_time_complexity.kt
    /* \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71 */\nfun randomNumbers(n: Int): Array<Int?> {\n    val nums = IntArray(n)\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (i in 0..<n) {\n        nums[i] = i + 1\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    nums.shuffle()\n    val res = arrayOfNulls<Int>(n)\n    for (i in 0..<n) {\n        res[i] = nums[i]\n    }\n    return res\n}\n\n/* \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 */\nfun findOne(nums: Array<Int?>): Int {\n    for (i in nums.indices) {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (nums[i] == 1)\n            return i\n    }\n    return -1\n}\n
    worst_best_time_complexity.rb
    ### \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a: 1, 2, ..., n \uff0c\u987a\u5e8f\u88ab\u6253\u4e71 ###\ndef random_numbers(n)\n  # \u751f\u6210\u6570\u7ec4 nums =: 1, 2, 3, ..., n\n  nums = Array.new(n) { |i| i + 1 }\n  # \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n  nums.shuffle!\nend\n\n### \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15 ###\ndef find_one(nums)\n  for i in 0...nums.length\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n    # \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n    return i if nums[i] == 1\n  end\n\n  -1\nend\n
    worst_best_time_complexity.zig
    // \u751f\u6210\u4e00\u4e2a\u6570\u7ec4\uff0c\u5143\u7d20\u4e3a { 1, 2, ..., n }\uff0c\u987a\u5e8f\u88ab\u6253\u4e71\nfn randomNumbers(comptime n: usize) [n]i32 {\n    var nums: [n]i32 = undefined;\n    // \u751f\u6210\u6570\u7ec4 nums = { 1, 2, 3, ..., n }\n    for (&nums, 0..) |*num, i| {\n        num.* = @as(i32, @intCast(i)) + 1;\n    }\n    // \u968f\u673a\u6253\u4e71\u6570\u7ec4\u5143\u7d20\n    const rand = std.crypto.random;\n    rand.shuffle(i32, &nums);\n    return nums;\n}\n\n// \u67e5\u627e\u6570\u7ec4 nums \u4e2d\u6570\u5b57 1 \u6240\u5728\u7d22\u5f15\nfn findOne(nums: []i32) i32 {\n    for (nums, 0..) |num, i| {\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5934\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 O(1)\n        // \u5f53\u5143\u7d20 1 \u5728\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u8fbe\u5230\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6 O(n)\n        if (num == 1) return @intCast(i);\n    }\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6211\u4eec\u5728\u5b9e\u9645\u4e2d\u5f88\u5c11\u4f7f\u7528\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u56e0\u4e3a\u901a\u5e38\u53ea\u6709\u5728\u5f88\u5c0f\u6982\u7387\u4e0b\u624d\u80fd\u8fbe\u5230\uff0c\u53ef\u80fd\u4f1a\u5e26\u6765\u4e00\u5b9a\u7684\u8bef\u5bfc\u6027\u3002\u800c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u66f4\u4e3a\u5b9e\u7528\uff0c\u56e0\u4e3a\u5b83\u7ed9\u51fa\u4e86\u4e00\u4e2a\u6548\u7387\u5b89\u5168\u503c\uff0c\u8ba9\u6211\u4eec\u53ef\u4ee5\u653e\u5fc3\u5730\u4f7f\u7528\u7b97\u6cd5\u3002

    \u4ece\u4e0a\u8ff0\u793a\u4f8b\u53ef\u4ee5\u770b\u51fa\uff0c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u53ea\u51fa\u73b0\u4e8e\u201c\u7279\u6b8a\u7684\u6570\u636e\u5206\u5e03\u201d\uff0c\u8fd9\u4e9b\u60c5\u51b5\u7684\u51fa\u73b0\u6982\u7387\u53ef\u80fd\u5f88\u5c0f\uff0c\u5e76\u4e0d\u80fd\u771f\u5b9e\u5730\u53cd\u6620\u7b97\u6cd5\u8fd0\u884c\u6548\u7387\u3002\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f53\u73b0\u7b97\u6cd5\u5728\u968f\u673a\u8f93\u5165\u6570\u636e\u4e0b\u7684\u8fd0\u884c\u6548\u7387\uff0c\u7528 \\(\\Theta\\) \u8bb0\u53f7\u6765\u8868\u793a\u3002

    \u5bf9\u4e8e\u90e8\u5206\u7b97\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5355\u5730\u63a8\u7b97\u51fa\u968f\u673a\u6570\u636e\u5206\u5e03\u4e0b\u7684\u5e73\u5747\u60c5\u51b5\u3002\u6bd4\u5982\u4e0a\u8ff0\u793a\u4f8b\uff0c\u7531\u4e8e\u8f93\u5165\u6570\u7ec4\u662f\u88ab\u6253\u4e71\u7684\uff0c\u56e0\u6b64\u5143\u7d20 \\(1\\) \u51fa\u73b0\u5728\u4efb\u610f\u7d22\u5f15\u7684\u6982\u7387\u90fd\u662f\u76f8\u7b49\u7684\uff0c\u90a3\u4e48\u7b97\u6cd5\u7684\u5e73\u5747\u5faa\u73af\u6b21\u6570\u5c31\u662f\u6570\u7ec4\u957f\u5ea6\u7684\u4e00\u534a \\(n / 2\\) \uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(\\Theta(n / 2) = \\Theta(n)\\) \u3002

    \u4f46\u5bf9\u4e8e\u8f83\u4e3a\u590d\u6742\u7684\u7b97\u6cd5\uff0c\u8ba1\u7b97\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u5f80\u5f80\u6bd4\u8f83\u56f0\u96be\uff0c\u56e0\u4e3a\u5f88\u96be\u5206\u6790\u51fa\u5728\u6570\u636e\u5206\u5e03\u4e0b\u7684\u6574\u4f53\u6570\u5b66\u671f\u671b\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u901a\u5e38\u4f7f\u7528\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4f5c\u4e3a\u7b97\u6cd5\u6548\u7387\u7684\u8bc4\u5224\u6807\u51c6\u3002

    \u4e3a\u4ec0\u4e48\u5f88\u5c11\u770b\u5230 \\(\\Theta\\) \u7b26\u53f7\uff1f

    \u53ef\u80fd\u7531\u4e8e \\(O\\) \u7b26\u53f7\u8fc7\u4e8e\u6717\u6717\u4e0a\u53e3\uff0c\u56e0\u6b64\u6211\u4eec\u5e38\u5e38\u4f7f\u7528\u5b83\u6765\u8868\u793a\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u4f46\u4ece\u4e25\u683c\u610f\u4e49\u4e0a\u8bb2\uff0c\u8fd9\u79cd\u505a\u6cd5\u5e76\u4e0d\u89c4\u8303\u3002\u5728\u672c\u4e66\u548c\u5176\u4ed6\u8d44\u6599\u4e2d\uff0c\u82e5\u9047\u5230\u7c7b\u4f3c\u201c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\)\u201d\u7684\u8868\u8ff0\uff0c\u8bf7\u5c06\u5176\u76f4\u63a5\u7406\u89e3\u4e3a \\(\\Theta(n)\\) \u3002

    "},{"location":"chapter_data_structure/","title":"\u7b2c 3 \u7ae0 \u00a0 \u6570\u636e\u7ed3\u6784","text":"

    Abstract

    \u6570\u636e\u7ed3\u6784\u5982\u540c\u4e00\u526f\u7a33\u56fa\u800c\u591a\u6837\u7684\u6846\u67b6\u3002

    \u5b83\u4e3a\u6570\u636e\u7684\u6709\u5e8f\u7ec4\u7ec7\u63d0\u4f9b\u4e86\u84dd\u56fe\uff0c\u7b97\u6cd5\u5f97\u4ee5\u5728\u6b64\u57fa\u7840\u4e0a\u751f\u52a8\u8d77\u6765\u3002

    "},{"location":"chapter_data_structure/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 3.1 \u00a0 \u6570\u636e\u7ed3\u6784\u5206\u7c7b
    • 3.2 \u00a0 \u57fa\u672c\u6570\u636e\u7c7b\u578b
    • 3.3 \u00a0 \u6570\u5b57\u7f16\u7801 *
    • 3.4 \u00a0 \u5b57\u7b26\u7f16\u7801 *
    • 3.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_data_structure/basic_data_types/","title":"3.2 \u00a0 \u57fa\u672c\u6570\u636e\u7c7b\u578b","text":"

    \u5f53\u8c08\u53ca\u8ba1\u7b97\u673a\u4e2d\u7684\u6570\u636e\u65f6\uff0c\u6211\u4eec\u4f1a\u60f3\u5230\u6587\u672c\u3001\u56fe\u7247\u3001\u89c6\u9891\u3001\u8bed\u97f3\u30013D \u6a21\u578b\u7b49\u5404\u79cd\u5f62\u5f0f\u3002\u5c3d\u7ba1\u8fd9\u4e9b\u6570\u636e\u7684\u7ec4\u7ec7\u5f62\u5f0f\u5404\u5f02\uff0c\u4f46\u5b83\u4eec\u90fd\u7531\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6784\u6210\u3002

    \u57fa\u672c\u6570\u636e\u7c7b\u578b\u662f CPU \u53ef\u4ee5\u76f4\u63a5\u8fdb\u884c\u8fd0\u7b97\u7684\u7c7b\u578b\uff0c\u5728\u7b97\u6cd5\u4e2d\u76f4\u63a5\u88ab\u4f7f\u7528\uff0c\u4e3b\u8981\u5305\u62ec\u4ee5\u4e0b\u51e0\u79cd\u3002

    • \u6574\u6570\u7c7b\u578b byte\u3001short\u3001int\u3001long \u3002
    • \u6d6e\u70b9\u6570\u7c7b\u578b float\u3001double \uff0c\u7528\u4e8e\u8868\u793a\u5c0f\u6570\u3002
    • \u5b57\u7b26\u7c7b\u578b char \uff0c\u7528\u4e8e\u8868\u793a\u5404\u79cd\u8bed\u8a00\u7684\u5b57\u6bcd\u3001\u6807\u70b9\u7b26\u53f7\u751a\u81f3\u8868\u60c5\u7b26\u53f7\u7b49\u3002
    • \u5e03\u5c14\u7c7b\u578b bool \uff0c\u7528\u4e8e\u8868\u793a\u201c\u662f\u201d\u4e0e\u201c\u5426\u201d\u5224\u65ad\u3002

    \u57fa\u672c\u6570\u636e\u7c7b\u578b\u4ee5\u4e8c\u8fdb\u5236\u7684\u5f62\u5f0f\u5b58\u50a8\u5728\u8ba1\u7b97\u673a\u4e2d\u3002\u4e00\u4e2a\u4e8c\u8fdb\u5236\u4f4d\u5373\u4e3a \\(1\\) \u6bd4\u7279\u3002\u5728\u7edd\u5927\u591a\u6570\u73b0\u4ee3\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\\(1\\) \u5b57\u8282\uff08byte\uff09\u7531 \\(8\\) \u6bd4\u7279\uff08bit\uff09\u7ec4\u6210\u3002

    \u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u53d6\u503c\u8303\u56f4\u53d6\u51b3\u4e8e\u5176\u5360\u7528\u7684\u7a7a\u95f4\u5927\u5c0f\u3002\u4e0b\u9762\u4ee5 Java \u4e3a\u4f8b\u3002

    • \u6574\u6570\u7c7b\u578b byte \u5360\u7528 \\(1\\) \u5b57\u8282 = \\(8\\) \u6bd4\u7279 \uff0c\u53ef\u4ee5\u8868\u793a \\(2^{8}\\) \u4e2a\u6570\u5b57\u3002
    • \u6574\u6570\u7c7b\u578b int \u5360\u7528 \\(4\\) \u5b57\u8282 = \\(32\\) \u6bd4\u7279 \uff0c\u53ef\u4ee5\u8868\u793a \\(2^{32}\\) \u4e2a\u6570\u5b57\u3002

    \u8868 3-1 \u5217\u4e3e\u4e86 Java \u4e2d\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5360\u7528\u7a7a\u95f4\u3001\u53d6\u503c\u8303\u56f4\u548c\u9ed8\u8ba4\u503c\u3002\u6b64\u8868\u683c\u65e0\u987b\u6b7b\u8bb0\u786c\u80cc\uff0c\u5927\u81f4\u7406\u89e3\u5373\u53ef\uff0c\u9700\u8981\u65f6\u53ef\u4ee5\u901a\u8fc7\u67e5\u8868\u6765\u56de\u5fc6\u3002

    \u8868 3-1 \u00a0 \u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5360\u7528\u7a7a\u95f4\u548c\u53d6\u503c\u8303\u56f4

    \u7c7b\u578b \u7b26\u53f7 \u5360\u7528\u7a7a\u95f4 \u6700\u5c0f\u503c \u6700\u5927\u503c \u9ed8\u8ba4\u503c \u6574\u6570 byte 1 \u5b57\u8282 \\(-2^7\\) (\\(-128\\)) \\(2^7 - 1\\) (\\(127\\)) \\(0\\) short 2 \u5b57\u8282 \\(-2^{15}\\) \\(2^{15} - 1\\) \\(0\\) int 4 \u5b57\u8282 \\(-2^{31}\\) \\(2^{31} - 1\\) \\(0\\) long 8 \u5b57\u8282 \\(-2^{63}\\) \\(2^{63} - 1\\) \\(0\\) \u6d6e\u70b9\u6570 float 4 \u5b57\u8282 \\(1.175 \\times 10^{-38}\\) \\(3.403 \\times 10^{38}\\) \\(0.0\\text{f}\\) double 8 \u5b57\u8282 \\(2.225 \\times 10^{-308}\\) \\(1.798 \\times 10^{308}\\) \\(0.0\\) \u5b57\u7b26 char 2 \u5b57\u8282 \\(0\\) \\(2^{16} - 1\\) \\(0\\) \u5e03\u5c14 bool 1 \u5b57\u8282 \\(\\text{false}\\) \\(\\text{true}\\) \\(\\text{false}\\)

    \u8bf7\u6ce8\u610f\uff0c\u8868 3-1 \u9488\u5bf9\u7684\u662f Java \u7684\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u60c5\u51b5\u3002\u6bcf\u79cd\u7f16\u7a0b\u8bed\u8a00\u90fd\u6709\u5404\u81ea\u7684\u6570\u636e\u7c7b\u578b\u5b9a\u4e49\uff0c\u5b83\u4eec\u7684\u5360\u7528\u7a7a\u95f4\u3001\u53d6\u503c\u8303\u56f4\u548c\u9ed8\u8ba4\u503c\u53ef\u80fd\u4f1a\u6709\u6240\u4e0d\u540c\u3002

    • \u5728 Python \u4e2d\uff0c\u6574\u6570\u7c7b\u578b int \u53ef\u4ee5\u662f\u4efb\u610f\u5927\u5c0f\uff0c\u53ea\u53d7\u9650\u4e8e\u53ef\u7528\u5185\u5b58\uff1b\u6d6e\u70b9\u6570 float \u662f\u53cc\u7cbe\u5ea6 64 \u4f4d\uff1b\u6ca1\u6709 char \u7c7b\u578b\uff0c\u5355\u4e2a\u5b57\u7b26\u5b9e\u9645\u4e0a\u662f\u957f\u5ea6\u4e3a 1 \u7684\u5b57\u7b26\u4e32 str \u3002
    • C \u548c C++ \u672a\u660e\u786e\u89c4\u5b9a\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u5927\u5c0f\uff0c\u800c\u56e0\u5b9e\u73b0\u548c\u5e73\u53f0\u5404\u5f02\u3002\u8868 3-1 \u9075\u5faa LP64 \u6570\u636e\u6a21\u578b\uff0c\u5176\u7528\u4e8e\u5305\u62ec Linux \u548c macOS \u5728\u5185\u7684 Unix 64 \u4f4d\u64cd\u4f5c\u7cfb\u7edf\u3002
    • \u5b57\u7b26 char \u7684\u5927\u5c0f\u5728 C \u548c C++ \u4e2d\u4e3a 1 \u5b57\u8282\uff0c\u5728\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u4e2d\u53d6\u51b3\u4e8e\u7279\u5b9a\u7684\u5b57\u7b26\u7f16\u7801\u65b9\u6cd5\uff0c\u8be6\u89c1\u201c\u5b57\u7b26\u7f16\u7801\u201d\u7ae0\u8282\u3002
    • \u5373\u4f7f\u8868\u793a\u5e03\u5c14\u91cf\u4ec5\u9700 1 \u4f4d\uff08\\(0\\) \u6216 \\(1\\)\uff09\uff0c\u5b83\u5728\u5185\u5b58\u4e2d\u901a\u5e38\u4e5f\u5b58\u50a8\u4e3a 1 \u5b57\u8282\u3002\u8fd9\u662f\u56e0\u4e3a\u73b0\u4ee3\u8ba1\u7b97\u673a CPU \u901a\u5e38\u5c06 1 \u5b57\u8282\u4f5c\u4e3a\u6700\u5c0f\u5bfb\u5740\u5185\u5b58\u5355\u5143\u3002

    \u90a3\u4e48\uff0c\u57fa\u672c\u6570\u636e\u7c7b\u578b\u4e0e\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u6709\u4ec0\u4e48\u8054\u7cfb\u5462\uff1f\u6211\u4eec\u77e5\u9053\uff0c\u6570\u636e\u7ed3\u6784\u662f\u5728\u8ba1\u7b97\u673a\u4e2d\u7ec4\u7ec7\u4e0e\u5b58\u50a8\u6570\u636e\u7684\u65b9\u5f0f\u3002\u8fd9\u53e5\u8bdd\u7684\u4e3b\u8bed\u662f\u201c\u7ed3\u6784\u201d\u800c\u975e\u201c\u6570\u636e\u201d\u3002

    \u5982\u679c\u60f3\u8868\u793a\u201c\u4e00\u6392\u6570\u5b57\u201d\uff0c\u6211\u4eec\u81ea\u7136\u4f1a\u60f3\u5230\u4f7f\u7528\u6570\u7ec4\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u7ec4\u7684\u7ebf\u6027\u7ed3\u6784\u53ef\u4ee5\u8868\u793a\u6570\u5b57\u7684\u76f8\u90bb\u5173\u7cfb\u548c\u987a\u5e8f\u5173\u7cfb\uff0c\u4f46\u81f3\u4e8e\u5b58\u50a8\u7684\u5185\u5bb9\u662f\u6574\u6570 int\u3001\u5c0f\u6570 float \u8fd8\u662f\u5b57\u7b26 char \uff0c\u5219\u4e0e\u201c\u6570\u636e\u7ed3\u6784\u201d\u65e0\u5173\u3002

    \u6362\u53e5\u8bdd\u8bf4\uff0c\u57fa\u672c\u6570\u636e\u7c7b\u578b\u63d0\u4f9b\u4e86\u6570\u636e\u7684\u201c\u5185\u5bb9\u7c7b\u578b\u201d\uff0c\u800c\u6570\u636e\u7ed3\u6784\u63d0\u4f9b\u4e86\u6570\u636e\u7684\u201c\u7ec4\u7ec7\u65b9\u5f0f\u201d\u3002\u4f8b\u5982\u4ee5\u4e0b\u4ee3\u7801\uff0c\u6211\u4eec\u7528\u76f8\u540c\u7684\u6570\u636e\u7ed3\u6784\uff08\u6570\u7ec4\uff09\u6765\u5b58\u50a8\u4e0e\u8868\u793a\u4e0d\u540c\u7684\u57fa\u672c\u6570\u636e\u7c7b\u578b\uff0c\u5305\u62ec int\u3001float\u3001char\u3001bool \u7b49\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nnumbers: list[int] = [0] * 5\ndecimals: list[float] = [0.0] * 5\n# Python \u7684\u5b57\u7b26\u5b9e\u9645\u4e0a\u662f\u957f\u5ea6\u4e3a 1 \u7684\u5b57\u7b26\u4e32\ncharacters: list[str] = ['0'] * 5\nbools: list[bool] = [False] * 5\n# Python \u7684\u5217\u8868\u53ef\u4ee5\u81ea\u7531\u5b58\u50a8\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u5bf9\u8c61\u5f15\u7528\ndata = [0, 0.0, 'a', False, ListNode(0)]\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint numbers[5];\nfloat decimals[5];\nchar characters[5];\nbool bools[5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nboolean[] bools = new boolean[5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint[] numbers = new int[5];\nfloat[] decimals = new float[5];\nchar[] characters = new char[5];\nbool[] bools = new bool[5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nvar numbers = [5]int{}\nvar decimals = [5]float64{}\nvar characters = [5]byte{}\nvar bools = [5]bool{}\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nlet numbers = Array(repeating: 0, count: 5)\nlet decimals = Array(repeating: 0.0, count: 5)\nlet characters: [Character] = Array(repeating: \"a\", count: 5)\nlet bools = Array(repeating: false, count: 5)\n
    // JavaScript \u7684\u6570\u7ec4\u53ef\u4ee5\u81ea\u7531\u5b58\u50a8\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u5bf9\u8c61\nconst array = [0, 0.0, 'a', false];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nconst numbers: number[] = [];\nconst characters: string[] = [];\nconst bools: boolean[] = [];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nList<int> numbers = List.filled(5, 0);\nList<double> decimals = List.filled(5, 0.0);\nList<String> characters = List.filled(5, 'a');\nList<bool> bools = List.filled(5, false);\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nlet numbers: Vec<i32> = vec![0; 5];\nlet decimals: Vec<f32> = vec![0.0; 5];\nlet characters: Vec<char> = vec!['0'; 5];\nlet bools: Vec<bool> = vec![false; 5];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nint numbers[10];\nfloat decimals[10];\nchar characters[10];\nbool bools[10];\n
    // \u4f7f\u7528\u591a\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u6765\u521d\u59cb\u5316\u6570\u7ec4\nval numbers = IntArray(5)\nval decinals = FloatArray(5)\nval characters = CharArray(5)\nval bools = BooleanArray(5)\n
    # Ruby \u7684\u5217\u8868\u53ef\u4ee5\u81ea\u7531\u5b58\u50a8\u5404\u79cd\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u5bf9\u8c61\u5f15\u7528\ndata = [0, 0.0, 'a', false, ListNode(0)]\n
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_data_structure/character_encoding/","title":"3.4 \u00a0 \u5b57\u7b26\u7f16\u7801 *","text":"

    \u5728\u8ba1\u7b97\u673a\u4e2d\uff0c\u6240\u6709\u6570\u636e\u90fd\u662f\u4ee5\u4e8c\u8fdb\u5236\u6570\u7684\u5f62\u5f0f\u5b58\u50a8\u7684\uff0c\u5b57\u7b26 char \u4e5f\u4e0d\u4f8b\u5916\u3002\u4e3a\u4e86\u8868\u793a\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u5efa\u7acb\u4e00\u5957\u201c\u5b57\u7b26\u96c6\u201d\uff0c\u89c4\u5b9a\u6bcf\u4e2a\u5b57\u7b26\u548c\u4e8c\u8fdb\u5236\u6570\u4e4b\u95f4\u7684\u4e00\u4e00\u5bf9\u5e94\u5173\u7cfb\u3002\u6709\u4e86\u5b57\u7b26\u96c6\u4e4b\u540e\uff0c\u8ba1\u7b97\u673a\u5c31\u53ef\u4ee5\u901a\u8fc7\u67e5\u8868\u5b8c\u6210\u4e8c\u8fdb\u5236\u6570\u5230\u5b57\u7b26\u7684\u8f6c\u6362\u3002

    "},{"location":"chapter_data_structure/character_encoding/#341-ascii","title":"3.4.1 \u00a0 ASCII \u5b57\u7b26\u96c6","text":"

    ASCII \u7801\u662f\u6700\u65e9\u51fa\u73b0\u7684\u5b57\u7b26\u96c6\uff0c\u5176\u5168\u79f0\u4e3a American Standard Code for Information Interchange\uff08\u7f8e\u56fd\u6807\u51c6\u4fe1\u606f\u4ea4\u6362\u4ee3\u7801\uff09\u3002\u5b83\u4f7f\u7528 7 \u4f4d\u4e8c\u8fdb\u5236\u6570\uff08\u4e00\u4e2a\u5b57\u8282\u7684\u4f4e 7 \u4f4d\uff09\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u6700\u591a\u80fd\u591f\u8868\u793a 128 \u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u3002\u5982\u56fe 3-6 \u6240\u793a\uff0cASCII \u7801\u5305\u62ec\u82f1\u6587\u5b57\u6bcd\u7684\u5927\u5c0f\u5199\u3001\u6570\u5b57 0 ~ 9\u3001\u4e00\u4e9b\u6807\u70b9\u7b26\u53f7\uff0c\u4ee5\u53ca\u4e00\u4e9b\u63a7\u5236\u5b57\u7b26\uff08\u5982\u6362\u884c\u7b26\u548c\u5236\u8868\u7b26\uff09\u3002

    \u56fe 3-6 \u00a0 ASCII \u7801

    \u7136\u800c\uff0cASCII \u7801\u4ec5\u80fd\u591f\u8868\u793a\u82f1\u6587\u3002\u968f\u7740\u8ba1\u7b97\u673a\u7684\u5168\u7403\u5316\uff0c\u8bde\u751f\u4e86\u4e00\u79cd\u80fd\u591f\u8868\u793a\u66f4\u591a\u8bed\u8a00\u7684 EASCII \u5b57\u7b26\u96c6\u3002\u5b83\u5728 ASCII \u7684 7 \u4f4d\u57fa\u7840\u4e0a\u6269\u5c55\u5230 8 \u4f4d\uff0c\u80fd\u591f\u8868\u793a 256 \u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u3002

    \u5728\u4e16\u754c\u8303\u56f4\u5185\uff0c\u9646\u7eed\u51fa\u73b0\u4e86\u4e00\u6279\u9002\u7528\u4e8e\u4e0d\u540c\u5730\u533a\u7684 EASCII \u5b57\u7b26\u96c6\u3002\u8fd9\u4e9b\u5b57\u7b26\u96c6\u7684\u524d 128 \u4e2a\u5b57\u7b26\u7edf\u4e00\u4e3a ASCII \u7801\uff0c\u540e 128 \u4e2a\u5b57\u7b26\u5b9a\u4e49\u4e0d\u540c\uff0c\u4ee5\u9002\u5e94\u4e0d\u540c\u8bed\u8a00\u7684\u9700\u6c42\u3002

    "},{"location":"chapter_data_structure/character_encoding/#342-gbk","title":"3.4.2 \u00a0 GBK \u5b57\u7b26\u96c6","text":"

    \u540e\u6765\u4eba\u4eec\u53d1\u73b0\uff0cEASCII \u7801\u4ecd\u7136\u65e0\u6cd5\u6ee1\u8db3\u8bb8\u591a\u8bed\u8a00\u7684\u5b57\u7b26\u6570\u91cf\u8981\u6c42\u3002\u6bd4\u5982\u6c49\u5b57\u6709\u8fd1\u5341\u4e07\u4e2a\uff0c\u5149\u65e5\u5e38\u4f7f\u7528\u7684\u5c31\u6709\u51e0\u5343\u4e2a\u3002\u4e2d\u56fd\u56fd\u5bb6\u6807\u51c6\u603b\u5c40\u4e8e 1980 \u5e74\u53d1\u5e03\u4e86 GB2312 \u5b57\u7b26\u96c6\uff0c\u5176\u6536\u5f55\u4e86 6763 \u4e2a\u6c49\u5b57\uff0c\u57fa\u672c\u6ee1\u8db3\u4e86\u6c49\u5b57\u7684\u8ba1\u7b97\u673a\u5904\u7406\u9700\u8981\u3002

    \u7136\u800c\uff0cGB2312 \u65e0\u6cd5\u5904\u7406\u90e8\u5206\u7f55\u89c1\u5b57\u548c\u7e41\u4f53\u5b57\u3002GBK \u5b57\u7b26\u96c6\u662f\u5728 GB2312 \u7684\u57fa\u7840\u4e0a\u6269\u5c55\u5f97\u5230\u7684\uff0c\u5b83\u5171\u6536\u5f55\u4e86 21886 \u4e2a\u6c49\u5b57\u3002\u5728 GBK \u7684\u7f16\u7801\u65b9\u6848\u4e2d\uff0cASCII \u5b57\u7b26\u4f7f\u7528\u4e00\u4e2a\u5b57\u8282\u8868\u793a\uff0c\u6c49\u5b57\u4f7f\u7528\u4e24\u4e2a\u5b57\u8282\u8868\u793a\u3002

    "},{"location":"chapter_data_structure/character_encoding/#343-unicode","title":"3.4.3 \u00a0 Unicode \u5b57\u7b26\u96c6","text":"

    \u968f\u7740\u8ba1\u7b97\u673a\u6280\u672f\u7684\u84ec\u52c3\u53d1\u5c55\uff0c\u5b57\u7b26\u96c6\u4e0e\u7f16\u7801\u6807\u51c6\u767e\u82b1\u9f50\u653e\uff0c\u800c\u8fd9\u5e26\u6765\u4e86\u8bb8\u591a\u95ee\u9898\u3002\u4e00\u65b9\u9762\uff0c\u8fd9\u4e9b\u5b57\u7b26\u96c6\u4e00\u822c\u53ea\u5b9a\u4e49\u4e86\u7279\u5b9a\u8bed\u8a00\u7684\u5b57\u7b26\uff0c\u65e0\u6cd5\u5728\u591a\u8bed\u8a00\u73af\u5883\u4e0b\u6b63\u5e38\u5de5\u4f5c\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u540c\u4e00\u79cd\u8bed\u8a00\u5b58\u5728\u591a\u79cd\u5b57\u7b26\u96c6\u6807\u51c6\uff0c\u5982\u679c\u4e24\u53f0\u8ba1\u7b97\u673a\u4f7f\u7528\u7684\u662f\u4e0d\u540c\u7684\u7f16\u7801\u6807\u51c6\uff0c\u5219\u5728\u4fe1\u606f\u4f20\u9012\u65f6\u5c31\u4f1a\u51fa\u73b0\u4e71\u7801\u3002

    \u90a3\u4e2a\u65f6\u4ee3\u7684\u7814\u7a76\u4eba\u5458\u5c31\u5728\u60f3\uff1a\u5982\u679c\u63a8\u51fa\u4e00\u4e2a\u8db3\u591f\u5b8c\u6574\u7684\u5b57\u7b26\u96c6\uff0c\u5c06\u4e16\u754c\u8303\u56f4\u5185\u7684\u6240\u6709\u8bed\u8a00\u548c\u7b26\u53f7\u90fd\u6536\u5f55\u5176\u4e2d\uff0c\u4e0d\u5c31\u53ef\u4ee5\u89e3\u51b3\u8de8\u8bed\u8a00\u73af\u5883\u548c\u4e71\u7801\u95ee\u9898\u4e86\u5417\uff1f\u5728\u8fd9\u79cd\u60f3\u6cd5\u7684\u9a71\u52a8\u4e0b\uff0c\u4e00\u4e2a\u5927\u800c\u5168\u7684\u5b57\u7b26\u96c6 Unicode \u5e94\u8fd0\u800c\u751f\u3002

    Unicode \u7684\u4e2d\u6587\u540d\u79f0\u4e3a\u201c\u7edf\u4e00\u7801\u201d\uff0c\u7406\u8bba\u4e0a\u80fd\u5bb9\u7eb3 100 \u591a\u4e07\u4e2a\u5b57\u7b26\u3002\u5b83\u81f4\u529b\u4e8e\u5c06\u5168\u7403\u8303\u56f4\u5185\u7684\u5b57\u7b26\u7eb3\u5165\u7edf\u4e00\u7684\u5b57\u7b26\u96c6\u4e4b\u4e2d\uff0c\u63d0\u4f9b\u4e00\u79cd\u901a\u7528\u7684\u5b57\u7b26\u96c6\u6765\u5904\u7406\u548c\u663e\u793a\u5404\u79cd\u8bed\u8a00\u6587\u5b57\uff0c\u51cf\u5c11\u56e0\u4e3a\u7f16\u7801\u6807\u51c6\u4e0d\u540c\u800c\u4ea7\u751f\u7684\u4e71\u7801\u95ee\u9898\u3002

    \u81ea 1991 \u5e74\u53d1\u5e03\u4ee5\u6765\uff0cUnicode \u4e0d\u65ad\u6269\u5145\u65b0\u7684\u8bed\u8a00\u4e0e\u5b57\u7b26\u3002\u622a\u81f3 2022 \u5e74 9 \u6708\uff0cUnicode \u5df2\u7ecf\u5305\u542b 149186 \u4e2a\u5b57\u7b26\uff0c\u5305\u62ec\u5404\u79cd\u8bed\u8a00\u7684\u5b57\u7b26\u3001\u7b26\u53f7\u751a\u81f3\u8868\u60c5\u7b26\u53f7\u7b49\u3002\u5728\u5e9e\u5927\u7684 Unicode \u5b57\u7b26\u96c6\u4e2d\uff0c\u5e38\u7528\u7684\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\uff0c\u6709\u4e9b\u751f\u50fb\u7684\u5b57\u7b26\u5360\u7528 3 \u5b57\u8282\u751a\u81f3 4 \u5b57\u8282\u3002

    Unicode \u662f\u4e00\u79cd\u901a\u7528\u5b57\u7b26\u96c6\uff0c\u672c\u8d28\u4e0a\u662f\u7ed9\u6bcf\u4e2a\u5b57\u7b26\u5206\u914d\u4e00\u4e2a\u7f16\u53f7\uff08\u79f0\u4e3a\u201c\u7801\u70b9\u201d\uff09\uff0c\u4f46\u5b83\u5e76\u6ca1\u6709\u89c4\u5b9a\u5728\u8ba1\u7b97\u673a\u4e2d\u5982\u4f55\u5b58\u50a8\u8fd9\u4e9b\u5b57\u7b26\u7801\u70b9\u3002\u6211\u4eec\u4e0d\u7981\u4f1a\u95ee\uff1a\u5f53\u591a\u79cd\u957f\u5ea6\u7684 Unicode \u7801\u70b9\u540c\u65f6\u51fa\u73b0\u5728\u4e00\u4e2a\u6587\u672c\u4e2d\u65f6\uff0c\u7cfb\u7edf\u5982\u4f55\u89e3\u6790\u5b57\u7b26\uff1f\u4f8b\u5982\u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a 2 \u5b57\u8282\u7684\u7f16\u7801\uff0c\u7cfb\u7edf\u5982\u4f55\u786e\u8ba4\u5b83\u662f\u4e00\u4e2a 2 \u5b57\u8282\u7684\u5b57\u7b26\u8fd8\u662f\u4e24\u4e2a 1 \u5b57\u8282\u7684\u5b57\u7b26\uff1f

    \u5bf9\u4e8e\u4ee5\u4e0a\u95ee\u9898\uff0c\u4e00\u79cd\u76f4\u63a5\u7684\u89e3\u51b3\u65b9\u6848\u662f\u5c06\u6240\u6709\u5b57\u7b26\u5b58\u50a8\u4e3a\u7b49\u957f\u7684\u7f16\u7801\u3002\u5982\u56fe 3-7 \u6240\u793a\uff0c\u201cHello\u201d\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 1 \u5b57\u8282\uff0c\u201c\u7b97\u6cd5\u201d\u4e2d\u7684\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u9ad8\u4f4d\u586b 0 \u5c06\u201cHello \u7b97\u6cd5\u201d\u4e2d\u7684\u6240\u6709\u5b57\u7b26\u90fd\u7f16\u7801\u4e3a 2 \u5b57\u8282\u957f\u5ea6\u3002\u8fd9\u6837\u7cfb\u7edf\u5c31\u53ef\u4ee5\u6bcf\u9694 2 \u5b57\u8282\u89e3\u6790\u4e00\u4e2a\u5b57\u7b26\uff0c\u6062\u590d\u8fd9\u4e2a\u77ed\u8bed\u7684\u5185\u5bb9\u4e86\u3002

    \u56fe 3-7 \u00a0 Unicode \u7f16\u7801\u793a\u4f8b

    \u7136\u800c ASCII \u7801\u5df2\u7ecf\u5411\u6211\u4eec\u8bc1\u660e\uff0c\u7f16\u7801\u82f1\u6587\u53ea\u9700 1 \u5b57\u8282\u3002\u82e5\u91c7\u7528\u4e0a\u8ff0\u65b9\u6848\uff0c\u82f1\u6587\u6587\u672c\u5360\u7528\u7a7a\u95f4\u7684\u5927\u5c0f\u5c06\u4f1a\u662f ASCII \u7f16\u7801\u4e0b\u7684\u4e24\u500d\uff0c\u975e\u5e38\u6d6a\u8d39\u5185\u5b58\u7a7a\u95f4\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u9700\u8981\u4e00\u79cd\u66f4\u52a0\u9ad8\u6548\u7684 Unicode \u7f16\u7801\u65b9\u6cd5\u3002

    "},{"location":"chapter_data_structure/character_encoding/#344-utf-8","title":"3.4.4 \u00a0 UTF-8 \u7f16\u7801","text":"

    \u76ee\u524d\uff0cUTF-8 \u5df2\u6210\u4e3a\u56fd\u9645\u4e0a\u4f7f\u7528\u6700\u5e7f\u6cdb\u7684 Unicode \u7f16\u7801\u65b9\u6cd5\u3002\u5b83\u662f\u4e00\u79cd\u53ef\u53d8\u957f\u5ea6\u7684\u7f16\u7801\uff0c\u4f7f\u7528 1 \u5230 4 \u5b57\u8282\u6765\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u6839\u636e\u5b57\u7b26\u7684\u590d\u6742\u6027\u800c\u53d8\u3002ASCII \u5b57\u7b26\u53ea\u9700 1 \u5b57\u8282\uff0c\u62c9\u4e01\u5b57\u6bcd\u548c\u5e0c\u814a\u5b57\u6bcd\u9700\u8981 2 \u5b57\u8282\uff0c\u5e38\u7528\u7684\u4e2d\u6587\u5b57\u7b26\u9700\u8981 3 \u5b57\u8282\uff0c\u5176\u4ed6\u7684\u4e00\u4e9b\u751f\u50fb\u5b57\u7b26\u9700\u8981 4 \u5b57\u8282\u3002

    UTF-8 \u7684\u7f16\u7801\u89c4\u5219\u5e76\u4e0d\u590d\u6742\uff0c\u5206\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u60c5\u51b5\u3002

    • \u5bf9\u4e8e\u957f\u5ea6\u4e3a 1 \u5b57\u8282\u7684\u5b57\u7b26\uff0c\u5c06\u6700\u9ad8\u4f4d\u8bbe\u7f6e\u4e3a \\(0\\) \uff0c\u5176\u4f59 7 \u4f4d\u8bbe\u7f6e\u4e3a Unicode \u7801\u70b9\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cASCII \u5b57\u7b26\u5728 Unicode \u5b57\u7b26\u96c6\u4e2d\u5360\u636e\u4e86\u524d 128 \u4e2a\u7801\u70b9\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cUTF-8 \u7f16\u7801\u53ef\u4ee5\u5411\u4e0b\u517c\u5bb9 ASCII \u7801\u3002\u8fd9\u610f\u5473\u7740\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 UTF-8 \u6765\u89e3\u6790\u5e74\u4ee3\u4e45\u8fdc\u7684 ASCII \u7801\u6587\u672c\u3002
    • \u5bf9\u4e8e\u957f\u5ea6\u4e3a \\(n\\) \u5b57\u8282\u7684\u5b57\u7b26\uff08\u5176\u4e2d \\(n > 1\\)\uff09\uff0c\u5c06\u9996\u4e2a\u5b57\u8282\u7684\u9ad8 \\(n\\) \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(1\\) \uff0c\u7b2c \\(n + 1\\) \u4f4d\u8bbe\u7f6e\u4e3a \\(0\\) \uff1b\u4ece\u7b2c\u4e8c\u4e2a\u5b57\u8282\u5f00\u59cb\uff0c\u5c06\u6bcf\u4e2a\u5b57\u8282\u7684\u9ad8 2 \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(10\\) \uff1b\u5176\u4f59\u6240\u6709\u4f4d\u7528\u4e8e\u586b\u5145\u5b57\u7b26\u7684 Unicode \u7801\u70b9\u3002

    \u56fe 3-8 \u5c55\u793a\u4e86\u201cHello\u7b97\u6cd5\u201d\u5bf9\u5e94\u7684 UTF-8 \u7f16\u7801\u3002\u89c2\u5bdf\u53d1\u73b0\uff0c\u7531\u4e8e\u6700\u9ad8 \\(n\\) \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(1\\) \uff0c\u56e0\u6b64\u7cfb\u7edf\u53ef\u4ee5\u901a\u8fc7\u8bfb\u53d6\u6700\u9ad8\u4f4d \\(1\\) \u7684\u4e2a\u6570\u6765\u89e3\u6790\u51fa\u5b57\u7b26\u7684\u957f\u5ea6\u4e3a \\(n\\) \u3002

    \u4f46\u4e3a\u4ec0\u4e48\u8981\u5c06\u5176\u4f59\u6240\u6709\u5b57\u8282\u7684\u9ad8 2 \u4f4d\u90fd\u8bbe\u7f6e\u4e3a \\(10\\) \u5462\uff1f\u5b9e\u9645\u4e0a\uff0c\u8fd9\u4e2a \\(10\\) \u80fd\u591f\u8d77\u5230\u6821\u9a8c\u7b26\u7684\u4f5c\u7528\u3002\u5047\u8bbe\u7cfb\u7edf\u4ece\u4e00\u4e2a\u9519\u8bef\u7684\u5b57\u8282\u5f00\u59cb\u89e3\u6790\u6587\u672c\uff0c\u5b57\u8282\u5934\u90e8\u7684 \\(10\\) \u80fd\u591f\u5e2e\u52a9\u7cfb\u7edf\u5feb\u901f\u5224\u65ad\u51fa\u5f02\u5e38\u3002

    \u4e4b\u6240\u4ee5\u5c06 \\(10\\) \u5f53\u4f5c\u6821\u9a8c\u7b26\uff0c\u662f\u56e0\u4e3a\u5728 UTF-8 \u7f16\u7801\u89c4\u5219\u4e0b\uff0c\u4e0d\u53ef\u80fd\u6709\u5b57\u7b26\u7684\u6700\u9ad8\u4e24\u4f4d\u662f \\(10\\) \u3002\u8fd9\u4e2a\u7ed3\u8bba\u53ef\u4ee5\u7528\u53cd\u8bc1\u6cd5\u6765\u8bc1\u660e\uff1a\u5047\u8bbe\u4e00\u4e2a\u5b57\u7b26\u7684\u6700\u9ad8\u4e24\u4f4d\u662f \\(10\\) \uff0c\u8bf4\u660e\u8be5\u5b57\u7b26\u7684\u957f\u5ea6\u4e3a \\(1\\) \uff0c\u5bf9\u5e94 ASCII \u7801\u3002\u800c ASCII \u7801\u7684\u6700\u9ad8\u4f4d\u5e94\u8be5\u662f \\(0\\) \uff0c\u4e0e\u5047\u8bbe\u77db\u76fe\u3002

    \u56fe 3-8 \u00a0 UTF-8 \u7f16\u7801\u793a\u4f8b

    \u9664\u4e86 UTF-8 \u4e4b\u5916\uff0c\u5e38\u89c1\u7684\u7f16\u7801\u65b9\u5f0f\u8fd8\u5305\u62ec\u4ee5\u4e0b\u4e24\u79cd\u3002

    • UTF-16 \u7f16\u7801\uff1a\u4f7f\u7528 2 \u6216 4 \u5b57\u8282\u6765\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\u3002\u6240\u6709\u7684 ASCII \u5b57\u7b26\u548c\u5e38\u7528\u7684\u975e\u82f1\u6587\u5b57\u7b26\uff0c\u90fd\u7528 2 \u5b57\u8282\u8868\u793a\uff1b\u5c11\u6570\u5b57\u7b26\u9700\u8981\u7528\u5230 4 \u5b57\u8282\u8868\u793a\u3002\u5bf9\u4e8e 2 \u5b57\u8282\u7684\u5b57\u7b26\uff0cUTF-16 \u7f16\u7801\u4e0e Unicode \u7801\u70b9\u76f8\u7b49\u3002
    • UTF-32 \u7f16\u7801\uff1a\u6bcf\u4e2a\u5b57\u7b26\u90fd\u4f7f\u7528 4 \u5b57\u8282\u3002\u8fd9\u610f\u5473\u7740 UTF-32 \u6bd4 UTF-8 \u548c UTF-16 \u66f4\u5360\u7528\u7a7a\u95f4\uff0c\u7279\u522b\u662f\u5bf9\u4e8e ASCII \u5b57\u7b26\u5360\u6bd4\u8f83\u9ad8\u7684\u6587\u672c\u3002

    \u4ece\u5b58\u50a8\u7a7a\u95f4\u5360\u7528\u7684\u89d2\u5ea6\u770b\uff0c\u4f7f\u7528 UTF-8 \u8868\u793a\u82f1\u6587\u5b57\u7b26\u975e\u5e38\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u4ec5\u9700 1 \u5b57\u8282\uff1b\u4f7f\u7528 UTF-16 \u7f16\u7801\u67d0\u4e9b\u975e\u82f1\u6587\u5b57\u7b26\uff08\u4f8b\u5982\u4e2d\u6587\uff09\u4f1a\u66f4\u52a0\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u4ec5\u9700 2 \u5b57\u8282\uff0c\u800c UTF-8 \u53ef\u80fd\u9700\u8981 3 \u5b57\u8282\u3002

    \u4ece\u517c\u5bb9\u6027\u7684\u89d2\u5ea6\u770b\uff0cUTF-8 \u7684\u901a\u7528\u6027\u6700\u4f73\uff0c\u8bb8\u591a\u5de5\u5177\u548c\u5e93\u4f18\u5148\u652f\u6301 UTF-8 \u3002

    "},{"location":"chapter_data_structure/character_encoding/#345","title":"3.4.5 \u00a0 \u7f16\u7a0b\u8bed\u8a00\u7684\u5b57\u7b26\u7f16\u7801","text":"

    \u5bf9\u4e8e\u4ee5\u5f80\u7684\u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\uff0c\u7a0b\u5e8f\u8fd0\u884c\u4e2d\u7684\u5b57\u7b26\u4e32\u90fd\u91c7\u7528 UTF-16 \u6216 UTF-32 \u8fd9\u7c7b\u7b49\u957f\u7f16\u7801\u3002\u5728\u7b49\u957f\u7f16\u7801\u4e0b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5b57\u7b26\u4e32\u770b\u4f5c\u6570\u7ec4\u6765\u5904\u7406\uff0c\u8fd9\u79cd\u505a\u6cd5\u5177\u6709\u4ee5\u4e0b\u4f18\u70b9\u3002

    • \u968f\u673a\u8bbf\u95ee\uff1aUTF-16 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u8fdb\u884c\u968f\u673a\u8bbf\u95ee\u3002UTF-8 \u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u8981\u60f3\u627e\u5230\u7b2c \\(i\\) \u4e2a\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u4ece\u5b57\u7b26\u4e32\u7684\u5f00\u59cb\u5904\u904d\u5386\u5230\u7b2c \\(i\\) \u4e2a\u5b57\u7b26\uff0c\u8fd9\u9700\u8981 \\(O(n)\\) \u7684\u65f6\u95f4\u3002
    • \u5b57\u7b26\u8ba1\u6570\uff1a\u4e0e\u968f\u673a\u8bbf\u95ee\u7c7b\u4f3c\uff0c\u8ba1\u7b97 UTF-16 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u4e5f\u662f \\(O(1)\\) \u7684\u64cd\u4f5c\u3002\u4f46\u662f\uff0c\u8ba1\u7b97 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u9700\u8981\u904d\u5386\u6574\u4e2a\u5b57\u7b26\u4e32\u3002
    • \u5b57\u7b26\u4e32\u64cd\u4f5c\uff1a\u5728 UTF-16 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u4e0a\uff0c\u5f88\u591a\u5b57\u7b26\u4e32\u64cd\u4f5c\uff08\u5982\u5206\u5272\u3001\u8fde\u63a5\u3001\u63d2\u5165\u3001\u5220\u9664\u7b49\uff09\u66f4\u5bb9\u6613\u8fdb\u884c\u3002\u5728 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u4e0a\uff0c\u8fdb\u884c\u8fd9\u4e9b\u64cd\u4f5c\u901a\u5e38\u9700\u8981\u989d\u5916\u7684\u8ba1\u7b97\uff0c\u4ee5\u786e\u4fdd\u4e0d\u4f1a\u4ea7\u751f\u65e0\u6548\u7684 UTF-8 \u7f16\u7801\u3002

    \u5b9e\u9645\u4e0a\uff0c\u7f16\u7a0b\u8bed\u8a00\u7684\u5b57\u7b26\u7f16\u7801\u65b9\u6848\u8bbe\u8ba1\u662f\u4e00\u4e2a\u5f88\u6709\u8da3\u7684\u8bdd\u9898\uff0c\u6d89\u53ca\u8bb8\u591a\u56e0\u7d20\u3002

    • Java \u7684 String \u7c7b\u578b\u4f7f\u7528 UTF-16 \u7f16\u7801\uff0c\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\u3002\u8fd9\u662f\u56e0\u4e3a Java \u8bed\u8a00\u8bbe\u8ba1\u4e4b\u521d\uff0c\u4eba\u4eec\u8ba4\u4e3a 16 \u4f4d\u8db3\u4ee5\u8868\u793a\u6240\u6709\u53ef\u80fd\u7684\u5b57\u7b26\u3002\u7136\u800c\uff0c\u8fd9\u662f\u4e00\u4e2a\u4e0d\u6b63\u786e\u7684\u5224\u65ad\u3002\u540e\u6765 Unicode \u89c4\u8303\u6269\u5c55\u5230\u4e86\u8d85\u8fc7 16 \u4f4d\uff0c\u6240\u4ee5 Java \u4e2d\u7684\u5b57\u7b26\u73b0\u5728\u53ef\u80fd\u7531\u4e00\u5bf9 16 \u4f4d\u7684\u503c\uff08\u79f0\u4e3a\u201c\u4ee3\u7406\u5bf9\u201d\uff09\u8868\u793a\u3002
    • JavaScript \u548c TypeScript \u7684\u5b57\u7b26\u4e32\u4f7f\u7528 UTF-16 \u7f16\u7801\u7684\u539f\u56e0\u4e0e Java \u7c7b\u4f3c\u3002\u5f53 1995 \u5e74 Netscape \u516c\u53f8\u9996\u6b21\u63a8\u51fa JavaScript \u8bed\u8a00\u65f6\uff0cUnicode \u8fd8\u5904\u4e8e\u53d1\u5c55\u65e9\u671f\uff0c\u90a3\u65f6\u5019\u4f7f\u7528 16 \u4f4d\u7684\u7f16\u7801\u5c31\u8db3\u4ee5\u8868\u793a\u6240\u6709\u7684 Unicode \u5b57\u7b26\u4e86\u3002
    • C# \u4f7f\u7528 UTF-16 \u7f16\u7801\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a .NET \u5e73\u53f0\u662f\u7531 Microsoft \u8bbe\u8ba1\u7684\uff0c\u800c Microsoft \u7684\u5f88\u591a\u6280\u672f\uff08\u5305\u62ec Windows \u64cd\u4f5c\u7cfb\u7edf\uff09\u90fd\u5e7f\u6cdb\u4f7f\u7528 UTF-16 \u7f16\u7801\u3002

    \u7531\u4e8e\u4ee5\u4e0a\u7f16\u7a0b\u8bed\u8a00\u5bf9\u5b57\u7b26\u6570\u91cf\u7684\u4f4e\u4f30\uff0c\u5b83\u4eec\u4e0d\u5f97\u4e0d\u91c7\u53d6\u201c\u4ee3\u7406\u5bf9\u201d\u7684\u65b9\u5f0f\u6765\u8868\u793a\u8d85\u8fc7 16 \u4f4d\u957f\u5ea6\u7684 Unicode \u5b57\u7b26\u3002\u8fd9\u662f\u4e00\u4e2a\u4e0d\u5f97\u5df2\u4e3a\u4e4b\u7684\u65e0\u5948\u4e4b\u4e3e\u3002\u4e00\u65b9\u9762\uff0c\u5305\u542b\u4ee3\u7406\u5bf9\u7684\u5b57\u7b26\u4e32\u4e2d\uff0c\u4e00\u4e2a\u5b57\u7b26\u53ef\u80fd\u5360\u7528 2 \u5b57\u8282\u6216 4 \u5b57\u8282\uff0c\u4ece\u800c\u4e27\u5931\u4e86\u7b49\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u5904\u7406\u4ee3\u7406\u5bf9\u9700\u8981\u989d\u5916\u589e\u52a0\u4ee3\u7801\uff0c\u8fd9\u63d0\u9ad8\u4e86\u7f16\u7a0b\u7684\u590d\u6742\u6027\u548c\u8c03\u8bd5\u96be\u5ea6\u3002

    \u51fa\u4e8e\u4ee5\u4e0a\u539f\u56e0\uff0c\u90e8\u5206\u7f16\u7a0b\u8bed\u8a00\u63d0\u51fa\u4e86\u4e00\u4e9b\u4e0d\u540c\u7684\u7f16\u7801\u65b9\u6848\u3002

    • Python \u4e2d\u7684 str \u4f7f\u7528 Unicode \u7f16\u7801\uff0c\u5e76\u91c7\u7528\u4e00\u79cd\u7075\u6d3b\u7684\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u5b58\u50a8\u7684\u5b57\u7b26\u957f\u5ea6\u53d6\u51b3\u4e8e\u5b57\u7b26\u4e32\u4e2d\u6700\u5927\u7684 Unicode \u7801\u70b9\u3002\u82e5\u5b57\u7b26\u4e32\u4e2d\u5168\u90e8\u662f ASCII \u5b57\u7b26\uff0c\u5219\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 1 \u5b57\u8282\uff1b\u5982\u679c\u6709\u5b57\u7b26\u8d85\u51fa\u4e86 ASCII \u8303\u56f4\uff0c\u4f46\u5168\u90e8\u5728\u57fa\u672c\u591a\u8bed\u8a00\u5e73\u9762\uff08BMP\uff09\u5185\uff0c\u5219\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 2 \u5b57\u8282\uff1b\u5982\u679c\u6709\u8d85\u51fa BMP \u7684\u5b57\u7b26\uff0c\u5219\u6bcf\u4e2a\u5b57\u7b26\u5360\u7528 4 \u5b57\u8282\u3002
    • Go \u8bed\u8a00\u7684 string \u7c7b\u578b\u5728\u5185\u90e8\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002Go \u8bed\u8a00\u8fd8\u63d0\u4f9b\u4e86 rune \u7c7b\u578b\uff0c\u5b83\u7528\u4e8e\u8868\u793a\u5355\u4e2a Unicode \u7801\u70b9\u3002
    • Rust \u8bed\u8a00\u7684 str \u548c String \u7c7b\u578b\u5728\u5185\u90e8\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002Rust \u4e5f\u63d0\u4f9b\u4e86 char \u7c7b\u578b\uff0c\u7528\u4e8e\u8868\u793a\u5355\u4e2a Unicode \u7801\u70b9\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4ee5\u4e0a\u8ba8\u8bba\u7684\u90fd\u662f\u5b57\u7b26\u4e32\u5728\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u5b58\u50a8\u65b9\u5f0f\uff0c\u8fd9\u548c\u5b57\u7b26\u4e32\u5982\u4f55\u5728\u6587\u4ef6\u4e2d\u5b58\u50a8\u6216\u5728\u7f51\u7edc\u4e2d\u4f20\u8f93\u662f\u4e0d\u540c\u7684\u95ee\u9898\u3002\u5728\u6587\u4ef6\u5b58\u50a8\u6216\u7f51\u7edc\u4f20\u8f93\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5c06\u5b57\u7b26\u4e32\u7f16\u7801\u4e3a UTF-8 \u683c\u5f0f\uff0c\u4ee5\u8fbe\u5230\u6700\u4f18\u7684\u517c\u5bb9\u6027\u548c\u7a7a\u95f4\u6548\u7387\u3002

    "},{"location":"chapter_data_structure/classification_of_data_structure/","title":"3.1 \u00a0 \u6570\u636e\u7ed3\u6784\u5206\u7c7b","text":"

    \u5e38\u89c1\u7684\u6570\u636e\u7ed3\u6784\u5305\u62ec\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\uff0c\u5b83\u4eec\u53ef\u4ee5\u4ece\u201c\u903b\u8f91\u7ed3\u6784\u201d\u548c\u201c\u7269\u7406\u7ed3\u6784\u201d\u4e24\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u5206\u7c7b\u3002

    "},{"location":"chapter_data_structure/classification_of_data_structure/#311","title":"3.1.1 \u00a0 \u903b\u8f91\u7ed3\u6784\uff1a\u7ebf\u6027\u4e0e\u975e\u7ebf\u6027","text":"

    \u903b\u8f91\u7ed3\u6784\u63ed\u793a\u4e86\u6570\u636e\u5143\u7d20\u4e4b\u95f4\u7684\u903b\u8f91\u5173\u7cfb\u3002\u5728\u6570\u7ec4\u548c\u94fe\u8868\u4e2d\uff0c\u6570\u636e\u6309\u7167\u4e00\u5b9a\u987a\u5e8f\u6392\u5217\uff0c\u4f53\u73b0\u4e86\u6570\u636e\u4e4b\u95f4\u7684\u7ebf\u6027\u5173\u7cfb\uff1b\u800c\u5728\u6811\u4e2d\uff0c\u6570\u636e\u4ece\u9876\u90e8\u5411\u4e0b\u6309\u5c42\u6b21\u6392\u5217\uff0c\u8868\u73b0\u51fa\u201c\u7956\u5148\u201d\u4e0e\u201c\u540e\u4ee3\u201d\u4e4b\u95f4\u7684\u6d3e\u751f\u5173\u7cfb\uff1b\u56fe\u5219\u7531\u8282\u70b9\u548c\u8fb9\u6784\u6210\uff0c\u53cd\u6620\u4e86\u590d\u6742\u7684\u7f51\u7edc\u5173\u7cfb\u3002

    \u5982\u56fe 3-1 \u6240\u793a\uff0c\u903b\u8f91\u7ed3\u6784\u53ef\u5206\u4e3a\u201c\u7ebf\u6027\u201d\u548c\u201c\u975e\u7ebf\u6027\u201d\u4e24\u5927\u7c7b\u3002\u7ebf\u6027\u7ed3\u6784\u6bd4\u8f83\u76f4\u89c2\uff0c\u6307\u6570\u636e\u5728\u903b\u8f91\u5173\u7cfb\u4e0a\u5448\u7ebf\u6027\u6392\u5217\uff1b\u975e\u7ebf\u6027\u7ed3\u6784\u5219\u76f8\u53cd\uff0c\u5448\u975e\u7ebf\u6027\u6392\u5217\u3002

    • \u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff1a\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\uff0c\u5143\u7d20\u4e4b\u95f4\u662f\u4e00\u5bf9\u4e00\u7684\u987a\u5e8f\u5173\u7cfb\u3002
    • \u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff1a\u6811\u3001\u5806\u3001\u56fe\u3001\u54c8\u5e0c\u8868\u3002

    \u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u8fdb\u4e00\u6b65\u5212\u5206\u4e3a\u6811\u5f62\u7ed3\u6784\u548c\u7f51\u72b6\u7ed3\u6784\u3002

    • \u6811\u5f62\u7ed3\u6784\uff1a\u6811\u3001\u5806\u3001\u54c8\u5e0c\u8868\uff0c\u5143\u7d20\u4e4b\u95f4\u662f\u4e00\u5bf9\u591a\u7684\u5173\u7cfb\u3002
    • \u7f51\u72b6\u7ed3\u6784\uff1a\u56fe\uff0c\u5143\u7d20\u4e4b\u95f4\u662f\u591a\u5bf9\u591a\u7684\u5173\u7cfb\u3002

    \u56fe 3-1 \u00a0 \u7ebf\u6027\u6570\u636e\u7ed3\u6784\u4e0e\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784

    "},{"location":"chapter_data_structure/classification_of_data_structure/#312","title":"3.1.2 \u00a0 \u7269\u7406\u7ed3\u6784\uff1a\u8fde\u7eed\u4e0e\u5206\u6563","text":"

    \u5f53\u7b97\u6cd5\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6b63\u5728\u5904\u7406\u7684\u6570\u636e\u4e3b\u8981\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\u3002\u56fe 3-2 \u5c55\u793a\u4e86\u4e00\u4e2a\u8ba1\u7b97\u673a\u5185\u5b58\u6761\uff0c\u5176\u4e2d\u6bcf\u4e2a\u9ed1\u8272\u65b9\u5757\u90fd\u5305\u542b\u4e00\u5757\u5185\u5b58\u7a7a\u95f4\u3002\u6211\u4eec\u53ef\u4ee5\u5c06\u5185\u5b58\u60f3\u8c61\u6210\u4e00\u4e2a\u5de8\u5927\u7684 Excel \u8868\u683c\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5355\u5143\u683c\u90fd\u53ef\u4ee5\u5b58\u50a8\u4e00\u5b9a\u5927\u5c0f\u7684\u6570\u636e\u3002

    \u7cfb\u7edf\u901a\u8fc7\u5185\u5b58\u5730\u5740\u6765\u8bbf\u95ee\u76ee\u6807\u4f4d\u7f6e\u7684\u6570\u636e\u3002\u5982\u56fe 3-2 \u6240\u793a\uff0c\u8ba1\u7b97\u673a\u6839\u636e\u7279\u5b9a\u89c4\u5219\u4e3a\u8868\u683c\u4e2d\u7684\u6bcf\u4e2a\u5355\u5143\u683c\u5206\u914d\u7f16\u53f7\uff0c\u786e\u4fdd\u6bcf\u4e2a\u5185\u5b58\u7a7a\u95f4\u90fd\u6709\u552f\u4e00\u7684\u5185\u5b58\u5730\u5740\u3002\u6709\u4e86\u8fd9\u4e9b\u5730\u5740\uff0c\u7a0b\u5e8f\u4fbf\u53ef\u4ee5\u8bbf\u95ee\u5185\u5b58\u4e2d\u7684\u6570\u636e\u3002

    \u56fe 3-2 \u00a0 \u5185\u5b58\u6761\u3001\u5185\u5b58\u7a7a\u95f4\u3001\u5185\u5b58\u5730\u5740

    Tip

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u5c06\u5185\u5b58\u6bd4\u4f5c Excel \u8868\u683c\u662f\u4e00\u4e2a\u7b80\u5316\u7684\u7c7b\u6bd4\uff0c\u5b9e\u9645\u5185\u5b58\u7684\u5de5\u4f5c\u673a\u5236\u6bd4\u8f83\u590d\u6742\uff0c\u6d89\u53ca\u5730\u5740\u7a7a\u95f4\u3001\u5185\u5b58\u7ba1\u7406\u3001\u7f13\u5b58\u673a\u5236\u3001\u865a\u62df\u5185\u5b58\u548c\u7269\u7406\u5185\u5b58\u7b49\u6982\u5ff5\u3002

    \u5185\u5b58\u662f\u6240\u6709\u7a0b\u5e8f\u7684\u5171\u4eab\u8d44\u6e90\uff0c\u5f53\u67d0\u5757\u5185\u5b58\u88ab\u67d0\u4e2a\u7a0b\u5e8f\u5360\u7528\u65f6\uff0c\u5219\u65e0\u6cd5\u88ab\u5176\u4ed6\u7a0b\u5e8f\u540c\u65f6\u4f7f\u7528\u4e86\u3002\u56e0\u6b64\u5728\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u8bbe\u8ba1\u4e2d\uff0c\u5185\u5b58\u8d44\u6e90\u662f\u4e00\u4e2a\u91cd\u8981\u7684\u8003\u8651\u56e0\u7d20\u3002\u6bd4\u5982\uff0c\u7b97\u6cd5\u6240\u5360\u7528\u7684\u5185\u5b58\u5cf0\u503c\u4e0d\u5e94\u8d85\u8fc7\u7cfb\u7edf\u5269\u4f59\u7a7a\u95f2\u5185\u5b58\uff1b\u5982\u679c\u7f3a\u5c11\u8fde\u7eed\u5927\u5757\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u90a3\u4e48\u6240\u9009\u7528\u7684\u6570\u636e\u7ed3\u6784\u5fc5\u987b\u80fd\u591f\u5b58\u50a8\u5728\u5206\u6563\u7684\u5185\u5b58\u7a7a\u95f4\u5185\u3002

    \u5982\u56fe 3-3 \u6240\u793a\uff0c\u7269\u7406\u7ed3\u6784\u53cd\u6620\u4e86\u6570\u636e\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u7684\u5b58\u50a8\u65b9\u5f0f\uff0c\u53ef\u5206\u4e3a\u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\uff08\u6570\u7ec4\uff09\u548c\u5206\u6563\u7a7a\u95f4\u5b58\u50a8\uff08\u94fe\u8868\uff09\u3002\u7269\u7406\u7ed3\u6784\u4ece\u5e95\u5c42\u51b3\u5b9a\u4e86\u6570\u636e\u7684\u8bbf\u95ee\u3001\u66f4\u65b0\u3001\u589e\u5220\u7b49\u64cd\u4f5c\u65b9\u6cd5\uff0c\u4e24\u79cd\u7269\u7406\u7ed3\u6784\u5728\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u65b9\u9762\u5448\u73b0\u51fa\u4e92\u8865\u7684\u7279\u70b9\u3002

    \u56fe 3-3 \u00a0 \u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\u4e0e\u5206\u6563\u7a7a\u95f4\u5b58\u50a8

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6240\u6709\u6570\u636e\u7ed3\u6784\u90fd\u662f\u57fa\u4e8e\u6570\u7ec4\u3001\u94fe\u8868\u6216\u4e8c\u8005\u7684\u7ec4\u5408\u5b9e\u73b0\u7684\u3002\u4f8b\u5982\uff0c\u6808\u548c\u961f\u5217\u65e2\u53ef\u4ee5\u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u94fe\u8868\u5b9e\u73b0\uff1b\u800c\u54c8\u5e0c\u8868\u7684\u5b9e\u73b0\u53ef\u80fd\u540c\u65f6\u5305\u542b\u6570\u7ec4\u548c\u94fe\u8868\u3002

    • \u57fa\u4e8e\u6570\u7ec4\u53ef\u5b9e\u73b0\uff1a\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\u3001\u77e9\u9635\u3001\u5f20\u91cf\uff08\u7ef4\u5ea6 \\(\\geq 3\\) \u7684\u6570\u7ec4\uff09\u7b49\u3002
    • \u57fa\u4e8e\u94fe\u8868\u53ef\u5b9e\u73b0\uff1a\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\u7b49\u3002

    \u94fe\u8868\u5728\u521d\u59cb\u5316\u540e\uff0c\u4ecd\u53ef\u4ee5\u5728\u7a0b\u5e8f\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u5bf9\u5176\u957f\u5ea6\u8fdb\u884c\u8c03\u6574\uff0c\u56e0\u6b64\u4e5f\u79f0\u201c\u52a8\u6001\u6570\u636e\u7ed3\u6784\u201d\u3002\u6570\u7ec4\u5728\u521d\u59cb\u5316\u540e\u957f\u5ea6\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u4e5f\u79f0\u201c\u9759\u6001\u6570\u636e\u7ed3\u6784\u201d\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6570\u7ec4\u53ef\u901a\u8fc7\u91cd\u65b0\u5206\u914d\u5185\u5b58\u5b9e\u73b0\u957f\u5ea6\u53d8\u5316\uff0c\u4ece\u800c\u5177\u5907\u4e00\u5b9a\u7684\u201c\u52a8\u6001\u6027\u201d\u3002

    Tip

    \u5982\u679c\u4f60\u611f\u89c9\u7269\u7406\u7ed3\u6784\u7406\u89e3\u8d77\u6765\u6709\u56f0\u96be\uff0c\u5efa\u8bae\u5148\u9605\u8bfb\u4e0b\u4e00\u7ae0\uff0c\u7136\u540e\u518d\u56de\u987e\u672c\u8282\u5185\u5bb9\u3002

    "},{"location":"chapter_data_structure/number_encoding/","title":"3.3 \u00a0 \u6570\u5b57\u7f16\u7801 *","text":"

    Tip

    \u5728\u672c\u4e66\u4e2d\uff0c\u6807\u9898\u5e26\u6709 * \u7b26\u53f7\u7684\u662f\u9009\u8bfb\u7ae0\u8282\u3002\u5982\u679c\u4f60\u65f6\u95f4\u6709\u9650\u6216\u611f\u5230\u7406\u89e3\u56f0\u96be\uff0c\u53ef\u4ee5\u5148\u8df3\u8fc7\uff0c\u7b49\u5b66\u5b8c\u5fc5\u8bfb\u7ae0\u8282\u540e\u518d\u5355\u72ec\u653b\u514b\u3002

    "},{"location":"chapter_data_structure/number_encoding/#331","title":"3.3.1 \u00a0 \u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801","text":"

    \u5728\u4e0a\u4e00\u8282\u7684\u8868\u683c\u4e2d\u6211\u4eec\u53d1\u73b0\uff0c\u6240\u6709\u6574\u6570\u7c7b\u578b\u80fd\u591f\u8868\u793a\u7684\u8d1f\u6570\u90fd\u6bd4\u6b63\u6570\u591a\u4e00\u4e2a\uff0c\u4f8b\u5982 byte \u7684\u53d6\u503c\u8303\u56f4\u662f \\([-128, 127]\\) \u3002\u8fd9\u4e2a\u73b0\u8c61\u6bd4\u8f83\u53cd\u76f4\u89c9\uff0c\u5b83\u7684\u5185\u5728\u539f\u56e0\u6d89\u53ca\u539f\u7801\u3001\u53cd\u7801\u3001\u8865\u7801\u7684\u76f8\u5173\u77e5\u8bc6\u3002

    \u9996\u5148\u9700\u8981\u6307\u51fa\uff0c\u6570\u5b57\u662f\u4ee5\u201c\u8865\u7801\u201d\u7684\u5f62\u5f0f\u5b58\u50a8\u5728\u8ba1\u7b97\u673a\u4e2d\u7684\u3002\u5728\u5206\u6790\u8fd9\u6837\u505a\u7684\u539f\u56e0\u4e4b\u524d\uff0c\u9996\u5148\u7ed9\u51fa\u4e09\u8005\u7684\u5b9a\u4e49\u3002

    • \u539f\u7801\uff1a\u6211\u4eec\u5c06\u6570\u5b57\u7684\u4e8c\u8fdb\u5236\u8868\u793a\u7684\u6700\u9ad8\u4f4d\u89c6\u4e3a\u7b26\u53f7\u4f4d\uff0c\u5176\u4e2d \\(0\\) \u8868\u793a\u6b63\u6570\uff0c\\(1\\) \u8868\u793a\u8d1f\u6570\uff0c\u5176\u4f59\u4f4d\u8868\u793a\u6570\u5b57\u7684\u503c\u3002
    • \u53cd\u7801\uff1a\u6b63\u6570\u7684\u53cd\u7801\u4e0e\u5176\u539f\u7801\u76f8\u540c\uff0c\u8d1f\u6570\u7684\u53cd\u7801\u662f\u5bf9\u5176\u539f\u7801\u9664\u7b26\u53f7\u4f4d\u5916\u7684\u6240\u6709\u4f4d\u53d6\u53cd\u3002
    • \u8865\u7801\uff1a\u6b63\u6570\u7684\u8865\u7801\u4e0e\u5176\u539f\u7801\u76f8\u540c\uff0c\u8d1f\u6570\u7684\u8865\u7801\u662f\u5728\u5176\u53cd\u7801\u7684\u57fa\u7840\u4e0a\u52a0 \\(1\\) \u3002

    \u56fe 3-4 \u5c55\u793a\u4e86\u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801\u4e4b\u95f4\u7684\u8f6c\u6362\u65b9\u6cd5\u3002

    \u56fe 3-4 \u00a0 \u539f\u7801\u3001\u53cd\u7801\u4e0e\u8865\u7801\u4e4b\u95f4\u7684\u76f8\u4e92\u8f6c\u6362

    \u539f\u7801\uff08sign-magnitude\uff09\u867d\u7136\u6700\u76f4\u89c2\uff0c\u4f46\u5b58\u5728\u4e00\u4e9b\u5c40\u9650\u6027\u3002\u4e00\u65b9\u9762\uff0c\u8d1f\u6570\u7684\u539f\u7801\u4e0d\u80fd\u76f4\u63a5\u7528\u4e8e\u8fd0\u7b97\u3002\u4f8b\u5982\u5728\u539f\u7801\u4e0b\u8ba1\u7b97 \\(1 + (-2)\\) \uff0c\u5f97\u5230\u7684\u7ed3\u679c\u662f \\(-3\\) \uff0c\u8fd9\u663e\u7136\u662f\u4e0d\u5bf9\u7684\u3002

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 + 1000 \\; 0010 \\newline & = 1000 \\; 0011 \\newline & \\rightarrow -3 \\end{aligned} \\]

    \u4e3a\u4e86\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u8ba1\u7b97\u673a\u5f15\u5165\u4e86\u53cd\u7801\uff081's complement\uff09\u3002\u5982\u679c\u6211\u4eec\u5148\u5c06\u539f\u7801\u8f6c\u6362\u4e3a\u53cd\u7801\uff0c\u5e76\u5728\u53cd\u7801\u4e0b\u8ba1\u7b97 \\(1 + (-2)\\) \uff0c\u6700\u540e\u5c06\u7ed3\u679c\u4ece\u53cd\u7801\u8f6c\u6362\u56de\u539f\u7801\uff0c\u5219\u53ef\u5f97\u5230\u6b63\u786e\u7ed3\u679c \\(-1\\) \u3002

    \\[ \\begin{aligned} & 1 + (-2) \\newline & \\rightarrow 0000 \\; 0001 \\; \\text{(\u539f\u7801)} + 1000 \\; 0010 \\; \\text{(\u539f\u7801)} \\newline & = 0000 \\; 0001 \\; \\text{(\u53cd\u7801)} + 1111 \\; 1101 \\; \\text{(\u53cd\u7801)} \\newline & = 1111 \\; 1110 \\; \\text{(\u53cd\u7801)} \\newline & = 1000 \\; 0001 \\; \\text{(\u539f\u7801)} \\newline & \\rightarrow -1 \\end{aligned} \\]

    \u53e6\u4e00\u65b9\u9762\uff0c\u6570\u5b57\u96f6\u7684\u539f\u7801\u6709 \\(+0\\) \u548c \\(-0\\) \u4e24\u79cd\u8868\u793a\u65b9\u5f0f\u3002\u8fd9\u610f\u5473\u7740\u6570\u5b57\u96f6\u5bf9\u5e94\u4e24\u4e2a\u4e0d\u540c\u7684\u4e8c\u8fdb\u5236\u7f16\u7801\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5e26\u6765\u6b67\u4e49\u3002\u6bd4\u5982\u5728\u6761\u4ef6\u5224\u65ad\u4e2d\uff0c\u5982\u679c\u6ca1\u6709\u533a\u5206\u6b63\u96f6\u548c\u8d1f\u96f6\uff0c\u5219\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5224\u65ad\u7ed3\u679c\u51fa\u9519\u3002\u800c\u5982\u679c\u6211\u4eec\u60f3\u5904\u7406\u6b63\u96f6\u548c\u8d1f\u96f6\u6b67\u4e49\uff0c\u5219\u9700\u8981\u5f15\u5165\u989d\u5916\u7684\u5224\u65ad\u64cd\u4f5c\uff0c\u8fd9\u53ef\u80fd\u4f1a\u964d\u4f4e\u8ba1\u7b97\u673a\u7684\u8fd0\u7b97\u6548\u7387\u3002

    \\[ \\begin{aligned} +0 & \\rightarrow 0000 \\; 0000 \\newline -0 & \\rightarrow 1000 \\; 0000 \\end{aligned} \\]

    \u4e0e\u539f\u7801\u4e00\u6837\uff0c\u53cd\u7801\u4e5f\u5b58\u5728\u6b63\u8d1f\u96f6\u6b67\u4e49\u95ee\u9898\uff0c\u56e0\u6b64\u8ba1\u7b97\u673a\u8fdb\u4e00\u6b65\u5f15\u5165\u4e86\u8865\u7801\uff082's complement\uff09\u3002\u6211\u4eec\u5148\u6765\u89c2\u5bdf\u4e00\u4e0b\u8d1f\u96f6\u7684\u539f\u7801\u3001\u53cd\u7801\u3001\u8865\u7801\u7684\u8f6c\u6362\u8fc7\u7a0b\uff1a

    \\[ \\begin{aligned} -0 \\rightarrow \\; & 1000 \\; 0000 \\; \\text{(\u539f\u7801)} \\newline = \\; & 1111 \\; 1111 \\; \\text{(\u53cd\u7801)} \\newline = 1 \\; & 0000 \\; 0000 \\; \\text{(\u8865\u7801)} \\newline \\end{aligned} \\]

    \u5728\u8d1f\u96f6\u7684\u53cd\u7801\u57fa\u7840\u4e0a\u52a0 \\(1\\) \u4f1a\u4ea7\u751f\u8fdb\u4f4d\uff0c\u4f46 byte \u7c7b\u578b\u7684\u957f\u5ea6\u53ea\u6709 8 \u4f4d\uff0c\u56e0\u6b64\u6ea2\u51fa\u5230\u7b2c 9 \u4f4d\u7684 \\(1\\) \u4f1a\u88ab\u820d\u5f03\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u8d1f\u96f6\u7684\u8865\u7801\u4e3a \\(0000 \\; 0000\\) \uff0c\u4e0e\u6b63\u96f6\u7684\u8865\u7801\u76f8\u540c\u3002\u8fd9\u610f\u5473\u7740\u5728\u8865\u7801\u8868\u793a\u4e2d\u53ea\u5b58\u5728\u4e00\u4e2a\u96f6\uff0c\u6b63\u8d1f\u96f6\u6b67\u4e49\u4ece\u800c\u5f97\u5230\u89e3\u51b3\u3002

    \u8fd8\u5269\u6700\u540e\u4e00\u4e2a\u7591\u60d1\uff1abyte \u7c7b\u578b\u7684\u53d6\u503c\u8303\u56f4\u662f \\([-128, 127]\\) \uff0c\u591a\u51fa\u6765\u7684\u4e00\u4e2a\u8d1f\u6570 \\(-128\\) \u662f\u5982\u4f55\u5f97\u5230\u7684\u5462\uff1f\u6211\u4eec\u6ce8\u610f\u5230\uff0c\u533a\u95f4 \\([-127, +127]\\) \u5185\u7684\u6240\u6709\u6574\u6570\u90fd\u6709\u5bf9\u5e94\u7684\u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801\uff0c\u5e76\u4e14\u539f\u7801\u548c\u8865\u7801\u4e4b\u95f4\u53ef\u4ee5\u4e92\u76f8\u8f6c\u6362\u3002

    \u7136\u800c\uff0c\u8865\u7801 \\(1000 \\; 0000\\) \u662f\u4e00\u4e2a\u4f8b\u5916\uff0c\u5b83\u5e76\u6ca1\u6709\u5bf9\u5e94\u7684\u539f\u7801\u3002\u6839\u636e\u8f6c\u6362\u65b9\u6cd5\uff0c\u6211\u4eec\u5f97\u5230\u8be5\u8865\u7801\u7684\u539f\u7801\u4e3a \\(0000 \\; 0000\\) \u3002\u8fd9\u663e\u7136\u662f\u77db\u76fe\u7684\uff0c\u56e0\u4e3a\u8be5\u539f\u7801\u8868\u793a\u6570\u5b57 \\(0\\) \uff0c\u5b83\u7684\u8865\u7801\u5e94\u8be5\u662f\u81ea\u8eab\u3002\u8ba1\u7b97\u673a\u89c4\u5b9a\u8fd9\u4e2a\u7279\u6b8a\u7684\u8865\u7801 \\(1000 \\; 0000\\) \u4ee3\u8868 \\(-128\\) \u3002\u5b9e\u9645\u4e0a\uff0c\\((-1) + (-127)\\) \u5728\u8865\u7801\u4e0b\u7684\u8ba1\u7b97\u7ed3\u679c\u5c31\u662f \\(-128\\) \u3002

    \\[ \\begin{aligned} & (-127) + (-1) \\newline & \\rightarrow 1111 \\; 1111 \\; \\text{(\u539f\u7801)} + 1000 \\; 0001 \\; \\text{(\u539f\u7801)} \\newline & = 1000 \\; 0000 \\; \\text{(\u53cd\u7801)} + 1111 \\; 1110 \\; \\text{(\u53cd\u7801)} \\newline & = 1000 \\; 0001 \\; \\text{(\u8865\u7801)} + 1111 \\; 1111 \\; \\text{(\u8865\u7801)} \\newline & = 1000 \\; 0000 \\; \\text{(\u8865\u7801)} \\newline & \\rightarrow -128 \\end{aligned} \\]

    \u4f60\u53ef\u80fd\u5df2\u7ecf\u53d1\u73b0\u4e86\uff0c\u4e0a\u8ff0\u6240\u6709\u8ba1\u7b97\u90fd\u662f\u52a0\u6cd5\u8fd0\u7b97\u3002\u8fd9\u6697\u793a\u7740\u4e00\u4e2a\u91cd\u8981\u4e8b\u5b9e\uff1a\u8ba1\u7b97\u673a\u5185\u90e8\u7684\u786c\u4ef6\u7535\u8def\u4e3b\u8981\u662f\u57fa\u4e8e\u52a0\u6cd5\u8fd0\u7b97\u8bbe\u8ba1\u7684\u3002\u8fd9\u662f\u56e0\u4e3a\u52a0\u6cd5\u8fd0\u7b97\u76f8\u5bf9\u4e8e\u5176\u4ed6\u8fd0\u7b97\uff08\u6bd4\u5982\u4e58\u6cd5\u3001\u9664\u6cd5\u548c\u51cf\u6cd5\uff09\u6765\u8bf4\uff0c\u786c\u4ef6\u5b9e\u73b0\u8d77\u6765\u66f4\u7b80\u5355\uff0c\u66f4\u5bb9\u6613\u8fdb\u884c\u5e76\u884c\u5316\u5904\u7406\uff0c\u8fd0\u7b97\u901f\u5ea6\u66f4\u5feb\u3002

    \u8bf7\u6ce8\u610f\uff0c\u8fd9\u5e76\u4e0d\u610f\u5473\u7740\u8ba1\u7b97\u673a\u53ea\u80fd\u505a\u52a0\u6cd5\u3002\u901a\u8fc7\u5c06\u52a0\u6cd5\u4e0e\u4e00\u4e9b\u57fa\u672c\u903b\u8f91\u8fd0\u7b97\u7ed3\u5408\uff0c\u8ba1\u7b97\u673a\u80fd\u591f\u5b9e\u73b0\u5404\u79cd\u5176\u4ed6\u7684\u6570\u5b66\u8fd0\u7b97\u3002\u4f8b\u5982\uff0c\u8ba1\u7b97\u51cf\u6cd5 \\(a - b\\) \u53ef\u4ee5\u8f6c\u6362\u4e3a\u8ba1\u7b97\u52a0\u6cd5 \\(a + (-b)\\) \uff1b\u8ba1\u7b97\u4e58\u6cd5\u548c\u9664\u6cd5\u53ef\u4ee5\u8f6c\u6362\u4e3a\u8ba1\u7b97\u591a\u6b21\u52a0\u6cd5\u6216\u51cf\u6cd5\u3002

    \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u603b\u7ed3\u51fa\u8ba1\u7b97\u673a\u4f7f\u7528\u8865\u7801\u7684\u539f\u56e0\uff1a\u57fa\u4e8e\u8865\u7801\u8868\u793a\uff0c\u8ba1\u7b97\u673a\u53ef\u4ee5\u7528\u540c\u6837\u7684\u7535\u8def\u548c\u64cd\u4f5c\u6765\u5904\u7406\u6b63\u6570\u548c\u8d1f\u6570\u7684\u52a0\u6cd5\uff0c\u4e0d\u9700\u8981\u8bbe\u8ba1\u7279\u6b8a\u7684\u786c\u4ef6\u7535\u8def\u6765\u5904\u7406\u51cf\u6cd5\uff0c\u5e76\u4e14\u65e0\u987b\u7279\u522b\u5904\u7406\u6b63\u8d1f\u96f6\u7684\u6b67\u4e49\u95ee\u9898\u3002\u8fd9\u5927\u5927\u7b80\u5316\u4e86\u786c\u4ef6\u8bbe\u8ba1\uff0c\u63d0\u9ad8\u4e86\u8fd0\u7b97\u6548\u7387\u3002

    \u8865\u7801\u7684\u8bbe\u8ba1\u975e\u5e38\u7cbe\u5999\uff0c\u56e0\u7bc7\u5e45\u5173\u7cfb\u6211\u4eec\u5c31\u5148\u4ecb\u7ecd\u5230\u8fd9\u91cc\uff0c\u5efa\u8bae\u6709\u5174\u8da3\u7684\u8bfb\u8005\u8fdb\u4e00\u6b65\u6df1\u5165\u4e86\u89e3\u3002

    "},{"location":"chapter_data_structure/number_encoding/#332","title":"3.3.2 \u00a0 \u6d6e\u70b9\u6570\u7f16\u7801","text":"

    \u7ec6\u5fc3\u7684\u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0\uff1aint \u548c float \u957f\u5ea6\u76f8\u540c\uff0c\u90fd\u662f 4 \u5b57\u8282 \uff0c\u4f46\u4e3a\u4ec0\u4e48 float \u7684\u53d6\u503c\u8303\u56f4\u8fdc\u5927\u4e8e int \uff1f\u8fd9\u975e\u5e38\u53cd\u76f4\u89c9\uff0c\u56e0\u4e3a\u6309\u7406\u8bf4 float \u9700\u8981\u8868\u793a\u5c0f\u6570\uff0c\u53d6\u503c\u8303\u56f4\u5e94\u8be5\u53d8\u5c0f\u624d\u5bf9\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8fd9\u662f\u56e0\u4e3a\u6d6e\u70b9\u6570 float \u91c7\u7528\u4e86\u4e0d\u540c\u7684\u8868\u793a\u65b9\u5f0f\u3002\u8bb0\u4e00\u4e2a 32 \u6bd4\u7279\u957f\u5ea6\u7684\u4e8c\u8fdb\u5236\u6570\u4e3a\uff1a

    \\[ b_{31} b_{30} b_{29} \\ldots b_2 b_1 b_0 \\]

    \u6839\u636e IEEE 754 \u6807\u51c6\uff0c32-bit \u957f\u5ea6\u7684 float \u7531\u4ee5\u4e0b\u4e09\u4e2a\u90e8\u5206\u6784\u6210\u3002

    • \u7b26\u53f7\u4f4d \\(\\mathrm{S}\\) \uff1a\u5360 1 \u4f4d \uff0c\u5bf9\u5e94 \\(b_{31}\\) \u3002
    • \u6307\u6570\u4f4d \\(\\mathrm{E}\\) \uff1a\u5360 8 \u4f4d \uff0c\u5bf9\u5e94 \\(b_{30} b_{29} \\ldots b_{23}\\) \u3002
    • \u5206\u6570\u4f4d \\(\\mathrm{N}\\) \uff1a\u5360 23 \u4f4d \uff0c\u5bf9\u5e94 \\(b_{22} b_{21} \\ldots b_0\\) \u3002

    \u4e8c\u8fdb\u5236\u6570 float \u5bf9\u5e94\u503c\u7684\u8ba1\u7b97\u65b9\u6cd5\u4e3a\uff1a

    \\[ \\text {val} = (-1)^{b_{31}} \\times 2^{\\left(b_{30} b_{29} \\ldots b_{23}\\right)_2-127} \\times\\left(1 . b_{22} b_{21} \\ldots b_0\\right)_2 \\]

    \u8f6c\u5316\u5230\u5341\u8fdb\u5236\u4e0b\u7684\u8ba1\u7b97\u516c\u5f0f\u4e3a\uff1a

    \\[ \\text {val}=(-1)^{\\mathrm{S}} \\times 2^{\\mathrm{E} -127} \\times (1 + \\mathrm{N}) \\]

    \u5176\u4e2d\u5404\u9879\u7684\u53d6\u503c\u8303\u56f4\u4e3a\uff1a

    \\[ \\begin{aligned} \\mathrm{S} \\in & \\{ 0, 1\\}, \\quad \\mathrm{E} \\in \\{ 1, 2, \\dots, 254 \\} \\newline (1 + \\mathrm{N}) = & (1 + \\sum_{i=1}^{23} b_{23-i} 2^{-i}) \\subset [1, 2 - 2^{-23}] \\end{aligned} \\]

    \u56fe 3-5 \u00a0 IEEE 754 \u6807\u51c6\u4e0b\u7684 float \u7684\u8ba1\u7b97\u793a\u4f8b

    \u89c2\u5bdf\u56fe 3-5 \uff0c\u7ed9\u5b9a\u4e00\u4e2a\u793a\u4f8b\u6570\u636e \\(\\mathrm{S} = 0\\) \uff0c \\(\\mathrm{E} = 124\\) \uff0c\\(\\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\\) \uff0c\u5219\u6709\uff1a

    \\[ \\text { val } = (-1)^0 \\times 2^{124 - 127} \\times (1 + 0.375) = 0.171875 \\]

    \u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u56de\u7b54\u6700\u521d\u7684\u95ee\u9898\uff1afloat \u7684\u8868\u793a\u65b9\u5f0f\u5305\u542b\u6307\u6570\u4f4d\uff0c\u5bfc\u81f4\u5176\u53d6\u503c\u8303\u56f4\u8fdc\u5927\u4e8e int \u3002\u6839\u636e\u4ee5\u4e0a\u8ba1\u7b97\uff0cfloat \u53ef\u8868\u793a\u7684\u6700\u5927\u6b63\u6570\u4e3a \\(2^{254 - 127} \\times (2 - 2^{-23}) \\approx 3.4 \\times 10^{38}\\) \uff0c\u5207\u6362\u7b26\u53f7\u4f4d\u4fbf\u53ef\u5f97\u5230\u6700\u5c0f\u8d1f\u6570\u3002

    \u5c3d\u7ba1\u6d6e\u70b9\u6570 float \u6269\u5c55\u4e86\u53d6\u503c\u8303\u56f4\uff0c\u4f46\u5176\u526f\u4f5c\u7528\u662f\u727a\u7272\u4e86\u7cbe\u5ea6\u3002\u6574\u6570\u7c7b\u578b int \u5c06\u5168\u90e8 32 \u6bd4\u7279\u7528\u4e8e\u8868\u793a\u6570\u5b57\uff0c\u6570\u5b57\u662f\u5747\u5300\u5206\u5e03\u7684\uff1b\u800c\u7531\u4e8e\u6307\u6570\u4f4d\u7684\u5b58\u5728\uff0c\u6d6e\u70b9\u6570 float \u7684\u6570\u503c\u8d8a\u5927\uff0c\u76f8\u90bb\u4e24\u4e2a\u6570\u5b57\u4e4b\u95f4\u7684\u5dee\u503c\u5c31\u4f1a\u8d8b\u5411\u8d8a\u5927\u3002

    \u5982\u8868 3-2 \u6240\u793a\uff0c\u6307\u6570\u4f4d \\(\\mathrm{E} = 0\\) \u548c \\(\\mathrm{E} = 255\\) \u5177\u6709\u7279\u6b8a\u542b\u4e49\uff0c\u7528\u4e8e\u8868\u793a\u96f6\u3001\u65e0\u7a77\u5927\u3001\\(\\mathrm{NaN}\\) \u7b49\u3002

    \u8868 3-2 \u00a0 \u6307\u6570\u4f4d\u542b\u4e49

    \u6307\u6570\u4f4d E \u5206\u6570\u4f4d \\(\\mathrm{N} = 0\\) \u5206\u6570\u4f4d \\(\\mathrm{N} \\ne 0\\) \u8ba1\u7b97\u516c\u5f0f \\(0\\) \\(\\pm 0\\) \u6b21\u6b63\u89c4\u6570 \\((-1)^{\\mathrm{S}} \\times 2^{-126} \\times (0.\\mathrm{N})\\) \\(1, 2, \\dots, 254\\) \u6b63\u89c4\u6570 \u6b63\u89c4\u6570 \\((-1)^{\\mathrm{S}} \\times 2^{(\\mathrm{E} -127)} \\times (1.\\mathrm{N})\\) \\(255\\) \\(\\pm \\infty\\) \\(\\mathrm{NaN}\\)

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6b21\u6b63\u89c4\u6570\u663e\u8457\u63d0\u5347\u4e86\u6d6e\u70b9\u6570\u7684\u7cbe\u5ea6\u3002\u6700\u5c0f\u6b63\u6b63\u89c4\u6570\u4e3a \\(2^{-126}\\) \uff0c\u6700\u5c0f\u6b63\u6b21\u6b63\u89c4\u6570\u4e3a \\(2^{-126} \\times 2^{-23}\\) \u3002

    \u53cc\u7cbe\u5ea6 double \u4e5f\u91c7\u7528\u7c7b\u4f3c\u4e8e float \u7684\u8868\u793a\u65b9\u6cd5\uff0c\u5728\u6b64\u4e0d\u505a\u8d58\u8ff0\u3002

    "},{"location":"chapter_data_structure/summary/","title":"3.5 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_data_structure/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u4ece\u903b\u8f91\u7ed3\u6784\u548c\u7269\u7406\u7ed3\u6784\u4e24\u4e2a\u89d2\u5ea6\u8fdb\u884c\u5206\u7c7b\u3002\u903b\u8f91\u7ed3\u6784\u63cf\u8ff0\u4e86\u6570\u636e\u5143\u7d20\u4e4b\u95f4\u7684\u903b\u8f91\u5173\u7cfb\uff0c\u800c\u7269\u7406\u7ed3\u6784\u63cf\u8ff0\u4e86\u6570\u636e\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u7684\u5b58\u50a8\u65b9\u5f0f\u3002
    • \u5e38\u89c1\u7684\u903b\u8f91\u7ed3\u6784\u5305\u62ec\u7ebf\u6027\u3001\u6811\u72b6\u548c\u7f51\u72b6\u7b49\u3002\u901a\u5e38\u6211\u4eec\u6839\u636e\u903b\u8f91\u7ed3\u6784\u5c06\u6570\u636e\u7ed3\u6784\u5206\u4e3a\u7ebf\u6027\uff08\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\uff09\u548c\u975e\u7ebf\u6027\uff08\u6811\u3001\u56fe\u3001\u5806\uff09\u4e24\u79cd\u3002\u54c8\u5e0c\u8868\u7684\u5b9e\u73b0\u53ef\u80fd\u540c\u65f6\u5305\u542b\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u548c\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002
    • \u5f53\u7a0b\u5e8f\u8fd0\u884c\u65f6\uff0c\u6570\u636e\u88ab\u5b58\u50a8\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\u3002\u6bcf\u4e2a\u5185\u5b58\u7a7a\u95f4\u90fd\u62e5\u6709\u5bf9\u5e94\u7684\u5185\u5b58\u5730\u5740\uff0c\u7a0b\u5e8f\u901a\u8fc7\u8fd9\u4e9b\u5185\u5b58\u5730\u5740\u8bbf\u95ee\u6570\u636e\u3002
    • \u7269\u7406\u7ed3\u6784\u4e3b\u8981\u5206\u4e3a\u8fde\u7eed\u7a7a\u95f4\u5b58\u50a8\uff08\u6570\u7ec4\uff09\u548c\u5206\u6563\u7a7a\u95f4\u5b58\u50a8\uff08\u94fe\u8868\uff09\u3002\u6240\u6709\u6570\u636e\u7ed3\u6784\u90fd\u662f\u7531\u6570\u7ec4\u3001\u94fe\u8868\u6216\u4e24\u8005\u7684\u7ec4\u5408\u5b9e\u73b0\u7684\u3002
    • \u8ba1\u7b97\u673a\u4e2d\u7684\u57fa\u672c\u6570\u636e\u7c7b\u578b\u5305\u62ec\u6574\u6570 byte\u3001short\u3001int\u3001long \uff0c\u6d6e\u70b9\u6570 float\u3001double \uff0c\u5b57\u7b26 char \u548c\u5e03\u5c14 bool \u3002\u5b83\u4eec\u7684\u53d6\u503c\u8303\u56f4\u53d6\u51b3\u4e8e\u5360\u7528\u7a7a\u95f4\u5927\u5c0f\u548c\u8868\u793a\u65b9\u5f0f\u3002
    • \u539f\u7801\u3001\u53cd\u7801\u548c\u8865\u7801\u662f\u5728\u8ba1\u7b97\u673a\u4e2d\u7f16\u7801\u6570\u5b57\u7684\u4e09\u79cd\u65b9\u6cd5\uff0c\u5b83\u4eec\u4e4b\u95f4\u53ef\u4ee5\u76f8\u4e92\u8f6c\u6362\u3002\u6574\u6570\u7684\u539f\u7801\u7684\u6700\u9ad8\u4f4d\u662f\u7b26\u53f7\u4f4d\uff0c\u5176\u4f59\u4f4d\u662f\u6570\u5b57\u7684\u503c\u3002
    • \u6574\u6570\u5728\u8ba1\u7b97\u673a\u4e2d\u662f\u4ee5\u8865\u7801\u7684\u5f62\u5f0f\u5b58\u50a8\u7684\u3002\u5728\u8865\u7801\u8868\u793a\u4e0b\uff0c\u8ba1\u7b97\u673a\u53ef\u4ee5\u5bf9\u6b63\u6570\u548c\u8d1f\u6570\u7684\u52a0\u6cd5\u4e00\u89c6\u540c\u4ec1\uff0c\u4e0d\u9700\u8981\u4e3a\u51cf\u6cd5\u64cd\u4f5c\u5355\u72ec\u8bbe\u8ba1\u7279\u6b8a\u7684\u786c\u4ef6\u7535\u8def\uff0c\u5e76\u4e14\u4e0d\u5b58\u5728\u6b63\u8d1f\u96f6\u6b67\u4e49\u7684\u95ee\u9898\u3002
    • \u6d6e\u70b9\u6570\u7684\u7f16\u7801\u7531 1 \u4f4d\u7b26\u53f7\u4f4d\u30018 \u4f4d\u6307\u6570\u4f4d\u548c 23 \u4f4d\u5206\u6570\u4f4d\u6784\u6210\u3002\u7531\u4e8e\u5b58\u5728\u6307\u6570\u4f4d\uff0c\u56e0\u6b64\u6d6e\u70b9\u6570\u7684\u53d6\u503c\u8303\u56f4\u8fdc\u5927\u4e8e\u6574\u6570\uff0c\u4ee3\u4ef7\u662f\u727a\u7272\u4e86\u7cbe\u5ea6\u3002
    • ASCII \u7801\u662f\u6700\u65e9\u51fa\u73b0\u7684\u82f1\u6587\u5b57\u7b26\u96c6\uff0c\u957f\u5ea6\u4e3a 1 \u5b57\u8282\uff0c\u5171\u6536\u5f55 127 \u4e2a\u5b57\u7b26\u3002GBK \u5b57\u7b26\u96c6\u662f\u5e38\u7528\u7684\u4e2d\u6587\u5b57\u7b26\u96c6\uff0c\u5171\u6536\u5f55\u4e24\u4e07\u591a\u4e2a\u6c49\u5b57\u3002Unicode \u81f4\u529b\u4e8e\u63d0\u4f9b\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\u96c6\u6807\u51c6\uff0c\u6536\u5f55\u4e16\u754c\u4e0a\u5404\u79cd\u8bed\u8a00\u7684\u5b57\u7b26\uff0c\u4ece\u800c\u89e3\u51b3\u7531\u4e8e\u5b57\u7b26\u7f16\u7801\u65b9\u6cd5\u4e0d\u4e00\u81f4\u800c\u5bfc\u81f4\u7684\u4e71\u7801\u95ee\u9898\u3002
    • UTF-8 \u662f\u6700\u53d7\u6b22\u8fce\u7684 Unicode \u7f16\u7801\u65b9\u6cd5\uff0c\u901a\u7528\u6027\u975e\u5e38\u597d\u3002\u5b83\u662f\u4e00\u79cd\u53d8\u957f\u7684\u7f16\u7801\u65b9\u6cd5\uff0c\u5177\u6709\u5f88\u597d\u7684\u6269\u5c55\u6027\uff0c\u6709\u6548\u63d0\u5347\u4e86\u5b58\u50a8\u7a7a\u95f4\u7684\u4f7f\u7528\u6548\u7387\u3002UTF-16 \u548c UTF-32 \u662f\u7b49\u957f\u7684\u7f16\u7801\u65b9\u6cd5\u3002\u5728\u7f16\u7801\u4e2d\u6587\u65f6\uff0cUTF-16 \u5360\u7528\u7684\u7a7a\u95f4\u6bd4 UTF-8 \u66f4\u5c0f\u3002Java \u548c C# \u7b49\u7f16\u7a0b\u8bed\u8a00\u9ed8\u8ba4\u4f7f\u7528 UTF-16 \u7f16\u7801\u3002
    "},{"location":"chapter_data_structure/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u4e3a\u4ec0\u4e48\u54c8\u5e0c\u8868\u540c\u65f6\u5305\u542b\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u548c\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff1f

    \u54c8\u5e0c\u8868\u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u800c\u4e3a\u4e86\u89e3\u51b3\u54c8\u5e0c\u51b2\u7a81\uff0c\u6211\u4eec\u53ef\u80fd\u4f1a\u4f7f\u7528\u201c\u94fe\u5f0f\u5730\u5740\u201d\uff08\u540e\u7eed\u201c\u54c8\u5e0c\u51b2\u7a81\u201d\u7ae0\u8282\u4f1a\u8bb2\uff09\uff1a\u6570\u7ec4\u4e2d\u6bcf\u4e2a\u6876\u6307\u5411\u4e00\u4e2a\u94fe\u8868\uff0c\u5f53\u94fe\u8868\u957f\u5ea6\u8d85\u8fc7\u4e00\u5b9a\u9608\u503c\u65f6\uff0c\u53c8\u53ef\u80fd\u88ab\u8f6c\u5316\u4e3a\u6811\uff08\u901a\u5e38\u4e3a\u7ea2\u9ed1\u6811\uff09\u3002

    \u4ece\u5b58\u50a8\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u54c8\u5e0c\u8868\u7684\u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u5176\u4e2d\u6bcf\u4e00\u4e2a\u6876\u69fd\u4f4d\u53ef\u80fd\u5305\u542b\u4e00\u4e2a\u503c\uff0c\u4e5f\u53ef\u80fd\u5305\u542b\u4e00\u4e2a\u94fe\u8868\u6216\u4e00\u68f5\u6811\u3002\u56e0\u6b64\uff0c\u54c8\u5e0c\u8868\u53ef\u80fd\u540c\u65f6\u5305\u542b\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff08\u6570\u7ec4\u3001\u94fe\u8868\uff09\u548c\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff08\u6811\uff09\u3002

    Q\uff1achar \u7c7b\u578b\u7684\u957f\u5ea6\u662f 1 \u5b57\u8282\u5417\uff1f

    char \u7c7b\u578b\u7684\u957f\u5ea6\u7531\u7f16\u7a0b\u8bed\u8a00\u91c7\u7528\u7684\u7f16\u7801\u65b9\u6cd5\u51b3\u5b9a\u3002\u4f8b\u5982\uff0cJava\u3001JavaScript\u3001TypeScript\u3001C# \u90fd\u91c7\u7528 UTF-16 \u7f16\u7801\uff08\u4fdd\u5b58 Unicode \u7801\u70b9\uff09\uff0c\u56e0\u6b64 char \u7c7b\u578b\u7684\u957f\u5ea6\u4e3a 2 \u5b57\u8282\u3002

    Q\uff1a\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u4e5f\u79f0\u201c\u9759\u6001\u6570\u636e\u7ed3\u6784\u201d \u662f\u5426\u6709\u6b67\u4e49\uff1f\u6808\u4e5f\u53ef\u4ee5\u8fdb\u884c\u51fa\u6808\u548c\u5165\u6808\u7b49\u64cd\u4f5c\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u90fd\u662f\u201c\u52a8\u6001\u201d\u7684\u3002

    \u6808\u786e\u5b9e\u53ef\u4ee5\u5b9e\u73b0\u52a8\u6001\u7684\u6570\u636e\u64cd\u4f5c\uff0c\u4f46\u6570\u636e\u7ed3\u6784\u4ecd\u7136\u662f\u201c\u9759\u6001\u201d\uff08\u957f\u5ea6\u4e0d\u53ef\u53d8\uff09\u7684\u3002\u5c3d\u7ba1\u57fa\u4e8e\u6570\u7ec4\u7684\u6570\u636e\u7ed3\u6784\u53ef\u4ee5\u52a8\u6001\u5730\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\uff0c\u4f46\u5b83\u4eec\u7684\u5bb9\u91cf\u662f\u56fa\u5b9a\u7684\u3002\u5982\u679c\u6570\u636e\u91cf\u8d85\u51fa\u4e86\u9884\u5206\u914d\u7684\u5927\u5c0f\uff0c\u5c31\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u66f4\u5927\u7684\u6570\u7ec4\uff0c\u5e76\u5c06\u65e7\u6570\u7ec4\u7684\u5185\u5bb9\u590d\u5236\u5230\u65b0\u6570\u7ec4\u4e2d\u3002

    Q\uff1a\u5728\u6784\u5efa\u6808\uff08\u961f\u5217\uff09\u7684\u65f6\u5019\uff0c\u672a\u6307\u5b9a\u5b83\u7684\u5927\u5c0f\uff0c\u4e3a\u4ec0\u4e48\u5b83\u4eec\u662f\u201c\u9759\u6001\u6570\u636e\u7ed3\u6784\u201d\u5462\uff1f

    \u5728\u9ad8\u7ea7\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u6211\u4eec\u65e0\u987b\u4eba\u5de5\u6307\u5b9a\u6808\uff08\u961f\u5217\uff09\u7684\u521d\u59cb\u5bb9\u91cf\uff0c\u8fd9\u4e2a\u5de5\u4f5c\u7531\u7c7b\u5185\u90e8\u81ea\u52a8\u5b8c\u6210\u3002\u4f8b\u5982\uff0cJava \u7684 ArrayList \u7684\u521d\u59cb\u5bb9\u91cf\u901a\u5e38\u4e3a 10\u3002\u53e6\u5916\uff0c\u6269\u5bb9\u64cd\u4f5c\u4e5f\u662f\u81ea\u52a8\u5b9e\u73b0\u7684\u3002\u8be6\u89c1\u540e\u7eed\u7684\u201c\u5217\u8868\u201d\u7ae0\u8282\u3002

    Q\uff1a\u539f\u7801\u8f6c\u8865\u7801\u7684\u65b9\u6cd5\u662f\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\uff0c\u90a3\u4e48\u8865\u7801\u8f6c\u539f\u7801\u5e94\u8be5\u662f\u9006\u8fd0\u7b97\u201c\u5148\u51cf 1 \u540e\u53d6\u53cd\u201d\uff0c\u800c\u8865\u7801\u8f6c\u539f\u7801\u4e5f\u4e00\u6837\u53ef\u4ee5\u901a\u8fc7\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5f97\u5230\uff0c\u8fd9\u662f\u4e3a\u4ec0\u4e48\u5462\uff1f

    A\uff1a\u8fd9\u662f\u56e0\u4e3a\u539f\u7801\u548c\u8865\u7801\u7684\u76f8\u4e92\u8f6c\u6362\u5b9e\u9645\u4e0a\u662f\u8ba1\u7b97\u201c\u8865\u6570\u201d\u7684\u8fc7\u7a0b\u3002\u6211\u4eec\u5148\u7ed9\u51fa\u8865\u6570\u7684\u5b9a\u4e49\uff1a\u5047\u8bbe \\(a + b = c\\) \uff0c\u90a3\u4e48\u6211\u4eec\u79f0 \\(a\\) \u662f \\(b\\) \u5230 \\(c\\) \u7684\u8865\u6570\uff0c\u53cd\u4e4b\u4e5f\u79f0 \\(b\\) \u662f \\(a\\) \u5230 \\(c\\) \u7684\u8865\u6570\u3002

    \u7ed9\u5b9a\u4e00\u4e2a \\(n = 4\\) \u4f4d\u957f\u5ea6\u7684\u4e8c\u8fdb\u5236\u6570 \\(0010\\) \uff0c\u5982\u679c\u5c06\u8fd9\u4e2a\u6570\u5b57\u770b\u4f5c\u539f\u7801\uff08\u4e0d\u8003\u8651\u7b26\u53f7\u4f4d\uff09\uff0c\u90a3\u4e48\u5b83\u7684\u8865\u7801\u9700\u901a\u8fc7\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5f97\u5230\uff1a

    \\[ 0010 \\rightarrow 1101 \\rightarrow 1110 \\]

    \u6211\u4eec\u4f1a\u53d1\u73b0\uff0c\u539f\u7801\u548c\u8865\u7801\u7684\u548c\u662f \\(0010 + 1110 = 10000\\) \uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8865\u7801 \\(1110\\) \u662f\u539f\u7801 \\(0010\\) \u5230 \\(10000\\) \u7684\u201c\u8865\u6570\u201d\u3002\u8fd9\u610f\u5473\u7740\u4e0a\u8ff0\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5b9e\u9645\u4e0a\u662f\u8ba1\u7b97\u5230 \\(10000\\) \u7684\u8865\u6570\u7684\u8fc7\u7a0b\u3002

    \u90a3\u4e48\uff0c\u8865\u7801 \\(1110\\) \u5230 \\(10000\\) \u7684\u201c\u8865\u6570\u201d\u662f\u591a\u5c11\u5462\uff1f\u6211\u4eec\u4f9d\u7136\u53ef\u4ee5\u7528\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u5f97\u5230\u5b83\uff1a

    \\[ 1110 \\rightarrow 0001 \\rightarrow 0010 \\]

    \u6362\u53e5\u8bdd\u8bf4\uff0c\u539f\u7801\u548c\u8865\u7801\u4e92\u4e3a\u5bf9\u65b9\u5230 \\(10000\\) \u7684\u201c\u8865\u6570\u201d\uff0c\u56e0\u6b64\u201c\u539f\u7801\u8f6c\u8865\u7801\u201d\u548c\u201c\u8865\u7801\u8f6c\u539f\u7801\u201d\u53ef\u4ee5\u7528\u76f8\u540c\u7684\u64cd\u4f5c\uff08\u5148\u53d6\u53cd\u540e\u52a0 1 \uff09\u5b9e\u73b0\u3002

    \u5f53\u7136\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u7528\u9006\u8fd0\u7b97\u6765\u6c42\u8865\u7801 \\(1110\\) \u7684\u539f\u7801\uff0c\u5373\u201c\u5148\u51cf 1 \u540e\u53d6\u53cd\u201d\uff1a

    \\[ 1110 \\rightarrow 1101 \\rightarrow 0010 \\]

    \u603b\u7ed3\u6765\u770b\uff0c\u201c\u5148\u53d6\u53cd\u540e\u52a0 1\u201d\u548c\u201c\u5148\u51cf 1 \u540e\u53d6\u53cd\u201d\u8fd9\u4e24\u79cd\u8fd0\u7b97\u90fd\u662f\u5728\u8ba1\u7b97\u5230 \\(10000\\) \u7684\u8865\u6570\uff0c\u5b83\u4eec\u662f\u7b49\u4ef7\u7684\u3002

    \u672c\u8d28\u4e0a\u770b\uff0c\u201c\u53d6\u53cd\u201d\u64cd\u4f5c\u5b9e\u9645\u4e0a\u662f\u6c42\u5230 \\(1111\\) \u7684\u8865\u6570\uff08\u56e0\u4e3a\u6052\u6709 \u539f\u7801 + \u53cd\u7801 = 1111\uff09\uff1b\u800c\u5728\u53cd\u7801\u57fa\u7840\u4e0a\u518d\u52a0 1 \u5f97\u5230\u7684\u8865\u7801\uff0c\u5c31\u662f\u5230 \\(10000\\) \u7684\u8865\u6570\u3002

    \u4e0a\u8ff0 \\(n = 4\\) \u4e3a\u4f8b\uff0c\u5176\u53ef\u63a8\u5e7f\u81f3\u4efb\u610f\u4f4d\u6570\u7684\u4e8c\u8fdb\u5236\u6570\u3002

    "},{"location":"chapter_divide_and_conquer/","title":"\u7b2c 12 \u7ae0 \u00a0 \u5206\u6cbb","text":"

    Abstract

    \u96be\u9898\u88ab\u9010\u5c42\u62c6\u89e3\uff0c\u6bcf\u4e00\u6b21\u7684\u62c6\u89e3\u90fd\u4f7f\u5b83\u53d8\u5f97\u66f4\u4e3a\u7b80\u5355\u3002

    \u5206\u800c\u6cbb\u4e4b\u63ed\u793a\u4e86\u4e00\u4e2a\u91cd\u8981\u7684\u4e8b\u5b9e\uff1a\u4ece\u7b80\u5355\u505a\u8d77\uff0c\u4e00\u5207\u90fd\u4e0d\u518d\u590d\u6742\u3002

    "},{"location":"chapter_divide_and_conquer/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 12.1 \u00a0 \u5206\u6cbb\u7b97\u6cd5
    • 12.2 \u00a0 \u5206\u6cbb\u641c\u7d22\u7b56\u7565
    • 12.3 \u00a0 \u6784\u5efa\u6811\u95ee\u9898
    • 12.4 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898
    • 12.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_divide_and_conquer/binary_search_recur/","title":"12.2 \u00a0 \u5206\u6cbb\u641c\u7d22\u7b56\u7565","text":"

    \u6211\u4eec\u5df2\u7ecf\u5b66\u8fc7\uff0c\u641c\u7d22\u7b97\u6cd5\u5206\u4e3a\u4e24\u5927\u7c7b\u3002

    • \u66b4\u529b\u641c\u7d22\uff1a\u5b83\u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u5b9e\u73b0\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002
    • \u81ea\u9002\u5e94\u641c\u7d22\uff1a\u5b83\u5229\u7528\u7279\u6709\u7684\u6570\u636e\u7ec4\u7ec7\u5f62\u5f0f\u6216\u5148\u9a8c\u4fe1\u606f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe\u5230 \\(O(\\log n)\\) \u751a\u81f3 \\(O(1)\\) \u3002

    \u5b9e\u9645\u4e0a\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u7684\u641c\u7d22\u7b97\u6cd5\u901a\u5e38\u662f\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u5b9e\u73b0\u7684\uff0c\u4f8b\u5982\u4e8c\u5206\u67e5\u627e\u548c\u6811\u3002

    • \u4e8c\u5206\u67e5\u627e\u7684\u6bcf\u4e00\u6b65\u90fd\u5c06\u95ee\u9898\uff08\u5728\u6570\u7ec4\u4e2d\u641c\u7d22\u76ee\u6807\u5143\u7d20\uff09\u5206\u89e3\u4e3a\u4e00\u4e2a\u5c0f\u95ee\u9898\uff08\u5728\u6570\u7ec4\u7684\u4e00\u534a\u4e2d\u641c\u7d22\u76ee\u6807\u5143\u7d20\uff09\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u4e00\u76f4\u6301\u7eed\u5230\u6570\u7ec4\u4e3a\u7a7a\u6216\u627e\u5230\u76ee\u6807\u5143\u7d20\u4e3a\u6b62\u3002
    • \u6811\u662f\u5206\u6cbb\u601d\u60f3\u7684\u4ee3\u8868\uff0c\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u3001AVL \u6811\u3001\u5806\u7b49\u6570\u636e\u7ed3\u6784\u4e2d\uff0c\u5404\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7686\u4e3a \\(O(\\log n)\\) \u3002

    \u4e8c\u5206\u67e5\u627e\u7684\u5206\u6cbb\u7b56\u7565\u5982\u4e0b\u6240\u793a\u3002

    • \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u4e8c\u5206\u67e5\u627e\u9012\u5f52\u5730\u5c06\u539f\u95ee\u9898\uff08\u5728\u6570\u7ec4\u4e2d\u8fdb\u884c\u67e5\u627e\uff09\u5206\u89e3\u4e3a\u5b50\u95ee\u9898\uff08\u5728\u6570\u7ec4\u7684\u4e00\u534a\u4e2d\u8fdb\u884c\u67e5\u627e\uff09\uff0c\u8fd9\u662f\u901a\u8fc7\u6bd4\u8f83\u4e2d\u95f4\u5143\u7d20\u548c\u76ee\u6807\u5143\u7d20\u6765\u5b9e\u73b0\u7684\u3002
    • \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u5728\u4e8c\u5206\u67e5\u627e\u4e2d\uff0c\u6bcf\u8f6e\u53ea\u5904\u7406\u4e00\u4e2a\u5b50\u95ee\u9898\uff0c\u5b83\u4e0d\u53d7\u5176\u4ed6\u5b50\u95ee\u9898\u7684\u5f71\u54cd\u3002
    • \u5b50\u95ee\u9898\u7684\u89e3\u65e0\u987b\u5408\u5e76\uff1a\u4e8c\u5206\u67e5\u627e\u65e8\u5728\u67e5\u627e\u4e00\u4e2a\u7279\u5b9a\u5143\u7d20\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u8fdb\u884c\u5408\u5e76\u3002\u5f53\u5b50\u95ee\u9898\u5f97\u5230\u89e3\u51b3\u65f6\uff0c\u539f\u95ee\u9898\u4e5f\u4f1a\u540c\u65f6\u5f97\u5230\u89e3\u51b3\u3002

    \u5206\u6cbb\u80fd\u591f\u63d0\u5347\u641c\u7d22\u6548\u7387\uff0c\u672c\u8d28\u4e0a\u662f\u56e0\u4e3a\u66b4\u529b\u641c\u7d22\u6bcf\u8f6e\u53ea\u80fd\u6392\u9664\u4e00\u4e2a\u9009\u9879\uff0c\u800c\u5206\u6cbb\u641c\u7d22\u6bcf\u8f6e\u53ef\u4ee5\u6392\u9664\u4e00\u534a\u9009\u9879\u3002

    "},{"location":"chapter_divide_and_conquer/binary_search_recur/#1","title":"1. \u00a0 \u57fa\u4e8e\u5206\u6cbb\u5b9e\u73b0\u4e8c\u5206\u67e5\u627e","text":"

    \u5728\u4e4b\u524d\u7684\u7ae0\u8282\u4e2d\uff0c\u4e8c\u5206\u67e5\u627e\u662f\u57fa\u4e8e\u9012\u63a8\uff08\u8fed\u4ee3\uff09\u5b9e\u73b0\u7684\u3002\u73b0\u5728\u6211\u4eec\u57fa\u4e8e\u5206\u6cbb\uff08\u9012\u5f52\uff09\u6765\u5b9e\u73b0\u5b83\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6709\u5e8f\u6570\u7ec4 nums \uff0c\u5176\u4e2d\u6240\u6709\u5143\u7d20\u90fd\u662f\u552f\u4e00\u7684\uff0c\u8bf7\u67e5\u627e\u5143\u7d20 target \u3002

    \u4ece\u5206\u6cbb\u89d2\u5ea6\uff0c\u6211\u4eec\u5c06\u641c\u7d22\u533a\u95f4 \\([i, j]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u8bb0\u4e3a \\(f(i, j)\\) \u3002

    \u4ee5\u539f\u95ee\u9898 \\(f(0, n-1)\\) \u4e3a\u8d77\u59cb\u70b9\uff0c\u901a\u8fc7\u4ee5\u4e0b\u6b65\u9aa4\u8fdb\u884c\u4e8c\u5206\u67e5\u627e\u3002

    1. \u8ba1\u7b97\u641c\u7d22\u533a\u95f4 \\([i, j]\\) \u7684\u4e2d\u70b9 \\(m\\) \uff0c\u6839\u636e\u5b83\u6392\u9664\u4e00\u534a\u641c\u7d22\u533a\u95f4\u3002
    2. \u9012\u5f52\u6c42\u89e3\u89c4\u6a21\u51cf\u5c0f\u4e00\u534a\u7684\u5b50\u95ee\u9898\uff0c\u53ef\u80fd\u4e3a \\(f(i, m-1)\\) \u6216 \\(f(m+1, j)\\) \u3002
    3. \u5faa\u73af\u7b2c 1. \u6b65\u548c\u7b2c 2. \u6b65\uff0c\u76f4\u81f3\u627e\u5230 target \u6216\u533a\u95f4\u4e3a\u7a7a\u65f6\u8fd4\u56de\u3002

    \u56fe 12-4 \u5c55\u793a\u4e86\u5728\u6570\u7ec4\u4e2d\u4e8c\u5206\u67e5\u627e\u5143\u7d20 \\(6\\) \u7684\u5206\u6cbb\u8fc7\u7a0b\u3002

    \u56fe 12-4 \u00a0 \u4e8c\u5206\u67e5\u627e\u7684\u5206\u6cbb\u8fc7\u7a0b

    \u5728\u5b9e\u73b0\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u9012\u5f52\u51fd\u6570 dfs() \u6765\u6c42\u89e3\u95ee\u9898 \\(f(i, j)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_recur.py
    def dfs(nums: list[int], target: int, i: int, j: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j)\"\"\"\n    # \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j:\n        return -1\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) // 2\n    if nums[m] < target:\n        # \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j)\n    elif nums[m] > target:\n        # \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1)\n    else:\n        # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n\ndef binary_search(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\"\"\"\n    n = len(nums)\n    # \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1)\n
    binary_search_recur.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(vector<int> &nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(vector<int> &nums, int target) {\n    int n = nums.size();\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.java
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(int[] nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(int[] nums, int target) {\n    int n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.cs
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint DFS(int[] nums, int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return DFS(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return DFS(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint BinarySearch(int[] nums, int target) {\n    int n = nums.Length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return DFS(nums, target, 0, n - 1);\n}\n
    binary_search_recur.go
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunc dfs(nums []int, target, i, j int) int {\n    // \u5982\u679c\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u6ca1\u6709\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1\n    }\n    //    \u8ba1\u7b97\u7d22\u5f15\u4e2d\u70b9\n    m := i + ((j - i) >> 1)\n    //\u5224\u65ad\u4e2d\u70b9\u4e0e\u76ee\u6807\u5143\u7d20\u5927\u5c0f\n    if nums[m] < target {\n        // \u5c0f\u4e8e\u5219\u9012\u5f52\u53f3\u534a\u6570\u7ec4\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m+1, j)\n    } else if nums[m] > target {\n        // \u5c0f\u4e8e\u5219\u9012\u5f52\u5de6\u534a\u6570\u7ec4\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m-1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunc binarySearch(nums []int, target int) int {\n    n := len(nums)\n    return dfs(nums, target, 0, n-1)\n}\n
    binary_search_recur.swift
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunc dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    let m = (i + j) / 2\n    if nums[m] < target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums: nums, target: target, i: m + 1, j: j)\n    } else if nums[m] > target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums: nums, target: target, i: i, j: m - 1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunc binarySearch(nums: [Int], target: Int) -> Int {\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    dfs(nums: nums, target: target, i: nums.startIndex, j: nums.endIndex - 1)\n}\n
    binary_search_recur.js
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunction dfs(nums, target, i, j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    const m = i + ((j - i) >> 1);\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunction binarySearch(nums, target) {\n    const n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.ts
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfunction dfs(nums: number[], target: number, i: number, j: number): number {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    const m = i + ((j - i) >> 1);\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfunction binarySearch(nums: number[], target: number): number {\n    const n = nums.length;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.dart
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(List<int> nums, int target, int i, int j) {\n  // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n  if (i > j) {\n    return -1;\n  }\n  // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n  int m = (i + j) ~/ 2;\n  if (nums[m] < target) {\n    // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n    return dfs(nums, target, m + 1, j);\n  } else if (nums[m] > target) {\n    // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n    return dfs(nums, target, i, m - 1);\n  } else {\n    // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return m;\n  }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(List<int> nums, int target) {\n  int n = nums.length;\n  // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n  return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.rs
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfn dfs(nums: &[i32], target: i32, i: i32, j: i32) -> i32 {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if i > j {\n        return -1;\n    }\n    let m: i32 = (i + j) / 2;\n    if nums[m as usize] < target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if nums[m as usize] > target {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfn binary_search(nums: &[i32], target: i32) -> i32 {\n    let n = nums.len() as i32;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    dfs(nums, target, 0, n - 1)\n}\n
    binary_search_recur.c
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nint dfs(int nums[], int target, int i, int j) {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1;\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    int m = (i + j) / 2;\n    if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        return dfs(nums, target, m + 1, j);\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        return dfs(nums, target, i, m - 1);\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        return m;\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nint binarySearch(int nums[], int target, int numsSize) {\n    int n = numsSize;\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1);\n}\n
    binary_search_recur.kt
    /* \u4e8c\u5206\u67e5\u627e\uff1a\u95ee\u9898 f(i, j) */\nfun dfs(\n    nums: IntArray,\n    target: Int,\n    i: Int,\n    j: Int\n): Int {\n    // \u82e5\u533a\u95f4\u4e3a\u7a7a\uff0c\u4ee3\u8868\u65e0\u76ee\u6807\u5143\u7d20\uff0c\u5219\u8fd4\u56de -1\n    if (i > j) {\n        return -1\n    }\n    // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    val m = (i + j) / 2\n    return if (nums[m] < target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(m+1, j)\n        dfs(nums, target, m + 1, j)\n    } else if (nums[m] > target) {\n        // \u9012\u5f52\u5b50\u95ee\u9898 f(i, m-1)\n        dfs(nums, target, i, m - 1)\n    } else {\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        m\n    }\n}\n\n/* \u4e8c\u5206\u67e5\u627e */\nfun binarySearch(nums: IntArray, target: Int): Int {\n    val n = nums.size\n    // \u6c42\u89e3\u95ee\u9898 f(0, n-1)\n    return dfs(nums, target, 0, n - 1)\n}\n
    binary_search_recur.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{binary_search}\n
    binary_search_recur.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{binarySearch}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/","title":"12.3 \u00a0 \u6784\u5efa\u4e8c\u53c9\u6811\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a\u4e00\u68f5\u4e8c\u53c9\u6811\u7684\u524d\u5e8f\u904d\u5386 preorder \u548c\u4e2d\u5e8f\u904d\u5386 inorder \uff0c\u8bf7\u4ece\u4e2d\u6784\u5efa\u4e8c\u53c9\u6811\uff0c\u8fd4\u56de\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\u3002\u5047\u8bbe\u4e8c\u53c9\u6811\u4e2d\u6ca1\u6709\u503c\u91cd\u590d\u7684\u8282\u70b9\uff08\u5982\u56fe 12-5 \u6240\u793a\uff09\u3002

    \u56fe 12-5 \u00a0 \u6784\u5efa\u4e8c\u53c9\u6811\u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#1","title":"1. \u00a0 \u5224\u65ad\u662f\u5426\u4e3a\u5206\u6cbb\u95ee\u9898","text":"

    \u539f\u95ee\u9898\u5b9a\u4e49\u4e3a\u4ece preorder \u548c inorder \u6784\u5efa\u4e8c\u53c9\u6811\uff0c\u662f\u4e00\u4e2a\u5178\u578b\u7684\u5206\u6cbb\u95ee\u9898\u3002

    • \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u4ece\u5206\u6cbb\u7684\u89d2\u5ea6\u5207\u5165\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u539f\u95ee\u9898\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\u3001\u6784\u5efa\u53f3\u5b50\u6811\uff0c\u52a0\u4e0a\u4e00\u6b65\u64cd\u4f5c\uff1a\u521d\u59cb\u5316\u6839\u8282\u70b9\u3002\u800c\u5bf9\u4e8e\u6bcf\u68f5\u5b50\u6811\uff08\u5b50\u95ee\u9898\uff09\uff0c\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u590d\u7528\u4ee5\u4e0a\u5212\u5206\u65b9\u6cd5\uff0c\u5c06\u5176\u5212\u5206\u4e3a\u66f4\u5c0f\u7684\u5b50\u6811\uff08\u5b50\u95ee\u9898\uff09\uff0c\u76f4\u81f3\u8fbe\u5230\u6700\u5c0f\u5b50\u95ee\u9898\uff08\u7a7a\u5b50\u6811\uff09\u65f6\u7ec8\u6b62\u3002
    • \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u662f\u76f8\u4e92\u72ec\u7acb\u7684\uff0c\u5b83\u4eec\u4e4b\u95f4\u6ca1\u6709\u4ea4\u96c6\u3002\u5728\u6784\u5efa\u5de6\u5b50\u6811\u65f6\uff0c\u6211\u4eec\u53ea\u9700\u5173\u6ce8\u4e2d\u5e8f\u904d\u5386\u548c\u524d\u5e8f\u904d\u5386\u4e2d\u4e0e\u5de6\u5b50\u6811\u5bf9\u5e94\u7684\u90e8\u5206\u3002\u53f3\u5b50\u6811\u540c\u7406\u3002
    • \u5b50\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u5408\u5e76\uff1a\u4e00\u65e6\u5f97\u5230\u4e86\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\uff08\u5b50\u95ee\u9898\u7684\u89e3\uff09\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5c06\u5b83\u4eec\u94fe\u63a5\u5230\u6839\u8282\u70b9\u4e0a\uff0c\u5f97\u5230\u539f\u95ee\u9898\u7684\u89e3\u3002
    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#2","title":"2. \u00a0 \u5982\u4f55\u5212\u5206\u5b50\u6811","text":"

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u8fd9\u9053\u9898\u53ef\u4ee5\u4f7f\u7528\u5206\u6cbb\u6765\u6c42\u89e3\uff0c\u4f46\u5982\u4f55\u901a\u8fc7\u524d\u5e8f\u904d\u5386 preorder \u548c\u4e2d\u5e8f\u904d\u5386 inorder \u6765\u5212\u5206\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u5462\uff1f

    \u6839\u636e\u5b9a\u4e49\uff0cpreorder \u548c inorder \u90fd\u53ef\u4ee5\u5212\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\u3002

    • \u524d\u5e8f\u904d\u5386\uff1a[ \u6839\u8282\u70b9 | \u5de6\u5b50\u6811 | \u53f3\u5b50\u6811 ] \uff0c\u4f8b\u5982\u56fe 12-5 \u7684\u6811\u5bf9\u5e94 [ 3 | 9 | 2 1 7 ] \u3002
    • \u4e2d\u5e8f\u904d\u5386\uff1a[ \u5de6\u5b50\u6811 | \u6839\u8282\u70b9 \uff5c \u53f3\u5b50\u6811 ] \uff0c\u4f8b\u5982\u56fe 12-5 \u7684\u6811\u5bf9\u5e94 [ 9 | 3 | 1 2 7 ] \u3002

    \u4ee5\u4e0a\u56fe\u6570\u636e\u4e3a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u56fe 12-6 \u6240\u793a\u7684\u6b65\u9aa4\u5f97\u5230\u5212\u5206\u7ed3\u679c\u3002

    1. \u524d\u5e8f\u904d\u5386\u7684\u9996\u5143\u7d20 3 \u662f\u6839\u8282\u70b9\u7684\u503c\u3002
    2. \u67e5\u627e\u6839\u8282\u70b9 3 \u5728 inorder \u4e2d\u7684\u7d22\u5f15\uff0c\u5229\u7528\u8be5\u7d22\u5f15\u53ef\u5c06 inorder \u5212\u5206\u4e3a [ 9 | 3 \uff5c 1 2 7 ] \u3002
    3. \u6839\u636e inorder \u7684\u5212\u5206\u7ed3\u679c\uff0c\u6613\u5f97\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u7684\u8282\u70b9\u6570\u91cf\u5206\u522b\u4e3a 1 \u548c 3 \uff0c\u4ece\u800c\u53ef\u5c06 preorder \u5212\u5206\u4e3a [ 3 | 9 | 2 1 7 ] \u3002

    \u56fe 12-6 \u00a0 \u5728\u524d\u5e8f\u904d\u5386\u548c\u4e2d\u5e8f\u904d\u5386\u4e2d\u5212\u5206\u5b50\u6811

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#3","title":"3. \u00a0 \u57fa\u4e8e\u53d8\u91cf\u63cf\u8ff0\u5b50\u6811\u533a\u95f4","text":"

    \u6839\u636e\u4ee5\u4e0a\u5212\u5206\u65b9\u6cd5\uff0c\u6211\u4eec\u5df2\u7ecf\u5f97\u5230\u6839\u8282\u70b9\u3001\u5de6\u5b50\u6811\u3001\u53f3\u5b50\u6811\u5728 preorder \u548c inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4\u3002\u800c\u4e3a\u4e86\u63cf\u8ff0\u8fd9\u4e9b\u7d22\u5f15\u533a\u95f4\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u51e0\u4e2a\u6307\u9488\u53d8\u91cf\u3002

    • \u5c06\u5f53\u524d\u6811\u7684\u6839\u8282\u70b9\u5728 preorder \u4e2d\u7684\u7d22\u5f15\u8bb0\u4e3a \\(i\\) \u3002
    • \u5c06\u5f53\u524d\u6811\u7684\u6839\u8282\u70b9\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u8bb0\u4e3a \\(m\\) \u3002
    • \u5c06\u5f53\u524d\u6811\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4\u8bb0\u4e3a \\([l, r]\\) \u3002

    \u5982\u8868 12-1 \u6240\u793a\uff0c\u901a\u8fc7\u4ee5\u4e0a\u53d8\u91cf\u5373\u53ef\u8868\u793a\u6839\u8282\u70b9\u5728 preorder \u4e2d\u7684\u7d22\u5f15\uff0c\u4ee5\u53ca\u5b50\u6811\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4\u3002

    \u8868 12-1 \u00a0 \u6839\u8282\u70b9\u548c\u5b50\u6811\u5728\u524d\u5e8f\u904d\u5386\u548c\u4e2d\u5e8f\u904d\u5386\u4e2d\u7684\u7d22\u5f15

    \u6839\u8282\u70b9\u5728 preorder \u4e2d\u7684\u7d22\u5f15 \u5b50\u6811\u5728 inorder \u4e2d\u7684\u7d22\u5f15\u533a\u95f4 \u5f53\u524d\u6811 \\(i\\) \\([l, r]\\) \u5de6\u5b50\u6811 \\(i + 1\\) \\([l, m-1]\\) \u53f3\u5b50\u6811 \\(i + 1 + (m - l)\\) \\([m+1, r]\\)

    \u8bf7\u6ce8\u610f\uff0c\u53f3\u5b50\u6811\u6839\u8282\u70b9\u7d22\u5f15\u4e2d\u7684 \\((m-l)\\) \u7684\u542b\u4e49\u662f\u201c\u5de6\u5b50\u6811\u7684\u8282\u70b9\u6570\u91cf\u201d\uff0c\u5efa\u8bae\u7ed3\u5408\u56fe 12-7 \u7406\u89e3\u3002

    \u56fe 12-7 \u00a0 \u6839\u8282\u70b9\u548c\u5de6\u53f3\u5b50\u6811\u7684\u7d22\u5f15\u533a\u95f4\u8868\u793a

    "},{"location":"chapter_divide_and_conquer/build_binary_tree_problem/#4","title":"4. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u4e3a\u4e86\u63d0\u5347\u67e5\u8be2 \\(m\\) \u7684\u6548\u7387\uff0c\u6211\u4eec\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u8868 hmap \u6765\u5b58\u50a8\u6570\u7ec4 inorder \u4e2d\u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig build_tree.py
    def dfs(\n    preorder: list[int],\n    inorder_map: dict[int, int],\n    i: int,\n    l: int,\n    r: int,\n) -> TreeNode | None:\n    \"\"\"\u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb\"\"\"\n    # \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0:\n        return None\n    # \u521d\u59cb\u5316\u6839\u8282\u70b9\n    root = TreeNode(preorder[i])\n    # \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    m = inorder_map[preorder[i]]\n    # \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorder_map, i + 1, l, m - 1)\n    # \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r)\n    # \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n\ndef build_tree(preorder: list[int], inorder: list[int]) -> TreeNode | None:\n    \"\"\"\u6784\u5efa\u4e8c\u53c9\u6811\"\"\"\n    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    inorder_map = {val: i for i, val in enumerate(inorder)}\n    root = dfs(preorder, inorder_map, 0, 0, len(inorder) - 1)\n    return root\n
    build_tree.cpp
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode *dfs(vector<int> &preorder, unordered_map<int, int> &inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return NULL;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode *root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    unordered_map<int, int> inorderMap;\n    for (int i = 0; i < inorder.size(); i++) {\n        inorderMap[inorder[i]] = i;\n    }\n    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorder.size() - 1);\n    return root;\n}\n
    build_tree.java
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode dfs(int[] preorder, Map<Integer, Integer> inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode buildTree(int[] preorder, int[] inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    Map<Integer, Integer> inorderMap = new HashMap<>();\n    for (int i = 0; i < inorder.length; i++) {\n        inorderMap.put(inorder[i], i);\n    }\n    TreeNode root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.cs
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode? DFS(int[] preorder, Dictionary<int, int> inorderMap, int i, int l, int r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode root = new(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = DFS(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = DFS(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode? BuildTree(int[] preorder, int[] inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    Dictionary<int, int> inorderMap = [];\n    for (int i = 0; i < inorder.Length; i++) {\n        inorderMap.TryAdd(inorder[i], i);\n    }\n    TreeNode? root = DFS(preorder, inorderMap, 0, 0, inorder.Length - 1);\n    return root;\n}\n
    build_tree.go
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunc dfsBuildTree(preorder []int, inorderMap map[int]int, i, l, r int) *TreeNode {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r-l < 0 {\n        return nil\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    root := NewTreeNode(preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    m := inorderMap[preorder[i]]\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.Left = dfsBuildTree(preorder, inorderMap, i+1, l, m-1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.Right = dfsBuildTree(preorder, inorderMap, i+1+m-l, m+1, r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunc buildTree(preorder, inorder []int) *TreeNode {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    inorderMap := make(map[int]int, len(inorder))\n    for i := 0; i < len(inorder); i++ {\n        inorderMap[inorder[i]] = i\n    }\n\n    root := dfsBuildTree(preorder, inorderMap, 0, 0, len(inorder)-1)\n    return root\n}\n
    build_tree.swift
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunc dfs(preorder: [Int], inorderMap: [Int: Int], i: Int, l: Int, r: Int) -> TreeNode? {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0 {\n        return nil\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    let root = TreeNode(x: preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    let m = inorderMap[preorder[i]]!\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1, l: l, r: m - 1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder: preorder, inorderMap: inorderMap, i: i + 1 + m - l, l: m + 1, r: r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunc buildTree(preorder: [Int], inorder: [Int]) -> TreeNode? {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = inorder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }\n    return dfs(preorder: preorder, inorderMap: inorderMap, i: inorder.startIndex, l: inorder.startIndex, r: inorder.endIndex - 1)\n}\n
    build_tree.js
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunction dfs(preorder, inorderMap, i, l, r) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    const root = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    const m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunction buildTree(preorder, inorder) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = new Map();\n    for (let i = 0; i < inorder.length; i++) {\n        inorderMap.set(inorder[i], i);\n    }\n    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.ts
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfunction dfs(\n    preorder: number[],\n    inorderMap: Map<number, number>,\n    i: number,\n    l: number,\n    r: number\n): TreeNode | null {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    const root: TreeNode = new TreeNode(preorder[i]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    const m = inorderMap.get(preorder[i]);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfunction buildTree(preorder: number[], inorder: number[]): TreeNode | null {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let inorderMap = new Map<number, number>();\n    for (let i = 0; i < inorder.length; i++) {\n        inorderMap.set(inorder[i], i);\n    }\n    const root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n    return root;\n}\n
    build_tree.dart
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode? dfs(\n  List<int> preorder,\n  Map<int, int> inorderMap,\n  int i,\n  int l,\n  int r,\n) {\n  // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n  if (r - l < 0) {\n    return null;\n  }\n  // \u521d\u59cb\u5316\u6839\u8282\u70b9\n  TreeNode? root = TreeNode(preorder[i]);\n  // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n  int m = inorderMap[preorder[i]]!;\n  // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n  root.left = dfs(preorder, inorderMap, i + 1, l, m - 1);\n  // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n  root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);\n  // \u8fd4\u56de\u6839\u8282\u70b9\n  return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode? buildTree(List<int> preorder, List<int> inorder) {\n  // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n  Map<int, int> inorderMap = {};\n  for (int i = 0; i < inorder.length; i++) {\n    inorderMap[inorder[i]] = i;\n  }\n  TreeNode? root = dfs(preorder, inorderMap, 0, 0, inorder.length - 1);\n  return root;\n}\n
    build_tree.rs
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfn dfs(\n    preorder: &[i32],\n    inorder_map: &HashMap<i32, i32>,\n    i: i32,\n    l: i32,\n    r: i32,\n) -> Option<Rc<RefCell<TreeNode>>> {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if r - l < 0 {\n        return None;\n    }\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    let root = TreeNode::new(preorder[i as usize]);\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    let m = inorder_map.get(&preorder[i as usize]).unwrap();\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.borrow_mut().left = dfs(preorder, inorder_map, i + 1, l, m - 1);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.borrow_mut().right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    Some(root)\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfn build_tree(preorder: &[i32], inorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    let mut inorder_map: HashMap<i32, i32> = HashMap::new();\n    for i in 0..inorder.len() {\n        inorder_map.insert(inorder[i], i as i32);\n    }\n    let root = dfs(preorder, &inorder_map, 0, 0, inorder.len() as i32 - 1);\n    root\n}\n
    build_tree.c
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nTreeNode *dfs(int *preorder, int *inorderMap, int i, int l, int r, int size) {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0)\n        return NULL;\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));\n    root->val = preorder[i];\n    root->left = NULL;\n    root->right = NULL;\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    int m = inorderMap[preorder[i]];\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root->left = dfs(preorder, inorderMap, i + 1, l, m - 1, size);\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r, size);\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root;\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nTreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    int *inorderMap = (int *)malloc(sizeof(int) * MAX_SIZE);\n    for (int i = 0; i < inorderSize; i++) {\n        inorderMap[inorder[i]] = i;\n    }\n    TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorderSize - 1, inorderSize);\n    free(inorderMap);\n    return root;\n}\n
    build_tree.kt
    /* \u6784\u5efa\u4e8c\u53c9\u6811\uff1a\u5206\u6cbb */\nfun dfs(\n    preorder: IntArray,\n    inorderMap: Map<Int?, Int?>,\n    i: Int,\n    l: Int,\n    r: Int\n): TreeNode? {\n    // \u5b50\u6811\u533a\u95f4\u4e3a\u7a7a\u65f6\u7ec8\u6b62\n    if (r - l < 0) return null\n    // \u521d\u59cb\u5316\u6839\u8282\u70b9\n    val root = TreeNode(preorder[i])\n    // \u67e5\u8be2 m \uff0c\u4ece\u800c\u5212\u5206\u5de6\u53f3\u5b50\u6811\n    val m = inorderMap[preorder[i]]!!\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u5de6\u5b50\u6811\n    root.left = dfs(preorder, inorderMap, i + 1, l, m - 1)\n    // \u5b50\u95ee\u9898\uff1a\u6784\u5efa\u53f3\u5b50\u6811\n    root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r)\n    // \u8fd4\u56de\u6839\u8282\u70b9\n    return root\n}\n\n/* \u6784\u5efa\u4e8c\u53c9\u6811 */\nfun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {\n    // \u521d\u59cb\u5316\u54c8\u5e0c\u8868\uff0c\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\n    val inorderMap = HashMap<Int?, Int?>()\n    for (i in inorder.indices) {\n        inorderMap[inorder[i]] = i\n    }\n    val root = dfs(preorder, inorderMap, 0, 0, inorder.size - 1)\n    return root\n}\n
    build_tree.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{build_tree}\n
    build_tree.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{buildTree}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 12-8 \u5c55\u793a\u4e86\u6784\u5efa\u4e8c\u53c9\u6811\u7684\u9012\u5f52\u8fc7\u7a0b\uff0c\u5404\u4e2a\u8282\u70b9\u662f\u5728\u5411\u4e0b\u201c\u9012\u201d\u7684\u8fc7\u7a0b\u4e2d\u5efa\u7acb\u7684\uff0c\u800c\u5404\u6761\u8fb9\uff08\u5f15\u7528\uff09\u662f\u5728\u5411\u4e0a\u201c\u5f52\u201d\u7684\u8fc7\u7a0b\u4e2d\u5efa\u7acb\u7684\u3002

    <1><2><3><4><5><6><7><8><9>

    \u56fe 12-8 \u00a0 \u6784\u5efa\u4e8c\u53c9\u6811\u7684\u9012\u5f52\u8fc7\u7a0b

    \u6bcf\u4e2a\u9012\u5f52\u51fd\u6570\u5185\u7684\u524d\u5e8f\u904d\u5386 preorder \u548c\u4e2d\u5e8f\u904d\u5386 inorder \u7684\u5212\u5206\u7ed3\u679c\u5982\u56fe 12-9 \u6240\u793a\u3002

    \u56fe 12-9 \u00a0 \u6bcf\u4e2a\u9012\u5f52\u51fd\u6570\u4e2d\u7684\u5212\u5206\u7ed3\u679c

    \u8bbe\u6811\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(n\\) \uff0c\u521d\u59cb\u5316\u6bcf\u4e00\u4e2a\u8282\u70b9\uff08\u6267\u884c\u4e00\u4e2a\u9012\u5f52\u51fd\u6570 dfs() \uff09\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002\u56e0\u6b64\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    \u54c8\u5e0c\u8868\u5b58\u50a8 inorder \u5143\u7d20\u5230\u7d22\u5f15\u7684\u6620\u5c04\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u5373\u4e8c\u53c9\u6811\u9000\u5316\u4e3a\u94fe\u8868\u65f6\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230 \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u7684\u6808\u5e27\u7a7a\u95f4\u3002\u56e0\u6b64\u603b\u4f53\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/","title":"12.1 \u00a0 \u5206\u6cbb\u7b97\u6cd5","text":"

    \u5206\u6cbb\uff08divide and conquer\uff09\uff0c\u5168\u79f0\u5206\u800c\u6cbb\u4e4b\uff0c\u662f\u4e00\u79cd\u975e\u5e38\u91cd\u8981\u4e14\u5e38\u89c1\u7684\u7b97\u6cd5\u7b56\u7565\u3002\u5206\u6cbb\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\uff0c\u5305\u62ec\u201c\u5206\u201d\u548c\u201c\u6cbb\u201d\u4e24\u4e2a\u6b65\u9aa4\u3002

    1. \u5206\uff08\u5212\u5206\u9636\u6bb5\uff09\uff1a\u9012\u5f52\u5730\u5c06\u539f\u95ee\u9898\u5206\u89e3\u4e3a\u4e24\u4e2a\u6216\u591a\u4e2a\u5b50\u95ee\u9898\uff0c\u76f4\u81f3\u5230\u8fbe\u6700\u5c0f\u5b50\u95ee\u9898\u65f6\u7ec8\u6b62\u3002
    2. \u6cbb\uff08\u5408\u5e76\u9636\u6bb5\uff09\uff1a\u4ece\u5df2\u77e5\u89e3\u7684\u6700\u5c0f\u5b50\u95ee\u9898\u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5730\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u8fdb\u884c\u5408\u5e76\uff0c\u4ece\u800c\u6784\u5efa\u51fa\u539f\u95ee\u9898\u7684\u89e3\u3002

    \u5982\u56fe 12-1 \u6240\u793a\uff0c\u201c\u5f52\u5e76\u6392\u5e8f\u201d\u662f\u5206\u6cbb\u7b56\u7565\u7684\u5178\u578b\u5e94\u7528\u4e4b\u4e00\u3002

    1. \u5206\uff1a\u9012\u5f52\u5730\u5c06\u539f\u6570\u7ec4\uff08\u539f\u95ee\u9898\uff09\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\uff09\uff0c\u76f4\u5230\u5b50\u6570\u7ec4\u53ea\u5269\u4e00\u4e2a\u5143\u7d20\uff08\u6700\u5c0f\u5b50\u95ee\u9898\uff09\u3002
    2. \u6cbb\uff1a\u4ece\u5e95\u81f3\u9876\u5730\u5c06\u6709\u5e8f\u7684\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\u7684\u89e3\uff09\u8fdb\u884c\u5408\u5e76\uff0c\u4ece\u800c\u5f97\u5230\u6709\u5e8f\u7684\u539f\u6570\u7ec4\uff08\u539f\u95ee\u9898\u7684\u89e3\uff09\u3002

    \u56fe 12-1 \u00a0 \u5f52\u5e76\u6392\u5e8f\u7684\u5206\u6cbb\u7b56\u7565

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1211","title":"12.1.1 \u00a0 \u5982\u4f55\u5224\u65ad\u5206\u6cbb\u95ee\u9898","text":"

    \u4e00\u4e2a\u95ee\u9898\u662f\u5426\u9002\u5408\u4f7f\u7528\u5206\u6cbb\u89e3\u51b3\uff0c\u901a\u5e38\u53ef\u4ee5\u53c2\u8003\u4ee5\u4e0b\u51e0\u4e2a\u5224\u65ad\u4f9d\u636e\u3002

    1. \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u539f\u95ee\u9898\u53ef\u4ee5\u5206\u89e3\u6210\u89c4\u6a21\u66f4\u5c0f\u3001\u7c7b\u4f3c\u7684\u5b50\u95ee\u9898\uff0c\u4ee5\u53ca\u80fd\u591f\u4ee5\u76f8\u540c\u65b9\u5f0f\u9012\u5f52\u5730\u8fdb\u884c\u5212\u5206\u3002
    2. \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u5b50\u95ee\u9898\u4e4b\u95f4\u6ca1\u6709\u91cd\u53e0\uff0c\u4e92\u4e0d\u4f9d\u8d56\uff0c\u53ef\u4ee5\u72ec\u7acb\u89e3\u51b3\u3002
    3. \u5b50\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u5408\u5e76\uff1a\u539f\u95ee\u9898\u7684\u89e3\u901a\u8fc7\u5408\u5e76\u5b50\u95ee\u9898\u7684\u89e3\u5f97\u6765\u3002

    \u663e\u7136\uff0c\u5f52\u5e76\u6392\u5e8f\u6ee1\u8db3\u4ee5\u4e0a\u4e09\u4e2a\u5224\u65ad\u4f9d\u636e\u3002

    1. \u95ee\u9898\u53ef\u4ee5\u5206\u89e3\uff1a\u9012\u5f52\u5730\u5c06\u6570\u7ec4\uff08\u539f\u95ee\u9898\uff09\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\uff09\u3002
    2. \u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff1a\u6bcf\u4e2a\u5b50\u6570\u7ec4\u90fd\u53ef\u4ee5\u72ec\u7acb\u5730\u8fdb\u884c\u6392\u5e8f\uff08\u5b50\u95ee\u9898\u53ef\u4ee5\u72ec\u7acb\u8fdb\u884c\u6c42\u89e3\uff09\u3002
    3. \u5b50\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u5408\u5e76\uff1a\u4e24\u4e2a\u6709\u5e8f\u5b50\u6570\u7ec4\uff08\u5b50\u95ee\u9898\u7684\u89e3\uff09\u53ef\u4ee5\u5408\u5e76\u4e3a\u4e00\u4e2a\u6709\u5e8f\u6570\u7ec4\uff08\u539f\u95ee\u9898\u7684\u89e3\uff09\u3002
    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1212","title":"12.1.2 \u00a0 \u901a\u8fc7\u5206\u6cbb\u63d0\u5347\u6548\u7387","text":"

    \u5206\u6cbb\u4e0d\u4ec5\u53ef\u4ee5\u6709\u6548\u5730\u89e3\u51b3\u7b97\u6cd5\u95ee\u9898\uff0c\u5f80\u5f80\u8fd8\u53ef\u4ee5\u63d0\u5347\u7b97\u6cd5\u6548\u7387\u3002\u5728\u6392\u5e8f\u7b97\u6cd5\u4e2d\uff0c\u5feb\u901f\u6392\u5e8f\u3001\u5f52\u5e76\u6392\u5e8f\u3001\u5806\u6392\u5e8f\u76f8\u8f83\u4e8e\u9009\u62e9\u3001\u5192\u6ce1\u3001\u63d2\u5165\u6392\u5e8f\u66f4\u5feb\uff0c\u5c31\u662f\u56e0\u4e3a\u5b83\u4eec\u5e94\u7528\u4e86\u5206\u6cbb\u7b56\u7565\u3002

    \u90a3\u4e48\uff0c\u6211\u4eec\u4e0d\u7981\u53d1\u95ee\uff1a\u4e3a\u4ec0\u4e48\u5206\u6cbb\u53ef\u4ee5\u63d0\u5347\u7b97\u6cd5\u6548\u7387\uff0c\u5176\u5e95\u5c42\u903b\u8f91\u662f\u4ec0\u4e48\uff1f\u6362\u53e5\u8bdd\u8bf4\uff0c\u5c06\u5927\u95ee\u9898\u5206\u89e3\u4e3a\u591a\u4e2a\u5b50\u95ee\u9898\u3001\u89e3\u51b3\u5b50\u95ee\u9898\u3001\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u5408\u5e76\u4e3a\u539f\u95ee\u9898\u7684\u89e3\uff0c\u8fd9\u51e0\u6b65\u7684\u6548\u7387\u4e3a\u4ec0\u4e48\u6bd4\u76f4\u63a5\u89e3\u51b3\u539f\u95ee\u9898\u7684\u6548\u7387\u66f4\u9ad8\uff1f\u8fd9\u4e2a\u95ee\u9898\u53ef\u4ee5\u4ece\u64cd\u4f5c\u6570\u91cf\u548c\u5e76\u884c\u8ba1\u7b97\u4e24\u65b9\u9762\u6765\u8ba8\u8bba\u3002

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1","title":"1. \u00a0 \u64cd\u4f5c\u6570\u91cf\u4f18\u5316","text":"

    \u4ee5\u201c\u5192\u6ce1\u6392\u5e8f\u201d\u4e3a\u4f8b\uff0c\u5176\u5904\u7406\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\u9700\u8981 \\(O(n^2)\\) \u65f6\u95f4\u3002\u5047\u8bbe\u6211\u4eec\u6309\u7167\u56fe 12-2 \u6240\u793a\u7684\u65b9\u5f0f\uff0c\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5904\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u5219\u5212\u5206\u9700\u8981 \\(O(n)\\) \u65f6\u95f4\uff0c\u6392\u5e8f\u6bcf\u4e2a\u5b50\u6570\u7ec4\u9700\u8981 \\(O((n / 2)^2)\\) \u65f6\u95f4\uff0c\u5408\u5e76\u4e24\u4e2a\u5b50\u6570\u7ec4\u9700\u8981 \\(O(n)\\) \u65f6\u95f4\uff0c\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\uff1a

    \\[ O(n + (\\frac{n}{2})^2 \\times 2 + n) = O(\\frac{n^2}{2} + 2n) \\]

    \u56fe 12-2 \u00a0 \u5212\u5206\u6570\u7ec4\u524d\u540e\u7684\u5192\u6ce1\u6392\u5e8f

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8ba1\u7b97\u4ee5\u4e0b\u4e0d\u7b49\u5f0f\uff0c\u5176\u5de6\u8fb9\u548c\u53f3\u8fb9\u5206\u522b\u4e3a\u5212\u5206\u524d\u548c\u5212\u5206\u540e\u7684\u64cd\u4f5c\u603b\u6570\uff1a

    \\[ \\begin{aligned} n^2 & > \\frac{n^2}{2} + 2n \\newline n^2 - \\frac{n^2}{2} - 2n & > 0 \\newline n(n - 4) & > 0 \\end{aligned} \\]

    \u8fd9\u610f\u5473\u7740\u5f53 \\(n > 4\\) \u65f6\uff0c\u5212\u5206\u540e\u7684\u64cd\u4f5c\u6570\u91cf\u66f4\u5c11\uff0c\u6392\u5e8f\u6548\u7387\u5e94\u8be5\u66f4\u9ad8\u3002\u8bf7\u6ce8\u610f\uff0c\u5212\u5206\u540e\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u7136\u662f\u5e73\u65b9\u9636 \\(O(n^2)\\) \uff0c\u53ea\u662f\u590d\u6742\u5ea6\u4e2d\u7684\u5e38\u6570\u9879\u53d8\u5c0f\u4e86\u3002

    \u8fdb\u4e00\u6b65\u60f3\uff0c\u5982\u679c\u6211\u4eec\u628a\u5b50\u6570\u7ec4\u4e0d\u65ad\u5730\u518d\u4ece\u4e2d\u70b9\u5904\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u53ea\u5269\u4e00\u4e2a\u5143\u7d20\u65f6\u505c\u6b62\u5212\u5206\u5462\uff1f\u8fd9\u79cd\u601d\u8def\u5b9e\u9645\u4e0a\u5c31\u662f\u201c\u5f52\u5e76\u6392\u5e8f\u201d\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    \u518d\u601d\u8003\uff0c\u5982\u679c\u6211\u4eec\u591a\u8bbe\u7f6e\u51e0\u4e2a\u5212\u5206\u70b9\uff0c\u5c06\u539f\u6570\u7ec4\u5e73\u5747\u5212\u5206\u4e3a \\(k\\) \u4e2a\u5b50\u6570\u7ec4\u5462\uff1f\u8fd9\u79cd\u60c5\u51b5\u4e0e\u201c\u6876\u6392\u5e8f\u201d\u975e\u5e38\u7c7b\u4f3c\uff0c\u5b83\u975e\u5e38\u9002\u5408\u6392\u5e8f\u6d77\u91cf\u6570\u636e\uff0c\u7406\u8bba\u4e0a\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230 \\(O(n + k)\\) \u3002

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#2","title":"2. \u00a0 \u5e76\u884c\u8ba1\u7b97\u4f18\u5316","text":"

    \u6211\u4eec\u77e5\u9053\uff0c\u5206\u6cbb\u751f\u6210\u7684\u5b50\u95ee\u9898\u662f\u76f8\u4e92\u72ec\u7acb\u7684\uff0c\u56e0\u6b64\u901a\u5e38\u53ef\u4ee5\u5e76\u884c\u89e3\u51b3\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5206\u6cbb\u4e0d\u4ec5\u53ef\u4ee5\u964d\u4f4e\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8fd8\u6709\u5229\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u7684\u5e76\u884c\u4f18\u5316\u3002

    \u5e76\u884c\u4f18\u5316\u5728\u591a\u6838\u6216\u591a\u5904\u7406\u5668\u7684\u73af\u5883\u4e2d\u5c24\u5176\u6709\u6548\uff0c\u56e0\u4e3a\u7cfb\u7edf\u53ef\u4ee5\u540c\u65f6\u5904\u7406\u591a\u4e2a\u5b50\u95ee\u9898\uff0c\u66f4\u52a0\u5145\u5206\u5730\u5229\u7528\u8ba1\u7b97\u8d44\u6e90\uff0c\u4ece\u800c\u663e\u8457\u51cf\u5c11\u603b\u4f53\u7684\u8fd0\u884c\u65f6\u95f4\u3002

    \u6bd4\u5982\u5728\u56fe 12-3 \u6240\u793a\u7684\u201c\u6876\u6392\u5e8f\u201d\u4e2d\uff0c\u6211\u4eec\u5c06\u6d77\u91cf\u7684\u6570\u636e\u5e73\u5747\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\uff0c\u5219\u53ef\u5c06\u6240\u6709\u6876\u7684\u6392\u5e8f\u4efb\u52a1\u5206\u6563\u5230\u5404\u4e2a\u8ba1\u7b97\u5355\u5143\uff0c\u5b8c\u6210\u540e\u518d\u5408\u5e76\u7ed3\u679c\u3002

    \u56fe 12-3 \u00a0 \u6876\u6392\u5e8f\u7684\u5e76\u884c\u8ba1\u7b97

    "},{"location":"chapter_divide_and_conquer/divide_and_conquer/#1213","title":"12.1.3 \u00a0 \u5206\u6cbb\u5e38\u89c1\u5e94\u7528","text":"

    \u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u53ef\u4ee5\u7528\u6765\u89e3\u51b3\u8bb8\u591a\u7ecf\u5178\u7b97\u6cd5\u95ee\u9898\u3002

    • \u5bfb\u627e\u6700\u8fd1\u70b9\u5bf9\uff1a\u8be5\u7b97\u6cd5\u9996\u5148\u5c06\u70b9\u96c6\u5206\u6210\u4e24\u90e8\u5206\uff0c\u7136\u540e\u5206\u522b\u627e\u51fa\u4e24\u90e8\u5206\u4e2d\u7684\u6700\u8fd1\u70b9\u5bf9\uff0c\u6700\u540e\u627e\u51fa\u8de8\u8d8a\u4e24\u90e8\u5206\u7684\u6700\u8fd1\u70b9\u5bf9\u3002
    • \u5927\u6574\u6570\u4e58\u6cd5\uff1a\u4f8b\u5982 Karatsuba \u7b97\u6cd5\uff0c\u5b83\u5c06\u5927\u6574\u6570\u4e58\u6cd5\u5206\u89e3\u4e3a\u51e0\u4e2a\u8f83\u5c0f\u7684\u6574\u6570\u7684\u4e58\u6cd5\u548c\u52a0\u6cd5\u3002
    • \u77e9\u9635\u4e58\u6cd5\uff1a\u4f8b\u5982 Strassen \u7b97\u6cd5\uff0c\u5b83\u5c06\u5927\u77e9\u9635\u4e58\u6cd5\u5206\u89e3\u4e3a\u591a\u4e2a\u5c0f\u77e9\u9635\u7684\u4e58\u6cd5\u548c\u52a0\u6cd5\u3002
    • \u6c49\u8bfa\u5854\u95ee\u9898\uff1a\u6c49\u8bfa\u5854\u95ee\u9898\u53ef\u4ee5\u901a\u8fc7\u9012\u5f52\u89e3\u51b3\uff0c\u8fd9\u662f\u5178\u578b\u7684\u5206\u6cbb\u7b56\u7565\u5e94\u7528\u3002
    • \u6c42\u89e3\u9006\u5e8f\u5bf9\uff1a\u5728\u4e00\u4e2a\u5e8f\u5217\u4e2d\uff0c\u5982\u679c\u524d\u9762\u7684\u6570\u5b57\u5927\u4e8e\u540e\u9762\u7684\u6570\u5b57\uff0c\u90a3\u4e48\u8fd9\u4e24\u4e2a\u6570\u5b57\u6784\u6210\u4e00\u4e2a\u9006\u5e8f\u5bf9\u3002\u6c42\u89e3\u9006\u5e8f\u5bf9\u95ee\u9898\u53ef\u4ee5\u5229\u7528\u5206\u6cbb\u7684\u601d\u60f3\uff0c\u501f\u52a9\u5f52\u5e76\u6392\u5e8f\u8fdb\u884c\u6c42\u89e3\u3002

    \u53e6\u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u5728\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u7684\u8bbe\u8ba1\u4e2d\u5e94\u7528\u5f97\u975e\u5e38\u5e7f\u6cdb\u3002

    • \u4e8c\u5206\u67e5\u627e\uff1a\u4e8c\u5206\u67e5\u627e\u662f\u5c06\u6709\u5e8f\u6570\u7ec4\u4ece\u4e2d\u70b9\u7d22\u5f15\u5904\u5206\u4e3a\u4e24\u90e8\u5206\uff0c\u7136\u540e\u6839\u636e\u76ee\u6807\u503c\u4e0e\u4e2d\u95f4\u5143\u7d20\u503c\u6bd4\u8f83\u7ed3\u679c\uff0c\u51b3\u5b9a\u6392\u9664\u54ea\u4e00\u534a\u533a\u95f4\uff0c\u5e76\u5728\u5269\u4f59\u533a\u95f4\u6267\u884c\u76f8\u540c\u7684\u4e8c\u5206\u64cd\u4f5c\u3002
    • \u5f52\u5e76\u6392\u5e8f\uff1a\u672c\u8282\u5f00\u5934\u5df2\u4ecb\u7ecd\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002
    • \u5feb\u901f\u6392\u5e8f\uff1a\u5feb\u901f\u6392\u5e8f\u662f\u9009\u53d6\u4e00\u4e2a\u57fa\u51c6\u503c\uff0c\u7136\u540e\u628a\u6570\u7ec4\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u5143\u7d20\u6bd4\u57fa\u51c6\u503c\u5c0f\uff0c\u53e6\u4e00\u5b50\u6570\u7ec4\u7684\u5143\u7d20\u6bd4\u57fa\u51c6\u503c\u5927\uff0c\u518d\u5bf9\u8fd9\u4e24\u90e8\u5206\u8fdb\u884c\u76f8\u540c\u7684\u5212\u5206\u64cd\u4f5c\uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u53ea\u5269\u4e0b\u4e00\u4e2a\u5143\u7d20\u3002
    • \u6876\u6392\u5e8f\uff1a\u6876\u6392\u5e8f\u7684\u57fa\u672c\u601d\u60f3\u662f\u5c06\u6570\u636e\u5206\u6563\u5230\u591a\u4e2a\u6876\uff0c\u7136\u540e\u5bf9\u6bcf\u4e2a\u6876\u5185\u7684\u5143\u7d20\u8fdb\u884c\u6392\u5e8f\uff0c\u6700\u540e\u5c06\u5404\u4e2a\u6876\u7684\u5143\u7d20\u4f9d\u6b21\u53d6\u51fa\uff0c\u4ece\u800c\u5f97\u5230\u4e00\u4e2a\u6709\u5e8f\u6570\u7ec4\u3002
    • \u6811\uff1a\u4f8b\u5982\u4e8c\u53c9\u641c\u7d22\u6811\u3001AVL \u6811\u3001\u7ea2\u9ed1\u6811\u3001B \u6811\u3001B+ \u6811\u7b49\uff0c\u5b83\u4eec\u7684\u67e5\u627e\u3001\u63d2\u5165\u548c\u5220\u9664\u7b49\u64cd\u4f5c\u90fd\u53ef\u4ee5\u89c6\u4e3a\u5206\u6cbb\u7b56\u7565\u7684\u5e94\u7528\u3002
    • \u5806\uff1a\u5806\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u5176\u5404\u79cd\u64cd\u4f5c\uff0c\u5982\u63d2\u5165\u3001\u5220\u9664\u548c\u5806\u5316\uff0c\u5b9e\u9645\u4e0a\u90fd\u9690\u542b\u4e86\u5206\u6cbb\u7684\u601d\u60f3\u3002
    • \u54c8\u5e0c\u8868\uff1a\u867d\u7136\u54c8\u5e0c\u8868\u5e76\u4e0d\u76f4\u63a5\u5e94\u7528\u5206\u6cbb\uff0c\u4f46\u67d0\u4e9b\u54c8\u5e0c\u51b2\u7a81\u89e3\u51b3\u65b9\u6848\u95f4\u63a5\u5e94\u7528\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u4f8b\u5982\uff0c\u94fe\u5f0f\u5730\u5740\u4e2d\u7684\u957f\u94fe\u8868\u4f1a\u88ab\u8f6c\u5316\u4e3a\u7ea2\u9ed1\u6811\uff0c\u4ee5\u63d0\u5347\u67e5\u8be2\u6548\u7387\u3002

    \u53ef\u4ee5\u770b\u51fa\uff0c\u5206\u6cbb\u662f\u4e00\u79cd\u201c\u6da6\u7269\u7ec6\u65e0\u58f0\u201d\u7684\u7b97\u6cd5\u601d\u60f3\uff0c\u9690\u542b\u5728\u5404\u79cd\u7b97\u6cd5\u4e0e\u6570\u636e\u7ed3\u6784\u4e4b\u4e2d\u3002

    "},{"location":"chapter_divide_and_conquer/hanota_problem/","title":"12.4 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898","text":"

    \u5728\u5f52\u5e76\u6392\u5e8f\u548c\u6784\u5efa\u4e8c\u53c9\u6811\u4e2d\uff0c\u6211\u4eec\u90fd\u662f\u5c06\u539f\u95ee\u9898\u5206\u89e3\u4e3a\u4e24\u4e2a\u89c4\u6a21\u4e3a\u539f\u95ee\u9898\u4e00\u534a\u7684\u5b50\u95ee\u9898\u3002\u7136\u800c\u5bf9\u4e8e\u6c49\u8bfa\u5854\u95ee\u9898\uff0c\u6211\u4eec\u91c7\u7528\u4e0d\u540c\u7684\u5206\u89e3\u7b56\u7565\u3002

    Question

    \u7ed9\u5b9a\u4e09\u6839\u67f1\u5b50\uff0c\u8bb0\u4e3a A\u3001B \u548c C \u3002\u8d77\u59cb\u72b6\u6001\u4e0b\uff0c\u67f1\u5b50 A \u4e0a\u5957\u7740 \\(n\\) \u4e2a\u5706\u76d8\uff0c\u5b83\u4eec\u4ece\u4e0a\u5230\u4e0b\u6309\u7167\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u3002\u6211\u4eec\u7684\u4efb\u52a1\u662f\u8981\u628a\u8fd9 \\(n\\) \u4e2a\u5706\u76d8\u79fb\u5230\u67f1\u5b50 C \u4e0a\uff0c\u5e76\u4fdd\u6301\u5b83\u4eec\u7684\u539f\u6709\u987a\u5e8f\u4e0d\u53d8\uff08\u5982\u56fe 12-10 \u6240\u793a\uff09\u3002\u5728\u79fb\u52a8\u5706\u76d8\u7684\u8fc7\u7a0b\u4e2d\uff0c\u9700\u8981\u9075\u5b88\u4ee5\u4e0b\u89c4\u5219\u3002

    1. \u5706\u76d8\u53ea\u80fd\u4ece\u4e00\u6839\u67f1\u5b50\u9876\u90e8\u62ff\u51fa\uff0c\u4ece\u53e6\u4e00\u6839\u67f1\u5b50\u9876\u90e8\u653e\u5165\u3002
    2. \u6bcf\u6b21\u53ea\u80fd\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\u3002
    3. \u5c0f\u5706\u76d8\u5fc5\u987b\u65f6\u523b\u4f4d\u4e8e\u5927\u5706\u76d8\u4e4b\u4e0a\u3002

    \u56fe 12-10 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898\u793a\u4f8b

    \u6211\u4eec\u5c06\u89c4\u6a21\u4e3a \\(i\\) \u7684\u6c49\u8bfa\u5854\u95ee\u9898\u8bb0\u4f5c \\(f(i)\\) \u3002\u4f8b\u5982 \\(f(3)\\) \u4ee3\u8868\u5c06 \\(3\\) \u4e2a\u5706\u76d8\u4ece A \u79fb\u52a8\u81f3 C \u7684\u6c49\u8bfa\u5854\u95ee\u9898\u3002

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#1","title":"1. \u00a0 \u8003\u8651\u57fa\u672c\u60c5\u51b5","text":"

    \u5982\u56fe 12-11 \u6240\u793a\uff0c\u5bf9\u4e8e\u95ee\u9898 \\(f(1)\\) \uff0c\u5373\u5f53\u53ea\u6709\u4e00\u4e2a\u5706\u76d8\u65f6\uff0c\u6211\u4eec\u5c06\u5b83\u76f4\u63a5\u4ece A \u79fb\u52a8\u81f3 C \u5373\u53ef\u3002

    <1><2>

    \u56fe 12-11 \u00a0 \u89c4\u6a21\u4e3a 1 \u7684\u95ee\u9898\u7684\u89e3

    \u5982\u56fe 12-12 \u6240\u793a\uff0c\u5bf9\u4e8e\u95ee\u9898 \\(f(2)\\) \uff0c\u5373\u5f53\u6709\u4e24\u4e2a\u5706\u76d8\u65f6\uff0c\u7531\u4e8e\u8981\u65f6\u523b\u6ee1\u8db3\u5c0f\u5706\u76d8\u5728\u5927\u5706\u76d8\u4e4b\u4e0a\uff0c\u56e0\u6b64\u9700\u8981\u501f\u52a9 B \u6765\u5b8c\u6210\u79fb\u52a8\u3002

    1. \u5148\u5c06\u4e0a\u9762\u7684\u5c0f\u5706\u76d8\u4ece A \u79fb\u81f3 B \u3002
    2. \u518d\u5c06\u5927\u5706\u76d8\u4ece A \u79fb\u81f3 C \u3002
    3. \u6700\u540e\u5c06\u5c0f\u5706\u76d8\u4ece B \u79fb\u81f3 C \u3002
    <1><2><3><4>

    \u56fe 12-12 \u00a0 \u89c4\u6a21\u4e3a 2 \u7684\u95ee\u9898\u7684\u89e3

    \u89e3\u51b3\u95ee\u9898 \\(f(2)\\) \u7684\u8fc7\u7a0b\u53ef\u603b\u7ed3\u4e3a\uff1a\u5c06\u4e24\u4e2a\u5706\u76d8\u501f\u52a9 B \u4ece A \u79fb\u81f3 C \u3002\u5176\u4e2d\uff0cC \u79f0\u4e3a\u76ee\u6807\u67f1\u3001B \u79f0\u4e3a\u7f13\u51b2\u67f1\u3002

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#2","title":"2. \u00a0 \u5b50\u95ee\u9898\u5206\u89e3","text":"

    \u5bf9\u4e8e\u95ee\u9898 \\(f(3)\\) \uff0c\u5373\u5f53\u6709\u4e09\u4e2a\u5706\u76d8\u65f6\uff0c\u60c5\u51b5\u53d8\u5f97\u7a0d\u5fae\u590d\u6742\u4e86\u4e00\u4e9b\u3002

    \u56e0\u4e3a\u5df2\u77e5 \\(f(1)\\) \u548c \\(f(2)\\) \u7684\u89e3\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ece\u5206\u6cbb\u89d2\u5ea6\u601d\u8003\uff0c\u5c06 A \u9876\u90e8\u7684\u4e24\u4e2a\u5706\u76d8\u770b\u4f5c\u4e00\u4e2a\u6574\u4f53\uff0c\u6267\u884c\u56fe 12-13 \u6240\u793a\u7684\u6b65\u9aa4\u3002\u8fd9\u6837\u4e09\u4e2a\u5706\u76d8\u5c31\u88ab\u987a\u5229\u5730\u4ece A \u79fb\u81f3 C \u4e86\u3002

    1. \u4ee4 B \u4e3a\u76ee\u6807\u67f1\u3001C \u4e3a\u7f13\u51b2\u67f1\uff0c\u5c06\u4e24\u4e2a\u5706\u76d8\u4ece A \u79fb\u81f3 B \u3002
    2. \u5c06 A \u4e2d\u5269\u4f59\u7684\u4e00\u4e2a\u5706\u76d8\u4ece A \u76f4\u63a5\u79fb\u52a8\u81f3 C \u3002
    3. \u4ee4 C \u4e3a\u76ee\u6807\u67f1\u3001A \u4e3a\u7f13\u51b2\u67f1\uff0c\u5c06\u4e24\u4e2a\u5706\u76d8\u4ece B \u79fb\u81f3 C \u3002
    <1><2><3><4>

    \u56fe 12-13 \u00a0 \u89c4\u6a21\u4e3a 3 \u7684\u95ee\u9898\u7684\u89e3

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u6211\u4eec\u5c06\u95ee\u9898 \\(f(3)\\) \u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u95ee\u9898 \\(f(2)\\) \u548c\u4e00\u4e2a\u5b50\u95ee\u9898 \\(f(1)\\) \u3002\u6309\u987a\u5e8f\u89e3\u51b3\u8fd9\u4e09\u4e2a\u5b50\u95ee\u9898\u4e4b\u540e\uff0c\u539f\u95ee\u9898\u968f\u4e4b\u5f97\u5230\u89e3\u51b3\u3002\u8fd9\u8bf4\u660e\u5b50\u95ee\u9898\u662f\u72ec\u7acb\u7684\uff0c\u800c\u4e14\u89e3\u53ef\u4ee5\u5408\u5e76\u3002

    \u81f3\u6b64\uff0c\u6211\u4eec\u53ef\u603b\u7ed3\u51fa\u56fe 12-14 \u6240\u793a\u7684\u89e3\u51b3\u6c49\u8bfa\u5854\u95ee\u9898\u7684\u5206\u6cbb\u7b56\u7565\uff1a\u5c06\u539f\u95ee\u9898 \\(f(n)\\) \u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u95ee\u9898 \\(f(n-1)\\) \u548c\u4e00\u4e2a\u5b50\u95ee\u9898 \\(f(1)\\) \uff0c\u5e76\u6309\u7167\u4ee5\u4e0b\u987a\u5e8f\u89e3\u51b3\u8fd9\u4e09\u4e2a\u5b50\u95ee\u9898\u3002

    1. \u5c06 \\(n-1\\) \u4e2a\u5706\u76d8\u501f\u52a9 C \u4ece A \u79fb\u81f3 B \u3002
    2. \u5c06\u5269\u4f59 \\(1\\) \u4e2a\u5706\u76d8\u4ece A \u76f4\u63a5\u79fb\u81f3 C \u3002
    3. \u5c06 \\(n-1\\) \u4e2a\u5706\u76d8\u501f\u52a9 A \u4ece B \u79fb\u81f3 C \u3002

    \u5bf9\u4e8e\u8fd9\u4e24\u4e2a\u5b50\u95ee\u9898 \\(f(n-1)\\) \uff0c\u53ef\u4ee5\u901a\u8fc7\u76f8\u540c\u7684\u65b9\u5f0f\u8fdb\u884c\u9012\u5f52\u5212\u5206\uff0c\u76f4\u81f3\u8fbe\u5230\u6700\u5c0f\u5b50\u95ee\u9898 \\(f(1)\\) \u3002\u800c \\(f(1)\\) \u7684\u89e3\u662f\u5df2\u77e5\u7684\uff0c\u53ea\u9700\u4e00\u6b21\u79fb\u52a8\u64cd\u4f5c\u5373\u53ef\u3002

    \u56fe 12-14 \u00a0 \u89e3\u51b3\u6c49\u8bfa\u5854\u95ee\u9898\u7684\u5206\u6cbb\u7b56\u7565

    "},{"location":"chapter_divide_and_conquer/hanota_problem/#3","title":"3. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5728\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u9012\u5f52\u51fd\u6570 dfs(i, src, buf, tar) \uff0c\u5b83\u7684\u4f5c\u7528\u662f\u5c06\u67f1 src \u9876\u90e8\u7684 \\(i\\) \u4e2a\u5706\u76d8\u501f\u52a9\u7f13\u51b2\u67f1 buf \u79fb\u52a8\u81f3\u76ee\u6807\u67f1 tar \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hanota.py
    def move(src: list[int], tar: list[int]):\n    \"\"\"\u79fb\u52a8\u4e00\u4e2a\u5706\u76d8\"\"\"\n    # \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    pan = src.pop()\n    # \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.append(pan)\n\ndef dfs(i: int, src: list[int], buf: list[int], tar: list[int]):\n    \"\"\"\u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i)\"\"\"\n    # \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1:\n        move(src, tar)\n        return\n    # \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf)\n    # \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    # \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar)\n\ndef solve_hanota(A: list[int], B: list[int], C: list[int]):\n    \"\"\"\u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898\"\"\"\n    n = len(A)\n    # \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C)\n
    hanota.cpp
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(vector<int> &src, vector<int> &tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src.back();\n    src.pop_back();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push_back(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, vector<int> &src, vector<int> &buf, vector<int> &tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(vector<int> &A, vector<int> &B, vector<int> &C) {\n    int n = A.size();\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.java
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(List<Integer> src, List<Integer> tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    Integer pan = src.remove(src.size() - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, List<Integer> src, List<Integer> buf, List<Integer> tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(List<Integer> A, List<Integer> B, List<Integer> C) {\n    int n = A.size();\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.cs
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid Move(List<int> src, List<int> tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src[^1];\n    src.RemoveAt(src.Count - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.Add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid DFS(int i, List<int> src, List<int> buf, List<int> tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        Move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    DFS(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    Move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    DFS(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid SolveHanota(List<int> A, List<int> B, List<int> C) {\n    int n = A.Count;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    DFS(n, A, B, C);\n}\n
    hanota.go
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunc move(src, tar *list.List) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    pan := src.Back()\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.PushBack(pan.Value)\n    // \u79fb\u9664 src \u9876\u90e8\u5706\u76d8\n    src.Remove(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunc dfsHanota(i int, src, buf, tar *list.List) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move(src, tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfsHanota(i-1, src, tar, buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfsHanota(i-1, buf, src, tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunc solveHanota(A, B, C *list.List) {\n    n := A.Len()\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfsHanota(n, A, B, C)\n}\n
    hanota.swift
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunc move(src: inout [Int], tar: inout [Int]) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    let pan = src.popLast()!\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.append(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunc dfs(i: Int, src: inout [Int], buf: inout [Int], tar: inout [Int]) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move(src: &src, tar: &tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i: i - 1, src: &src, buf: &tar, tar: &buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src: &src, tar: &tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i: i - 1, src: &buf, buf: &src, tar: &tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunc solveHanota(A: inout [Int], B: inout [Int], C: inout [Int]) {\n    let n = A.count\n    // \u5217\u8868\u5c3e\u90e8\u662f\u67f1\u5b50\u9876\u90e8\n    // \u5c06 src \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(i: n, src: &A, buf: &B, tar: &C)\n}\n
    hanota.js
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunction move(src, tar) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    const pan = src.pop();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunction dfs(i, src, buf, tar) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i === 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunction solveHanota(A, B, C) {\n    const n = A.length;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.ts
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfunction move(src: number[], tar: number[]): void {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    const pan = src.pop();\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfunction dfs(i: number, src: number[], buf: number[], tar: number[]): void {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i === 1) {\n        move(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfunction solveHanota(A: number[], B: number[], C: number[]): void {\n    const n = A.length;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.dart
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(List<int> src, List<int> tar) {\n  // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n  int pan = src.removeLast();\n  // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n  tar.add(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, List<int> src, List<int> buf, List<int> tar) {\n  // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n  if (i == 1) {\n    move(src, tar);\n    return;\n  }\n  // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n  dfs(i - 1, src, tar, buf);\n  // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n  move(src, tar);\n  // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n  dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(List<int> A, List<int> B, List<int> C) {\n  int n = A.length;\n  // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n  dfs(n, A, B, C);\n}\n
    hanota.rs
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfn move_pan(src: &mut Vec<i32>, tar: &mut Vec<i32>) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    let pan = src.remove(src.len() - 1);\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.push(pan);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfn dfs(i: i32, src: &mut Vec<i32>, buf: &mut Vec<i32>, tar: &mut Vec<i32>) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if i == 1 {\n        move_pan(src, tar);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move_pan(src, tar);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfn solve_hanota(A: &mut Vec<i32>, B: &mut Vec<i32>, C: &mut Vec<i32>) {\n    let n = A.len() as i32;\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C);\n}\n
    hanota.c
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nvoid move(int *src, int *srcSize, int *tar, int *tarSize) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    int pan = src[*srcSize - 1];\n    src[*srcSize - 1] = 0;\n    (*srcSize)--;\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar[*tarSize] = pan;\n    (*tarSize)++;\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nvoid dfs(int i, int *src, int *srcSize, int *buf, int *bufSize, int *tar, int *tarSize) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, srcSize, tar, tarSize);\n        return;\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, srcSize, tar, tarSize, buf, bufSize);\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, srcSize, tar, tarSize);\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, bufSize, src, srcSize, tar, tarSize);\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nvoid solveHanota(int *A, int *ASize, int *B, int *BSize, int *C, int *CSize) {\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(*ASize, A, ASize, B, BSize, C, CSize);\n}\n
    hanota.kt
    /* \u79fb\u52a8\u4e00\u4e2a\u5706\u76d8 */\nfun move(src: MutableList<Int>, tar: MutableList<Int>) {\n    // \u4ece src \u9876\u90e8\u62ff\u51fa\u4e00\u4e2a\u5706\u76d8\n    val pan = src.removeAt(src.size - 1)\n    // \u5c06\u5706\u76d8\u653e\u5165 tar \u9876\u90e8\n    tar.add(pan)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 f(i) */\nfun dfs(i: Int, src: MutableList<Int>, buf: MutableList<Int>, tar: MutableList<Int>) {\n    // \u82e5 src \u53ea\u5269\u4e0b\u4e00\u4e2a\u5706\u76d8\uff0c\u5219\u76f4\u63a5\u5c06\u5176\u79fb\u5230 tar\n    if (i == 1) {\n        move(src, tar)\n        return\n    }\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 src \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 tar \u79fb\u5230 buf\n    dfs(i - 1, src, tar, buf)\n    // \u5b50\u95ee\u9898 f(1) \uff1a\u5c06 src \u5269\u4f59\u4e00\u4e2a\u5706\u76d8\u79fb\u5230 tar\n    move(src, tar)\n    // \u5b50\u95ee\u9898 f(i-1) \uff1a\u5c06 buf \u9876\u90e8 i-1 \u4e2a\u5706\u76d8\u501f\u52a9 src \u79fb\u5230 tar\n    dfs(i - 1, buf, src, tar)\n}\n\n/* \u6c42\u89e3\u6c49\u8bfa\u5854\u95ee\u9898 */\nfun solveHanota(A: MutableList<Int>, B: MutableList<Int>, C: MutableList<Int>) {\n    val n = A.size\n    // \u5c06 A \u9876\u90e8 n \u4e2a\u5706\u76d8\u501f\u52a9 B \u79fb\u5230 C\n    dfs(n, A, B, C)\n}\n
    hanota.rb
    [class]{}-[func]{move}\n\n[class]{}-[func]{dfs}\n\n[class]{}-[func]{solve_hanota}\n
    hanota.zig
    [class]{}-[func]{move}\n\n[class]{}-[func]{dfs}\n\n[class]{}-[func]{solveHanota}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 12-15 \u6240\u793a\uff0c\u6c49\u8bfa\u5854\u95ee\u9898\u5f62\u6210\u4e00\u68f5\u9ad8\u5ea6\u4e3a \\(n\\) \u7684\u9012\u5f52\u6811\uff0c\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u4e00\u4e2a\u5b50\u95ee\u9898\uff0c\u5bf9\u5e94\u4e00\u4e2a\u5f00\u542f\u7684 dfs() \u51fd\u6570\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    \u56fe 12-15 \u00a0 \u6c49\u8bfa\u5854\u95ee\u9898\u7684\u9012\u5f52\u6811

    Quote

    \u6c49\u8bfa\u5854\u95ee\u9898\u6e90\u81ea\u4e00\u4e2a\u53e4\u8001\u7684\u4f20\u8bf4\u3002\u5728\u53e4\u5370\u5ea6\u7684\u4e00\u4e2a\u5bfa\u5e99\u91cc\uff0c\u50e7\u4fa3\u4eec\u6709\u4e09\u6839\u9ad8\u5927\u7684\u94bb\u77f3\u67f1\u5b50\uff0c\u4ee5\u53ca \\(64\\) \u4e2a\u5927\u5c0f\u4e0d\u4e00\u7684\u91d1\u5706\u76d8\u3002\u50e7\u4fa3\u4eec\u4e0d\u65ad\u5730\u79fb\u52a8\u5706\u76d8\uff0c\u4ed6\u4eec\u76f8\u4fe1\u5728\u6700\u540e\u4e00\u4e2a\u5706\u76d8\u88ab\u6b63\u786e\u653e\u7f6e\u7684\u90a3\u4e00\u523b\uff0c\u8fd9\u4e2a\u4e16\u754c\u5c31\u4f1a\u7ed3\u675f\u3002

    \u7136\u800c\uff0c\u5373\u4f7f\u50e7\u4fa3\u4eec\u6bcf\u79d2\u949f\u79fb\u52a8\u4e00\u6b21\uff0c\u603b\u5171\u9700\u8981\u5927\u7ea6 \\(2^{64} \\approx 1.84\u00d710^{19}\\) \u79d2\uff0c\u5408\u7ea6 \\(5850\\) \u4ebf\u5e74\uff0c\u8fdc\u8fdc\u8d85\u8fc7\u4e86\u73b0\u5728\u5bf9\u5b87\u5b99\u5e74\u9f84\u7684\u4f30\u8ba1\u3002\u6240\u4ee5\uff0c\u5018\u82e5\u8fd9\u4e2a\u4f20\u8bf4\u662f\u771f\u7684\uff0c\u6211\u4eec\u5e94\u8be5\u4e0d\u9700\u8981\u62c5\u5fc3\u4e16\u754c\u672b\u65e5\u7684\u5230\u6765\u3002

    "},{"location":"chapter_divide_and_conquer/summary/","title":"12.5 \u00a0 \u5c0f\u7ed3","text":"
    • \u5206\u6cbb\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u7b97\u6cd5\u8bbe\u8ba1\u7b56\u7565\uff0c\u5305\u62ec\u5206\uff08\u5212\u5206\uff09\u548c\u6cbb\uff08\u5408\u5e76\uff09\u4e24\u4e2a\u9636\u6bb5\uff0c\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\u3002
    • \u5224\u65ad\u662f\u5426\u662f\u5206\u6cbb\u7b97\u6cd5\u95ee\u9898\u7684\u4f9d\u636e\u5305\u62ec\uff1a\u95ee\u9898\u80fd\u5426\u5206\u89e3\u3001\u5b50\u95ee\u9898\u662f\u5426\u72ec\u7acb\u3001\u5b50\u95ee\u9898\u80fd\u5426\u5408\u5e76\u3002
    • \u5f52\u5e76\u6392\u5e8f\u662f\u5206\u6cbb\u7b56\u7565\u7684\u5178\u578b\u5e94\u7528\uff0c\u5176\u9012\u5f52\u5730\u5c06\u6570\u7ec4\u5212\u5206\u4e3a\u7b49\u957f\u7684\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u76f4\u5230\u53ea\u5269\u4e00\u4e2a\u5143\u7d20\u65f6\u5f00\u59cb\u9010\u5c42\u5408\u5e76\uff0c\u4ece\u800c\u5b8c\u6210\u6392\u5e8f\u3002
    • \u5f15\u5165\u5206\u6cbb\u7b56\u7565\u5f80\u5f80\u53ef\u4ee5\u63d0\u5347\u7b97\u6cd5\u6548\u7387\u3002\u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u7b56\u7565\u51cf\u5c11\u4e86\u64cd\u4f5c\u6570\u91cf\uff1b\u53e6\u4e00\u65b9\u9762\uff0c\u5206\u6cbb\u540e\u6709\u5229\u4e8e\u7cfb\u7edf\u7684\u5e76\u884c\u4f18\u5316\u3002
    • \u5206\u6cbb\u65e2\u53ef\u4ee5\u89e3\u51b3\u8bb8\u591a\u7b97\u6cd5\u95ee\u9898\uff0c\u4e5f\u5e7f\u6cdb\u5e94\u7528\u4e8e\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u8bbe\u8ba1\u4e2d\uff0c\u5904\u5904\u53ef\u89c1\u5176\u8eab\u5f71\u3002
    • \u76f8\u8f83\u4e8e\u66b4\u529b\u641c\u7d22\uff0c\u81ea\u9002\u5e94\u641c\u7d22\u6548\u7387\u66f4\u9ad8\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u7684\u641c\u7d22\u7b97\u6cd5\u901a\u5e38\u662f\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u5b9e\u73b0\u7684\u3002
    • \u4e8c\u5206\u67e5\u627e\u662f\u5206\u6cbb\u7b56\u7565\u7684\u53e6\u4e00\u4e2a\u5178\u578b\u5e94\u7528\uff0c\u5b83\u4e0d\u5305\u542b\u5c06\u5b50\u95ee\u9898\u7684\u89e3\u8fdb\u884c\u5408\u5e76\u7684\u6b65\u9aa4\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u9012\u5f52\u5206\u6cbb\u5b9e\u73b0\u4e8c\u5206\u67e5\u627e\u3002
    • \u5728\u6784\u5efa\u4e8c\u53c9\u6811\u7684\u95ee\u9898\u4e2d\uff0c\u6784\u5efa\u6811\uff08\u539f\u95ee\u9898\uff09\u53ef\u4ee5\u5212\u5206\u4e3a\u6784\u5efa\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\uff08\u5b50\u95ee\u9898\uff09\uff0c\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5212\u5206\u524d\u5e8f\u904d\u5386\u548c\u4e2d\u5e8f\u904d\u5386\u7684\u7d22\u5f15\u533a\u95f4\u6765\u5b9e\u73b0\u3002
    • \u5728\u6c49\u8bfa\u5854\u95ee\u9898\u4e2d\uff0c\u4e00\u4e2a\u89c4\u6a21\u4e3a \\(n\\) \u7684\u95ee\u9898\u53ef\u4ee5\u5212\u5206\u4e3a\u4e24\u4e2a\u89c4\u6a21\u4e3a \\(n-1\\) \u7684\u5b50\u95ee\u9898\u548c\u4e00\u4e2a\u89c4\u6a21\u4e3a \\(1\\) \u7684\u5b50\u95ee\u9898\u3002\u6309\u987a\u5e8f\u89e3\u51b3\u8fd9\u4e09\u4e2a\u5b50\u95ee\u9898\u540e\uff0c\u539f\u95ee\u9898\u968f\u4e4b\u5f97\u5230\u89e3\u51b3\u3002
    "},{"location":"chapter_dynamic_programming/","title":"\u7b2c 14 \u7ae0 \u00a0 \u52a8\u6001\u89c4\u5212","text":"

    Abstract

    \u5c0f\u6eaa\u6c47\u5165\u6cb3\u6d41\uff0c\u6c5f\u6cb3\u6c47\u5165\u5927\u6d77\u3002

    \u52a8\u6001\u89c4\u5212\u5c06\u5c0f\u95ee\u9898\u7684\u89e3\u6c47\u96c6\u6210\u5927\u95ee\u9898\u7684\u7b54\u6848\uff0c\u4e00\u6b65\u6b65\u5f15\u9886\u6211\u4eec\u8d70\u5411\u89e3\u51b3\u95ee\u9898\u7684\u5f7c\u5cb8\u3002

    "},{"location":"chapter_dynamic_programming/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 14.1 \u00a0 \u521d\u63a2\u52a8\u6001\u89c4\u5212
    • 14.2 \u00a0 DP \u95ee\u9898\u7279\u6027
    • 14.3 \u00a0 DP \u89e3\u9898\u601d\u8def
    • 14.4 \u00a0 0-1 \u80cc\u5305\u95ee\u9898
    • 14.5 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898
    • 14.6 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898
    • 14.7 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_dynamic_programming/dp_problem_features/","title":"14.2 \u00a0 \u52a8\u6001\u89c4\u5212\u95ee\u9898\u7279\u6027","text":"

    \u5728\u4e0a\u4e00\u8282\u4e2d\uff0c\u6211\u4eec\u5b66\u4e60\u4e86\u52a8\u6001\u89c4\u5212\u662f\u5982\u4f55\u901a\u8fc7\u5b50\u95ee\u9898\u5206\u89e3\u6765\u6c42\u89e3\u539f\u95ee\u9898\u7684\u3002\u5b9e\u9645\u4e0a\uff0c\u5b50\u95ee\u9898\u5206\u89e3\u662f\u4e00\u79cd\u901a\u7528\u7684\u7b97\u6cd5\u601d\u8def\uff0c\u5728\u5206\u6cbb\u3001\u52a8\u6001\u89c4\u5212\u3001\u56de\u6eaf\u4e2d\u7684\u4fa7\u91cd\u70b9\u4e0d\u540c\u3002

    • \u5206\u6cbb\u7b97\u6cd5\u9012\u5f52\u5730\u5c06\u539f\u95ee\u9898\u5212\u5206\u4e3a\u591a\u4e2a\u76f8\u4e92\u72ec\u7acb\u7684\u5b50\u95ee\u9898\uff0c\u76f4\u81f3\u6700\u5c0f\u5b50\u95ee\u9898\uff0c\u5e76\u5728\u56de\u6eaf\u4e2d\u5408\u5e76\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u6700\u7ec8\u5f97\u5230\u539f\u95ee\u9898\u7684\u89e3\u3002
    • \u52a8\u6001\u89c4\u5212\u4e5f\u5bf9\u95ee\u9898\u8fdb\u884c\u9012\u5f52\u5206\u89e3\uff0c\u4f46\u4e0e\u5206\u6cbb\u7b97\u6cd5\u7684\u4e3b\u8981\u533a\u522b\u662f\uff0c\u52a8\u6001\u89c4\u5212\u4e2d\u7684\u5b50\u95ee\u9898\u662f\u76f8\u4e92\u4f9d\u8d56\u7684\uff0c\u5728\u5206\u89e3\u8fc7\u7a0b\u4e2d\u4f1a\u51fa\u73b0\u8bb8\u591a\u91cd\u53e0\u5b50\u95ee\u9898\u3002
    • \u56de\u6eaf\u7b97\u6cd5\u5728\u5c1d\u8bd5\u548c\u56de\u9000\u4e2d\u7a77\u4e3e\u6240\u6709\u53ef\u80fd\u7684\u89e3\uff0c\u5e76\u901a\u8fc7\u526a\u679d\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u641c\u7d22\u5206\u652f\u3002\u539f\u95ee\u9898\u7684\u89e3\u7531\u4e00\u7cfb\u5217\u51b3\u7b56\u6b65\u9aa4\u6784\u6210\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6bcf\u4e2a\u51b3\u7b56\u6b65\u9aa4\u4e4b\u524d\u7684\u5b50\u5e8f\u5217\u770b\u4f5c\u4e00\u4e2a\u5b50\u95ee\u9898\u3002

    \u5b9e\u9645\u4e0a\uff0c\u52a8\u6001\u89c4\u5212\u5e38\u7528\u6765\u6c42\u89e3\u6700\u4f18\u5316\u95ee\u9898\uff0c\u5b83\u4eec\u4e0d\u4ec5\u5305\u542b\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u8fd8\u5177\u6709\u53e6\u5916\u4e24\u5927\u7279\u6027\uff1a\u6700\u4f18\u5b50\u7ed3\u6784\u3001\u65e0\u540e\u6548\u6027\u3002

    "},{"location":"chapter_dynamic_programming/dp_problem_features/#1421","title":"14.2.1 \u00a0 \u6700\u4f18\u5b50\u7ed3\u6784","text":"

    \u6211\u4eec\u5bf9\u722c\u697c\u68af\u95ee\u9898\u7a0d\u4f5c\u6539\u52a8\uff0c\u4f7f\u4e4b\u66f4\u52a0\u9002\u5408\u5c55\u793a\u6700\u4f18\u5b50\u7ed3\u6784\u6982\u5ff5\u3002

    \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7

    \u7ed9\u5b9a\u4e00\u4e2a\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\uff0c\u6bcf\u4e00\u9636\u697c\u68af\u4e0a\u90fd\u8d34\u6709\u4e00\u4e2a\u975e\u8d1f\u6574\u6570\uff0c\u8868\u793a\u4f60\u5728\u8be5\u53f0\u9636\u6240\u9700\u8981\u4ed8\u51fa\u7684\u4ee3\u4ef7\u3002\u7ed9\u5b9a\u4e00\u4e2a\u975e\u8d1f\u6574\u6570\u6570\u7ec4 \\(cost\\) \uff0c\u5176\u4e2d \\(cost[i]\\) \u8868\u793a\u5728\u7b2c \\(i\\) \u4e2a\u53f0\u9636\u9700\u8981\u4ed8\u51fa\u7684\u4ee3\u4ef7\uff0c\\(cost[0]\\) \u4e3a\u5730\u9762\uff08\u8d77\u59cb\u70b9\uff09\u3002\u8bf7\u8ba1\u7b97\u6700\u5c11\u9700\u8981\u4ed8\u51fa\u591a\u5c11\u4ee3\u4ef7\u624d\u80fd\u5230\u8fbe\u9876\u90e8\uff1f

    \u5982\u56fe 14-6 \u6240\u793a\uff0c\u82e5\u7b2c \\(1\\)\u3001\\(2\\)\u3001\\(3\\) \u9636\u7684\u4ee3\u4ef7\u5206\u522b\u4e3a \\(1\\)\u3001\\(10\\)\u3001\\(1\\) \uff0c\u5219\u4ece\u5730\u9762\u722c\u5230\u7b2c \\(3\\) \u9636\u7684\u6700\u5c0f\u4ee3\u4ef7\u4e3a \\(2\\) \u3002

    \u56fe 14-6 \u00a0 \u722c\u5230\u7b2c 3 \u9636\u7684\u6700\u5c0f\u4ee3\u4ef7

    \u8bbe \\(dp[i]\\) \u4e3a\u722c\u5230\u7b2c \\(i\\) \u9636\u7d2f\u8ba1\u4ed8\u51fa\u7684\u4ee3\u4ef7\uff0c\u7531\u4e8e\u7b2c \\(i\\) \u9636\u53ea\u53ef\u80fd\u4ece \\(i - 1\\) \u9636\u6216 \\(i - 2\\) \u9636\u8d70\u6765\uff0c\u56e0\u6b64 \\(dp[i]\\) \u53ea\u53ef\u80fd\u7b49\u4e8e \\(dp[i - 1] + cost[i]\\) \u6216 \\(dp[i - 2] + cost[i]\\) \u3002\u4e3a\u4e86\u5c3d\u53ef\u80fd\u51cf\u5c11\u4ee3\u4ef7\uff0c\u6211\u4eec\u5e94\u8be5\u9009\u62e9\u4e24\u8005\u4e2d\u8f83\u5c0f\u7684\u90a3\u4e00\u4e2a\uff1a

    \\[ dp[i] = \\min(dp[i-1], dp[i-2]) + cost[i] \\]

    \u8fd9\u4fbf\u53ef\u4ee5\u5f15\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\u7684\u542b\u4e49\uff1a\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u662f\u4ece\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u6784\u5efa\u5f97\u6765\u7684\u3002

    \u672c\u9898\u663e\u7136\u5177\u6709\u6700\u4f18\u5b50\u7ed3\u6784\uff1a\u6211\u4eec\u4ece\u4e24\u4e2a\u5b50\u95ee\u9898\u6700\u4f18\u89e3 \\(dp[i-1]\\) \u548c \\(dp[i-2]\\) \u4e2d\u6311\u9009\u51fa\u8f83\u4f18\u7684\u90a3\u4e00\u4e2a\uff0c\u5e76\u7528\u5b83\u6784\u5efa\u51fa\u539f\u95ee\u9898 \\(dp[i]\\) \u7684\u6700\u4f18\u89e3\u3002

    \u90a3\u4e48\uff0c\u4e0a\u4e00\u8282\u7684\u722c\u697c\u68af\u9898\u76ee\u6709\u6ca1\u6709\u6700\u4f18\u5b50\u7ed3\u6784\u5462\uff1f\u5b83\u7684\u76ee\u6807\u662f\u6c42\u89e3\u65b9\u6848\u6570\u91cf\uff0c\u770b\u4f3c\u662f\u4e00\u4e2a\u8ba1\u6570\u95ee\u9898\uff0c\u4f46\u5982\u679c\u6362\u4e00\u79cd\u95ee\u6cd5\uff1a\u201c\u6c42\u89e3\u6700\u5927\u65b9\u6848\u6570\u91cf\u201d\u3002\u6211\u4eec\u610f\u5916\u5730\u53d1\u73b0\uff0c\u867d\u7136\u9898\u76ee\u4fee\u6539\u524d\u540e\u662f\u7b49\u4ef7\u7684\uff0c\u4f46\u6700\u4f18\u5b50\u7ed3\u6784\u6d6e\u73b0\u51fa\u6765\u4e86\uff1a\u7b2c \\(n\\) \u9636\u6700\u5927\u65b9\u6848\u6570\u91cf\u7b49\u4e8e\u7b2c \\(n-1\\) \u9636\u548c\u7b2c \\(n-2\\) \u9636\u6700\u5927\u65b9\u6848\u6570\u91cf\u4e4b\u548c\u3002\u6240\u4ee5\u8bf4\uff0c\u6700\u4f18\u5b50\u7ed3\u6784\u7684\u89e3\u91ca\u65b9\u5f0f\u6bd4\u8f83\u7075\u6d3b\uff0c\u5728\u4e0d\u540c\u95ee\u9898\u4e2d\u4f1a\u6709\u4e0d\u540c\u7684\u542b\u4e49\u3002

    \u6839\u636e\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff0c\u4ee5\u53ca\u521d\u59cb\u72b6\u6001 \\(dp[1] = cost[1]\\) \u548c \\(dp[2] = cost[2]\\) \uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5f97\u5230\u52a8\u6001\u89c4\u5212\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp(cost: list[int]) -> int:\n    \"\"\"\u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(cost) - 1\n    if n == 1 or n == 2:\n        return cost[n]\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [0] * (n + 1)\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1], dp[2] = cost[1], cost[2]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    return dp[n]\n
    min_cost_climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(vector<int> &cost) {\n    int n = cost.size() - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<int> dp(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.java
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(int[] cost) {\n    int n = cost.length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint MinCostClimbingStairsDP(int[] cost) {\n    int n = cost.Length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = Math.Min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.go
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDP(cost []int) int {\n    n := len(cost) - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    min := func(a, b int) int {\n        if a < b {\n            return a\n        }\n        return b\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i] = min(dp[i-1], dp[i-2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDP(cost: [Int]) -> Int {\n    let n = cost.count - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: 0, count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.js
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDP(cost) {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDP(cost: Array<number>): number {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    min_cost_climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(List<int> cost) {\n  int n = cost.length - 1;\n  if (n == 1 || n == 2) return cost[n];\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<int> dp = List.filled(n + 1, 0);\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1] = cost[1];\n  dp[2] = cost[2];\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];\n  }\n  return dp[n];\n}\n
    min_cost_climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfn min_cost_climbing_stairs_dp(cost: &[i32]) -> i32 {\n    let n = cost.len() - 1;\n    if n == 1 || n == 2 {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![-1; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i] = cmp::min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    dp[n]\n}\n
    min_cost_climbing_stairs_dp.c
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDP(int cost[], int costSize) {\n    int n = costSize - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int *dp = calloc(n + 1, sizeof(int));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = myMin(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    int res = dp[n];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    min_cost_climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212 */\nfun minCostClimbingStairsDP(cost: IntArray): Int {\n    val n = cost.size - 1\n    if (n == 1 || n == 2) return cost[n]\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = IntArray(n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1]\n    dp[2] = cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]\n    }\n    return dp[n]\n}\n
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp}\n
    min_cost_climbing_stairs_dp.zig
    // \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u52a8\u6001\u89c4\u5212\nfn minCostClimbingStairsDP(comptime cost: []i32) i32 {\n    comptime var n = cost.len - 1;\n    if (n == 1 or n == 2) {\n        return cost[n];\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_]i32{-1} ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = cost[1];\n    dp[2] = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i] = @min(dp[i - 1], dp[i - 2]) + cost[i];\n    }\n    return dp[n];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-7 \u5c55\u793a\u4e86\u4ee5\u4e0a\u4ee3\u7801\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b\u3002

    \u56fe 14-7 \u00a0 \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u672c\u9898\u4e5f\u53ef\u4ee5\u8fdb\u884c\u7a7a\u95f4\u4f18\u5316\uff0c\u5c06\u4e00\u7ef4\u538b\u7f29\u81f3\u96f6\u7ef4\uff0c\u4f7f\u5f97\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n)\\) \u964d\u81f3 \\(O(1)\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_cost_climbing_stairs_dp.py
    def min_cost_climbing_stairs_dp_comp(cost: list[int]) -> int:\n    \"\"\"\u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(cost) - 1\n    if n == 1 or n == 2:\n        return cost[n]\n    a, b = cost[1], cost[2]\n    for i in range(3, n + 1):\n        a, b = b, min(a, b) + cost[i]\n    return b\n
    min_cost_climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(vector<int> &cost) {\n    int n = cost.size() - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.java
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(int[] cost) {\n    int n = cost.length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint MinCostClimbingStairsDPComp(int[] cost) {\n    int n = cost.Length - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = Math.Min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.go
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDPComp(cost []int) int {\n    n := len(cost) - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    min := func(a, b int) int {\n        if a < b {\n            return a\n        }\n        return b\n    }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    a, b := cost[1], cost[2]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        tmp := b\n        b = min(a, tmp) + cost[i]\n        a = tmp\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minCostClimbingStairsDPComp(cost: [Int]) -> Int {\n    let n = cost.count - 1\n    if n == 1 || n == 2 {\n        return cost[n]\n    }\n    var (a, b) = (cost[1], cost[2])\n    for i in 3 ... n {\n        (a, b) = (b, min(a, b) + cost[i])\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.js
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDPComp(cost) {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    let a = cost[1],\n        b = cost[2];\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minCostClimbingStairsDPComp(cost: Array<number>): number {\n    const n = cost.length - 1;\n    if (n === 1 || n === 2) {\n        return cost[n];\n    }\n    let a = cost[1],\n        b = cost[2];\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = Math.min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(List<int> cost) {\n  int n = cost.length - 1;\n  if (n == 1 || n == 2) return cost[n];\n  int a = cost[1], b = cost[2];\n  for (int i = 3; i <= n; i++) {\n    int tmp = b;\n    b = min(a, tmp) + cost[i];\n    a = tmp;\n  }\n  return b;\n}\n
    min_cost_climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn min_cost_climbing_stairs_dp_comp(cost: &[i32]) -> i32 {\n    let n = cost.len() - 1;\n    if n == 1 || n == 2 {\n        return cost[n];\n    };\n    let (mut a, mut b) = (cost[1], cost[2]);\n    for i in 3..=n {\n        let tmp = b;\n        b = cmp::min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    b\n}\n
    min_cost_climbing_stairs_dp.c
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minCostClimbingStairsDPComp(int cost[], int costSize) {\n    int n = costSize - 1;\n    if (n == 1 || n == 2)\n        return cost[n];\n    int a = cost[1], b = cost[2];\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = myMin(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    min_cost_climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun minCostClimbingStairsDPComp(cost: IntArray): Int {\n    val n = cost.size - 1\n    if (n == 1 || n == 2) return cost[n]\n    var a = cost[1]\n    var b = cost[2]\n    for (i in 3..n) {\n        val tmp = b\n        b = min(a, tmp) + cost[i]\n        a = tmp\n    }\n    return b\n}\n
    min_cost_climbing_stairs_dp.rb
    [class]{}-[func]{min_cost_climbing_stairs_dp_comp}\n
    min_cost_climbing_stairs_dp.zig
    // \u722c\u697c\u68af\u6700\u5c0f\u4ee3\u4ef7\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn minCostClimbingStairsDPComp(cost: []i32) i32 {\n    var n = cost.len - 1;\n    if (n == 1 or n == 2) {\n        return cost[n];\n    }\n    var a = cost[1];\n    var b = cost[2];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        var tmp = b;\n        b = @min(a, tmp) + cost[i];\n        a = tmp;\n    }\n    return b;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/dp_problem_features/#1422","title":"14.2.2 \u00a0 \u65e0\u540e\u6548\u6027","text":"

    \u65e0\u540e\u6548\u6027\u662f\u52a8\u6001\u89c4\u5212\u80fd\u591f\u6709\u6548\u89e3\u51b3\u95ee\u9898\u7684\u91cd\u8981\u7279\u6027\u4e4b\u4e00\uff0c\u5176\u5b9a\u4e49\u4e3a\uff1a\u7ed9\u5b9a\u4e00\u4e2a\u786e\u5b9a\u7684\u72b6\u6001\uff0c\u5b83\u7684\u672a\u6765\u53d1\u5c55\u53ea\u4e0e\u5f53\u524d\u72b6\u6001\u6709\u5173\uff0c\u800c\u4e0e\u8fc7\u53bb\u7ecf\u5386\u7684\u6240\u6709\u72b6\u6001\u65e0\u5173\u3002

    \u4ee5\u722c\u697c\u68af\u95ee\u9898\u4e3a\u4f8b\uff0c\u7ed9\u5b9a\u72b6\u6001 \\(i\\) \uff0c\u5b83\u4f1a\u53d1\u5c55\u51fa\u72b6\u6001 \\(i+1\\) \u548c\u72b6\u6001 \\(i+2\\) \uff0c\u5206\u522b\u5bf9\u5e94\u8df3 \\(1\\) \u6b65\u548c\u8df3 \\(2\\) \u6b65\u3002\u5728\u505a\u51fa\u8fd9\u4e24\u79cd\u9009\u62e9\u65f6\uff0c\u6211\u4eec\u65e0\u987b\u8003\u8651\u72b6\u6001 \\(i\\) \u4e4b\u524d\u7684\u72b6\u6001\uff0c\u5b83\u4eec\u5bf9\u72b6\u6001 \\(i\\) \u7684\u672a\u6765\u6ca1\u6709\u5f71\u54cd\u3002

    \u7136\u800c\uff0c\u5982\u679c\u6211\u4eec\u7ed9\u722c\u697c\u68af\u95ee\u9898\u6dfb\u52a0\u4e00\u4e2a\u7ea6\u675f\uff0c\u60c5\u51b5\u5c31\u4e0d\u4e00\u6837\u4e86\u3002

    \u5e26\u7ea6\u675f\u722c\u697c\u68af

    \u7ed9\u5b9a\u4e00\u4e2a\u5171\u6709 \\(n\\) \u9636\u7684\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\uff0c\u4f46\u4e0d\u80fd\u8fde\u7eed\u4e24\u8f6e\u8df3 \\(1\\) \u9636\uff0c\u8bf7\u95ee\u6709\u591a\u5c11\u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\uff1f

    \u5982\u56fe 14-8 \u6240\u793a\uff0c\u722c\u4e0a\u7b2c \\(3\\) \u9636\u4ec5\u5269 \\(2\\) \u79cd\u53ef\u884c\u65b9\u6848\uff0c\u5176\u4e2d\u8fde\u7eed\u4e09\u6b21\u8df3 \\(1\\) \u9636\u7684\u65b9\u6848\u4e0d\u6ee1\u8db3\u7ea6\u675f\u6761\u4ef6\uff0c\u56e0\u6b64\u88ab\u820d\u5f03\u3002

    \u56fe 14-8 \u00a0 \u5e26\u7ea6\u675f\u722c\u5230\u7b2c 3 \u9636\u7684\u65b9\u6848\u6570\u91cf

    \u5728\u8be5\u95ee\u9898\u4e2d\uff0c\u5982\u679c\u4e0a\u4e00\u8f6e\u662f\u8df3 \\(1\\) \u9636\u4e0a\u6765\u7684\uff0c\u90a3\u4e48\u4e0b\u4e00\u8f6e\u5c31\u5fc5\u987b\u8df3 \\(2\\) \u9636\u3002\u8fd9\u610f\u5473\u7740\uff0c\u4e0b\u4e00\u6b65\u9009\u62e9\u4e0d\u80fd\u7531\u5f53\u524d\u72b6\u6001\uff08\u5f53\u524d\u6240\u5728\u697c\u68af\u9636\u6570\uff09\u72ec\u7acb\u51b3\u5b9a\uff0c\u8fd8\u548c\u524d\u4e00\u4e2a\u72b6\u6001\uff08\u4e0a\u4e00\u8f6e\u6240\u5728\u697c\u68af\u9636\u6570\uff09\u6709\u5173\u3002

    \u4e0d\u96be\u53d1\u73b0\uff0c\u6b64\u95ee\u9898\u5df2\u4e0d\u6ee1\u8db3\u65e0\u540e\u6548\u6027\uff0c\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b \\(dp[i] = dp[i-1] + dp[i-2]\\) \u4e5f\u5931\u6548\u4e86\uff0c\u56e0\u4e3a \\(dp[i-1]\\) \u4ee3\u8868\u672c\u8f6e\u8df3 \\(1\\) \u9636\uff0c\u4f46\u5176\u4e2d\u5305\u542b\u4e86\u8bb8\u591a\u201c\u4e0a\u4e00\u8f6e\u662f\u8df3 \\(1\\) \u9636\u4e0a\u6765\u7684\u201d\u65b9\u6848\uff0c\u800c\u4e3a\u4e86\u6ee1\u8db3\u7ea6\u675f\uff0c\u6211\u4eec\u5c31\u4e0d\u80fd\u5c06 \\(dp[i-1]\\) \u76f4\u63a5\u8ba1\u5165 \\(dp[i]\\) \u4e2d\u3002

    \u4e3a\u6b64\uff0c\u6211\u4eec\u9700\u8981\u6269\u5c55\u72b6\u6001\u5b9a\u4e49\uff1a\u72b6\u6001 \\([i, j]\\) \u8868\u793a\u5904\u5728\u7b2c \\(i\\) \u9636\u5e76\u4e14\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(j\\) \u9636\uff0c\u5176\u4e2d \\(j \\in \\{1, 2\\}\\) \u3002\u6b64\u72b6\u6001\u5b9a\u4e49\u6709\u6548\u5730\u533a\u5206\u4e86\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(1\\) \u9636\u8fd8\u662f \\(2\\) \u9636\uff0c\u6211\u4eec\u53ef\u4ee5\u636e\u6b64\u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u4ece\u4f55\u800c\u6765\u7684\u3002

    • \u5f53\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(1\\) \u9636\u65f6\uff0c\u4e0a\u4e0a\u4e00\u8f6e\u53ea\u80fd\u9009\u62e9\u8df3 \\(2\\) \u9636\uff0c\u5373 \\(dp[i, 1]\\) \u53ea\u80fd\u4ece \\(dp[i-1, 2]\\) \u8f6c\u79fb\u8fc7\u6765\u3002
    • \u5f53\u4e0a\u4e00\u8f6e\u8df3\u4e86 \\(2\\) \u9636\u65f6\uff0c\u4e0a\u4e0a\u4e00\u8f6e\u53ef\u9009\u62e9\u8df3 \\(1\\) \u9636\u6216\u8df3 \\(2\\) \u9636\uff0c\u5373 \\(dp[i, 2]\\) \u53ef\u4ee5\u4ece \\(dp[i-2, 1]\\) \u6216 \\(dp[i-2, 2]\\) \u8f6c\u79fb\u8fc7\u6765\u3002

    \u5982\u56fe 14-9 \u6240\u793a\uff0c\u5728\u8be5\u5b9a\u4e49\u4e0b\uff0c\\(dp[i, j]\\) \u8868\u793a\u72b6\u6001 \\([i, j]\\) \u5bf9\u5e94\u7684\u65b9\u6848\u6570\u3002\u6b64\u65f6\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ \\begin{cases} dp[i, 1] = dp[i-1, 2] \\\\ dp[i, 2] = dp[i-2, 1] + dp[i-2, 2] \\end{cases} \\]

    \u56fe 14-9 \u00a0 \u8003\u8651\u7ea6\u675f\u4e0b\u7684\u9012\u63a8\u5173\u7cfb

    \u6700\u7ec8\uff0c\u8fd4\u56de \\(dp[n, 1] + dp[n, 2]\\) \u5373\u53ef\uff0c\u4e24\u8005\u4e4b\u548c\u4ee3\u8868\u722c\u5230\u7b2c \\(n\\) \u9636\u7684\u65b9\u6848\u603b\u6570\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_constraint_dp.py
    def climbing_stairs_constraint_dp(n: int) -> int:\n    \"\"\"\u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return 1\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [[0] * 3 for _ in range(n + 1)]\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1], dp[1][2] = 1, 0\n    dp[2][1], dp[2][2] = 0, 1\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    return dp[n][1] + dp[n][2]\n
    climbing_stairs_constraint_dp.cpp
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<vector<int>> dp(n + 1, vector<int>(3, 0));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.java
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[][] dp = new int[n + 1][3];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.cs
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[,] dp = new int[n + 1, 3];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1, 1] = 1;\n    dp[1, 2] = 0;\n    dp[2, 1] = 0;\n    dp[2, 2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i, 1] = dp[i - 1, 2];\n        dp[i, 2] = dp[i - 2, 1] + dp[i - 2, 2];\n    }\n    return dp[n, 1] + dp[n, 2];\n}\n
    climbing_stairs_constraint_dp.go
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsConstraintDP(n int) int {\n    if n == 1 || n == 2 {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([][3]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i][1] = dp[i-1][2]\n        dp[i][2] = dp[i-2][1] + dp[i-2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.swift
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsConstraintDP(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: Array(repeating: 0, count: 3), count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.js
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsConstraintDP(n) {\n    if (n === 1 || n === 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = Array.from(new Array(n + 1), () => new Array(3));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.ts
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsConstraintDP(n: number): number {\n    if (n === 1 || n === 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = Array.from({ length: n + 1 }, () => new Array(3));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.dart
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n  if (n == 1 || n == 2) {\n    return 1;\n  }\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(3, 0));\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1][1] = 1;\n  dp[1][2] = 0;\n  dp[2][1] = 0;\n  dp[2][2] = 1;\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i][1] = dp[i - 1][2];\n    dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n  }\n  return dp[n][1] + dp[n][2];\n}\n
    climbing_stairs_constraint_dp.rs
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_constraint_dp(n: usize) -> i32 {\n    if n == 1 || n == 2 {\n        return 1;\n    };\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![vec![-1; 3]; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.c
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsConstraintDP(int n) {\n    if (n == 1 || n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(3, sizeof(int));\n    }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    int res = dp[n][1] + dp[n][2];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    climbing_stairs_constraint_dp.kt
    /* \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsConstraintDP(n: Int): Int {\n    if (n == 1 || n == 2) {\n        return 1\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = Array(n + 1) { IntArray(3) }\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1\n    dp[1][2] = 0\n    dp[2][1] = 0\n    dp[2][2] = 1\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i][1] = dp[i - 1][2]\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2]\n    }\n    return dp[n][1] + dp[n][2]\n}\n
    climbing_stairs_constraint_dp.rb
    [class]{}-[func]{climbing_stairs_constraint_dp}\n
    climbing_stairs_constraint_dp.zig
    // \u5e26\u7ea6\u675f\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\nfn climbingStairsConstraintDP(comptime n: usize) i32 {\n    if (n == 1 or n == 2) {\n        return 1;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_][3]i32{ [_]i32{ -1, -1, -1 } } ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1][1] = 1;\n    dp[1][2] = 0;\n    dp[2][1] = 0;\n    dp[2][2] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i][1] = dp[i - 1][2];\n        dp[i][2] = dp[i - 2][1] + dp[i - 2][2];\n    }\n    return dp[n][1] + dp[n][2];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5728\u4e0a\u9762\u7684\u6848\u4f8b\u4e2d\uff0c\u7531\u4e8e\u4ec5\u9700\u591a\u8003\u8651\u524d\u9762\u4e00\u4e2a\u72b6\u6001\uff0c\u56e0\u6b64\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u901a\u8fc7\u6269\u5c55\u72b6\u6001\u5b9a\u4e49\uff0c\u4f7f\u5f97\u95ee\u9898\u91cd\u65b0\u6ee1\u8db3\u65e0\u540e\u6548\u6027\u3002\u7136\u800c\uff0c\u67d0\u4e9b\u95ee\u9898\u5177\u6709\u975e\u5e38\u4e25\u91cd\u7684\u201c\u6709\u540e\u6548\u6027\u201d\u3002

    \u722c\u697c\u68af\u4e0e\u969c\u788d\u751f\u6210

    \u7ed9\u5b9a\u4e00\u4e2a\u5171\u6709 \\(n\\) \u9636\u7684\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\u3002\u89c4\u5b9a\u5f53\u722c\u5230\u7b2c \\(i\\) \u9636\u65f6\uff0c\u7cfb\u7edf\u81ea\u52a8\u4f1a\u5728\u7b2c \\(2i\\) \u9636\u4e0a\u653e\u4e0a\u969c\u788d\u7269\uff0c\u4e4b\u540e\u6240\u6709\u8f6e\u90fd\u4e0d\u5141\u8bb8\u8df3\u5230\u7b2c \\(2i\\) \u9636\u4e0a\u3002\u4f8b\u5982\uff0c\u524d\u4e24\u8f6e\u5206\u522b\u8df3\u5230\u4e86\u7b2c \\(2\\)\u3001\\(3\\) \u9636\u4e0a\uff0c\u5219\u4e4b\u540e\u5c31\u4e0d\u80fd\u8df3\u5230\u7b2c \\(4\\)\u3001\\(6\\) \u9636\u4e0a\u3002\u8bf7\u95ee\u6709\u591a\u5c11\u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\uff1f

    \u5728\u8fd9\u4e2a\u95ee\u9898\u4e2d\uff0c\u4e0b\u6b21\u8df3\u8dc3\u4f9d\u8d56\u8fc7\u53bb\u6240\u6709\u7684\u72b6\u6001\uff0c\u56e0\u4e3a\u6bcf\u4e00\u6b21\u8df3\u8dc3\u90fd\u4f1a\u5728\u66f4\u9ad8\u7684\u9636\u68af\u4e0a\u8bbe\u7f6e\u969c\u788d\uff0c\u5e76\u5f71\u54cd\u672a\u6765\u7684\u8df3\u8dc3\u3002\u5bf9\u4e8e\u8fd9\u7c7b\u95ee\u9898\uff0c\u52a8\u6001\u89c4\u5212\u5f80\u5f80\u96be\u4ee5\u89e3\u51b3\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u590d\u6742\u7684\u7ec4\u5408\u4f18\u5316\u95ee\u9898\uff08\u4f8b\u5982\u65c5\u884c\u5546\u95ee\u9898\uff09\u4e0d\u6ee1\u8db3\u65e0\u540e\u6548\u6027\u3002\u5bf9\u4e8e\u8fd9\u7c7b\u95ee\u9898\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u9009\u62e9\u4f7f\u7528\u5176\u4ed6\u65b9\u6cd5\uff0c\u4f8b\u5982\u542f\u53d1\u5f0f\u641c\u7d22\u3001\u9057\u4f20\u7b97\u6cd5\u3001\u5f3a\u5316\u5b66\u4e60\u7b49\uff0c\u4ece\u800c\u5728\u6709\u9650\u65f6\u95f4\u5185\u5f97\u5230\u53ef\u7528\u7684\u5c40\u90e8\u6700\u4f18\u89e3\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/","title":"14.3 \u00a0 \u52a8\u6001\u89c4\u5212\u89e3\u9898\u601d\u8def","text":"

    \u4e0a\u4e24\u8282\u4ecb\u7ecd\u4e86\u52a8\u6001\u89c4\u5212\u95ee\u9898\u7684\u4e3b\u8981\u7279\u5f81\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u4e00\u8d77\u63a2\u7a76\u4e24\u4e2a\u66f4\u52a0\u5b9e\u7528\u7684\u95ee\u9898\u3002

    1. \u5982\u4f55\u5224\u65ad\u4e00\u4e2a\u95ee\u9898\u662f\u4e0d\u662f\u52a8\u6001\u89c4\u5212\u95ee\u9898\uff1f
    2. \u6c42\u89e3\u52a8\u6001\u89c4\u5212\u95ee\u9898\u8be5\u4ece\u4f55\u5904\u5165\u624b\uff0c\u5b8c\u6574\u6b65\u9aa4\u662f\u4ec0\u4e48\uff1f
    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1431","title":"14.3.1 \u00a0 \u95ee\u9898\u5224\u65ad","text":"

    \u603b\u7684\u6765\u8bf4\uff0c\u5982\u679c\u4e00\u4e2a\u95ee\u9898\u5305\u542b\u91cd\u53e0\u5b50\u95ee\u9898\u3001\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u5e76\u6ee1\u8db3\u65e0\u540e\u6548\u6027\uff0c\u90a3\u4e48\u5b83\u901a\u5e38\u9002\u5408\u7528\u52a8\u6001\u89c4\u5212\u6c42\u89e3\u3002\u7136\u800c\uff0c\u6211\u4eec\u5f88\u96be\u4ece\u95ee\u9898\u63cf\u8ff0\u4e2d\u76f4\u63a5\u63d0\u53d6\u51fa\u8fd9\u4e9b\u7279\u6027\u3002\u56e0\u6b64\u6211\u4eec\u901a\u5e38\u4f1a\u653e\u5bbd\u6761\u4ef6\uff0c\u5148\u89c2\u5bdf\u95ee\u9898\u662f\u5426\u9002\u5408\u4f7f\u7528\u56de\u6eaf\uff08\u7a77\u4e3e\uff09\u89e3\u51b3\u3002

    \u9002\u5408\u7528\u56de\u6eaf\u89e3\u51b3\u7684\u95ee\u9898\u901a\u5e38\u6ee1\u8db3\u201c\u51b3\u7b56\u6811\u6a21\u578b\u201d\uff0c\u8fd9\u79cd\u95ee\u9898\u53ef\u4ee5\u4f7f\u7528\u6811\u5f62\u7ed3\u6784\u6765\u63cf\u8ff0\uff0c\u5176\u4e2d\u6bcf\u4e00\u4e2a\u8282\u70b9\u4ee3\u8868\u4e00\u4e2a\u51b3\u7b56\uff0c\u6bcf\u4e00\u6761\u8def\u5f84\u4ee3\u8868\u4e00\u4e2a\u51b3\u7b56\u5e8f\u5217\u3002

    \u6362\u53e5\u8bdd\u8bf4\uff0c\u5982\u679c\u95ee\u9898\u5305\u542b\u660e\u786e\u7684\u51b3\u7b56\u6982\u5ff5\uff0c\u5e76\u4e14\u89e3\u662f\u901a\u8fc7\u4e00\u7cfb\u5217\u51b3\u7b56\u4ea7\u751f\u7684\uff0c\u90a3\u4e48\u5b83\u5c31\u6ee1\u8db3\u51b3\u7b56\u6811\u6a21\u578b\uff0c\u901a\u5e38\u53ef\u4ee5\u4f7f\u7528\u56de\u6eaf\u6765\u89e3\u51b3\u3002

    \u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u52a8\u6001\u89c4\u5212\u95ee\u9898\u8fd8\u6709\u4e00\u4e9b\u5224\u65ad\u7684\u201c\u52a0\u5206\u9879\u201d\u3002

    • \u95ee\u9898\u5305\u542b\u6700\u5927\uff08\u5c0f\uff09\u6216\u6700\u591a\uff08\u5c11\uff09\u7b49\u6700\u4f18\u5316\u63cf\u8ff0\u3002
    • \u95ee\u9898\u7684\u72b6\u6001\u80fd\u591f\u4f7f\u7528\u4e00\u4e2a\u5217\u8868\u3001\u591a\u7ef4\u77e9\u9635\u6216\u6811\u6765\u8868\u793a\uff0c\u5e76\u4e14\u4e00\u4e2a\u72b6\u6001\u4e0e\u5176\u5468\u56f4\u7684\u72b6\u6001\u5b58\u5728\u9012\u63a8\u5173\u7cfb\u3002

    \u76f8\u5e94\u5730\uff0c\u4e5f\u5b58\u5728\u4e00\u4e9b\u201c\u51cf\u5206\u9879\u201d\u3002

    • \u95ee\u9898\u7684\u76ee\u6807\u662f\u627e\u51fa\u6240\u6709\u53ef\u80fd\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u800c\u4e0d\u662f\u627e\u51fa\u6700\u4f18\u89e3\u3002
    • \u95ee\u9898\u63cf\u8ff0\u4e2d\u6709\u660e\u663e\u7684\u6392\u5217\u7ec4\u5408\u7684\u7279\u5f81\uff0c\u9700\u8981\u8fd4\u56de\u5177\u4f53\u7684\u591a\u4e2a\u65b9\u6848\u3002

    \u5982\u679c\u4e00\u4e2a\u95ee\u9898\u6ee1\u8db3\u51b3\u7b56\u6811\u6a21\u578b\uff0c\u5e76\u5177\u6709\u8f83\u4e3a\u660e\u663e\u7684\u201c\u52a0\u5206\u9879\u201d\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5047\u8bbe\u5b83\u662f\u4e00\u4e2a\u52a8\u6001\u89c4\u5212\u95ee\u9898\uff0c\u5e76\u5728\u6c42\u89e3\u8fc7\u7a0b\u4e2d\u9a8c\u8bc1\u5b83\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1432","title":"14.3.2 \u00a0 \u95ee\u9898\u6c42\u89e3\u6b65\u9aa4","text":"

    \u52a8\u6001\u89c4\u5212\u7684\u89e3\u9898\u6d41\u7a0b\u4f1a\u56e0\u95ee\u9898\u7684\u6027\u8d28\u548c\u96be\u5ea6\u800c\u6709\u6240\u4e0d\u540c\uff0c\u4f46\u901a\u5e38\u9075\u5faa\u4ee5\u4e0b\u6b65\u9aa4\uff1a\u63cf\u8ff0\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u5efa\u7acb \\(dp\\) \u8868\uff0c\u63a8\u5bfc\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff0c\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u7b49\u3002

    \u4e3a\u4e86\u66f4\u5f62\u8c61\u5730\u5c55\u793a\u89e3\u9898\u6b65\u9aa4\uff0c\u6211\u4eec\u4f7f\u7528\u4e00\u4e2a\u7ecf\u5178\u95ee\u9898\u201c\u6700\u5c0f\u8def\u5f84\u548c\u201d\u6765\u4e3e\u4f8b\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a \\(n \\times m\\) \u7684\u4e8c\u7ef4\u7f51\u683c grid \uff0c\u7f51\u683c\u4e2d\u7684\u6bcf\u4e2a\u5355\u5143\u683c\u5305\u542b\u4e00\u4e2a\u975e\u8d1f\u6574\u6570\uff0c\u8868\u793a\u8be5\u5355\u5143\u683c\u7684\u4ee3\u4ef7\u3002\u673a\u5668\u4eba\u4ee5\u5de6\u4e0a\u89d2\u5355\u5143\u683c\u4e3a\u8d77\u59cb\u70b9\uff0c\u6bcf\u6b21\u53ea\u80fd\u5411\u4e0b\u6216\u8005\u5411\u53f3\u79fb\u52a8\u4e00\u6b65\uff0c\u76f4\u81f3\u5230\u8fbe\u53f3\u4e0b\u89d2\u5355\u5143\u683c\u3002\u8bf7\u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230\u53f3\u4e0b\u89d2\u7684\u6700\u5c0f\u8def\u5f84\u548c\u3002

    \u56fe 14-10 \u5c55\u793a\u4e86\u4e00\u4e2a\u4f8b\u5b50\uff0c\u7ed9\u5b9a\u7f51\u683c\u7684\u6700\u5c0f\u8def\u5f84\u548c\u4e3a \\(13\\) \u3002

    \u56fe 14-10 \u00a0 \u6700\u5c0f\u8def\u5f84\u548c\u793a\u4f8b\u6570\u636e

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u672c\u9898\u7684\u6bcf\u4e00\u8f6e\u7684\u51b3\u7b56\u5c31\u662f\u4ece\u5f53\u524d\u683c\u5b50\u5411\u4e0b\u6216\u5411\u53f3\u8d70\u4e00\u6b65\u3002\u8bbe\u5f53\u524d\u683c\u5b50\u7684\u884c\u5217\u7d22\u5f15\u4e3a \\([i, j]\\) \uff0c\u5219\u5411\u4e0b\u6216\u5411\u53f3\u8d70\u4e00\u6b65\u540e\uff0c\u7d22\u5f15\u53d8\u4e3a \\([i+1, j]\\) \u6216 \\([i, j+1]\\) \u3002\u56e0\u6b64\uff0c\u72b6\u6001\u5e94\u5305\u542b\u884c\u7d22\u5f15\u548c\u5217\u7d22\u5f15\u4e24\u4e2a\u53d8\u91cf\uff0c\u8bb0\u4e3a \\([i, j]\\) \u3002

    \u72b6\u6001 \\([i, j]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u4e3a\uff1a\u4ece\u8d77\u59cb\u70b9 \\([0, 0]\\) \u8d70\u5230 \\([i, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\uff0c\u89e3\u8bb0\u4e3a \\(dp[i, j]\\) \u3002

    \u81f3\u6b64\uff0c\u6211\u4eec\u5c31\u5f97\u5230\u4e86\u56fe 14-11 \u6240\u793a\u7684\u4e8c\u7ef4 \\(dp\\) \u77e9\u9635\uff0c\u5176\u5c3a\u5bf8\u4e0e\u8f93\u5165\u7f51\u683c \\(grid\\) \u76f8\u540c\u3002

    \u56fe 14-11 \u00a0 \u72b6\u6001\u5b9a\u4e49\u4e0e dp \u8868

    Note

    \u52a8\u6001\u89c4\u5212\u548c\u56de\u6eaf\u8fc7\u7a0b\u53ef\u4ee5\u63cf\u8ff0\u4e3a\u4e00\u4e2a\u51b3\u7b56\u5e8f\u5217\uff0c\u800c\u72b6\u6001\u7531\u6240\u6709\u51b3\u7b56\u53d8\u91cf\u6784\u6210\u3002\u5b83\u5e94\u5f53\u5305\u542b\u63cf\u8ff0\u89e3\u9898\u8fdb\u5ea6\u7684\u6240\u6709\u53d8\u91cf\uff0c\u5176\u5305\u542b\u4e86\u8db3\u591f\u7684\u4fe1\u606f\uff0c\u80fd\u591f\u7528\u6765\u63a8\u5bfc\u51fa\u4e0b\u4e00\u4e2a\u72b6\u6001\u3002

    \u6bcf\u4e2a\u72b6\u6001\u90fd\u5bf9\u5e94\u4e00\u4e2a\u5b50\u95ee\u9898\uff0c\u6211\u4eec\u4f1a\u5b9a\u4e49\u4e00\u4e2a \\(dp\\) \u8868\u6765\u5b58\u50a8\u6240\u6709\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u72b6\u6001\u7684\u6bcf\u4e2a\u72ec\u7acb\u53d8\u91cf\u90fd\u662f \\(dp\\) \u8868\u7684\u4e00\u4e2a\u7ef4\u5ea6\u3002\u4ece\u672c\u8d28\u4e0a\u770b\uff0c\\(dp\\) \u8868\u662f\u72b6\u6001\u548c\u5b50\u95ee\u9898\u7684\u89e3\u4e4b\u95f4\u7684\u6620\u5c04\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u5bf9\u4e8e\u72b6\u6001 \\([i, j]\\) \uff0c\u5b83\u53ea\u80fd\u4ece\u4e0a\u8fb9\u683c\u5b50 \\([i-1, j]\\) \u548c\u5de6\u8fb9\u683c\u5b50 \\([i, j-1]\\) \u8f6c\u79fb\u800c\u6765\u3002\u56e0\u6b64\u6700\u4f18\u5b50\u7ed3\u6784\u4e3a\uff1a\u5230\u8fbe \\([i, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\u7531 \\([i, j-1]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\u4e0e \\([i-1, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c\u4e2d\u8f83\u5c0f\u7684\u90a3\u4e00\u4e2a\u51b3\u5b9a\u3002

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u53ef\u63a8\u51fa\u56fe 14-12 \u6240\u793a\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff1a

    \\[ dp[i, j] = \\min(dp[i-1, j], dp[i, j-1]) + grid[i, j] \\]

    \u56fe 14-12 \u00a0 \u6700\u4f18\u5b50\u7ed3\u6784\u4e0e\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    Note

    \u6839\u636e\u5b9a\u4e49\u597d\u7684 \\(dp\\) \u8868\uff0c\u601d\u8003\u539f\u95ee\u9898\u548c\u5b50\u95ee\u9898\u7684\u5173\u7cfb\uff0c\u627e\u51fa\u901a\u8fc7\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u6765\u6784\u9020\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u7684\u65b9\u6cd5\uff0c\u5373\u6700\u4f18\u5b50\u7ed3\u6784\u3002

    \u4e00\u65e6\u6211\u4eec\u627e\u5230\u4e86\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528\u5b83\u6765\u6784\u5efa\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5728\u672c\u9898\u4e2d\uff0c\u5904\u5728\u9996\u884c\u7684\u72b6\u6001\u53ea\u80fd\u4ece\u5176\u5de6\u8fb9\u7684\u72b6\u6001\u5f97\u6765\uff0c\u5904\u5728\u9996\u5217\u7684\u72b6\u6001\u53ea\u80fd\u4ece\u5176\u4e0a\u8fb9\u7684\u72b6\u6001\u5f97\u6765\uff0c\u56e0\u6b64\u9996\u884c \\(i = 0\\) \u548c\u9996\u5217 \\(j = 0\\) \u662f\u8fb9\u754c\u6761\u4ef6\u3002

    \u5982\u56fe 14-13 \u6240\u793a\uff0c\u7531\u4e8e\u6bcf\u4e2a\u683c\u5b50\u662f\u7531\u5176\u5de6\u65b9\u683c\u5b50\u548c\u4e0a\u65b9\u683c\u5b50\u8f6c\u79fb\u800c\u6765\uff0c\u56e0\u6b64\u6211\u4eec\u4f7f\u7528\u5faa\u73af\u6765\u904d\u5386\u77e9\u9635\uff0c\u5916\u5faa\u73af\u904d\u5386\u5404\u884c\uff0c\u5185\u5faa\u73af\u904d\u5386\u5404\u5217\u3002

    \u56fe 14-13 \u00a0 \u8fb9\u754c\u6761\u4ef6\u4e0e\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    Note

    \u8fb9\u754c\u6761\u4ef6\u5728\u52a8\u6001\u89c4\u5212\u4e2d\u7528\u4e8e\u521d\u59cb\u5316 \\(dp\\) \u8868\uff0c\u5728\u641c\u7d22\u4e2d\u7528\u4e8e\u526a\u679d\u3002

    \u72b6\u6001\u8f6c\u79fb\u987a\u5e8f\u7684\u6838\u5fc3\u662f\u8981\u4fdd\u8bc1\u5728\u8ba1\u7b97\u5f53\u524d\u95ee\u9898\u7684\u89e3\u65f6\uff0c\u6240\u6709\u5b83\u4f9d\u8d56\u7684\u66f4\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\u90fd\u5df2\u7ecf\u88ab\u6b63\u786e\u5730\u8ba1\u7b97\u51fa\u6765\u3002

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u6211\u4eec\u5df2\u7ecf\u53ef\u4ee5\u76f4\u63a5\u5199\u51fa\u52a8\u6001\u89c4\u5212\u4ee3\u7801\u3002\u7136\u800c\u5b50\u95ee\u9898\u5206\u89e3\u662f\u4e00\u79cd\u4ece\u9876\u81f3\u5e95\u7684\u601d\u60f3\uff0c\u56e0\u6b64\u6309\u7167\u201c\u66b4\u529b\u641c\u7d22 \\(\\rightarrow\\) \u8bb0\u5fc6\u5316\u641c\u7d22 \\(\\rightarrow\\) \u52a8\u6001\u89c4\u5212\u201d\u7684\u987a\u5e8f\u5b9e\u73b0\u66f4\u52a0\u7b26\u5408\u601d\u7ef4\u4e60\u60ef\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#1","title":"1. \u00a0 \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u641c\u7d22","text":"

    \u4ece\u72b6\u6001 \\([i, j]\\) \u5f00\u59cb\u641c\u7d22\uff0c\u4e0d\u65ad\u5206\u89e3\u4e3a\u66f4\u5c0f\u7684\u72b6\u6001 \\([i-1, j]\\) \u548c \\([i, j-1]\\) \uff0c\u9012\u5f52\u51fd\u6570\u5305\u62ec\u4ee5\u4e0b\u8981\u7d20\u3002

    • \u9012\u5f52\u53c2\u6570\uff1a\u72b6\u6001 \\([i, j]\\) \u3002
    • \u8fd4\u56de\u503c\uff1a\u4ece \\([0, 0]\\) \u5230 \\([i, j]\\) \u7684\u6700\u5c0f\u8def\u5f84\u548c \\(dp[i, j]\\) \u3002
    • \u7ec8\u6b62\u6761\u4ef6\uff1a\u5f53 \\(i = 0\\) \u4e14 \\(j = 0\\) \u65f6\uff0c\u8fd4\u56de\u4ee3\u4ef7 \\(grid[0, 0]\\) \u3002
    • \u526a\u679d\uff1a\u5f53 \\(i < 0\\) \u65f6\u6216 \\(j < 0\\) \u65f6\u7d22\u5f15\u8d8a\u754c\uff0c\u6b64\u65f6\u8fd4\u56de\u4ee3\u4ef7 \\(+\\infty\\) \uff0c\u4ee3\u8868\u4e0d\u53ef\u884c\u3002

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dfs(grid: list[list[int]], i: int, j: int) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22\"\"\"\n    # \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 and j == 0:\n        return grid[0][0]\n    # \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 or j < 0:\n        return inf\n    # \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up = min_path_sum_dfs(grid, i - 1, j)\n    left = min_path_sum_dfs(grid, i, j - 1)\n    # \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(vector<vector<int>> &grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(int[][] grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Integer.MAX_VALUE;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint MinPathSumDFS(int[][] grid, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return int.MaxValue;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = MinPathSumDFS(grid, i - 1, j);\n    int left = MinPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.Min(left, up) + grid[i][j];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc minPathSumDFS(grid [][]int, i, j int) int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return math.MaxInt\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up := minPathSumDFS(grid, i-1, j)\n    left := minPathSumDFS(grid, i, j-1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return int(math.Min(float64(left), float64(up))) + grid[i][j]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc minPathSumDFS(grid: [[Int]], i: Int, j: Int) -> Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0, j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return .max\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = minPathSumDFS(grid: grid, i: i - 1, j: j)\n    let left = minPathSumDFS(grid: grid, i: i, j: j - 1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction minPathSumDFS(grid, i, j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFS(grid, i - 1, j);\n    const left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction minPathSumDFS(\n    grid: Array<Array<number>>,\n    i: number,\n    j: number\n): number {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFS(grid, i - 1, j);\n    const left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return Math.min(left, up) + grid[i][j];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(List<List<int>> grid, int i, int j) {\n  // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n  if (i == 0 && j == 0) {\n    return grid[0][0];\n  }\n  // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n  if (i < 0 || j < 0) {\n    // \u5728 Dart \u4e2d\uff0cint \u7c7b\u578b\u662f\u56fa\u5b9a\u8303\u56f4\u7684\u6574\u6570\uff0c\u4e0d\u5b58\u5728\u8868\u793a\u201c\u65e0\u7a77\u5927\u201d\u7684\u503c\n    return BigInt.from(2).pow(31).toInt();\n  }\n  // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  int up = minPathSumDFS(grid, i - 1, j);\n  int left = minPathSumDFS(grid, i, j - 1);\n  // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  return min(left, up) + grid[i][j];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfn min_path_sum_dfs(grid: &Vec<Vec<i32>>, i: i32, j: i32) -> i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return i32::MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = min_path_sum_dfs(grid, i - 1, j);\n    let left = min_path_sum_dfs(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    std::cmp::min(left, up) + grid[i as usize][j as usize]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nint minPathSumDFS(int grid[MAX_SIZE][MAX_SIZE], int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFS(grid, i - 1, j);\n    int left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22 */\nfun minPathSumDFS(grid: Array<IntArray>, i: Int, j: Int): Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Int.MAX_VALUE\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    val up = minPathSumDFS(grid, i - 1, j)\n    val left = minPathSumDFS(grid, i, j - 1)\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return min(left, up) + grid[i][j]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u66b4\u529b\u641c\u7d22\nfn minPathSumDFS(grid: anytype, i: i32, j: i32) i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 and j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 or j < 0) {\n        return std.math.maxInt(i32);\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    var up = minPathSumDFS(grid, i - 1, j);\n    var left = minPathSumDFS(grid, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    return @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-14 \u7ed9\u51fa\u4e86\u4ee5 \\(dp[2, 1]\\) \u4e3a\u6839\u8282\u70b9\u7684\u9012\u5f52\u6811\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e9b\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u5176\u6570\u91cf\u4f1a\u968f\u7740\u7f51\u683c grid \u7684\u5c3a\u5bf8\u53d8\u5927\u800c\u6025\u5267\u589e\u591a\u3002

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u9020\u6210\u91cd\u53e0\u5b50\u95ee\u9898\u7684\u539f\u56e0\u4e3a\uff1a\u5b58\u5728\u591a\u6761\u8def\u5f84\u53ef\u4ee5\u4ece\u5de6\u4e0a\u89d2\u5230\u8fbe\u67d0\u4e00\u5355\u5143\u683c\u3002

    \u56fe 14-14 \u00a0 \u66b4\u529b\u641c\u7d22\u9012\u5f52\u6811

    \u6bcf\u4e2a\u72b6\u6001\u90fd\u6709\u5411\u4e0b\u548c\u5411\u53f3\u4e24\u79cd\u9009\u62e9\uff0c\u4ece\u5de6\u4e0a\u89d2\u8d70\u5230\u53f3\u4e0b\u89d2\u603b\u5171\u9700\u8981 \\(m + n - 2\\) \u6b65\uff0c\u6240\u4ee5\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^{m + n})\\) \u3002\u8bf7\u6ce8\u610f\uff0c\u8fd9\u79cd\u8ba1\u7b97\u65b9\u5f0f\u672a\u8003\u8651\u4e34\u8fd1\u7f51\u683c\u8fb9\u754c\u7684\u60c5\u51b5\uff0c\u5f53\u5230\u8fbe\u7f51\u7edc\u8fb9\u754c\u65f6\u53ea\u5269\u4e0b\u4e00\u79cd\u9009\u62e9\uff0c\u56e0\u6b64\u5b9e\u9645\u7684\u8def\u5f84\u6570\u91cf\u4f1a\u5c11\u4e00\u4e9b\u3002

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#2","title":"2. \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22","text":"

    \u6211\u4eec\u5f15\u5165\u4e00\u4e2a\u548c\u7f51\u683c grid \u76f8\u540c\u5c3a\u5bf8\u7684\u8bb0\u5fc6\u5217\u8868 mem \uff0c\u7528\u4e8e\u8bb0\u5f55\u5404\u4e2a\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5e76\u5c06\u91cd\u53e0\u5b50\u95ee\u9898\u8fdb\u884c\u526a\u679d\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dfs_mem(\n    grid: list[list[int]], mem: list[list[int]], i: int, j: int\n) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 and j == 0:\n        return grid[0][0]\n    # \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 or j < 0:\n        return inf\n    # \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1:\n        return mem[i][j]\n    # \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up = min_path_sum_dfs_mem(grid, mem, i - 1, j)\n    left = min_path_sum_dfs_mem(grid, mem, i, j - 1)\n    # \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(vector<vector<int>> &grid, vector<vector<int>> &mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX;\n    return mem[i][j];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Integer.MAX_VALUE;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint MinPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return int.MaxValue;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = MinPathSumDFSMem(grid, mem, i - 1, j);\n    int left = MinPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.Min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc minPathSumDFSMem(grid, mem [][]int, i, j int) int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return math.MaxInt\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1 {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    up := minPathSumDFSMem(grid, mem, i-1, j)\n    left := minPathSumDFSMem(grid, mem, i, j-1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = int(math.Min(float64(left), float64(up))) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc minPathSumDFSMem(grid: [[Int]], mem: inout [[Int]], i: Int, j: Int) -> Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0, j == 0 {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return .max\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][j] != -1 {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = minPathSumDFSMem(grid: grid, mem: &mem, i: i - 1, j: j)\n    let left = minPathSumDFSMem(grid: grid, mem: &mem, i: i, j: j - 1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction minPathSumDFSMem(grid, mem, i, j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] !== -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFSMem(grid, mem, i - 1, j);\n    const left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction minPathSumDFSMem(\n    grid: Array<Array<number>>,\n    mem: Array<Array<number>>,\n    i: number,\n    j: number\n): number {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i === 0 && j === 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Infinity;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    const up = minPathSumDFSMem(grid, mem, i - 1, j);\n    const left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = Math.min(left, up) + grid[i][j];\n    return mem[i][j];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(List<List<int>> grid, List<List<int>> mem, int i, int j) {\n  // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n  if (i == 0 && j == 0) {\n    return grid[0][0];\n  }\n  // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n  if (i < 0 || j < 0) {\n    // \u5728 Dart \u4e2d\uff0cint \u7c7b\u578b\u662f\u56fa\u5b9a\u8303\u56f4\u7684\u6574\u6570\uff0c\u4e0d\u5b58\u5728\u8868\u793a\u201c\u65e0\u7a77\u5927\u201d\u7684\u503c\n    return BigInt.from(2).pow(31).toInt();\n  }\n  // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  if (mem[i][j] != -1) {\n    return mem[i][j];\n  }\n  // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  int up = minPathSumDFSMem(grid, mem, i - 1, j);\n  int left = minPathSumDFSMem(grid, mem, i, j - 1);\n  // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n  mem[i][j] = min(left, up) + grid[i][j];\n  return mem[i][j];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn min_path_sum_dfs_mem(grid: &Vec<Vec<i32>>, mem: &mut Vec<Vec<i32>>, i: i32, j: i32) -> i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if i == 0 && j == 0 {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if i < 0 || j < 0 {\n        return i32::MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i as usize][j as usize] != -1 {\n        return mem[i as usize][j as usize];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    let up = min_path_sum_dfs_mem(grid, mem, i - 1, j);\n    let left = min_path_sum_dfs_mem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i as usize][j as usize] = std::cmp::min(left, up) + grid[i as usize][j as usize];\n    mem[i as usize][j as usize]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint minPathSumDFSMem(int grid[MAX_SIZE][MAX_SIZE], int mem[MAX_SIZE][MAX_SIZE], int i, int j) {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return INT_MAX;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j];\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    int up = minPathSumDFSMem(grid, mem, i - 1, j);\n    int left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = myMin(left, up) != INT_MAX ? myMin(left, up) + grid[i][j] : INT_MAX;\n    return mem[i][j];\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun minPathSumDFSMem(\n    grid: Array<IntArray>,\n    mem: Array<IntArray>,\n    i: Int,\n    j: Int\n): Int {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 && j == 0) {\n        return grid[0][0]\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 || j < 0) {\n        return Int.MAX_VALUE\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][j] != -1) {\n        return mem[i][j]\n    }\n    // \u5de6\u8fb9\u548c\u4e0a\u8fb9\u5355\u5143\u683c\u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    val up = minPathSumDFSMem(grid, mem, i - 1, j)\n    val left = minPathSumDFSMem(grid, mem, i, j - 1)\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[i][j] = min(left, up) + grid[i][j]\n    return mem[i][j]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dfs_mem}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn minPathSumDFSMem(grid: anytype, mem: anytype, i: i32, j: i32) i32 {\n    // \u82e5\u4e3a\u5de6\u4e0a\u89d2\u5355\u5143\u683c\uff0c\u5219\u7ec8\u6b62\u641c\u7d22\n    if (i == 0 and j == 0) {\n        return grid[0][0];\n    }\n    // \u82e5\u884c\u5217\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de +\u221e \u4ee3\u4ef7\n    if (i < 0 or j < 0) {\n        return std.math.maxInt(i32);\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] != -1) {\n        return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n    }\n    // \u8ba1\u7b97\u4ece\u5de6\u4e0a\u89d2\u5230 (i-1, j) \u548c (i, j-1) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    var up = minPathSumDFSMem(grid, mem, i - 1, j);\n    var left = minPathSumDFSMem(grid, mem, i, j - 1);\n    // \u8fd4\u56de\u4ece\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u5de6\u4e0a\u89d2\u5230 (i, j) \u7684\u6700\u5c0f\u8def\u5f84\u4ee3\u4ef7\n    mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] = @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n    return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-15 \u6240\u793a\uff0c\u5728\u5f15\u5165\u8bb0\u5fc6\u5316\u540e\uff0c\u6240\u6709\u5b50\u95ee\u9898\u7684\u89e3\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u72b6\u6001\u603b\u6570\uff0c\u5373\u7f51\u683c\u5c3a\u5bf8 \\(O(nm)\\) \u3002

    \u56fe 14-15 \u00a0 \u8bb0\u5fc6\u5316\u641c\u7d22\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#3","title":"3. \u00a0 \u65b9\u6cd5\u4e09\uff1a\u52a8\u6001\u89c4\u5212","text":"

    \u57fa\u4e8e\u8fed\u4ee3\u5b9e\u73b0\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dp(grid: list[list[int]]) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(grid), len(grid[0])\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * m for _ in range(n)]\n    dp[0][0] = grid[0][0]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in range(1, m):\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in range(1, n):\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n):\n        for j in range(1, m):\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n    return dp[n - 1][m - 1]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(vector<vector<int>> &grid) {\n    int n = grid.size(), m = grid[0].size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n, vector<int>(m));\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(int[][] grid) {\n    int n = grid.length, m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n][m];\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint MinPathSumDP(int[][] grid) {\n    int n = grid.Length, m = grid[0].Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n, m];\n    dp[0, 0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0, j] = dp[0, j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i, 0] = dp[i - 1, 0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i, j] = Math.Min(dp[i, j - 1], dp[i - 1, j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1, m - 1];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDP(grid [][]int) int {\n    n, m := len(grid), len(grid[0])\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n)\n    for i := 0; i < n; i++ {\n        dp[i] = make([]int, m)\n    }\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j := 1; j < m; j++ {\n        dp[0][j] = dp[0][j-1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i := 1; i < n; i++ {\n        dp[i][0] = dp[i-1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i < n; i++ {\n        for j := 1; j < m; j++ {\n            dp[i][j] = int(math.Min(float64(dp[i][j-1]), float64(dp[i-1][j]))) + grid[i][j]\n        }\n    }\n    return dp[n-1][m-1]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDP(grid: [[Int]]) -> Int {\n    let n = grid.count\n    let m = grid[0].count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: m), count: n)\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1 ..< m {\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in 1 ..< n {\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ..< n {\n        for j in 1 ..< m {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n        }\n    }\n    return dp[n - 1][m - 1]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDP(grid) {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n }, () =>\n        Array.from({ length: m }, () => 0)\n    );\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (let i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i < n; i++) {\n        for (let j = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDP(grid: Array<Array<number>>): number {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n }, () =>\n        Array.from({ length: m }, () => 0)\n    );\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (let i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i < n; i++) {\n        for (let j: number = 1; j < m; j++) {\n            dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(List<List<int>> grid) {\n  int n = grid.length, m = grid[0].length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n, (i) => List.filled(m, 0));\n  dp[0][0] = grid[0][0];\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n  for (int j = 1; j < m; j++) {\n    dp[0][j] = dp[0][j - 1] + grid[0][j];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n  for (int i = 1; i < n; i++) {\n    dp[i][0] = dp[i - 1][0] + grid[i][0];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i < n; i++) {\n    for (int j = 1; j < m; j++) {\n      dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n    }\n  }\n  return dp[n - 1][m - 1];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfn min_path_sum_dp(grid: &Vec<Vec<i32>>) -> i32 {\n    let (n, m) = (grid.len(), grid[0].len());\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; m]; n];\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1..m {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for i in 1..n {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..n {\n        for j in 1..m {\n            dp[i][j] = std::cmp::min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    dp[n - 1][m - 1]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nint minPathSumDP(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc(n * sizeof(int *));\n    for (int i = 0; i < n; i++) {\n        dp[i] = calloc(m, sizeof(int));\n    }\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (int i = 1; i < n; i++) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i < n; i++) {\n        for (int j = 1; j < m; j++) {\n            dp[i][j] = myMin(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    int res = dp[n - 1][m - 1];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i < n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212 */\nfun minPathSumDP(grid: Array<IntArray>): Int {\n    val n = grid.size\n    val m = grid[0].size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n) { IntArray(m) }\n    dp[0][0] = grid[0][0]\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (j in 1..<m) {\n        dp[0][j] = dp[0][j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (i in 1..<n) {\n        dp[i][0] = dp[i - 1][0] + grid[i][0]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..<n) {\n        for (j in 1..<m) {\n            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]\n        }\n    }\n    return dp[n - 1][m - 1]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u52a8\u6001\u89c4\u5212\nfn minPathSumDP(comptime grid: anytype) i32 {\n    comptime var n = grid.len;\n    comptime var m = grid[0].len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][m]i32{[_]i32{0} ** m} ** n;\n    dp[0][0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (1..m) |j| {\n        dp[0][j] = dp[0][j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    for (1..n) |i| {\n        dp[i][0] = dp[i - 1][0] + grid[i][0];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n) |i| {\n        for (1..m) |j| {\n            dp[i][j] = @min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];\n        }\n    }\n    return dp[n - 1][m - 1];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-16 \u5c55\u793a\u4e86\u6700\u5c0f\u8def\u5f84\u548c\u7684\u72b6\u6001\u8f6c\u79fb\u8fc7\u7a0b\uff0c\u5176\u904d\u5386\u4e86\u6574\u4e2a\u7f51\u683c\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nm)\\) \u3002

    \u6570\u7ec4 dp \u5927\u5c0f\u4e3a \\(n \\times m\\) \uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nm)\\) \u3002

    <1><2><3><4><5><6><7><8><9><10><11><12>

    \u56fe 14-16 \u00a0 \u6700\u5c0f\u8def\u5f84\u548c\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/dp_solution_pipeline/#4","title":"4. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e\u6bcf\u4e2a\u683c\u5b50\u53ea\u4e0e\u5176\u5de6\u8fb9\u548c\u4e0a\u8fb9\u7684\u683c\u5b50\u6709\u5173\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u53ea\u7528\u4e00\u4e2a\u5355\u884c\u6570\u7ec4\u6765\u5b9e\u73b0 \\(dp\\) \u8868\u3002

    \u8bf7\u6ce8\u610f\uff0c\u56e0\u4e3a\u6570\u7ec4 dp \u53ea\u80fd\u8868\u793a\u4e00\u884c\u7684\u72b6\u6001\uff0c\u6240\u4ee5\u6211\u4eec\u65e0\u6cd5\u63d0\u524d\u521d\u59cb\u5316\u9996\u5217\u72b6\u6001\uff0c\u800c\u662f\u5728\u904d\u5386\u6bcf\u884c\u65f6\u66f4\u65b0\u5b83\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig min_path_sum.py
    def min_path_sum_dp_comp(grid: list[list[int]]) -> int:\n    \"\"\"\u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(grid), len(grid[0])\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * m\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j in range(1, m):\n        dp[j] = dp[j - 1] + grid[0][j]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in range(1, n):\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in range(1, m):\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n    return dp[m - 1]\n
    min_path_sum.cpp
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(vector<vector<int>> &grid) {\n    int n = grid.size(), m = grid[0].size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.java
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(int[][] grid) {\n    int n = grid.length, m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[m];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.cs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint MinPathSumDPComp(int[][] grid) {\n    int n = grid.Length, m = grid[0].Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[m];\n    dp[0] = grid[0][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = Math.Min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.go
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDPComp(grid [][]int) int {\n    n, m := len(grid), len(grid[0])\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j := 1; j < m; j++ {\n        dp[j] = dp[j-1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i < n; i++ {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j := 1; j < m; j++ {\n            dp[j] = int(math.Min(float64(dp[j-1]), float64(dp[j]))) + grid[i][j]\n        }\n    }\n    return dp[m-1]\n}\n
    min_path_sum.swift
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc minPathSumDPComp(grid: [[Int]]) -> Int {\n    let n = grid.count\n    let m = grid[0].count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for j in 1 ..< m {\n        dp[j] = dp[j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1 ..< n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1 ..< m {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n        }\n    }\n    return dp[m - 1]\n}\n
    min_path_sum.js
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDPComp(grid) {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = new Array(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (let j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.ts
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction minPathSumDPComp(grid: Array<Array<number>>): number {\n    const n = grid.length,\n        m = grid[0].length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = new Array(m);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (let j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j < m; j++) {\n            dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    min_path_sum.dart
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(List<List<int>> grid) {\n  int n = grid.length, m = grid[0].length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(m, 0);\n  dp[0] = grid[0][0];\n  for (int j = 1; j < m; j++) {\n    dp[j] = dp[j - 1] + grid[0][j];\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n  for (int i = 1; i < n; i++) {\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    dp[0] = dp[0] + grid[i][0];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n    for (int j = 1; j < m; j++) {\n      dp[j] = min(dp[j - 1], dp[j]) + grid[i][j];\n    }\n  }\n  return dp[m - 1];\n}\n
    min_path_sum.rs
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn min_path_sum_dp_comp(grid: &Vec<Vec<i32>>) -> i32 {\n    let (n, m) = (grid.len(), grid[0].len());\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; m];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for j in 1..m {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1..n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1..m {\n            dp[j] = std::cmp::min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    dp[m - 1]\n}\n
    min_path_sum.c
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint minPathSumDPComp(int grid[MAX_SIZE][MAX_SIZE], int n, int m) {\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(m, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (int j = 1; j < m; j++) {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i < n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j < m; j++) {\n            dp[j] = myMin(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    int res = dp[m - 1];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    min_path_sum.kt
    /* \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun minPathSumDPComp(grid: Array<IntArray>): Int {\n    val n = grid.size\n    val m = grid[0].size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(m)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0]\n    for (j in 1..<m) {\n        dp[j] = dp[j - 1] + grid[0][j]\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (i in 1..<n) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0]\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (j in 1..<m) {\n            dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]\n        }\n    }\n    return dp[m - 1]\n}\n
    min_path_sum.rb
    [class]{}-[func]{min_path_sum_dp_comp}\n
    min_path_sum.zig
    // \u6700\u5c0f\u8def\u5f84\u548c\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn minPathSumDPComp(comptime grid: anytype) i32 {\n    comptime var n = grid.len;\n    comptime var m = grid[0].len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** m;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    dp[0] = grid[0][0];\n    for (1..m) |j| {\n        dp[j] = dp[j - 1] + grid[0][j];\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (1..n) |i| {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        dp[0] = dp[0] + grid[i][0];\n        for (1..m) |j| {\n            dp[j] = @min(dp[j - 1], dp[j]) + grid[i][j];\n        }\n    }\n    return dp[m - 1];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/","title":"14.6 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898","text":"

    \u7f16\u8f91\u8ddd\u79bb\uff0c\u4e5f\u79f0 Levenshtein \u8ddd\u79bb\uff0c\u6307\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e4b\u95f4\u4e92\u76f8\u8f6c\u6362\u7684\u6700\u5c11\u4fee\u6539\u6b21\u6570\uff0c\u901a\u5e38\u7528\u4e8e\u5728\u4fe1\u606f\u68c0\u7d22\u548c\u81ea\u7136\u8bed\u8a00\u5904\u7406\u4e2d\u5ea6\u91cf\u4e24\u4e2a\u5e8f\u5217\u7684\u76f8\u4f3c\u5ea6\u3002

    Question

    \u8f93\u5165\u4e24\u4e2a\u5b57\u7b26\u4e32 \\(s\\) \u548c \\(t\\) \uff0c\u8fd4\u56de\u5c06 \\(s\\) \u8f6c\u6362\u4e3a \\(t\\) \u6240\u9700\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u3002

    \u4f60\u53ef\u4ee5\u5728\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u8fdb\u884c\u4e09\u79cd\u7f16\u8f91\u64cd\u4f5c\uff1a\u63d2\u5165\u4e00\u4e2a\u5b57\u7b26\u3001\u5220\u9664\u4e00\u4e2a\u5b57\u7b26\u3001\u5c06\u5b57\u7b26\u66ff\u6362\u4e3a\u4efb\u610f\u4e00\u4e2a\u5b57\u7b26\u3002

    \u5982\u56fe 14-27 \u6240\u793a\uff0c\u5c06 kitten \u8f6c\u6362\u4e3a sitting \u9700\u8981\u7f16\u8f91 3 \u6b65\uff0c\u5305\u62ec 2 \u6b21\u66ff\u6362\u64cd\u4f5c\u4e0e 1 \u6b21\u6dfb\u52a0\u64cd\u4f5c\uff1b\u5c06 hello \u8f6c\u6362\u4e3a algo \u9700\u8981 3 \u6b65\uff0c\u5305\u62ec 2 \u6b21\u66ff\u6362\u64cd\u4f5c\u548c 1 \u6b21\u5220\u9664\u64cd\u4f5c\u3002

    \u56fe 14-27 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u7684\u793a\u4f8b\u6570\u636e

    \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898\u53ef\u4ee5\u5f88\u81ea\u7136\u5730\u7528\u51b3\u7b56\u6811\u6a21\u578b\u6765\u89e3\u91ca\u3002\u5b57\u7b26\u4e32\u5bf9\u5e94\u6811\u8282\u70b9\uff0c\u4e00\u8f6e\u51b3\u7b56\uff08\u4e00\u6b21\u7f16\u8f91\u64cd\u4f5c\uff09\u5bf9\u5e94\u6811\u7684\u4e00\u6761\u8fb9\u3002

    \u5982\u56fe 14-28 \u6240\u793a\uff0c\u5728\u4e0d\u9650\u5236\u64cd\u4f5c\u7684\u60c5\u51b5\u4e0b\uff0c\u6bcf\u4e2a\u8282\u70b9\u90fd\u53ef\u4ee5\u6d3e\u751f\u51fa\u8bb8\u591a\u6761\u8fb9\uff0c\u6bcf\u6761\u8fb9\u5bf9\u5e94\u4e00\u79cd\u64cd\u4f5c\uff0c\u8fd9\u610f\u5473\u7740\u4ece hello \u8f6c\u6362\u5230 algo \u6709\u8bb8\u591a\u79cd\u53ef\u80fd\u7684\u8def\u5f84\u3002

    \u4ece\u51b3\u7b56\u6811\u7684\u89d2\u5ea6\u770b\uff0c\u672c\u9898\u7684\u76ee\u6807\u662f\u6c42\u89e3\u8282\u70b9 hello \u548c\u8282\u70b9 algo \u4e4b\u95f4\u7684\u6700\u77ed\u8def\u5f84\u3002

    \u56fe 14-28 \u00a0 \u57fa\u4e8e\u51b3\u7b56\u6811\u6a21\u578b\u8868\u793a\u7f16\u8f91\u8ddd\u79bb\u95ee\u9898

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#1","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u6bcf\u4e00\u8f6e\u7684\u51b3\u7b56\u662f\u5bf9\u5b57\u7b26\u4e32 \\(s\\) \u8fdb\u884c\u4e00\u6b21\u7f16\u8f91\u64cd\u4f5c\u3002

    \u6211\u4eec\u5e0c\u671b\u5728\u7f16\u8f91\u64cd\u4f5c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u95ee\u9898\u7684\u89c4\u6a21\u9010\u6e10\u7f29\u5c0f\uff0c\u8fd9\u6837\u624d\u80fd\u6784\u5efa\u5b50\u95ee\u9898\u3002\u8bbe\u5b57\u7b26\u4e32 \\(s\\) \u548c \\(t\\) \u7684\u957f\u5ea6\u5206\u522b\u4e3a \\(n\\) \u548c \\(m\\) \uff0c\u6211\u4eec\u5148\u8003\u8651\u4e24\u5b57\u7b26\u4e32\u5c3e\u90e8\u7684\u5b57\u7b26 \\(s[n-1]\\) \u548c \\(t[m-1]\\) \u3002

    • \u82e5 \\(s[n-1]\\) \u548c \\(t[m-1]\\) \u76f8\u540c\uff0c\u6211\u4eec\u53ef\u4ee5\u8df3\u8fc7\u5b83\u4eec\uff0c\u76f4\u63a5\u8003\u8651 \\(s[n-2]\\) \u548c \\(t[m-2]\\) \u3002
    • \u82e5 \\(s[n-1]\\) \u548c \\(t[m-1]\\) \u4e0d\u540c\uff0c\u6211\u4eec\u9700\u8981\u5bf9 \\(s\\) \u8fdb\u884c\u4e00\u6b21\u7f16\u8f91\uff08\u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\uff09\uff0c\u4f7f\u5f97\u4e24\u5b57\u7b26\u4e32\u5c3e\u90e8\u7684\u5b57\u7b26\u76f8\u540c\uff0c\u4ece\u800c\u53ef\u4ee5\u8df3\u8fc7\u5b83\u4eec\uff0c\u8003\u8651\u89c4\u6a21\u66f4\u5c0f\u7684\u95ee\u9898\u3002

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u6211\u4eec\u5728\u5b57\u7b26\u4e32 \\(s\\) \u4e2d\u8fdb\u884c\u7684\u6bcf\u4e00\u8f6e\u51b3\u7b56\uff08\u7f16\u8f91\u64cd\u4f5c\uff09\uff0c\u90fd\u4f1a\u4f7f\u5f97 \\(s\\) \u548c \\(t\\) \u4e2d\u5269\u4f59\u7684\u5f85\u5339\u914d\u5b57\u7b26\u53d1\u751f\u53d8\u5316\u3002\u56e0\u6b64\uff0c\u72b6\u6001\u4e3a\u5f53\u524d\u5728 \\(s\\) \u548c \\(t\\) \u4e2d\u8003\u8651\u7684\u7b2c \\(i\\) \u548c\u7b2c \\(j\\) \u4e2a\u5b57\u7b26\uff0c\u8bb0\u4e3a \\([i, j]\\) \u3002

    \u72b6\u6001 \\([i, j]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\uff1a\u5c06 \\(s\\) \u7684\u524d \\(i\\) \u4e2a\u5b57\u7b26\u66f4\u6539\u4e3a \\(t\\) \u7684\u524d \\(j\\) \u4e2a\u5b57\u7b26\u6240\u9700\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u3002

    \u81f3\u6b64\uff0c\u5f97\u5230\u4e00\u4e2a\u5c3a\u5bf8\u4e3a \\((i+1) \\times (j+1)\\) \u7684\u4e8c\u7ef4 \\(dp\\) \u8868\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u8003\u8651\u5b50\u95ee\u9898 \\(dp[i, j]\\) \uff0c\u5176\u5bf9\u5e94\u7684\u4e24\u4e2a\u5b57\u7b26\u4e32\u7684\u5c3e\u90e8\u5b57\u7b26\u4e3a \\(s[i-1]\\) \u548c \\(t[j-1]\\) \uff0c\u53ef\u6839\u636e\u4e0d\u540c\u7f16\u8f91\u64cd\u4f5c\u5206\u4e3a\u56fe 14-29 \u6240\u793a\u7684\u4e09\u79cd\u60c5\u51b5\u3002

    1. \u5728 \\(s[i-1]\\) \u4e4b\u540e\u6dfb\u52a0 \\(t[j-1]\\) \uff0c\u5219\u5269\u4f59\u5b50\u95ee\u9898 \\(dp[i, j-1]\\) \u3002
    2. \u5220\u9664 \\(s[i-1]\\) \uff0c\u5219\u5269\u4f59\u5b50\u95ee\u9898 \\(dp[i-1, j]\\) \u3002
    3. \u5c06 \\(s[i-1]\\) \u66ff\u6362\u4e3a \\(t[j-1]\\) \uff0c\u5219\u5269\u4f59\u5b50\u95ee\u9898 \\(dp[i-1, j-1]\\) \u3002

    \u56fe 14-29 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u7684\u72b6\u6001\u8f6c\u79fb

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u53ef\u5f97\u6700\u4f18\u5b50\u7ed3\u6784\uff1a\\(dp[i, j]\\) \u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u7b49\u4e8e \\(dp[i, j-1]\\)\u3001\\(dp[i-1, j]\\)\u3001\\(dp[i-1, j-1]\\) \u4e09\u8005\u4e2d\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\uff0c\u518d\u52a0\u4e0a\u672c\u6b21\u7684\u7f16\u8f91\u6b65\u6570 \\(1\\) \u3002\u5bf9\u5e94\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ dp[i, j] = \\min(dp[i, j-1], dp[i-1, j], dp[i-1, j-1]) + 1 \\]

    \u8bf7\u6ce8\u610f\uff0c\u5f53 \\(s[i-1]\\) \u548c \\(t[j-1]\\) \u76f8\u540c\u65f6\uff0c\u65e0\u987b\u7f16\u8f91\u5f53\u524d\u5b57\u7b26\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ dp[i, j] = dp[i-1, j-1] \\]

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5f53\u4e24\u5b57\u7b26\u4e32\u90fd\u4e3a\u7a7a\u65f6\uff0c\u7f16\u8f91\u6b65\u6570\u4e3a \\(0\\) \uff0c\u5373 \\(dp[0, 0] = 0\\) \u3002\u5f53 \\(s\\) \u4e3a\u7a7a\u4f46 \\(t\\) \u4e0d\u4e3a\u7a7a\u65f6\uff0c\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u7b49\u4e8e \\(t\\) \u7684\u957f\u5ea6\uff0c\u5373\u9996\u884c \\(dp[0, j] = j\\) \u3002\u5f53 \\(s\\) \u4e0d\u4e3a\u7a7a\u4f46 \\(t\\) \u4e3a\u7a7a\u65f6\uff0c\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u7b49\u4e8e \\(s\\) \u7684\u957f\u5ea6\uff0c\u5373\u9996\u5217 \\(dp[i, 0] = i\\) \u3002

    \u89c2\u5bdf\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff0c\u89e3 \\(dp[i, j]\\) \u4f9d\u8d56\u5de6\u65b9\u3001\u4e0a\u65b9\u3001\u5de6\u4e0a\u65b9\u7684\u89e3\uff0c\u56e0\u6b64\u901a\u8fc7\u4e24\u5c42\u5faa\u73af\u6b63\u5e8f\u904d\u5386\u6574\u4e2a \\(dp\\) \u8868\u5373\u53ef\u3002

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig edit_distance.py
    def edit_distance_dp(s: str, t: str) -> int:\n    \"\"\"\u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(s), len(t)\n    dp = [[0] * (m + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in range(1, n + 1):\n        dp[i][0] = i\n    for j in range(1, m + 1):\n        dp[0][j] = j\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n + 1):\n        for j in range(1, m + 1):\n            if s[i - 1] == t[j - 1]:\n                # \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            else:\n                # \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1\n    return dp[n][m]\n
    edit_distance.cpp
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(string s, string t) {\n    int n = s.length(), m = t.length();\n    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.java
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(String s, String t) {\n    int n = s.length(), m = t.length();\n    int[][] dp = new int[n + 1][m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) == t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.cs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint EditDistanceDP(string s, string t) {\n    int n = s.Length, m = t.Length;\n    int[,] dp = new int[n + 1, m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i, 0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0, j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i, j] = dp[i - 1, j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i, j] = Math.Min(Math.Min(dp[i, j - 1], dp[i - 1, j]), dp[i - 1, j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n, m];\n}\n
    edit_distance.go
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDP(s string, t string) int {\n    n := len(s)\n    m := len(t)\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, m+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i := 1; i <= n; i++ {\n        dp[i][0] = i\n    }\n    for j := 1; j <= m; j++ {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for j := 1; j <= m; j++ {\n            if s[i-1] == t[j-1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i-1][j-1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = MinInt(MinInt(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.swift
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDP(s: String, t: String) -> Int {\n    let n = s.utf8CString.count\n    let m = t.utf8CString.count\n    var dp = Array(repeating: Array(repeating: 0, count: m + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in 1 ... n {\n        dp[i][0] = i\n    }\n    for j in 1 ... m {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ... n {\n        for j in 1 ... m {\n            if s.utf8CString[i - 1] == t.utf8CString[j - 1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.js
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDP(s, t) {\n    const n = s.length,\n        m = t.length;\n    const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (let j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.ts
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDP(s: string, t: string): number {\n    const n = s.length,\n        m = t.length;\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: m + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (let j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let j = 1; j <= m; j++) {\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    edit_distance.dart
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(String s, String t) {\n  int n = s.length, m = t.length;\n  List<List<int>> dp = List.generate(n + 1, (_) => List.filled(m + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n  for (int i = 1; i <= n; i++) {\n    dp[i][0] = i;\n  }\n  for (int j = 1; j <= m; j++) {\n    dp[0][j] = j;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i <= n; i++) {\n    for (int j = 1; j <= m; j++) {\n      if (s[i - 1] == t[j - 1]) {\n        // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n        dp[i][j] = dp[i - 1][j - 1];\n      } else {\n        // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n        dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n      }\n    }\n  }\n  return dp[n][m];\n}\n
    edit_distance.rs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfn edit_distance_dp(s: &str, t: &str) -> i32 {\n    let (n, m) = (s.len(), t.len());\n    let mut dp = vec![vec![0; m + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for i in 1..=n {\n        dp[i][0] = i as i32;\n    }\n    for j in 1..m {\n        dp[0][j] = j as i32;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..=n {\n        for j in 1..=m {\n            if s.chars().nth(i - 1) == t.chars().nth(j - 1) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] =\n                    std::cmp::min(std::cmp::min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    dp[n][m]\n}\n
    edit_distance.c
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nint editDistanceDP(char *s, char *t, int n, int m) {\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(m + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int i = 1; i <= n; i++) {\n        dp[i][0] = i;\n    }\n    for (int j = 1; j <= m; j++) {\n        dp[0][j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= m; j++) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = myMin(myMin(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    int res = dp[n][m];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    edit_distance.kt
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212 */\nfun editDistanceDP(s: String, t: String): Int {\n    val n = s.length\n    val m = t.length\n    val dp = Array(n + 1) { IntArray(m + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (i in 1..n) {\n        dp[i][0] = i\n    }\n    for (j in 1..m) {\n        dp[0][j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..n) {\n        for (j in 1..m) {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1]\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1\n            }\n        }\n    }\n    return dp[n][m]\n}\n
    edit_distance.rb
    [class]{}-[func]{edit_distance_dp}\n
    edit_distance.zig
    // \u7f16\u8f91\u8ddd\u79bb\uff1a\u52a8\u6001\u89c4\u5212\nfn editDistanceDP(comptime s: []const u8, comptime t: []const u8) i32 {\n    comptime var n = s.len;\n    comptime var m = t.len;\n    var dp = [_][m + 1]i32{[_]i32{0} ** (m + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (1..n + 1) |i| {\n        dp[i][0] = @intCast(i);\n    }\n    for (1..m + 1) |j| {\n        dp[0][j] = @intCast(j);\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n + 1) |i| {\n        for (1..m + 1) |j| {\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[i][j] = dp[i - 1][j - 1];\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[i][j] = @min(@min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n            }\n        }\n    }\n    return dp[n][m];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-30 \u6240\u793a\uff0c\u7f16\u8f91\u8ddd\u79bb\u95ee\u9898\u7684\u72b6\u6001\u8f6c\u79fb\u8fc7\u7a0b\u4e0e\u80cc\u5305\u95ee\u9898\u975e\u5e38\u7c7b\u4f3c\uff0c\u90fd\u53ef\u4ee5\u770b\u4f5c\u586b\u5199\u4e00\u4e2a\u4e8c\u7ef4\u7f51\u683c\u7684\u8fc7\u7a0b\u3002

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>

    \u56fe 14-30 \u00a0 \u7f16\u8f91\u8ddd\u79bb\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/edit_distance_problem/#3","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e \\(dp[i,j]\\) \u662f\u7531\u4e0a\u65b9 \\(dp[i-1, j]\\)\u3001\u5de6\u65b9 \\(dp[i, j-1]\\)\u3001\u5de6\u4e0a\u65b9 \\(dp[i-1, j-1]\\) \u8f6c\u79fb\u800c\u6765\u7684\uff0c\u800c\u6b63\u5e8f\u904d\u5386\u4f1a\u4e22\u5931\u5de6\u4e0a\u65b9 \\(dp[i-1, j-1]\\) \uff0c\u5012\u5e8f\u904d\u5386\u65e0\u6cd5\u63d0\u524d\u6784\u5efa \\(dp[i, j-1]\\) \uff0c\u56e0\u6b64\u4e24\u79cd\u904d\u5386\u987a\u5e8f\u90fd\u4e0d\u53ef\u53d6\u3002

    \u4e3a\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u53d8\u91cf leftup \u6765\u6682\u5b58\u5de6\u4e0a\u65b9\u7684\u89e3 \\(dp[i-1, j-1]\\) \uff0c\u4ece\u800c\u53ea\u9700\u8003\u8651\u5de6\u65b9\u548c\u4e0a\u65b9\u7684\u89e3\u3002\u6b64\u65f6\u7684\u60c5\u51b5\u4e0e\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u76f8\u540c\uff0c\u53ef\u4f7f\u7528\u6b63\u5e8f\u904d\u5386\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig edit_distance.py
    def edit_distance_dp_comp(s: str, t: str) -> int:\n    \"\"\"\u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n, m = len(s), len(t)\n    dp = [0] * (m + 1)\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in range(1, m + 1):\n        dp[j] = j\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in range(1, n + 1):\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        leftup = dp[0]  # \u6682\u5b58 dp[i-1, j-1]\n        dp[0] += 1\n        # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in range(1, m + 1):\n            temp = dp[j]\n            if s[i - 1] == t[j - 1]:\n                # \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            else:\n                # \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(dp[j - 1], dp[j], leftup) + 1\n            leftup = temp  # \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n    return dp[m]\n
    edit_distance.cpp
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(string s, string t) {\n    int n = s.length(), m = t.length();\n    vector<int> dp(m + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.java
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(String s, String t) {\n    int n = s.length(), m = t.length();\n    int[] dp = new int[m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s.charAt(i - 1) == t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(Math.min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.cs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint EditDistanceDPComp(string s, string t) {\n    int n = s.Length, m = t.Length;\n    int[] dp = new int[m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.Min(Math.Min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.go
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDPComp(s string, t string) int {\n    n := len(s)\n    m := len(t)\n    dp := make([]int, m+1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j := 1; j <= m; j++ {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i := 1; i <= n; i++ {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        leftUp := dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j := 1; j <= m; j++ {\n            temp := dp[j]\n            if s[i-1] == t[j-1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftUp\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = MinInt(MinInt(dp[j-1], dp[j]), leftUp) + 1\n            }\n            leftUp = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.swift
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc editDistanceDPComp(s: String, t: String) -> Int {\n    let n = s.utf8CString.count\n    let m = t.utf8CString.count\n    var dp = Array(repeating: 0, count: m + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1 ... m {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1 ... n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1 ... m {\n            let temp = dp[j]\n            if s.utf8CString[i - 1] == t.utf8CString[j - 1] {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1\n            }\n            leftup = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.js
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDPComp(s, t) {\n    const n = s.length,\n        m = t.length;\n    const dp = new Array(m + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j <= m; j++) {\n            const temp = dp[j];\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(dp[j - 1], dp[j], leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.ts
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction editDistanceDPComp(s: string, t: string): number {\n    const n = s.length,\n        m = t.length;\n    const dp = new Array(m + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (let j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (let i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (let j = 1; j <= m; j++) {\n            const temp = dp[j];\n            if (s.charAt(i - 1) === t.charAt(j - 1)) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = Math.min(dp[j - 1], dp[j], leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    edit_distance.dart
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(String s, String t) {\n  int n = s.length, m = t.length;\n  List<int> dp = List.filled(m + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n  for (int j = 1; j <= m; j++) {\n    dp[j] = j;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n  for (int i = 1; i <= n; i++) {\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n    int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n    dp[0] = i;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n    for (int j = 1; j <= m; j++) {\n      int temp = dp[j];\n      if (s[i - 1] == t[j - 1]) {\n        // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n        dp[j] = leftup;\n      } else {\n        // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n        dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1;\n      }\n      leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n    }\n  }\n  return dp[m];\n}\n
    edit_distance.rs
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn edit_distance_dp_comp(s: &str, t: &str) -> i32 {\n    let (n, m) = (s.len(), t.len());\n    let mut dp = vec![0; m + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for j in 1..m {\n        dp[j] = j as i32;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for i in 1..=n {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        let mut leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i as i32;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for j in 1..=m {\n            let temp = dp[j];\n            if s.chars().nth(i - 1) == t.chars().nth(j - 1) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = std::cmp::min(std::cmp::min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    dp[m]\n}\n
    edit_distance.c
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint editDistanceDPComp(char *s, char *t, int n, int m) {\n    int *dp = calloc(m + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (int j = 1; j <= m; j++) {\n        dp[j] = j;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (int i = 1; i <= n; i++) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        int leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i;\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (int j = 1; j <= m; j++) {\n            int temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = myMin(myMin(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    int res = dp[m];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    edit_distance.kt
    /* \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun editDistanceDPComp(s: String, t: String): Int {\n    val n = s.length\n    val m = t.length\n    val dp = IntArray(m + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (j in 1..m) {\n        dp[j] = j\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (i in 1..n) {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0] // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = i\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (j in 1..m) {\n            val temp = dp[j]\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1\n            }\n            leftup = temp // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m]\n}\n
    edit_distance.rb
    [class]{}-[func]{edit_distance_dp_comp}\n
    edit_distance.zig
    // \u7f16\u8f91\u8ddd\u79bb\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn editDistanceDPComp(comptime s: []const u8, comptime t: []const u8) i32 {\n    comptime var n = s.len;\n    comptime var m = t.len;\n    var dp = [_]i32{0} ** (m + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\n    for (1..m + 1) |j| {\n        dp[j] = @intCast(j);\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\n    for (1..n + 1) |i| {\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u5217\n        var leftup = dp[0]; // \u6682\u5b58 dp[i-1, j-1]\n        dp[0] = @intCast(i);\n        // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u5217\n        for (1..m + 1) |j| {\n            var temp = dp[j];\n            if (s[i - 1] == t[j - 1]) {\n                // \u82e5\u4e24\u5b57\u7b26\u76f8\u7b49\uff0c\u5219\u76f4\u63a5\u8df3\u8fc7\u6b64\u4e24\u5b57\u7b26\n                dp[j] = leftup;\n            } else {\n                // \u6700\u5c11\u7f16\u8f91\u6b65\u6570 = \u63d2\u5165\u3001\u5220\u9664\u3001\u66ff\u6362\u8fd9\u4e09\u79cd\u64cd\u4f5c\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570 + 1\n                dp[j] = @min(@min(dp[j - 1], dp[j]), leftup) + 1;\n            }\n            leftup = temp; // \u66f4\u65b0\u4e3a\u4e0b\u4e00\u8f6e\u7684 dp[i-1, j-1]\n        }\n    }\n    return dp[m];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/","title":"14.1 \u00a0 \u521d\u63a2\u52a8\u6001\u89c4\u5212","text":"

    \u52a8\u6001\u89c4\u5212\uff08dynamic programming\uff09\u662f\u4e00\u4e2a\u91cd\u8981\u7684\u7b97\u6cd5\u8303\u5f0f\uff0c\u5b83\u5c06\u4e00\u4e2a\u95ee\u9898\u5206\u89e3\u4e3a\u4e00\u7cfb\u5217\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u5e76\u901a\u8fc7\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\u6765\u907f\u514d\u91cd\u590d\u8ba1\u7b97\uff0c\u4ece\u800c\u5927\u5e45\u63d0\u5347\u65f6\u95f4\u6548\u7387\u3002

    \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u4ece\u4e00\u4e2a\u7ecf\u5178\u4f8b\u9898\u5165\u624b\uff0c\u5148\u7ed9\u51fa\u5b83\u7684\u66b4\u529b\u56de\u6eaf\u89e3\u6cd5\uff0c\u89c2\u5bdf\u5176\u4e2d\u5305\u542b\u7684\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u518d\u9010\u6b65\u5bfc\u51fa\u66f4\u9ad8\u6548\u7684\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\u3002

    \u722c\u697c\u68af

    \u7ed9\u5b9a\u4e00\u4e2a\u5171\u6709 \\(n\\) \u9636\u7684\u697c\u68af\uff0c\u4f60\u6bcf\u6b65\u53ef\u4ee5\u4e0a \\(1\\) \u9636\u6216\u8005 \\(2\\) \u9636\uff0c\u8bf7\u95ee\u6709\u591a\u5c11\u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\uff1f

    \u5982\u56fe 14-1 \u6240\u793a\uff0c\u5bf9\u4e8e\u4e00\u4e2a \\(3\\) \u9636\u697c\u68af\uff0c\u5171\u6709 \\(3\\) \u79cd\u65b9\u6848\u53ef\u4ee5\u722c\u5230\u697c\u9876\u3002

    \u56fe 14-1 \u00a0 \u722c\u5230\u7b2c 3 \u9636\u7684\u65b9\u6848\u6570\u91cf

    \u672c\u9898\u7684\u76ee\u6807\u662f\u6c42\u89e3\u65b9\u6848\u6570\u91cf\uff0c\u6211\u4eec\u53ef\u4ee5\u8003\u8651\u901a\u8fc7\u56de\u6eaf\u6765\u7a77\u4e3e\u6240\u6709\u53ef\u80fd\u6027\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u5c06\u722c\u697c\u68af\u60f3\u8c61\u4e3a\u4e00\u4e2a\u591a\u8f6e\u9009\u62e9\u7684\u8fc7\u7a0b\uff1a\u4ece\u5730\u9762\u51fa\u53d1\uff0c\u6bcf\u8f6e\u9009\u62e9\u4e0a \\(1\\) \u9636\u6216 \\(2\\) \u9636\uff0c\u6bcf\u5f53\u5230\u8fbe\u697c\u68af\u9876\u90e8\u65f6\u5c31\u5c06\u65b9\u6848\u6570\u91cf\u52a0 \\(1\\) \uff0c\u5f53\u8d8a\u8fc7\u697c\u68af\u9876\u90e8\u65f6\u5c31\u5c06\u5176\u526a\u679d\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_backtrack.py
    def backtrack(choices: list[int], state: int, n: int, res: list[int]) -> int:\n    \"\"\"\u56de\u6eaf\"\"\"\n    # \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n:\n        res[0] += 1\n    # \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices:\n        # \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n:\n            continue\n        # \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res)\n        # \u56de\u9000\n\ndef climbing_stairs_backtrack(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u56de\u6eaf\"\"\"\n    choices = [1, 2]  # \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    state = 0  # \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    res = [0]  # \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res)\n    return res[0]\n
    climbing_stairs_backtrack.cpp
    /* \u56de\u6eaf */\nvoid backtrack(vector<int> &choices, int state, int n, vector<int> &res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (auto &choice : choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    vector<int> choices = {1, 2}; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0;                // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    vector<int> res = {0};        // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res[0];\n}\n
    climbing_stairs_backtrack.java
    /* \u56de\u6eaf */\nvoid backtrack(List<Integer> choices, int state, int n, List<Integer> res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (Integer choice : choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    List<Integer> choices = Arrays.asList(1, 2); // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    List<Integer> res = new ArrayList<>();\n    res.add(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.cs
    /* \u56de\u6eaf */\nvoid Backtrack(List<int> choices, int state, int n, List<int> res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    foreach (int choice in choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        Backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint ClimbingStairsBacktrack(int n) {\n    List<int> choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    List<int> res = [0]; // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    Backtrack(choices, state, n, res);\n    return res[0];\n}\n
    climbing_stairs_backtrack.go
    /* \u56de\u6eaf */\nfunc backtrack(choices []int, state, n int, res []int) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] = res[0] + 1\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for _, choice := range choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state+choice > n {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state+choice, n, res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunc climbingStairsBacktrack(n int) int {\n    // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    choices := []int{1, 2}\n    // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    state := 0\n    res := make([]int, 1)\n    // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    res[0] = 0\n    backtrack(choices, state, n, res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.swift
    /* \u56de\u6eaf */\nfunc backtrack(choices: [Int], state: Int, n: Int, res: inout [Int]) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] += 1\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for choice in choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n {\n            continue\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices: choices, state: state + choice, n: n, res: &res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunc climbingStairsBacktrack(n: Int) -> Int {\n    let choices = [1, 2] // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    let state = 0 // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    var res: [Int] = []\n    res.append(0) // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices: choices, state: state, n: n, res: &res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.js
    /* \u56de\u6eaf */\nfunction backtrack(choices, state, n, res) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state === n) res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunction climbingStairsBacktrack(n) {\n    const choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    const state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    const res = new Map();\n    res.set(0, 0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.ts
    /* \u56de\u6eaf */\nfunction backtrack(\n    choices: number[],\n    state: number,\n    n: number,\n    res: Map<0, any>\n): void {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state === n) res.set(0, res.get(0) + 1);\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (const choice of choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfunction climbingStairsBacktrack(n: number): number {\n    const choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    const state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    const res = new Map();\n    res.set(0, 0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res);\n    return res.get(0);\n}\n
    climbing_stairs_backtrack.dart
    /* \u56de\u6eaf */\nvoid backtrack(List<int> choices, int state, int n, List<int> res) {\n  // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n  if (state == n) {\n    res[0]++;\n  }\n  // \u904d\u5386\u6240\u6709\u9009\u62e9\n  for (int choice in choices) {\n    // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n    if (state + choice > n) continue;\n    // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n    backtrack(choices, state + choice, n, res);\n    // \u56de\u9000\n  }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n  List<int> choices = [1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n  int state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n  List<int> res = [];\n  res.add(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n  backtrack(choices, state, n, res);\n  return res[0];\n}\n
    climbing_stairs_backtrack.rs
    /* \u56de\u6eaf */\nfn backtrack(choices: &[i32], state: i32, n: i32, res: &mut [i32]) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if state == n {\n        res[0] = res[0] + 1;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for &choice in choices {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if state + choice > n {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfn climbing_stairs_backtrack(n: usize) -> i32 {\n    let choices = vec![1, 2]; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    let state = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    let mut res = Vec::new();\n    res.push(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(&choices, state, n as i32, &mut res);\n    res[0]\n}\n
    climbing_stairs_backtrack.c
    /* \u56de\u6eaf */\nvoid backtrack(int *choices, int state, int n, int *res, int len) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0]++;\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (int i = 0; i < len; i++) {\n        int choice = choices[i];\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n)\n            continue;\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res, len);\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nint climbingStairsBacktrack(int n) {\n    int choices[2] = {1, 2}; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    int state = 0;           // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    int *res = (int *)malloc(sizeof(int));\n    *res = 0; // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    int len = sizeof(choices) / sizeof(int);\n    backtrack(choices, state, n, res, len);\n    int result = *res;\n    free(res);\n    return result;\n}\n
    climbing_stairs_backtrack.kt
    /* \u56de\u6eaf */\nfun backtrack(\n    choices: MutableList<Int>,\n    state: Int,\n    n: Int,\n    res: MutableList<Int>\n) {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n)\n        res[0] = res[0] + 1\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choice in choices) {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) continue\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res)\n        // \u56de\u9000\n    }\n}\n\n/* \u722c\u697c\u68af\uff1a\u56de\u6eaf */\nfun climbingStairsBacktrack(n: Int): Int {\n    val choices = mutableListOf(1, 2) // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    val state = 0 // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    val res = mutableListOf<Int>()\n    res.add(0) // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(choices, state, n, res)\n    return res[0]\n}\n
    climbing_stairs_backtrack.rb
    [class]{}-[func]{backtrack}\n\n[class]{}-[func]{climbing_stairs_backtrack}\n
    climbing_stairs_backtrack.zig
    // \u56de\u6eaf\nfn backtrack(choices: []i32, state: i32, n: i32, res: std.ArrayList(i32)) void {\n    // \u5f53\u722c\u5230\u7b2c n \u9636\u65f6\uff0c\u65b9\u6848\u6570\u91cf\u52a0 1\n    if (state == n) {\n        res.items[0] = res.items[0] + 1;\n    }\n    // \u904d\u5386\u6240\u6709\u9009\u62e9\n    for (choices) |choice| {\n        // \u526a\u679d\uff1a\u4e0d\u5141\u8bb8\u8d8a\u8fc7\u7b2c n \u9636\n        if (state + choice > n) {\n            continue;\n        }\n        // \u5c1d\u8bd5\uff1a\u505a\u51fa\u9009\u62e9\uff0c\u66f4\u65b0\u72b6\u6001\n        backtrack(choices, state + choice, n, res);\n        // \u56de\u9000\n    }\n}\n\n// \u722c\u697c\u68af\uff1a\u56de\u6eaf\nfn climbingStairsBacktrack(n: usize) !i32 {\n    var choices = [_]i32{ 1, 2 }; // \u53ef\u9009\u62e9\u5411\u4e0a\u722c 1 \u9636\u6216 2 \u9636\n    var state: i32 = 0; // \u4ece\u7b2c 0 \u9636\u5f00\u59cb\u722c\n    var res = std.ArrayList(i32).init(std.heap.page_allocator);\n    defer res.deinit();\n    try res.append(0); // \u4f7f\u7528 res[0] \u8bb0\u5f55\u65b9\u6848\u6570\u91cf\n    backtrack(&choices, state, @intCast(n), res);\n    return res.items[0];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1411","title":"14.1.1 \u00a0 \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u641c\u7d22","text":"

    \u56de\u6eaf\u7b97\u6cd5\u901a\u5e38\u5e76\u4e0d\u663e\u5f0f\u5730\u5bf9\u95ee\u9898\u8fdb\u884c\u62c6\u89e3\uff0c\u800c\u662f\u5c06\u6c42\u89e3\u95ee\u9898\u770b\u4f5c\u4e00\u7cfb\u5217\u51b3\u7b56\u6b65\u9aa4\uff0c\u901a\u8fc7\u8bd5\u63a2\u548c\u526a\u679d\uff0c\u641c\u7d22\u6240\u6709\u53ef\u80fd\u7684\u89e3\u3002

    \u6211\u4eec\u53ef\u4ee5\u5c1d\u8bd5\u4ece\u95ee\u9898\u5206\u89e3\u7684\u89d2\u5ea6\u5206\u6790\u8fd9\u9053\u9898\u3002\u8bbe\u722c\u5230\u7b2c \\(i\\) \u9636\u5171\u6709 \\(dp[i]\\) \u79cd\u65b9\u6848\uff0c\u90a3\u4e48 \\(dp[i]\\) \u5c31\u662f\u539f\u95ee\u9898\uff0c\u5176\u5b50\u95ee\u9898\u5305\u62ec\uff1a

    \\[ dp[i-1], dp[i-2], \\dots, dp[2], dp[1] \\]

    \u7531\u4e8e\u6bcf\u8f6e\u53ea\u80fd\u4e0a \\(1\\) \u9636\u6216 \\(2\\) \u9636\uff0c\u56e0\u6b64\u5f53\u6211\u4eec\u7ad9\u5728\u7b2c \\(i\\) \u9636\u697c\u68af\u4e0a\u65f6\uff0c\u4e0a\u4e00\u8f6e\u53ea\u53ef\u80fd\u7ad9\u5728\u7b2c \\(i - 1\\) \u9636\u6216\u7b2c \\(i - 2\\) \u9636\u4e0a\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6211\u4eec\u53ea\u80fd\u4ece\u7b2c \\(i -1\\) \u9636\u6216\u7b2c \\(i - 2\\) \u9636\u8fc8\u5411\u7b2c \\(i\\) \u9636\u3002

    \u7531\u6b64\u4fbf\u53ef\u5f97\u51fa\u4e00\u4e2a\u91cd\u8981\u63a8\u8bba\uff1a\u722c\u5230\u7b2c \\(i - 1\\) \u9636\u7684\u65b9\u6848\u6570\u52a0\u4e0a\u722c\u5230\u7b2c \\(i - 2\\) \u9636\u7684\u65b9\u6848\u6570\u5c31\u7b49\u4e8e\u722c\u5230\u7b2c \\(i\\) \u9636\u7684\u65b9\u6848\u6570\u3002\u516c\u5f0f\u5982\u4e0b\uff1a

    \\[ dp[i] = dp[i-1] + dp[i-2] \\]

    \u8fd9\u610f\u5473\u7740\u5728\u722c\u697c\u68af\u95ee\u9898\u4e2d\uff0c\u5404\u4e2a\u5b50\u95ee\u9898\u4e4b\u95f4\u5b58\u5728\u9012\u63a8\u5173\u7cfb\uff0c\u539f\u95ee\u9898\u7684\u89e3\u53ef\u4ee5\u7531\u5b50\u95ee\u9898\u7684\u89e3\u6784\u5efa\u5f97\u6765\u3002\u56fe 14-2 \u5c55\u793a\u4e86\u8be5\u9012\u63a8\u5173\u7cfb\u3002

    \u56fe 14-2 \u00a0 \u65b9\u6848\u6570\u91cf\u9012\u63a8\u5173\u7cfb

    \u6211\u4eec\u53ef\u4ee5\u6839\u636e\u9012\u63a8\u516c\u5f0f\u5f97\u5230\u66b4\u529b\u641c\u7d22\u89e3\u6cd5\u3002\u4ee5 \\(dp[n]\\) \u4e3a\u8d77\u59cb\u70b9\uff0c\u9012\u5f52\u5730\u5c06\u4e00\u4e2a\u8f83\u5927\u95ee\u9898\u62c6\u89e3\u4e3a\u4e24\u4e2a\u8f83\u5c0f\u95ee\u9898\u7684\u548c\uff0c\u76f4\u81f3\u5230\u8fbe\u6700\u5c0f\u5b50\u95ee\u9898 \\(dp[1]\\) \u548c \\(dp[2]\\) \u65f6\u8fd4\u56de\u3002\u5176\u4e2d\uff0c\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\u662f\u5df2\u77e5\u7684\uff0c\u5373 \\(dp[1] = 1\\)\u3001\\(dp[2] = 2\\) \uff0c\u8868\u793a\u722c\u5230\u7b2c \\(1\\)\u3001\\(2\\) \u9636\u5206\u522b\u6709 \\(1\\)\u3001\\(2\\) \u79cd\u65b9\u6848\u3002

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u5b83\u548c\u6807\u51c6\u56de\u6eaf\u4ee3\u7801\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\uff0c\u4f46\u66f4\u52a0\u7b80\u6d01\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dfs.py
    def dfs(i: int) -> int:\n    \"\"\"\u641c\u7d22\"\"\"\n    # \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 or i == 2:\n        return i\n    # dp[i] = dp[i-1] + dp[i-2]\n    count = dfs(i - 1) + dfs(i - 2)\n    return count\n\ndef climbing_stairs_dfs(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u641c\u7d22\"\"\"\n    return dfs(n)\n
    climbing_stairs_dfs.cpp
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.java
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.cs
    /* \u641c\u7d22 */\nint DFS(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = DFS(i - 1) + DFS(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint ClimbingStairsDFS(int n) {\n    return DFS(n);\n}\n
    climbing_stairs_dfs.go
    /* \u641c\u7d22 */\nfunc dfs(i int) int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    count := dfs(i-1) + dfs(i-2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunc climbingStairsDFS(n int) int {\n    return dfs(n)\n}\n
    climbing_stairs_dfs.swift
    /* \u641c\u7d22 */\nfunc dfs(i: Int) -> Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i: i - 1) + dfs(i: i - 2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunc climbingStairsDFS(n: Int) -> Int {\n    dfs(i: n)\n}\n
    climbing_stairs_dfs.js
    /* \u641c\u7d22 */\nfunction dfs(i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunction climbingStairsDFS(n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.ts
    /* \u641c\u7d22 */\nfunction dfs(i: number): number {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfunction climbingStairsDFS(n: number): number {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.dart
    /* \u641c\u7d22 */\nint dfs(int i) {\n  // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n  if (i == 1 || i == 2) return i;\n  // dp[i] = dp[i-1] + dp[i-2]\n  int count = dfs(i - 1) + dfs(i - 2);\n  return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n  return dfs(n);\n}\n
    climbing_stairs_dfs.rs
    /* \u641c\u7d22 */\nfn dfs(i: usize) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i as i32;\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i - 1) + dfs(i - 2);\n    count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfn climbing_stairs_dfs(n: usize) -> i32 {\n    dfs(n)\n}\n
    climbing_stairs_dfs.c
    /* \u641c\u7d22 */\nint dfs(int i) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nint climbingStairsDFS(int n) {\n    return dfs(n);\n}\n
    climbing_stairs_dfs.kt
    /* \u641c\u7d22 */\nfun dfs(i: Int): Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2) return i\n    // dp[i] = dp[i-1] + dp[i-2]\n    val count = dfs(i - 1) + dfs(i - 2)\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u641c\u7d22 */\nfun climbingStairsDFS(n: Int): Int {\n    return dfs(n)\n}\n
    climbing_stairs_dfs.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{climbing_stairs_dfs}\n
    climbing_stairs_dfs.zig
    // \u641c\u7d22\nfn dfs(i: usize) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 or i == 2) {\n        return @intCast(i);\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    var count = dfs(i - 1) + dfs(i - 2);\n    return count;\n}\n\n// \u722c\u697c\u68af\uff1a\u641c\u7d22\nfn climbingStairsDFS(comptime n: usize) i32 {\n    return dfs(n);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-3 \u5c55\u793a\u4e86\u66b4\u529b\u641c\u7d22\u5f62\u6210\u7684\u9012\u5f52\u6811\u3002\u5bf9\u4e8e\u95ee\u9898 \\(dp[n]\\) \uff0c\u5176\u9012\u5f52\u6811\u7684\u6df1\u5ea6\u4e3a \\(n\\) \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \u3002\u6307\u6570\u9636\u5c5e\u4e8e\u7206\u70b8\u5f0f\u589e\u957f\uff0c\u5982\u679c\u6211\u4eec\u8f93\u5165\u4e00\u4e2a\u6bd4\u8f83\u5927\u7684 \\(n\\) \uff0c\u5219\u4f1a\u9677\u5165\u6f2b\u957f\u7684\u7b49\u5f85\u4e4b\u4e2d\u3002

    \u56fe 14-3 \u00a0 \u722c\u697c\u68af\u5bf9\u5e94\u9012\u5f52\u6811

    \u89c2\u5bdf\u56fe 14-3 \uff0c\u6307\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f\u201c\u91cd\u53e0\u5b50\u95ee\u9898\u201d\u5bfc\u81f4\u7684\u3002\u4f8b\u5982 \\(dp[9]\\) \u88ab\u5206\u89e3\u4e3a \\(dp[8]\\) \u548c \\(dp[7]\\) \uff0c\\(dp[8]\\) \u88ab\u5206\u89e3\u4e3a \\(dp[7]\\) \u548c \\(dp[6]\\) \uff0c\u4e24\u8005\u90fd\u5305\u542b\u5b50\u95ee\u9898 \\(dp[7]\\) \u3002

    \u4ee5\u6b64\u7c7b\u63a8\uff0c\u5b50\u95ee\u9898\u4e2d\u5305\u542b\u66f4\u5c0f\u7684\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u5b50\u5b50\u5b59\u5b59\u65e0\u7a77\u5c3d\u4e5f\u3002\u7edd\u5927\u90e8\u5206\u8ba1\u7b97\u8d44\u6e90\u90fd\u6d6a\u8d39\u5728\u8fd9\u4e9b\u91cd\u53e0\u7684\u5b50\u95ee\u9898\u4e0a\u3002

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1412","title":"14.1.2 \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22","text":"

    \u4e3a\u4e86\u63d0\u5347\u7b97\u6cd5\u6548\u7387\uff0c\u6211\u4eec\u5e0c\u671b\u6240\u6709\u7684\u91cd\u53e0\u5b50\u95ee\u9898\u90fd\u53ea\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u6570\u7ec4 mem \u6765\u8bb0\u5f55\u6bcf\u4e2a\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5e76\u5728\u641c\u7d22\u8fc7\u7a0b\u4e2d\u5c06\u91cd\u53e0\u5b50\u95ee\u9898\u526a\u679d\u3002

    1. \u5f53\u9996\u6b21\u8ba1\u7b97 \\(dp[i]\\) \u65f6\uff0c\u6211\u4eec\u5c06\u5176\u8bb0\u5f55\u81f3 mem[i] \uff0c\u4ee5\u4fbf\u4e4b\u540e\u4f7f\u7528\u3002
    2. \u5f53\u518d\u6b21\u9700\u8981\u8ba1\u7b97 \\(dp[i]\\) \u65f6\uff0c\u6211\u4eec\u4fbf\u53ef\u76f4\u63a5\u4ece mem[i] \u4e2d\u83b7\u53d6\u7ed3\u679c\uff0c\u4ece\u800c\u907f\u514d\u91cd\u590d\u8ba1\u7b97\u8be5\u5b50\u95ee\u9898\u3002

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dfs_mem.py
    def dfs(i: int, mem: list[int]) -> int:\n    \"\"\"\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 or i == 2:\n        return i\n    # \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1:\n        return mem[i]\n    # dp[i] = dp[i-1] + dp[i-2]\n    count = dfs(i - 1, mem) + dfs(i - 2, mem)\n    # \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n\ndef climbing_stairs_dfs_mem(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    mem = [-1] * (n + 1)\n    return dfs(n, mem)\n
    climbing_stairs_dfs_mem.cpp
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, vector<int> &mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    vector<int> mem(n + 1, -1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.java
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, int[] mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int[] mem = new int[n + 1];\n    Arrays.fill(mem, -1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.cs
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint DFS(int i, int[] mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = DFS(i - 1, mem) + DFS(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint ClimbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int[] mem = new int[n + 1];\n    Array.Fill(mem, -1);\n    return DFS(n, mem);\n}\n
    climbing_stairs_dfs_mem.go
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc dfsMem(i int, mem []int) int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i]\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    count := dfsMem(i-1, mem) + dfsMem(i-2, mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc climbingStairsDFSMem(n int) int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    mem := make([]int, n+1)\n    for i := range mem {\n        mem[i] = -1\n    }\n    return dfsMem(n, mem)\n}\n
    climbing_stairs_dfs_mem.swift
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc dfs(i: Int, mem: inout [Int]) -> Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i]\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i: i - 1, mem: &mem) + dfs(i: i - 2, mem: &mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc climbingStairsDFSMem(n: Int) -> Int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    var mem = Array(repeating: -1, count: n + 1)\n    return dfs(i: n, mem: &mem)\n}\n
    climbing_stairs_dfs_mem.js
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction dfs(i, mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction climbingStairsDFSMem(n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    const mem = new Array(n + 1).fill(-1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.ts
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction dfs(i: number, mem: number[]): number {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i === 1 || i === 2) return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    const count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction climbingStairsDFSMem(n: number): number {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    const mem = new Array(n + 1).fill(-1);\n    return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.dart
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, List<int> mem) {\n  // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n  if (i == 1 || i == 2) return i;\n  // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n  if (mem[i] != -1) return mem[i];\n  // dp[i] = dp[i-1] + dp[i-2]\n  int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n  // \u8bb0\u5f55 dp[i]\n  mem[i] = count;\n  return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n  // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n  List<int> mem = List.filled(n + 1, -1);\n  return dfs(n, mem);\n}\n
    climbing_stairs_dfs_mem.rs
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn dfs(i: usize, mem: &mut [i32]) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if i == 1 || i == 2 {\n        return i as i32;\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if mem[i] != -1 {\n        return mem[i];\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    let count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn climbing_stairs_dfs_mem(n: usize) -> i32 {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    let mut mem = vec![-1; n + 1];\n    dfs(n, &mut mem)\n}\n
    climbing_stairs_dfs_mem.c
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nint dfs(int i, int *mem) {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2)\n        return i;\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1)\n        return mem[i];\n    // dp[i] = dp[i-1] + dp[i-2]\n    int count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint climbingStairsDFSMem(int n) {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    int *mem = (int *)malloc((n + 1) * sizeof(int));\n    for (int i = 0; i <= n; i++) {\n        mem[i] = -1;\n    }\n    int result = dfs(n, mem);\n    free(mem);\n    return result;\n}\n
    climbing_stairs_dfs_mem.kt
    /* \u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun dfs(i: Int, mem: IntArray): Int {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 || i == 2) return i\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) return mem[i]\n    // dp[i] = dp[i-1] + dp[i-2]\n    val count = dfs(i - 1, mem) + dfs(i - 2, mem)\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count\n    return count\n}\n\n/* \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun climbingStairsDFSMem(n: Int): Int {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    val mem = IntArray(n + 1)\n    mem.fill(-1)\n    return dfs(n, mem)\n}\n
    climbing_stairs_dfs_mem.rb
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{climbing_stairs_dfs_mem}\n
    climbing_stairs_dfs_mem.zig
    // \u8bb0\u5fc6\u5316\u641c\u7d22\nfn dfs(i: usize, mem: []i32) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (i == 1 or i == 2) {\n        return @intCast(i);\n    }\n    // \u82e5\u5b58\u5728\u8bb0\u5f55 dp[i] \uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u4e4b\n    if (mem[i] != -1) {\n        return mem[i];\n    }\n    // dp[i] = dp[i-1] + dp[i-2]\n    var count = dfs(i - 1, mem) + dfs(i - 2, mem);\n    // \u8bb0\u5f55 dp[i]\n    mem[i] = count;\n    return count;\n}\n\n// \u722c\u697c\u68af\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn climbingStairsDFSMem(comptime n: usize) i32 {\n    // mem[i] \u8bb0\u5f55\u722c\u5230\u7b2c i \u9636\u7684\u65b9\u6848\u603b\u6570\uff0c-1 \u4ee3\u8868\u65e0\u8bb0\u5f55\n    var mem = [_]i32{ -1 } ** (n + 1);\n    return dfs(n, &mem);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u56fe 14-4 \uff0c\u7ecf\u8fc7\u8bb0\u5fc6\u5316\u5904\u7406\u540e\uff0c\u6240\u6709\u91cd\u53e0\u5b50\u95ee\u9898\u90fd\u53ea\u9700\u8ba1\u7b97\u4e00\u6b21\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(n)\\) \uff0c\u8fd9\u662f\u4e00\u4e2a\u5de8\u5927\u7684\u98de\u8dc3\u3002

    \u56fe 14-4 \u00a0 \u8bb0\u5fc6\u5316\u641c\u7d22\u5bf9\u5e94\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1413","title":"14.1.3 \u00a0 \u65b9\u6cd5\u4e09\uff1a\u52a8\u6001\u89c4\u5212","text":"

    \u8bb0\u5fc6\u5316\u641c\u7d22\u662f\u4e00\u79cd\u201c\u4ece\u9876\u81f3\u5e95\u201d\u7684\u65b9\u6cd5\uff1a\u6211\u4eec\u4ece\u539f\u95ee\u9898\uff08\u6839\u8282\u70b9\uff09\u5f00\u59cb\uff0c\u9012\u5f52\u5730\u5c06\u8f83\u5927\u5b50\u95ee\u9898\u5206\u89e3\u4e3a\u8f83\u5c0f\u5b50\u95ee\u9898\uff0c\u76f4\u81f3\u89e3\u5df2\u77e5\u7684\u6700\u5c0f\u5b50\u95ee\u9898\uff08\u53f6\u8282\u70b9\uff09\u3002\u4e4b\u540e\uff0c\u901a\u8fc7\u56de\u6eaf\u9010\u5c42\u6536\u96c6\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u6784\u5efa\u51fa\u539f\u95ee\u9898\u7684\u89e3\u3002

    \u4e0e\u4e4b\u76f8\u53cd\uff0c\u52a8\u6001\u89c4\u5212\u662f\u4e00\u79cd\u201c\u4ece\u5e95\u81f3\u9876\u201d\u7684\u65b9\u6cd5\uff1a\u4ece\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\u5f00\u59cb\uff0c\u8fed\u4ee3\u5730\u6784\u5efa\u66f4\u5927\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u76f4\u81f3\u5f97\u5230\u539f\u95ee\u9898\u7684\u89e3\u3002

    \u7531\u4e8e\u52a8\u6001\u89c4\u5212\u4e0d\u5305\u542b\u56de\u6eaf\u8fc7\u7a0b\uff0c\u56e0\u6b64\u53ea\u9700\u4f7f\u7528\u5faa\u73af\u8fed\u4ee3\u5b9e\u73b0\uff0c\u65e0\u987b\u4f7f\u7528\u9012\u5f52\u3002\u5728\u4ee5\u4e0b\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u521d\u59cb\u5316\u4e00\u4e2a\u6570\u7ec4 dp \u6765\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5b83\u8d77\u5230\u4e86\u4e0e\u8bb0\u5fc6\u5316\u641c\u7d22\u4e2d\u6570\u7ec4 mem \u76f8\u540c\u7684\u8bb0\u5f55\u4f5c\u7528\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dp.py
    def climbing_stairs_dp(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return n\n    # \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp = [0] * (n + 1)\n    # \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1], dp[2] = 1, 2\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in range(3, n + 1):\n        dp[i] = dp[i - 1] + dp[i - 2]\n    return dp[n]\n
    climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    vector<int> dp(n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.java
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int[] dp = new int[n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.go
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDP(n int) int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    dp := make([]int, n+1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        dp[i] = dp[i-1] + dp[i-2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDP(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = Array(repeating: 0, count: n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3 ... n {\n        dp[i] = dp[i - 1] + dp[i - 2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.js
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDP(n) {\n    if (n === 1 || n === 2) return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1).fill(-1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDP(n: number): number {\n    if (n === 1 || n === 2) return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    const dp = new Array(n + 1).fill(-1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (let i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n  if (n == 1 || n == 2) return n;\n  // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n  List<int> dp = List.filled(n + 1, 0);\n  // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n  dp[1] = 1;\n  dp[2] = 2;\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n  for (int i = 3; i <= n; i++) {\n    dp[i] = dp[i - 1] + dp[i - 2];\n  }\n  return dp[n];\n}\n
    climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_dp(n: usize) -> i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if n == 1 || n == 2 {\n        return n as i32;\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    let mut dp = vec![-1; n + 1];\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i in 3..=n {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    dp[n]\n}\n
    climbing_stairs_dp.c
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDP(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    int *dp = (int *)malloc((n + 1) * sizeof(int));\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (int i = 3; i <= n; i++) {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    int result = dp[n];\n    free(dp);\n    return result;\n}\n
    climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsDP(n: Int): Int {\n    if (n == 1 || n == 2) return n\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    val dp = IntArray(n + 1)\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1\n    dp[2] = 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (i in 3..n) {\n        dp[i] = dp[i - 1] + dp[i - 2]\n    }\n    return dp[n]\n}\n
    climbing_stairs_dp.rb
    [class]{}-[func]{climbing_stairs_dp}\n
    climbing_stairs_dp.zig
    // \u722c\u697c\u68af\uff1a\u52a8\u6001\u89c4\u5212\nfn climbingStairsDP(comptime n: usize) i32 {\n    // \u5df2\u77e5 dp[1] \u548c dp[2] \uff0c\u8fd4\u56de\u4e4b\n    if (n == 1 or n == 2) {\n        return @intCast(n);\n    }\n    // \u521d\u59cb\u5316 dp \u8868\uff0c\u7528\u4e8e\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\n    var dp = [_]i32{-1} ** (n + 1);\n    // \u521d\u59cb\u72b6\u6001\uff1a\u9884\u8bbe\u6700\u5c0f\u5b50\u95ee\u9898\u7684\u89e3\n    dp[1] = 1;\n    dp[2] = 2;\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for (3..n + 1) |i| {\n        dp[i] = dp[i - 1] + dp[i - 2];\n    }\n    return dp[n];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-5 \u6a21\u62df\u4e86\u4ee5\u4e0a\u4ee3\u7801\u7684\u6267\u884c\u8fc7\u7a0b\u3002

    \u56fe 14-5 \u00a0 \u722c\u697c\u68af\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u4e0e\u56de\u6eaf\u7b97\u6cd5\u4e00\u6837\uff0c\u52a8\u6001\u89c4\u5212\u4e5f\u4f7f\u7528\u201c\u72b6\u6001\u201d\u6982\u5ff5\u6765\u8868\u793a\u95ee\u9898\u6c42\u89e3\u7684\u7279\u5b9a\u9636\u6bb5\uff0c\u6bcf\u4e2a\u72b6\u6001\u90fd\u5bf9\u5e94\u4e00\u4e2a\u5b50\u95ee\u9898\u4ee5\u53ca\u76f8\u5e94\u7684\u5c40\u90e8\u6700\u4f18\u89e3\u3002\u4f8b\u5982\uff0c\u722c\u697c\u68af\u95ee\u9898\u7684\u72b6\u6001\u5b9a\u4e49\u4e3a\u5f53\u524d\u6240\u5728\u697c\u68af\u9636\u6570 \\(i\\) \u3002

    \u6839\u636e\u4ee5\u4e0a\u5185\u5bb9\uff0c\u6211\u4eec\u53ef\u4ee5\u603b\u7ed3\u51fa\u52a8\u6001\u89c4\u5212\u7684\u5e38\u7528\u672f\u8bed\u3002

    • \u5c06\u6570\u7ec4 dp \u79f0\u4e3a dp \u8868\uff0c\\(dp[i]\\) \u8868\u793a\u72b6\u6001 \\(i\\) \u5bf9\u5e94\u5b50\u95ee\u9898\u7684\u89e3\u3002
    • \u5c06\u6700\u5c0f\u5b50\u95ee\u9898\u5bf9\u5e94\u7684\u72b6\u6001\uff08\u7b2c \\(1\\) \u9636\u548c\u7b2c \\(2\\) \u9636\u697c\u68af\uff09\u79f0\u4e3a\u521d\u59cb\u72b6\u6001\u3002
    • \u5c06\u9012\u63a8\u516c\u5f0f \\(dp[i] = dp[i-1] + dp[i-2]\\) \u79f0\u4e3a\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002
    "},{"location":"chapter_dynamic_programming/intro_to_dynamic_programming/#1414","title":"14.1.4 \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7ec6\u5fc3\u7684\u8bfb\u8005\u53ef\u80fd\u53d1\u73b0\u4e86\uff0c\u7531\u4e8e \\(dp[i]\\) \u53ea\u4e0e \\(dp[i-1]\\) \u548c \\(dp[i-2]\\) \u6709\u5173\uff0c\u56e0\u6b64\u6211\u4eec\u65e0\u987b\u4f7f\u7528\u4e00\u4e2a\u6570\u7ec4 dp \u6765\u5b58\u50a8\u6240\u6709\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u800c\u53ea\u9700\u4e24\u4e2a\u53d8\u91cf\u6eda\u52a8\u524d\u8fdb\u5373\u53ef\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig climbing_stairs_dp.py
    def climbing_stairs_dp_comp(n: int) -> int:\n    \"\"\"\u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    if n == 1 or n == 2:\n        return n\n    a, b = 1, 2\n    for _ in range(3, n + 1):\n        a, b = b, a + b\n    return b\n
    climbing_stairs_dp.cpp
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.java
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.cs
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint ClimbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.go
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDPComp(n int) int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    a, b := 1, 2\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u4ece\u8f83\u5c0f\u5b50\u95ee\u9898\u9010\u6b65\u6c42\u89e3\u8f83\u5927\u5b50\u95ee\u9898\n    for i := 3; i <= n; i++ {\n        a, b = b, a+b\n    }\n    return b\n}\n
    climbing_stairs_dp.swift
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc climbingStairsDPComp(n: Int) -> Int {\n    if n == 1 || n == 2 {\n        return n\n    }\n    var a = 1\n    var b = 2\n    for _ in 3 ... n {\n        (a, b) = (b, a + b)\n    }\n    return b\n}\n
    climbing_stairs_dp.js
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDPComp(n) {\n    if (n === 1 || n === 2) return n;\n    let a = 1,\n        b = 2;\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.ts
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction climbingStairsDPComp(n: number): number {\n    if (n === 1 || n === 2) return n;\n    let a = 1,\n        b = 2;\n    for (let i = 3; i <= n; i++) {\n        const tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.dart
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n  if (n == 1 || n == 2) return n;\n  int a = 1, b = 2;\n  for (int i = 3; i <= n; i++) {\n    int tmp = b;\n    b = a + b;\n    a = tmp;\n  }\n  return b;\n}\n
    climbing_stairs_dp.rs
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn climbing_stairs_dp_comp(n: usize) -> i32 {\n    if n == 1 || n == 2 {\n        return n as i32;\n    }\n    let (mut a, mut b) = (1, 2);\n    for _ in 3..=n {\n        let tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    b\n}\n
    climbing_stairs_dp.c
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint climbingStairsDPComp(int n) {\n    if (n == 1 || n == 2)\n        return n;\n    int a = 1, b = 2;\n    for (int i = 3; i <= n; i++) {\n        int tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    climbing_stairs_dp.kt
    /* \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun climbingStairsDPComp(n: Int): Int {\n    if (n == 1 || n == 2) return n\n    var a = 1\n    var b = 2\n    for (i in 3..n) {\n        val temp = b\n        b += a\n        a = temp\n    }\n    return b\n}\n
    climbing_stairs_dp.rb
    [class]{}-[func]{climbing_stairs_dp_comp}\n
    climbing_stairs_dp.zig
    // \u722c\u697c\u68af\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn climbingStairsDPComp(comptime n: usize) i32 {\n    if (n == 1 or n == 2) {\n        return @intCast(n);\n    }\n    var a: i32 = 1;\n    var b: i32 = 2;\n    for (3..n + 1) |_| {\n        var tmp = b;\n        b = a + b;\n        a = tmp;\n    }\n    return b;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u4ee5\u4e0a\u4ee3\u7801\uff0c\u7531\u4e8e\u7701\u53bb\u4e86\u6570\u7ec4 dp \u5360\u7528\u7684\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n)\\) \u964d\u81f3 \\(O(1)\\) \u3002

    \u5728\u52a8\u6001\u89c4\u5212\u95ee\u9898\u4e2d\uff0c\u5f53\u524d\u72b6\u6001\u5f80\u5f80\u4ec5\u4e0e\u524d\u9762\u6709\u9650\u4e2a\u72b6\u6001\u6709\u5173\uff0c\u8fd9\u65f6\u6211\u4eec\u53ef\u4ee5\u53ea\u4fdd\u7559\u5fc5\u8981\u7684\u72b6\u6001\uff0c\u901a\u8fc7\u201c\u964d\u7ef4\u201d\u6765\u8282\u7701\u5185\u5b58\u7a7a\u95f4\u3002\u8fd9\u79cd\u7a7a\u95f4\u4f18\u5316\u6280\u5de7\u88ab\u79f0\u4e3a\u201c\u6eda\u52a8\u53d8\u91cf\u201d\u6216\u201c\u6eda\u52a8\u6570\u7ec4\u201d\u3002

    "},{"location":"chapter_dynamic_programming/knapsack_problem/","title":"14.4 \u00a0 0-1 \u80cc\u5305\u95ee\u9898","text":"

    \u80cc\u5305\u95ee\u9898\u662f\u4e00\u4e2a\u975e\u5e38\u597d\u7684\u52a8\u6001\u89c4\u5212\u5165\u95e8\u9898\u76ee\uff0c\u662f\u52a8\u6001\u89c4\u5212\u4e2d\u6700\u5e38\u89c1\u7684\u95ee\u9898\u5f62\u5f0f\u3002\u5176\u5177\u6709\u5f88\u591a\u53d8\u79cd\uff0c\u4f8b\u5982 0-1 \u80cc\u5305\u95ee\u9898\u3001\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u3001\u591a\u91cd\u80cc\u5305\u95ee\u9898\u7b49\u3002

    \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5148\u6765\u6c42\u89e3\u6700\u5e38\u89c1\u7684 0-1 \u80cc\u5305\u95ee\u9898\u3002

    Question

    \u7ed9\u5b9a \\(n\\) \u4e2a\u7269\u54c1\uff0c\u7b2c \\(i\\) \u4e2a\u7269\u54c1\u7684\u91cd\u91cf\u4e3a \\(wgt[i-1]\\)\u3001\u4ef7\u503c\u4e3a \\(val[i-1]\\) \uff0c\u548c\u4e00\u4e2a\u5bb9\u91cf\u4e3a \\(cap\\) \u7684\u80cc\u5305\u3002\u6bcf\u4e2a\u7269\u54c1\u53ea\u80fd\u9009\u62e9\u4e00\u6b21\uff0c\u95ee\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80fd\u653e\u5165\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u3002

    \u89c2\u5bdf\u56fe 14-17 \uff0c\u7531\u4e8e\u7269\u54c1\u7f16\u53f7 \\(i\\) \u4ece \\(1\\) \u5f00\u59cb\u8ba1\u6570\uff0c\u6570\u7ec4\u7d22\u5f15\u4ece \\(0\\) \u5f00\u59cb\u8ba1\u6570\uff0c\u56e0\u6b64\u7269\u54c1 \\(i\\) \u5bf9\u5e94\u91cd\u91cf \\(wgt[i-1]\\) \u548c\u4ef7\u503c \\(val[i-1]\\) \u3002

    \u56fe 14-17 \u00a0 0-1 \u80cc\u5305\u7684\u793a\u4f8b\u6570\u636e

    \u6211\u4eec\u53ef\u4ee5\u5c06 0-1 \u80cc\u5305\u95ee\u9898\u770b\u4f5c\u4e00\u4e2a\u7531 \\(n\\) \u8f6e\u51b3\u7b56\u7ec4\u6210\u7684\u8fc7\u7a0b\uff0c\u5bf9\u4e8e\u6bcf\u4e2a\u7269\u4f53\u90fd\u6709\u4e0d\u653e\u5165\u548c\u653e\u5165\u4e24\u79cd\u51b3\u7b56\uff0c\u56e0\u6b64\u8be5\u95ee\u9898\u6ee1\u8db3\u51b3\u7b56\u6811\u6a21\u578b\u3002

    \u8be5\u95ee\u9898\u7684\u76ee\u6807\u662f\u6c42\u89e3\u201c\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80fd\u653e\u5165\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u201d\uff0c\u56e0\u6b64\u8f83\u5927\u6982\u7387\u662f\u4e00\u4e2a\u52a8\u6001\u89c4\u5212\u95ee\u9898\u3002

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u5bf9\u4e8e\u6bcf\u4e2a\u7269\u54c1\u6765\u8bf4\uff0c\u4e0d\u653e\u5165\u80cc\u5305\uff0c\u80cc\u5305\u5bb9\u91cf\u4e0d\u53d8\uff1b\u653e\u5165\u80cc\u5305\uff0c\u80cc\u5305\u5bb9\u91cf\u51cf\u5c0f\u3002\u7531\u6b64\u53ef\u5f97\u72b6\u6001\u5b9a\u4e49\uff1a\u5f53\u524d\u7269\u54c1\u7f16\u53f7 \\(i\\) \u548c\u80cc\u5305\u5bb9\u91cf \\(c\\) \uff0c\u8bb0\u4e3a \\([i, c]\\) \u3002

    \u72b6\u6001 \\([i, c]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u4e3a\uff1a\u524d \\(i\\) \u4e2a\u7269\u54c1\u5728\u5bb9\u91cf\u4e3a \\(c\\) \u7684\u80cc\u5305\u4e2d\u7684\u6700\u5927\u4ef7\u503c\uff0c\u8bb0\u4e3a \\(dp[i, c]\\) \u3002

    \u5f85\u6c42\u89e3\u7684\u662f \\(dp[n, cap]\\) \uff0c\u56e0\u6b64\u9700\u8981\u4e00\u4e2a\u5c3a\u5bf8\u4e3a \\((n+1) \\times (cap+1)\\) \u7684\u4e8c\u7ef4 \\(dp\\) \u8868\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u5f53\u6211\u4eec\u505a\u51fa\u7269\u54c1 \\(i\\) \u7684\u51b3\u7b56\u540e\uff0c\u5269\u4f59\u7684\u662f\u524d \\(i-1\\) \u4e2a\u7269\u54c1\u51b3\u7b56\u7684\u5b50\u95ee\u9898\uff0c\u53ef\u5206\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u60c5\u51b5\u3002

    • \u4e0d\u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u80cc\u5305\u5bb9\u91cf\u4e0d\u53d8\uff0c\u72b6\u6001\u53d8\u5316\u4e3a \\([i-1, c]\\) \u3002
    • \u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u80cc\u5305\u5bb9\u91cf\u51cf\u5c11 \\(wgt[i-1]\\) \uff0c\u4ef7\u503c\u589e\u52a0 \\(val[i-1]\\) \uff0c\u72b6\u6001\u53d8\u5316\u4e3a \\([i-1, c-wgt[i-1]]\\) \u3002

    \u4e0a\u8ff0\u5206\u6790\u5411\u6211\u4eec\u63ed\u793a\u4e86\u672c\u9898\u7684\u6700\u4f18\u5b50\u7ed3\u6784\uff1a\u6700\u5927\u4ef7\u503c \\(dp[i, c]\\) \u7b49\u4e8e\u4e0d\u653e\u5165\u7269\u54c1 \\(i\\) \u548c\u653e\u5165\u7269\u54c1 \\(i\\) \u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\u3002\u7531\u6b64\u53ef\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\uff1a

    \\[ dp[i, c] = \\max(dp[i-1, c], dp[i-1, c - wgt[i-1]] + val[i-1]) \\]

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u82e5\u5f53\u524d\u7269\u54c1\u91cd\u91cf \\(wgt[i - 1]\\) \u8d85\u51fa\u5269\u4f59\u80cc\u5305\u5bb9\u91cf \\(c\\) \uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\u3002

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5f53\u65e0\u7269\u54c1\u6216\u80cc\u5305\u5bb9\u91cf\u4e3a \\(0\\) \u65f6\u6700\u5927\u4ef7\u503c\u4e3a \\(0\\) \uff0c\u5373\u9996\u5217 \\(dp[i, 0]\\) \u548c\u9996\u884c \\(dp[0, c]\\) \u90fd\u7b49\u4e8e \\(0\\) \u3002

    \u5f53\u524d\u72b6\u6001 \\([i, c]\\) \u4ece\u4e0a\u65b9\u7684\u72b6\u6001 \\([i-1, c]\\) \u548c\u5de6\u4e0a\u65b9\u7684\u72b6\u6001 \\([i-1, c-wgt[i-1]]\\) \u8f6c\u79fb\u800c\u6765\uff0c\u56e0\u6b64\u901a\u8fc7\u4e24\u5c42\u5faa\u73af\u6b63\u5e8f\u904d\u5386\u6574\u4e2a \\(dp\\) \u8868\u5373\u53ef\u3002

    \u6839\u636e\u4ee5\u4e0a\u5206\u6790\uff0c\u6211\u4eec\u63a5\u4e0b\u6765\u6309\u987a\u5e8f\u5b9e\u73b0\u66b4\u529b\u641c\u7d22\u3001\u8bb0\u5fc6\u5316\u641c\u7d22\u3001\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\u3002

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#1","title":"1. \u00a0 \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u641c\u7d22","text":"

    \u641c\u7d22\u4ee3\u7801\u5305\u542b\u4ee5\u4e0b\u8981\u7d20\u3002

    • \u9012\u5f52\u53c2\u6570\uff1a\u72b6\u6001 \\([i, c]\\) \u3002
    • \u8fd4\u56de\u503c\uff1a\u5b50\u95ee\u9898\u7684\u89e3 \\(dp[i, c]\\) \u3002
    • \u7ec8\u6b62\u6761\u4ef6\uff1a\u5f53\u7269\u54c1\u7f16\u53f7\u8d8a\u754c \\(i = 0\\) \u6216\u80cc\u5305\u5269\u4f59\u5bb9\u91cf\u4e3a \\(0\\) \u65f6\uff0c\u7ec8\u6b62\u9012\u5f52\u5e76\u8fd4\u56de\u4ef7\u503c \\(0\\) \u3002
    • \u526a\u679d\uff1a\u82e5\u5f53\u524d\u7269\u54c1\u91cd\u91cf\u8d85\u51fa\u80cc\u5305\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dfs(wgt: list[int], val: list[int], i: int, c: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22\"\"\"\n    # \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 or c == 0:\n        return 0\n    # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c:\n        return knapsack_dfs(wgt, val, i - 1, c)\n    # \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no = knapsack_dfs(wgt, val, i - 1, c)\n    yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]\n    # \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(vector<int> &wgt, vector<int> &val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes);\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(int[] wgt, int[] val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint KnapsackDFS(int[] weight, int[] val, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (weight[i - 1] > c) {\n        return KnapsackDFS(weight, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = KnapsackDFS(weight, val, i - 1, c);\n    int yes = KnapsackDFS(weight, val, i - 1, c - weight[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.Max(no, yes);\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc knapsackDFS(wgt, val []int, i, c int) int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i-1] > c {\n        return knapsackDFS(wgt, val, i-1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no := knapsackDFS(wgt, val, i-1, c)\n    yes := knapsackDFS(wgt, val, i-1, c-wgt[i-1]) + val[i-1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return int(math.Max(float64(no), float64(yes)))\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunc knapsackDFS(wgt: [Int], val: [Int], i: Int, c: Int) -> Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c {\n        return knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c)\n    let yes = knapsackDFS(wgt: wgt, val: val, i: i - 1, c: c - wgt[i - 1]) + val[i - 1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction knapsackDFS(wgt, val, i, c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFS(wgt, val, i - 1, c);\n    const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfunction knapsackDFS(\n    wgt: Array<number>,\n    val: Array<number>,\n    i: number,\n    c: number\n): number {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFS(wgt, val, i - 1, c);\n    const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return Math.max(no, yes);\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(List<int> wgt, List<int> val, int i, int c) {\n  // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n  if (i == 0 || c == 0) {\n    return 0;\n  }\n  // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n  if (wgt[i - 1] > c) {\n    return knapsackDFS(wgt, val, i - 1, c);\n  }\n  // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n  int no = knapsackDFS(wgt, val, i - 1, c);\n  int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n  // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n  return max(no, yes);\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfn knapsack_dfs(wgt: &[i32], val: &[i32], i: usize, c: usize) -> i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c as i32 {\n        return knapsack_dfs(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsack_dfs(wgt, val, i - 1, c);\n    let yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1] as usize) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    std::cmp::max(no, yes)\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nint knapsackDFS(int wgt[], int val[], int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFS(wgt, val, i - 1, c);\n    int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return myMax(no, yes);\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22 */\nfun knapsackDFS(\n    wgt: IntArray,\n    _val: IntArray,\n    i: Int,\n    c: Int\n): Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, _val, i - 1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    val no = knapsackDFS(wgt, _val, i - 1, c)\n    val yes = knapsackDFS(wgt, _val, i - 1, c - wgt[i - 1]) + _val[i - 1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return max(no, yes)\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dfs}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u66b4\u529b\u641c\u7d22\nfn knapsackDFS(wgt: []i32, val: []i32, i: usize, c: usize) i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 or c == 0) {\n        return 0;\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFS(wgt, val, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    var no = knapsackDFS(wgt, val, i - 1, c);\n    var yes = knapsackDFS(wgt, val, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1];\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    return @max(no, yes);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-18 \u6240\u793a\uff0c\u7531\u4e8e\u6bcf\u4e2a\u7269\u54c1\u90fd\u4f1a\u4ea7\u751f\u4e0d\u9009\u548c\u9009\u4e24\u6761\u641c\u7d22\u5206\u652f\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(2^n)\\) \u3002

    \u89c2\u5bdf\u9012\u5f52\u6811\uff0c\u5bb9\u6613\u53d1\u73b0\u5176\u4e2d\u5b58\u5728\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u4f8b\u5982 \\(dp[1, 10]\\) \u7b49\u3002\u800c\u5f53\u7269\u54c1\u8f83\u591a\u3001\u80cc\u5305\u5bb9\u91cf\u8f83\u5927\uff0c\u5c24\u5176\u662f\u76f8\u540c\u91cd\u91cf\u7684\u7269\u54c1\u8f83\u591a\u65f6\uff0c\u91cd\u53e0\u5b50\u95ee\u9898\u7684\u6570\u91cf\u5c06\u4f1a\u5927\u5e45\u589e\u591a\u3002

    \u56fe 14-18 \u00a0 0-1 \u80cc\u5305\u95ee\u9898\u7684\u66b4\u529b\u641c\u7d22\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#2","title":"2. \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22","text":"

    \u4e3a\u4e86\u4fdd\u8bc1\u91cd\u53e0\u5b50\u95ee\u9898\u53ea\u88ab\u8ba1\u7b97\u4e00\u6b21\uff0c\u6211\u4eec\u501f\u52a9\u8bb0\u5fc6\u5217\u8868 mem \u6765\u8bb0\u5f55\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u5176\u4e2d mem[i][c] \u5bf9\u5e94 \\(dp[i, c]\\) \u3002

    \u5f15\u5165\u8bb0\u5fc6\u5316\u4e4b\u540e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5b50\u95ee\u9898\u6570\u91cf\uff0c\u4e5f\u5c31\u662f \\(O(n \\times cap)\\) \u3002\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dfs_mem(\n    wgt: list[int], val: list[int], mem: list[list[int]], i: int, c: int\n) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\"\"\"\n    # \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 or c == 0:\n        return 0\n    # \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1:\n        return mem[i][c]\n    # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c:\n        return knapsack_dfs_mem(wgt, val, mem, i - 1, c)\n    # \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no = knapsack_dfs_mem(wgt, val, mem, i - 1, c)\n    yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1]\n    # \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(vector<int> &wgt, vector<int> &val, vector<vector<int>> &mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(int[] wgt, int[] val, int[][] mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint KnapsackDFSMem(int[] weight, int[] val, int[][] mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (weight[i - 1] > c) {\n        return KnapsackDFSMem(weight, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = KnapsackDFSMem(weight, val, mem, i - 1, c);\n    int yes = KnapsackDFSMem(weight, val, mem, i - 1, c - weight[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.Max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc knapsackDFSMem(wgt, val []int, mem [][]int, i, c int) int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i-1] > c {\n        return knapsackDFSMem(wgt, val, mem, i-1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    no := knapsackDFSMem(wgt, val, mem, i-1, c)\n    yes := knapsackDFSMem(wgt, val, mem, i-1, c-wgt[i-1]) + val[i-1]\n    // \u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = int(math.Max(float64(no), float64(yes)))\n    return mem[i][c]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunc knapsackDFSMem(wgt: [Int], val: [Int], mem: inout [[Int]], i: Int, c: Int) -> Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c {\n        return knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c)\n    let yes = knapsackDFSMem(wgt: wgt, val: val, mem: &mem, i: i - 1, c: c - wgt[i - 1]) + val[i - 1]\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction knapsackDFSMem(wgt, val, mem, i, c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] !== -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    const yes =\n        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfunction knapsackDFSMem(\n    wgt: Array<number>,\n    val: Array<number>,\n    mem: Array<Array<number>>,\n    i: number,\n    c: number\n): number {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i === 0 || c === 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] !== -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    const yes =\n        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = Math.max(no, yes);\n    return mem[i][c];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(\n  List<int> wgt,\n  List<int> val,\n  List<List<int>> mem,\n  int i,\n  int c,\n) {\n  // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n  if (i == 0 || c == 0) {\n    return 0;\n  }\n  // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  if (mem[i][c] != -1) {\n    return mem[i][c];\n  }\n  // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n  if (wgt[i - 1] > c) {\n    return knapsackDFSMem(wgt, val, mem, i - 1, c);\n  }\n  // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n  int no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n  int yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n  // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n  mem[i][c] = max(no, yes);\n  return mem[i][c];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfn knapsack_dfs_mem(wgt: &[i32], val: &[i32], mem: &mut Vec<Vec<i32>>, i: usize, c: usize) -> i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if i == 0 || c == 0 {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if mem[i][c] != -1 {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if wgt[i - 1] > c as i32 {\n        return knapsack_dfs_mem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    let no = knapsack_dfs_mem(wgt, val, mem, i - 1, c);\n    let yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1] as usize) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = std::cmp::max(no, yes);\n    mem[i][c]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nint knapsackDFSMem(int wgt[], int val[], int memCols, int **mem, int i, int c) {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, memCols, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    int no = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c);\n    int yes = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c - wgt[i - 1]) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = myMax(no, yes);\n    return mem[i][c];\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22 */\nfun knapsackDFSMem(\n    wgt: IntArray,\n    _val: IntArray,\n    mem: Array<IntArray>,\n    i: Int,\n    c: Int\n): Int {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 || c == 0) {\n        return 0\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c]\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, _val, mem, i - 1, c)\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    val no = knapsackDFSMem(wgt, _val, mem, i - 1, c)\n    val yes = knapsackDFSMem(wgt, _val, mem, i - 1, c - wgt[i - 1]) + _val[i - 1]\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = max(no, yes)\n    return mem[i][c]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dfs_mem}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u8bb0\u5fc6\u5316\u641c\u7d22\nfn knapsackDFSMem(wgt: []i32, val: []i32, mem: anytype, i: usize, c: usize) i32 {\n    // \u82e5\u5df2\u9009\u5b8c\u6240\u6709\u7269\u54c1\u6216\u80cc\u5305\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u5219\u8fd4\u56de\u4ef7\u503c 0\n    if (i == 0 or c == 0) {\n        return 0;\n    }\n    // \u82e5\u5df2\u6709\u8bb0\u5f55\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (mem[i][c] != -1) {\n        return mem[i][c];\n    }\n    // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u53ea\u80fd\u9009\u62e9\u4e0d\u653e\u5165\u80cc\u5305\n    if (wgt[i - 1] > c) {\n        return knapsackDFSMem(wgt, val, mem, i - 1, c);\n    }\n    // \u8ba1\u7b97\u4e0d\u653e\u5165\u548c\u653e\u5165\u7269\u54c1 i \u7684\u6700\u5927\u4ef7\u503c\n    var no = knapsackDFSMem(wgt, val, mem, i - 1, c);\n    var yes = knapsackDFSMem(wgt, val, mem, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1];\n    // \u8bb0\u5f55\u5e76\u8fd4\u56de\u4e24\u79cd\u65b9\u6848\u4e2d\u4ef7\u503c\u66f4\u5927\u7684\u90a3\u4e00\u4e2a\n    mem[i][c] = @max(no, yes);\n    return mem[i][c];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-19 \u5c55\u793a\u4e86\u5728\u8bb0\u5fc6\u5316\u641c\u7d22\u4e2d\u88ab\u526a\u6389\u7684\u641c\u7d22\u5206\u652f\u3002

    \u56fe 14-19 \u00a0 0-1 \u80cc\u5305\u95ee\u9898\u7684\u8bb0\u5fc6\u5316\u641c\u7d22\u9012\u5f52\u6811

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#3","title":"3. \u00a0 \u65b9\u6cd5\u4e09\uff1a\u52a8\u6001\u89c4\u5212","text":"

    \u52a8\u6001\u89c4\u5212\u5b9e\u8d28\u4e0a\u5c31\u662f\u5728\u72b6\u6001\u8f6c\u79fb\u4e2d\u586b\u5145 \\(dp\\) \u8868\u7684\u8fc7\u7a0b\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (cap + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1])\n    return dp[n][cap]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint KnapsackDP(int[] weight, int[] val, int cap) {\n    int n = weight.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (weight[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i, c] = dp[i - 1, c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i, c] = Math.Max(dp[i - 1, c - weight[i - 1]] + val[i - 1], dp[i - 1, c]);\n            }\n        }\n    }\n    return dp[n, cap];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDP(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, cap+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i-1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = int(math.Max(float64(dp[i-1][c]), float64(dp[i-1][c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDP(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(n + 1)\n        .fill(0)\n        .map(() => Array(cap + 1).fill(0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDP(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(cap + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[i][c] = dp[i - 1][c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[n][cap];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfn knapsack_dp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; cap + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = std::cmp::max(\n                    dp[i - 1][c],\n                    dp[i - 1][c - wgt[i - 1] as usize] + val[i - 1],\n                );\n            }\n        }\n    }\n    dp[n][cap]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint knapsackDP(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(cap + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = myMax(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[n][cap];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfun knapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(cap + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dp}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\nfn knapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = @max(dp[i - 1][c], dp[i - 1][c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 14-20 \u6240\u793a\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u90fd\u7531\u6570\u7ec4 dp \u5927\u5c0f\u51b3\u5b9a\uff0c\u5373 \\(O(n \\times cap)\\) \u3002

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14>

    \u56fe 14-20 \u00a0 0-1 \u80cc\u5305\u95ee\u9898\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/knapsack_problem/#4","title":"4. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e\u6bcf\u4e2a\u72b6\u6001\u90fd\u53ea\u4e0e\u5176\u4e0a\u4e00\u884c\u7684\u72b6\u6001\u6709\u5173\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e24\u4e2a\u6570\u7ec4\u6eda\u52a8\u524d\u8fdb\uff0c\u5c06\u7a7a\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n^2)\\) \u964d\u81f3 \\(O(n)\\) \u3002

    \u8fdb\u4e00\u6b65\u601d\u8003\uff0c\u6211\u4eec\u80fd\u5426\u4ec5\u7528\u4e00\u4e2a\u6570\u7ec4\u5b9e\u73b0\u7a7a\u95f4\u4f18\u5316\u5462\uff1f\u89c2\u5bdf\u53ef\u77e5\uff0c\u6bcf\u4e2a\u72b6\u6001\u90fd\u662f\u7531\u6b63\u4e0a\u65b9\u6216\u5de6\u4e0a\u65b9\u7684\u683c\u5b50\u8f6c\u79fb\u8fc7\u6765\u7684\u3002\u5047\u8bbe\u53ea\u6709\u4e00\u4e2a\u6570\u7ec4\uff0c\u5f53\u5f00\u59cb\u904d\u5386\u7b2c \\(i\\) \u884c\u65f6\uff0c\u8be5\u6570\u7ec4\u5b58\u50a8\u7684\u4ecd\u7136\u662f\u7b2c \\(i-1\\) \u884c\u7684\u72b6\u6001\u3002

    • \u5982\u679c\u91c7\u53d6\u6b63\u5e8f\u904d\u5386\uff0c\u90a3\u4e48\u904d\u5386\u5230 \\(dp[i, j]\\) \u65f6\uff0c\u5de6\u4e0a\u65b9 \\(dp[i-1, 1]\\) ~ \\(dp[i-1, j-1]\\) \u503c\u53ef\u80fd\u5df2\u7ecf\u88ab\u8986\u76d6\uff0c\u6b64\u65f6\u5c31\u65e0\u6cd5\u5f97\u5230\u6b63\u786e\u7684\u72b6\u6001\u8f6c\u79fb\u7ed3\u679c\u3002
    • \u5982\u679c\u91c7\u53d6\u5012\u5e8f\u904d\u5386\uff0c\u5219\u4e0d\u4f1a\u53d1\u751f\u8986\u76d6\u95ee\u9898\uff0c\u72b6\u6001\u8f6c\u79fb\u53ef\u4ee5\u6b63\u786e\u8fdb\u884c\u3002

    \u56fe 14-21 \u5c55\u793a\u4e86\u5728\u5355\u4e2a\u6570\u7ec4\u4e0b\u4ece\u7b2c \\(i = 1\\) \u884c\u8f6c\u6362\u81f3\u7b2c \\(i = 2\\) \u884c\u7684\u8fc7\u7a0b\u3002\u8bf7\u601d\u8003\u6b63\u5e8f\u904d\u5386\u548c\u5012\u5e8f\u904d\u5386\u7684\u533a\u522b\u3002

    <1><2><3><4><5><6>

    \u56fe 14-21 \u00a0 0-1 \u80cc\u5305\u7684\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u5728\u4ee3\u7801\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u4ec5\u9700\u5c06\u6570\u7ec4 dp \u7684\u7b2c\u4e00\u7ef4 \\(i\\) \u76f4\u63a5\u5220\u9664\uff0c\u5e76\u4e14\u628a\u5185\u5faa\u73af\u66f4\u6539\u4e3a\u5012\u5e8f\u904d\u5386\u5373\u53ef\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig knapsack.py
    def knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (cap + 1)\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u5012\u5e8f\u904d\u5386\n        for c in range(cap, 0, -1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n    return dp[cap]\n
    knapsack.cpp
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(cap + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.java
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.cs
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint KnapsackDPComp(int[] weight, int[] val, int cap) {\n    int n = weight.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c > 0; c--) {\n            if (weight[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.Max(dp[c], dp[c - weight[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.go
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDPComp(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, cap+1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u5012\u5e8f\u904d\u5386\n        for c := cap; c >= 1; c-- {\n            if wgt[i-1] <= c {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = int(math.Max(float64(dp[c]), float64(dp[c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.swift
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc knapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        // \u5012\u5e8f\u904d\u5386\n        for c in (1 ... cap).reversed() {\n            if wgt[i - 1] <= c {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.js
    /* 0-1 \u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDPComp(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(cap + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (let c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.ts
    /* 0-1 \u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction knapsackDPComp(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array(cap + 1).fill(0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (let c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    knapsack.dart
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(cap + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    // \u5012\u5e8f\u904d\u5386\n    for (int c = cap; c >= 1; c--) {\n      if (wgt[i - 1] <= c) {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[cap];\n}\n
    knapsack.rs
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn knapsack_dp_comp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        // \u5012\u5e8f\u904d\u5386\n        for c in (1..=cap).rev() {\n            if wgt[i - 1] <= c as i32 {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = std::cmp::max(dp[c], dp[c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    dp[cap]\n}\n
    knapsack.c
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint knapsackDPComp(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(cap + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        // \u5012\u5e8f\u904d\u5386\n        for (int c = cap; c >= 1; c--) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = myMax(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[cap];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    knapsack.kt
    /* 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun knapsackDPComp(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        // \u5012\u5e8f\u904d\u5386\n        for (c in cap downTo 1) {\n            if (wgt[i - 1] <= c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    knapsack.rb
    [class]{}-[func]{knapsack_dp_comp}\n
    knapsack.zig
    // 0-1 \u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn knapsackDPComp(wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (cap + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        // \u5012\u5e8f\u904d\u5386\n        var c = cap;\n        while (c > 0) : (c -= 1) {\n            if (wgt[i - 1] < c) {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = @max(dp[c], dp[c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/summary/","title":"14.7 \u00a0 \u5c0f\u7ed3","text":"
    • \u52a8\u6001\u89c4\u5212\u5bf9\u95ee\u9898\u8fdb\u884c\u5206\u89e3\uff0c\u5e76\u901a\u8fc7\u5b58\u50a8\u5b50\u95ee\u9898\u7684\u89e3\u6765\u89c4\u907f\u91cd\u590d\u8ba1\u7b97\uff0c\u63d0\u9ad8\u8ba1\u7b97\u6548\u7387\u3002
    • \u4e0d\u8003\u8651\u65f6\u95f4\u7684\u524d\u63d0\u4e0b\uff0c\u6240\u6709\u52a8\u6001\u89c4\u5212\u95ee\u9898\u90fd\u53ef\u4ee5\u7528\u56de\u6eaf\uff08\u66b4\u529b\u641c\u7d22\uff09\u8fdb\u884c\u6c42\u89e3\uff0c\u4f46\u9012\u5f52\u6811\u4e2d\u5b58\u5728\u5927\u91cf\u7684\u91cd\u53e0\u5b50\u95ee\u9898\uff0c\u6548\u7387\u6781\u4f4e\u3002\u901a\u8fc7\u5f15\u5165\u8bb0\u5fc6\u5316\u5217\u8868\uff0c\u53ef\u4ee5\u5b58\u50a8\u6240\u6709\u8ba1\u7b97\u8fc7\u7684\u5b50\u95ee\u9898\u7684\u89e3\uff0c\u4ece\u800c\u4fdd\u8bc1\u91cd\u53e0\u5b50\u95ee\u9898\u53ea\u88ab\u8ba1\u7b97\u4e00\u6b21\u3002
    • \u8bb0\u5fc6\u5316\u641c\u7d22\u662f\u4e00\u79cd\u4ece\u9876\u81f3\u5e95\u7684\u9012\u5f52\u5f0f\u89e3\u6cd5\uff0c\u800c\u4e0e\u4e4b\u5bf9\u5e94\u7684\u52a8\u6001\u89c4\u5212\u662f\u4e00\u79cd\u4ece\u5e95\u81f3\u9876\u7684\u9012\u63a8\u5f0f\u89e3\u6cd5\uff0c\u5176\u5982\u540c\u201c\u586b\u5199\u8868\u683c\u201d\u4e00\u6837\u3002\u7531\u4e8e\u5f53\u524d\u72b6\u6001\u4ec5\u4f9d\u8d56\u67d0\u4e9b\u5c40\u90e8\u72b6\u6001\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u6d88\u9664 \\(dp\\) \u8868\u7684\u4e00\u4e2a\u7ef4\u5ea6\uff0c\u4ece\u800c\u964d\u4f4e\u7a7a\u95f4\u590d\u6742\u5ea6\u3002
    • \u5b50\u95ee\u9898\u5206\u89e3\u662f\u4e00\u79cd\u901a\u7528\u7684\u7b97\u6cd5\u601d\u8def\uff0c\u5728\u5206\u6cbb\u3001\u52a8\u6001\u89c4\u5212\u3001\u56de\u6eaf\u4e2d\u5177\u6709\u4e0d\u540c\u7684\u6027\u8d28\u3002
    • \u52a8\u6001\u89c4\u5212\u95ee\u9898\u6709\u4e09\u5927\u7279\u6027\uff1a\u91cd\u53e0\u5b50\u95ee\u9898\u3001\u6700\u4f18\u5b50\u7ed3\u6784\u3001\u65e0\u540e\u6548\u6027\u3002
    • \u5982\u679c\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u53ef\u4ee5\u4ece\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u6784\u5efa\u5f97\u6765\uff0c\u5219\u5b83\u5c31\u5177\u6709\u6700\u4f18\u5b50\u7ed3\u6784\u3002
    • \u65e0\u540e\u6548\u6027\u6307\u5bf9\u4e8e\u4e00\u4e2a\u72b6\u6001\uff0c\u5176\u672a\u6765\u53d1\u5c55\u53ea\u4e0e\u8be5\u72b6\u6001\u6709\u5173\uff0c\u800c\u4e0e\u8fc7\u53bb\u7ecf\u5386\u7684\u6240\u6709\u72b6\u6001\u65e0\u5173\u3002\u8bb8\u591a\u7ec4\u5408\u4f18\u5316\u95ee\u9898\u4e0d\u5177\u6709\u65e0\u540e\u6548\u6027\uff0c\u65e0\u6cd5\u4f7f\u7528\u52a8\u6001\u89c4\u5212\u5feb\u901f\u6c42\u89e3\u3002

    \u80cc\u5305\u95ee\u9898

    • \u80cc\u5305\u95ee\u9898\u662f\u6700\u5178\u578b\u7684\u52a8\u6001\u89c4\u5212\u95ee\u9898\u4e4b\u4e00\uff0c\u5177\u6709 0-1 \u80cc\u5305\u3001\u5b8c\u5168\u80cc\u5305\u3001\u591a\u91cd\u80cc\u5305\u7b49\u53d8\u79cd\u3002
    • 0-1 \u80cc\u5305\u7684\u72b6\u6001\u5b9a\u4e49\u4e3a\u524d \\(i\\) \u4e2a\u7269\u54c1\u5728\u5bb9\u91cf\u4e3a \\(c\\) \u7684\u80cc\u5305\u4e2d\u7684\u6700\u5927\u4ef7\u503c\u3002\u6839\u636e\u4e0d\u653e\u5165\u80cc\u5305\u548c\u653e\u5165\u80cc\u5305\u4e24\u79cd\u51b3\u7b56\uff0c\u53ef\u5f97\u5230\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u5e76\u6784\u5efa\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002\u5728\u7a7a\u95f4\u4f18\u5316\u4e2d\uff0c\u7531\u4e8e\u6bcf\u4e2a\u72b6\u6001\u4f9d\u8d56\u6b63\u4e0a\u65b9\u548c\u5de6\u4e0a\u65b9\u7684\u72b6\u6001\uff0c\u56e0\u6b64\u9700\u8981\u5012\u5e8f\u904d\u5386\u5217\u8868\uff0c\u907f\u514d\u5de6\u4e0a\u65b9\u72b6\u6001\u88ab\u8986\u76d6\u3002
    • \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u6bcf\u79cd\u7269\u54c1\u7684\u9009\u53d6\u6570\u91cf\u65e0\u9650\u5236\uff0c\u56e0\u6b64\u9009\u62e9\u653e\u5165\u7269\u54c1\u7684\u72b6\u6001\u8f6c\u79fb\u4e0e 0-1 \u80cc\u5305\u95ee\u9898\u4e0d\u540c\u3002\u7531\u4e8e\u72b6\u6001\u4f9d\u8d56\u6b63\u4e0a\u65b9\u548c\u6b63\u5de6\u65b9\u7684\u72b6\u6001\uff0c\u56e0\u6b64\u5728\u7a7a\u95f4\u4f18\u5316\u4e2d\u5e94\u5f53\u6b63\u5e8f\u904d\u5386\u3002
    • \u96f6\u94b1\u5151\u6362\u95ee\u9898\u662f\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u4e00\u4e2a\u53d8\u79cd\u3002\u5b83\u4ece\u6c42\u201c\u6700\u5927\u201d\u4ef7\u503c\u53d8\u4e3a\u6c42\u201c\u6700\u5c0f\u201d\u786c\u5e01\u6570\u91cf\uff0c\u56e0\u6b64\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e2d\u7684 \\(\\max()\\) \u5e94\u6539\u4e3a \\(\\min()\\) \u3002\u4ece\u8ffd\u6c42\u201c\u4e0d\u8d85\u8fc7\u201d\u80cc\u5305\u5bb9\u91cf\u5230\u8ffd\u6c42\u201c\u6070\u597d\u201d\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u56e0\u6b64\u4f7f\u7528 \\(amt + 1\\) \u6765\u8868\u793a\u201c\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u201d\u7684\u65e0\u6548\u89e3\u3002
    • \u96f6\u94b1\u5151\u6362\u95ee\u9898 II \u4ece\u6c42\u201c\u6700\u5c11\u786c\u5e01\u6570\u91cf\u201d\u6539\u4e3a\u6c42\u201c\u786c\u5e01\u7ec4\u5408\u6570\u91cf\u201d\uff0c\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u76f8\u5e94\u5730\u4ece \\(\\min()\\) \u6539\u4e3a\u6c42\u548c\u8fd0\u7b97\u7b26\u3002

    \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898

    • \u7f16\u8f91\u8ddd\u79bb\uff08Levenshtein \u8ddd\u79bb\uff09\u7528\u4e8e\u8861\u91cf\u4e24\u4e2a\u5b57\u7b26\u4e32\u4e4b\u95f4\u7684\u76f8\u4f3c\u5ea6\uff0c\u5176\u5b9a\u4e49\u4e3a\u4ece\u4e00\u4e2a\u5b57\u7b26\u4e32\u5230\u53e6\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\uff0c\u7f16\u8f91\u64cd\u4f5c\u5305\u62ec\u6dfb\u52a0\u3001\u5220\u9664\u3001\u66ff\u6362\u3002
    • \u7f16\u8f91\u8ddd\u79bb\u95ee\u9898\u7684\u72b6\u6001\u5b9a\u4e49\u4e3a\u5c06 \\(s\\) \u7684\u524d \\(i\\) \u4e2a\u5b57\u7b26\u66f4\u6539\u4e3a \\(t\\) \u7684\u524d \\(j\\) \u4e2a\u5b57\u7b26\u6240\u9700\u7684\u6700\u5c11\u7f16\u8f91\u6b65\u6570\u3002\u5f53 \\(s[i] \\ne t[j]\\) \u65f6\uff0c\u5177\u6709\u4e09\u79cd\u51b3\u7b56\uff1a\u6dfb\u52a0\u3001\u5220\u9664\u3001\u66ff\u6362\uff0c\u5b83\u4eec\u90fd\u6709\u76f8\u5e94\u7684\u5269\u4f59\u5b50\u95ee\u9898\u3002\u636e\u6b64\u4fbf\u53ef\u4ee5\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\u4e0e\u6784\u5efa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u3002\u800c\u5f53 \\(s[i] = t[j]\\) \u65f6\uff0c\u65e0\u987b\u7f16\u8f91\u5f53\u524d\u5b57\u7b26\u3002
    • \u5728\u7f16\u8f91\u8ddd\u79bb\u4e2d\uff0c\u72b6\u6001\u4f9d\u8d56\u5176\u6b63\u4e0a\u65b9\u3001\u6b63\u5de6\u65b9\u3001\u5de6\u4e0a\u65b9\u7684\u72b6\u6001\uff0c\u56e0\u6b64\u7a7a\u95f4\u4f18\u5316\u540e\u6b63\u5e8f\u6216\u5012\u5e8f\u904d\u5386\u90fd\u65e0\u6cd5\u6b63\u786e\u5730\u8fdb\u884c\u72b6\u6001\u8f6c\u79fb\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u5229\u7528\u4e00\u4e2a\u53d8\u91cf\u6682\u5b58\u5de6\u4e0a\u65b9\u72b6\u6001\uff0c\u4ece\u800c\u8f6c\u5316\u5230\u4e0e\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7b49\u4ef7\u7684\u60c5\u51b5\uff0c\u53ef\u4ee5\u5728\u7a7a\u95f4\u4f18\u5316\u540e\u8fdb\u884c\u6b63\u5e8f\u904d\u5386\u3002
    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/","title":"14.5 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898","text":"

    \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5148\u6c42\u89e3\u53e6\u4e00\u4e2a\u5e38\u89c1\u7684\u80cc\u5305\u95ee\u9898\uff1a\u5b8c\u5168\u80cc\u5305\uff0c\u518d\u4e86\u89e3\u5b83\u7684\u4e00\u79cd\u7279\u4f8b\uff1a\u96f6\u94b1\u5151\u6362\u3002

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1451","title":"14.5.1 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a \\(n\\) \u4e2a\u7269\u54c1\uff0c\u7b2c \\(i\\) \u4e2a\u7269\u54c1\u7684\u91cd\u91cf\u4e3a \\(wgt[i-1]\\)\u3001\u4ef7\u503c\u4e3a \\(val[i-1]\\) \uff0c\u548c\u4e00\u4e2a\u5bb9\u91cf\u4e3a \\(cap\\) \u7684\u80cc\u5305\u3002\u6bcf\u4e2a\u7269\u54c1\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80fd\u653e\u5165\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u3002\u793a\u4f8b\u5982\u56fe 14-22 \u6240\u793a\u3002

    \u56fe 14-22 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u548c 0-1 \u80cc\u5305\u95ee\u9898\u975e\u5e38\u76f8\u4f3c\uff0c\u533a\u522b\u4ec5\u5728\u4e8e\u4e0d\u9650\u5236\u7269\u54c1\u7684\u9009\u62e9\u6b21\u6570\u3002

    • \u5728 0-1 \u80cc\u5305\u95ee\u9898\u4e2d\uff0c\u6bcf\u79cd\u7269\u54c1\u53ea\u6709\u4e00\u4e2a\uff0c\u56e0\u6b64\u5c06\u7269\u54c1 \\(i\\) \u653e\u5165\u80cc\u5305\u540e\uff0c\u53ea\u80fd\u4ece\u524d \\(i-1\\) \u4e2a\u7269\u54c1\u4e2d\u9009\u62e9\u3002
    • \u5728\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u4e2d\uff0c\u6bcf\u79cd\u7269\u54c1\u7684\u6570\u91cf\u662f\u65e0\u9650\u7684\uff0c\u56e0\u6b64\u5c06\u7269\u54c1 \\(i\\) \u653e\u5165\u80cc\u5305\u540e\uff0c\u4ecd\u53ef\u4ee5\u4ece\u524d \\(i\\) \u4e2a\u7269\u54c1\u4e2d\u9009\u62e9\u3002

    \u5728\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u89c4\u5b9a\u4e0b\uff0c\u72b6\u6001 \\([i, c]\\) \u7684\u53d8\u5316\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\u3002

    • \u4e0d\u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u4e0e 0-1 \u80cc\u5305\u95ee\u9898\u76f8\u540c\uff0c\u8f6c\u79fb\u81f3 \\([i-1, c]\\) \u3002
    • \u653e\u5165\u7269\u54c1 \\(i\\) \uff1a\u4e0e 0-1 \u80cc\u5305\u95ee\u9898\u4e0d\u540c\uff0c\u8f6c\u79fb\u81f3 \\([i, c-wgt[i-1]]\\) \u3002

    \u4ece\u800c\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u53d8\u4e3a\uff1a

    \\[ dp[i, c] = \\max(dp[i-1, c], dp[i, c - wgt[i-1]] + val[i-1]) \\]"},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5bf9\u6bd4\u4e24\u9053\u9898\u76ee\u7684\u4ee3\u7801\uff0c\u72b6\u6001\u8f6c\u79fb\u4e2d\u6709\u4e00\u5904\u4ece \\(i-1\\) \u53d8\u4e3a \\(i\\) \uff0c\u5176\u4f59\u5b8c\u5168\u4e00\u81f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig unbounded_knapsack.py
    def unbounded_knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (cap + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1])\n    return dp[n][cap]\n
    unbounded_knapsack.cpp
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.java
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.cs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint UnboundedKnapsackDP(int[] wgt, int[] val, int cap) {\n    int n = wgt.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i, c] = dp[i - 1, c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i, c] = Math.Max(dp[i - 1, c], dp[i, c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n, cap];\n}\n
    unbounded_knapsack.go
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDP(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, cap+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i-1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = int(math.Max(float64(dp[i-1][c]), float64(dp[i][c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.swift
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.js
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDP(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.ts
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDP(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: cap + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = Math.max(\n                    dp[i - 1][c],\n                    dp[i][c - wgt[i - 1]] + val[i - 1]\n                );\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.dart
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(cap + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[i][c] = dp[i - 1][c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[n][cap];\n}\n
    unbounded_knapsack.rs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfn unbounded_knapsack_dp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; cap + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = std::cmp::max(dp[i - 1][c], dp[i][c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    unbounded_knapsack.c
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDP(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(cap + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = myMax(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[n][cap];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    return res;\n}\n
    unbounded_knapsack.kt
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212 */\nfun unboundedKnapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(cap + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[n][cap]\n}\n
    unbounded_knapsack.rb
    [class]{}-[func]{unbounded_knapsack_dp}\n
    unbounded_knapsack.zig
    // \u5b8c\u5168\u80cc\u5305\uff1a\u52a8\u6001\u89c4\u5212\nfn unboundedKnapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[i][c] = dp[i - 1][c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[i][c] = @max(dp[i - 1][c], dp[i][c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[n][cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7531\u4e8e\u5f53\u524d\u72b6\u6001\u662f\u4ece\u5de6\u8fb9\u548c\u4e0a\u8fb9\u7684\u72b6\u6001\u8f6c\u79fb\u800c\u6765\u7684\uff0c\u56e0\u6b64\u7a7a\u95f4\u4f18\u5316\u540e\u5e94\u8be5\u5bf9 \\(dp\\) \u8868\u4e2d\u7684\u6bcf\u4e00\u884c\u8fdb\u884c\u6b63\u5e8f\u904d\u5386\u3002

    \u8fd9\u4e2a\u904d\u5386\u987a\u5e8f\u4e0e 0-1 \u80cc\u5305\u6b63\u597d\u76f8\u53cd\u3002\u8bf7\u501f\u52a9\u56fe 14-23 \u6765\u7406\u89e3\u4e24\u8005\u7684\u533a\u522b\u3002

    <1><2><3><4><5><6>

    \u56fe 14-23 \u00a0 \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u5728\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    \u4ee3\u7801\u5b9e\u73b0\u6bd4\u8f83\u7b80\u5355\uff0c\u4ec5\u9700\u5c06\u6570\u7ec4 dp \u7684\u7b2c\u4e00\u7ef4\u5220\u9664\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig unbounded_knapsack.py
    def unbounded_knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(wgt)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (cap + 1)\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for c in range(1, cap + 1):\n            if wgt[i - 1] > c:\n                # \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n    return dp[cap]\n
    unbounded_knapsack.cpp
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(vector<int> &wgt, vector<int> &val, int cap) {\n    int n = wgt.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(cap + 1, 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.java
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.cs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint UnboundedKnapsackDPComp(int[] wgt, int[] val, int cap) {\n    int n = wgt.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.Max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.go
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDPComp(wgt, val []int, cap int) int {\n    n := len(wgt)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, cap+1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        for c := 1; c <= cap; c++ {\n            if wgt[i-1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = int(math.Max(float64(dp[c]), float64(dp[c-wgt[i-1]]+val[i-1])))\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.swift
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc unboundedKnapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {\n    let n = wgt.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for c in 1 ... cap {\n            if wgt[i - 1] > c {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.js
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDPComp(wgt, val, cap) {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: cap + 1 }, () => 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.ts
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction unboundedKnapsackDPComp(\n    wgt: Array<number>,\n    val: Array<number>,\n    cap: number\n): number {\n    const n = wgt.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: cap + 1 }, () => 0);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    unbounded_knapsack.dart
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(List<int> wgt, List<int> val, int cap) {\n  int n = wgt.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(cap + 1, 0);\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int c = 1; c <= cap; c++) {\n      if (wgt[i - 1] > c) {\n        // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n        dp[c] = dp[c];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n        dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n      }\n    }\n  }\n  return dp[cap];\n}\n
    unbounded_knapsack.rs
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn unbounded_knapsack_dp_comp(wgt: &[i32], val: &[i32], cap: usize) -> i32 {\n    let n = wgt.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; cap + 1];\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for c in 1..=cap {\n            if wgt[i - 1] > c as i32 {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = std::cmp::max(dp[c], dp[c - wgt[i - 1] as usize] + val[i - 1]);\n            }\n        }\n    }\n    dp[cap]\n}\n
    unbounded_knapsack.c
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint unboundedKnapsackDPComp(int wgt[], int val[], int cap, int wgtSize) {\n    int n = wgtSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(cap + 1, sizeof(int));\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int c = 1; c <= cap; c++) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = myMax(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);\n            }\n        }\n    }\n    int res = dp[cap];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    unbounded_knapsack.kt
    /* \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun unboundedKnapsackDPComp(\n    wgt: IntArray,\n    _val: IntArray,\n    cap: Int\n): Int {\n    val n = wgt.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(cap + 1)\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (c in 1..cap) {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])\n            }\n        }\n    }\n    return dp[cap]\n}\n
    unbounded_knapsack.rb
    [class]{}-[func]{unbounded_knapsack_dp_comp}\n
    unbounded_knapsack.zig
    // \u5b8c\u5168\u80cc\u5305\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn unboundedKnapsackDPComp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 {\n    comptime var n = wgt.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (cap + 1);\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..cap + 1) |c| {\n            if (wgt[i - 1] > c) {\n                // \u82e5\u8d85\u8fc7\u80cc\u5305\u5bb9\u91cf\uff0c\u5219\u4e0d\u9009\u7269\u54c1 i\n                dp[c] = dp[c];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u7269\u54c1 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5927\u503c\n                dp[c] = @max(dp[c], dp[c - @as(usize, @intCast(wgt[i - 1]))] + val[i - 1]);\n            }\n        }\n    }\n    return dp[cap];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1452","title":"14.5.2 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898","text":"

    \u80cc\u5305\u95ee\u9898\u662f\u4e00\u5927\u7c7b\u52a8\u6001\u89c4\u5212\u95ee\u9898\u7684\u4ee3\u8868\uff0c\u5176\u62e5\u6709\u5f88\u591a\u53d8\u79cd\uff0c\u4f8b\u5982\u96f6\u94b1\u5151\u6362\u95ee\u9898\u3002

    Question

    \u7ed9\u5b9a \\(n\\) \u79cd\u786c\u5e01\uff0c\u7b2c \\(i\\) \u79cd\u786c\u5e01\u7684\u9762\u503c\u4e3a \\(coins[i - 1]\\) \uff0c\u76ee\u6807\u91d1\u989d\u4e3a \\(amt\\) \uff0c\u6bcf\u79cd\u786c\u5e01\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u80fd\u591f\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\u3002\u5982\u679c\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002\u793a\u4f8b\u5982\u56fe 14-24 \u6240\u793a\u3002

    \u56fe 14-24 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1_1","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u96f6\u94b1\u5151\u6362\u53ef\u4ee5\u770b\u4f5c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u4e00\u79cd\u7279\u6b8a\u60c5\u51b5\uff0c\u4e24\u8005\u5177\u6709\u4ee5\u4e0b\u8054\u7cfb\u4e0e\u4e0d\u540c\u70b9\u3002

    • \u4e24\u9053\u9898\u53ef\u4ee5\u76f8\u4e92\u8f6c\u6362\uff0c\u201c\u7269\u54c1\u201d\u5bf9\u5e94\u201c\u786c\u5e01\u201d\u3001\u201c\u7269\u54c1\u91cd\u91cf\u201d\u5bf9\u5e94\u201c\u786c\u5e01\u9762\u503c\u201d\u3001\u201c\u80cc\u5305\u5bb9\u91cf\u201d\u5bf9\u5e94\u201c\u76ee\u6807\u91d1\u989d\u201d\u3002
    • \u4f18\u5316\u76ee\u6807\u76f8\u53cd\uff0c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u662f\u8981\u6700\u5927\u5316\u7269\u54c1\u4ef7\u503c\uff0c\u96f6\u94b1\u5151\u6362\u95ee\u9898\u662f\u8981\u6700\u5c0f\u5316\u786c\u5e01\u6570\u91cf\u3002
    • \u5b8c\u5168\u80cc\u5305\u95ee\u9898\u662f\u6c42\u201c\u4e0d\u8d85\u8fc7\u201d\u80cc\u5305\u5bb9\u91cf\u4e0b\u7684\u89e3\uff0c\u96f6\u94b1\u5151\u6362\u662f\u6c42\u201c\u6070\u597d\u201d\u51d1\u5230\u76ee\u6807\u91d1\u989d\u7684\u89e3\u3002

    \u7b2c\u4e00\u6b65\uff1a\u601d\u8003\u6bcf\u8f6e\u7684\u51b3\u7b56\uff0c\u5b9a\u4e49\u72b6\u6001\uff0c\u4ece\u800c\u5f97\u5230 \\(dp\\) \u8868

    \u72b6\u6001 \\([i, a]\\) \u5bf9\u5e94\u7684\u5b50\u95ee\u9898\u4e3a\uff1a\u524d \\(i\\) \u79cd\u786c\u5e01\u80fd\u591f\u51d1\u51fa\u91d1\u989d \\(a\\) \u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\uff0c\u8bb0\u4e3a \\(dp[i, a]\\) \u3002

    \u4e8c\u7ef4 \\(dp\\) \u8868\u7684\u5c3a\u5bf8\u4e3a \\((n+1) \\times (amt+1)\\) \u3002

    \u7b2c\u4e8c\u6b65\uff1a\u627e\u51fa\u6700\u4f18\u5b50\u7ed3\u6784\uff0c\u8fdb\u800c\u63a8\u5bfc\u51fa\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b

    \u672c\u9898\u4e0e\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u7684\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u5b58\u5728\u4ee5\u4e0b\u4e24\u70b9\u5dee\u5f02\u3002

    • \u672c\u9898\u8981\u6c42\u6700\u5c0f\u503c\uff0c\u56e0\u6b64\u9700\u5c06\u8fd0\u7b97\u7b26 \\(\\max()\\) \u66f4\u6539\u4e3a \\(\\min()\\) \u3002
    • \u4f18\u5316\u4e3b\u4f53\u662f\u786c\u5e01\u6570\u91cf\u800c\u975e\u5546\u54c1\u4ef7\u503c\uff0c\u56e0\u6b64\u5728\u9009\u4e2d\u786c\u5e01\u65f6\u6267\u884c \\(+1\\) \u5373\u53ef\u3002
    \\[ dp[i, a] = \\min(dp[i-1, a], dp[i, a - coins[i-1]] + 1) \\]

    \u7b2c\u4e09\u6b65\uff1a\u786e\u5b9a\u8fb9\u754c\u6761\u4ef6\u548c\u72b6\u6001\u8f6c\u79fb\u987a\u5e8f

    \u5f53\u76ee\u6807\u91d1\u989d\u4e3a \\(0\\) \u65f6\uff0c\u51d1\u51fa\u5b83\u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\u4e3a \\(0\\) \uff0c\u5373\u9996\u5217\u6240\u6709 \\(dp[i, 0]\\) \u90fd\u7b49\u4e8e \\(0\\) \u3002

    \u5f53\u65e0\u786c\u5e01\u65f6\uff0c\u65e0\u6cd5\u51d1\u51fa\u4efb\u610f \\(> 0\\) \u7684\u76ee\u6807\u91d1\u989d\uff0c\u5373\u662f\u65e0\u6548\u89e3\u3002\u4e3a\u4f7f\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e2d\u7684 \\(\\min()\\) \u51fd\u6570\u80fd\u591f\u8bc6\u522b\u5e76\u8fc7\u6ee4\u65e0\u6548\u89e3\uff0c\u6211\u4eec\u8003\u8651\u4f7f\u7528 \\(+ \\infty\\) \u6765\u8868\u793a\u5b83\u4eec\uff0c\u5373\u4ee4\u9996\u884c\u6240\u6709 \\(dp[0, a]\\) \u90fd\u7b49\u4e8e \\(+ \\infty\\) \u3002

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2_1","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5927\u591a\u6570\u7f16\u7a0b\u8bed\u8a00\u5e76\u672a\u63d0\u4f9b \\(+ \\infty\\) \u53d8\u91cf\uff0c\u53ea\u80fd\u4f7f\u7528\u6574\u578b int \u7684\u6700\u5927\u503c\u6765\u4ee3\u66ff\u3002\u800c\u8fd9\u53c8\u4f1a\u5bfc\u81f4\u5927\u6570\u8d8a\u754c\uff1a\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e2d\u7684 \\(+ 1\\) \u64cd\u4f5c\u53ef\u80fd\u53d1\u751f\u6ea2\u51fa\u3002

    \u4e3a\u6b64\uff0c\u6211\u4eec\u91c7\u7528\u6570\u5b57 \\(amt + 1\\) \u6765\u8868\u793a\u65e0\u6548\u89e3\uff0c\u56e0\u4e3a\u51d1\u51fa \\(amt\\) \u7684\u786c\u5e01\u6570\u91cf\u6700\u591a\u4e3a \\(amt\\) \u3002\u6700\u540e\u8fd4\u56de\u524d\uff0c\u5224\u65ad \\(dp[n, amt]\\) \u662f\u5426\u7b49\u4e8e \\(amt + 1\\) \uff0c\u82e5\u662f\u5219\u8fd4\u56de \\(-1\\) \uff0c\u4ee3\u8868\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change.py
    def coin_change_dp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    MAX = amt + 1\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (amt + 1) for _ in range(n + 1)]\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in range(1, amt + 1):\n        dp[0][a] = MAX\n    # \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in range(1, n + 1):\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n    return dp[n][amt] if dp[n][amt] != MAX else -1\n
    coin_change.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(vector<int> &coins, int amt) {\n    int n = coins.size();\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(amt + 1, 0));\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(int[] coins, int amt) {\n    int n = coins.length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][amt + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint CoinChangeDP(int[] coins, int amt) {\n    int n = coins.Length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, amt + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0, a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i, a] = dp[i - 1, a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i, a] = Math.Min(dp[i - 1, a], dp[i, a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n, amt] != MAX ? dp[n, amt] : -1;\n}\n
    coin_change.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDP(coins []int, amt int) int {\n    n := len(coins)\n    max := amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, amt+1)\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a := 1; a <= amt; a++ {\n        dp[0][a] = max\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i-1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = int(math.Min(float64(dp[i-1][a]), float64(dp[i][a-coins[i-1]]+1)))\n            }\n        }\n    }\n    if dp[n][amt] != max {\n        return dp[n][amt]\n    }\n    return -1\n}\n
    coin_change.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDP(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    let MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in 1 ... amt {\n        dp[0][a] = MAX\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return dp[n][amt] != MAX ? dp[n][amt] : -1\n}\n
    coin_change.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDP(coins, amt) {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] !== MAX ? dp[n][amt] : -1;\n}\n
    coin_change.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDP(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (let a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = Math.min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[n][amt] !== MAX ? dp[n][amt] : -1;\n}\n
    coin_change.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(List<int> coins, int amt) {\n  int n = coins.length;\n  int MAX = amt + 1;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(amt + 1, 0));\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n  for (int a = 1; a <= amt; a++) {\n    dp[0][a] = MAX;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[i][a] = dp[i - 1][a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n        dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n      }\n    }\n  }\n  return dp[n][amt] != MAX ? dp[n][amt] : -1;\n}\n
    coin_change.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfn coin_change_dp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    let max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; amt + 1]; n + 1];\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for a in 1..=amt {\n        dp[0][a] = max;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = std::cmp::min(dp[i - 1][a], dp[i][a - coins[i - 1] as usize] + 1);\n            }\n        }\n    }\n    if dp[n][amt] != max {\n        return dp[n][amt] as i32;\n    } else {\n        -1\n    }\n}\n
    coin_change.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeDP(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(amt + 1, sizeof(int));\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (int a = 1; a <= amt; a++) {\n        dp[0][a] = MAX;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = myMin(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    int res = dp[n][amt] != MAX ? dp[n][amt] : -1;\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    coin_change.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfun coinChangeDP(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    val MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(amt + 1) }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (a in 1..amt) {\n        dp[0][a] = MAX\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return if (dp[n][amt] != MAX) dp[n][amt] else -1\n}\n
    coin_change.rb
    [class]{}-[func]{coin_change_dp}\n
    coin_change.zig
    // \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212\nfn coinChangeDP(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    comptime var max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1);\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u9996\u884c\u9996\u5217\n    for (1..amt + 1) |a| {\n        dp[0][a] = max;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = @min(dp[i - 1][a], dp[i][a - @as(usize, @intCast(coins[i - 1]))] + 1);\n            }\n        }\n    }\n    if (dp[n][amt] != max) {\n        return @intCast(dp[n][amt]);\n    } else {\n        return -1;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 14-25 \u5c55\u793a\u4e86\u96f6\u94b1\u5151\u6362\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b\uff0c\u548c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u975e\u5e38\u76f8\u4f3c\u3002

    <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>

    \u56fe 14-25 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898\u7684\u52a8\u6001\u89c4\u5212\u8fc7\u7a0b

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3_1","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u96f6\u94b1\u5151\u6362\u7684\u7a7a\u95f4\u4f18\u5316\u7684\u5904\u7406\u65b9\u5f0f\u548c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u4e00\u81f4\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change.py
    def coin_change_dp_comp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    MAX = amt + 1\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [MAX] * (amt + 1)\n    dp[0] = 0\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n    return dp[amt] if dp[amt] != MAX else -1\n
    coin_change.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(vector<int> &coins, int amt) {\n    int n = coins.size();\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(amt + 1, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(int[] coins, int amt) {\n    int n = coins.length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    Arrays.fill(dp, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint CoinChangeDPComp(int[] coins, int amt) {\n    int n = coins.Length;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    Array.Fill(dp, MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.Min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDPComp(coins []int, amt int) int {\n    n := len(coins)\n    max := amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, amt+1)\n    for i := 1; i <= amt; i++ {\n        dp[i] = max\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u6b63\u5e8f\u904d\u5386\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = int(math.Min(float64(dp[a]), float64(dp[a-coins[i-1]]+1)))\n            }\n        }\n    }\n    if dp[amt] != max {\n        return dp[amt]\n    }\n    return -1\n}\n
    coin_change.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeDPComp(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    let MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: MAX, count: amt + 1)\n    dp[0] = 0\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return dp[amt] != MAX ? dp[amt] : -1\n}\n
    coin_change.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDPComp(coins, amt) {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] !== MAX ? dp[amt] : -1;\n}\n
    coin_change.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeDPComp(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    const MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => MAX);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = Math.min(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    return dp[amt] !== MAX ? dp[amt] : -1;\n}\n
    coin_change.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(List<int> coins, int amt) {\n  int n = coins.length;\n  int MAX = amt + 1;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(amt + 1, MAX);\n  dp[0] = 0;\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[a] = dp[a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n        dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1);\n      }\n    }\n  }\n  return dp[amt] != MAX ? dp[amt] : -1;\n}\n
    coin_change.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn coin_change_dp_comp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    let max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; amt + 1];\n    dp.fill(max);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = std::cmp::min(dp[a], dp[a - coins[i - 1] as usize] + 1);\n            }\n        }\n    }\n    if dp[amt] != max {\n        return dp[amt] as i32;\n    } else {\n        -1\n    }\n}\n
    coin_change.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeDPComp(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    int MAX = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = malloc((amt + 1) * sizeof(int));\n    for (int j = 1; j <= amt; j++) {\n        dp[j] = MAX;\n    } \n    dp[0] = 0;\n\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = myMin(dp[a], dp[a - coins[i - 1]] + 1);\n            }\n        }\n    }\n    int res = dp[amt] != MAX ? dp[amt] : -1;\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    coin_change.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun coinChangeDPComp(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    val MAX = amt + 1\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(amt + 1)\n    dp.fill(MAX)\n    dp[0] = 0\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)\n            }\n        }\n    }\n    return if (dp[amt] != MAX) dp[amt] else -1\n}\n
    coin_change.rb
    [class]{}-[func]{coin_change_dp_comp}\n
    coin_change.zig
    // \u96f6\u94b1\u5151\u6362\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn coinChangeDPComp(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    comptime var max = amt + 1;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (amt + 1);\n    @memset(&dp, max);\n    dp[0] = 0;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = @min(dp[a], dp[a - @as(usize, @intCast(coins[i - 1]))] + 1);\n            }\n        }\n    }\n    if (dp[amt] != max) {\n        return @intCast(dp[amt]);\n    } else {\n        return -1;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1453-ii","title":"14.5.3 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898 II","text":"

    Question

    \u7ed9\u5b9a \\(n\\) \u79cd\u786c\u5e01\uff0c\u7b2c \\(i\\) \u79cd\u786c\u5e01\u7684\u9762\u503c\u4e3a \\(coins[i - 1]\\) \uff0c\u76ee\u6807\u91d1\u989d\u4e3a \\(amt\\) \uff0c\u6bcf\u79cd\u786c\u5e01\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u7684\u786c\u5e01\u7ec4\u5408\u6570\u91cf\u3002\u793a\u4f8b\u5982\u56fe 14-26 \u6240\u793a\u3002

    \u56fe 14-26 \u00a0 \u96f6\u94b1\u5151\u6362\u95ee\u9898 II \u7684\u793a\u4f8b\u6570\u636e

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#1_2","title":"1. \u00a0 \u52a8\u6001\u89c4\u5212\u601d\u8def","text":"

    \u76f8\u6bd4\u4e8e\u4e0a\u4e00\u9898\uff0c\u672c\u9898\u76ee\u6807\u662f\u6c42\u7ec4\u5408\u6570\u91cf\uff0c\u56e0\u6b64\u5b50\u95ee\u9898\u53d8\u4e3a\uff1a\u524d \\(i\\) \u79cd\u786c\u5e01\u80fd\u591f\u51d1\u51fa\u91d1\u989d \\(a\\) \u7684\u7ec4\u5408\u6570\u91cf\u3002\u800c \\(dp\\) \u8868\u4ecd\u7136\u662f\u5c3a\u5bf8\u4e3a \\((n+1) \\times (amt + 1)\\) \u7684\u4e8c\u7ef4\u77e9\u9635\u3002

    \u5f53\u524d\u72b6\u6001\u7684\u7ec4\u5408\u6570\u91cf\u7b49\u4e8e\u4e0d\u9009\u5f53\u524d\u786c\u5e01\u4e0e\u9009\u5f53\u524d\u786c\u5e01\u8fd9\u4e24\u79cd\u51b3\u7b56\u7684\u7ec4\u5408\u6570\u91cf\u4e4b\u548c\u3002\u72b6\u6001\u8f6c\u79fb\u65b9\u7a0b\u4e3a\uff1a

    \\[ dp[i, a] = dp[i-1, a] + dp[i, a - coins[i-1]] \\]

    \u5f53\u76ee\u6807\u91d1\u989d\u4e3a \\(0\\) \u65f6\uff0c\u65e0\u987b\u9009\u62e9\u4efb\u4f55\u786c\u5e01\u5373\u53ef\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u56e0\u6b64\u5e94\u5c06\u9996\u5217\u6240\u6709 \\(dp[i, 0]\\) \u90fd\u521d\u59cb\u5316\u4e3a \\(1\\) \u3002\u5f53\u65e0\u786c\u5e01\u65f6\uff0c\u65e0\u6cd5\u51d1\u51fa\u4efb\u4f55 \\(>0\\) \u7684\u76ee\u6807\u91d1\u989d\uff0c\u56e0\u6b64\u9996\u884c\u6240\u6709 \\(dp[0, a]\\) \u90fd\u7b49\u4e8e \\(0\\) \u3002

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#2_2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_ii.py
    def coin_change_ii_dp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [[0] * (amt + 1) for _ in range(n + 1)]\n    # \u521d\u59cb\u5316\u9996\u5217\n    for i in range(n + 1):\n        dp[i][0] = 1\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n    return dp[n][amt]\n
    coin_change_ii.cpp
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(vector<int> &coins, int amt) {\n    int n = coins.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<vector<int>> dp(n + 1, vector<int>(amt + 1, 0));\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.java
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(int[] coins, int amt) {\n    int n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[][] dp = new int[n + 1][amt + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.cs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint CoinChangeIIDP(int[] coins, int amt) {\n    int n = coins.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[,] dp = new int[n + 1, amt + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i, 0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i, a] = dp[i - 1, a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i, a] = dp[i - 1, a] + dp[i, a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n, amt];\n}\n
    coin_change_ii.go
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDP(coins []int, amt int) int {\n    n := len(coins)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([][]int, n+1)\n    for i := 0; i <= n; i++ {\n        dp[i] = make([]int, amt+1)\n    }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i := 0; i <= n; i++ {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\uff1a\u5176\u4f59\u884c\u548c\u5217\n    for i := 1; i <= n; i++ {\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i-1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i-1][a] + dp[i][a-coins[i-1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.swift
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDP(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i in 0 ... n {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.js
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDP(coins, amt) {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (let i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.ts
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDP(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: n + 1 }, () =>\n        Array.from({ length: amt + 1 }, () => 0)\n    );\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (let i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    coin_change_ii.dart
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(List<int> coins, int amt) {\n  int n = coins.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<List<int>> dp = List.generate(n + 1, (index) => List.filled(amt + 1, 0));\n  // \u521d\u59cb\u5316\u9996\u5217\n  for (int i = 0; i <= n; i++) {\n    dp[i][0] = 1;\n  }\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[i][a] = dp[i - 1][a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n        dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n      }\n    }\n  }\n  return dp[n][amt];\n}\n
    coin_change_ii.rs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfn coin_change_ii_dp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![vec![0; amt + 1]; n + 1];\n    // \u521d\u59cb\u5316\u9996\u5217\n    for i in 0..=n {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1] as usize];\n            }\n        }\n    }\n    dp[n][amt]\n}\n
    coin_change_ii.c
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDP(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int **dp = malloc((n + 1) * sizeof(int *));\n    for (int i = 0; i <= n; i++) {\n        dp[i] = calloc(amt + 1, sizeof(int));\n    }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (int i = 0; i <= n; i++) {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]];\n            }\n        }\n    }\n    int res = dp[n][amt];\n    // \u91ca\u653e\u5185\u5b58\n    for (int i = 0; i <= n; i++) {\n        free(dp[i]);\n    }\n    free(dp);\n    return res;\n}\n
    coin_change_ii.kt
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212 */\nfun coinChangeIIDP(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = Array(n + 1) { IntArray(amt + 1) }\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (i in 0..n) {\n        dp[i][0] = 1\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[n][amt]\n}\n
    coin_change_ii.rb
    [class]{}-[func]{coin_change_ii_dp}\n
    coin_change_ii.zig
    // \u96f6\u94b1\u5151\u6362 II\uff1a\u52a8\u6001\u89c4\u5212\nfn coinChangeIIDP(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1);\n    // \u521d\u59cb\u5316\u9996\u5217\n    for (0..n + 1) |i| {\n        dp[i][0] = 1;\n    }\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[i][a] = dp[i - 1][a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[i][a] = dp[i - 1][a] + dp[i][a - @as(usize, @intCast(coins[i - 1]))];\n            }\n        }\n    }\n    return dp[n][amt];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_dynamic_programming/unbounded_knapsack_problem/#3_2","title":"3. \u00a0 \u7a7a\u95f4\u4f18\u5316","text":"

    \u7a7a\u95f4\u4f18\u5316\u5904\u7406\u65b9\u5f0f\u76f8\u540c\uff0c\u5220\u9664\u786c\u5e01\u7ef4\u5ea6\u5373\u53ef\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_ii.py
    def coin_change_ii_dp_comp(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\"\"\"\n    n = len(coins)\n    # \u521d\u59cb\u5316 dp \u8868\n    dp = [0] * (amt + 1)\n    dp[0] = 1\n    # \u72b6\u6001\u8f6c\u79fb\n    for i in range(1, n + 1):\n        # \u6b63\u5e8f\u904d\u5386\n        for a in range(1, amt + 1):\n            if coins[i - 1] > a:\n                # \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            else:\n                # \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n    return dp[amt]\n
    coin_change_ii.cpp
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(vector<int> &coins, int amt) {\n    int n = coins.size();\n    // \u521d\u59cb\u5316 dp \u8868\n    vector<int> dp(amt + 1, 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.java
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(int[] coins, int amt) {\n    int n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.cs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint CoinChangeIIDPComp(int[] coins, int amt) {\n    int n = coins.Length;\n    // \u521d\u59cb\u5316 dp \u8868\n    int[] dp = new int[amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.go
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDPComp(coins []int, amt int) int {\n    n := len(coins)\n    // \u521d\u59cb\u5316 dp \u8868\n    dp := make([]int, amt+1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for i := 1; i <= n; i++ {\n        // \u6b63\u5e8f\u904d\u5386\n        for a := 1; a <= amt; a++ {\n            if coins[i-1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a-coins[i-1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.swift
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunc coinChangeIIDPComp(coins: [Int], amt: Int) -> Int {\n    let n = coins.count\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = Array(repeating: 0, count: amt + 1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1 ... n {\n        for a in 1 ... amt {\n            if coins[i - 1] > a {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.js
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDPComp(coins, amt) {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.ts
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u72b6\u6001\u538b\u7f29\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfunction coinChangeIIDPComp(coins: Array<number>, amt: number): number {\n    const n = coins.length;\n    // \u521d\u59cb\u5316 dp \u8868\n    const dp = Array.from({ length: amt + 1 }, () => 0);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (let i = 1; i <= n; i++) {\n        for (let a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    coin_change_ii.dart
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(List<int> coins, int amt) {\n  int n = coins.length;\n  // \u521d\u59cb\u5316 dp \u8868\n  List<int> dp = List.filled(amt + 1, 0);\n  dp[0] = 1;\n  // \u72b6\u6001\u8f6c\u79fb\n  for (int i = 1; i <= n; i++) {\n    for (int a = 1; a <= amt; a++) {\n      if (coins[i - 1] > a) {\n        // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n        dp[a] = dp[a];\n      } else {\n        // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n        dp[a] = dp[a] + dp[a - coins[i - 1]];\n      }\n    }\n  }\n  return dp[amt];\n}\n
    coin_change_ii.rs
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfn coin_change_ii_dp_comp(coins: &[i32], amt: usize) -> i32 {\n    let n = coins.len();\n    // \u521d\u59cb\u5316 dp \u8868\n    let mut dp = vec![0; amt + 1];\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for i in 1..=n {\n        for a in 1..=amt {\n            if coins[i - 1] > a as i32 {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1] as usize];\n            }\n        }\n    }\n    dp[amt]\n}\n
    coin_change_ii.c
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nint coinChangeIIDPComp(int coins[], int amt, int coinsSize) {\n    int n = coinsSize;\n    // \u521d\u59cb\u5316 dp \u8868\n    int *dp = calloc(amt + 1, sizeof(int));\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (int i = 1; i <= n; i++) {\n        for (int a = 1; a <= amt; a++) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]];\n            }\n        }\n    }\n    int res = dp[amt];\n    // \u91ca\u653e\u5185\u5b58\n    free(dp);\n    return res;\n}\n
    coin_change_ii.kt
    /* \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212 */\nfun coinChangeIIDPComp(coins: IntArray, amt: Int): Int {\n    val n = coins.size\n    // \u521d\u59cb\u5316 dp \u8868\n    val dp = IntArray(amt + 1)\n    dp[0] = 1\n    // \u72b6\u6001\u8f6c\u79fb\n    for (i in 1..n) {\n        for (a in 1..amt) {\n            if (coins[i - 1] > a) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a]\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u4e4b\u548c\n                dp[a] = dp[a] + dp[a - coins[i - 1]]\n            }\n        }\n    }\n    return dp[amt]\n}\n
    coin_change_ii.rb
    [class]{}-[func]{coin_change_ii_dp_comp}\n
    coin_change_ii.zig
    // \u96f6\u94b1\u5151\u6362 II\uff1a\u7a7a\u95f4\u4f18\u5316\u540e\u7684\u52a8\u6001\u89c4\u5212\nfn coinChangeIIDPComp(comptime coins: []i32, comptime amt: usize) i32 {\n    comptime var n = coins.len;\n    // \u521d\u59cb\u5316 dp \u8868\n    var dp = [_]i32{0} ** (amt + 1);\n    dp[0] = 1;\n    // \u72b6\u6001\u8f6c\u79fb\n    for (1..n + 1) |i| {\n        for (1..amt + 1) |a| {\n            if (coins[i - 1] > @as(i32, @intCast(a))) {\n                // \u82e5\u8d85\u8fc7\u76ee\u6807\u91d1\u989d\uff0c\u5219\u4e0d\u9009\u786c\u5e01 i\n                dp[a] = dp[a];\n            } else {\n                // \u4e0d\u9009\u548c\u9009\u786c\u5e01 i \u8fd9\u4e24\u79cd\u65b9\u6848\u7684\u8f83\u5c0f\u503c\n                dp[a] = dp[a] + dp[a - @as(usize, @intCast(coins[i - 1]))];\n            }\n        }\n    }\n    return dp[amt];\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_graph/","title":"\u7b2c 9 \u7ae0 \u00a0 \u56fe","text":"

    Abstract

    \u5728\u751f\u547d\u65c5\u9014\u4e2d\uff0c\u6211\u4eec\u5c31\u50cf\u662f\u4e00\u4e2a\u4e2a\u8282\u70b9\uff0c\u88ab\u65e0\u6570\u770b\u4e0d\u89c1\u7684\u8fb9\u76f8\u8fde\u3002

    \u6bcf\u4e00\u6b21\u7684\u76f8\u8bc6\u4e0e\u76f8\u79bb\uff0c\u90fd\u5728\u8fd9\u5f20\u5de8\u5927\u7684\u7f51\u7edc\u56fe\u4e2d\u7559\u4e0b\u72ec\u7279\u7684\u5370\u8bb0\u3002

    "},{"location":"chapter_graph/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 9.1 \u00a0 \u56fe
    • 9.2 \u00a0 \u56fe\u57fa\u7840\u64cd\u4f5c
    • 9.3 \u00a0 \u56fe\u7684\u904d\u5386
    • 9.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_graph/graph/","title":"9.1 \u00a0 \u56fe","text":"

    \u56fe\uff08graph\uff09\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u7531\u9876\u70b9\uff08vertex\uff09\u548c\u8fb9\uff08edge\uff09\u7ec4\u6210\u3002\u6211\u4eec\u53ef\u4ee5\u5c06\u56fe \\(G\\) \u62bd\u8c61\u5730\u8868\u793a\u4e3a\u4e00\u7ec4\u9876\u70b9 \\(V\\) \u548c\u4e00\u7ec4\u8fb9 \\(E\\) \u7684\u96c6\u5408\u3002\u4ee5\u4e0b\u793a\u4f8b\u5c55\u793a\u4e86\u4e00\u4e2a\u5305\u542b 5 \u4e2a\u9876\u70b9\u548c 7 \u6761\u8fb9\u7684\u56fe\u3002

    \\[ \\begin{aligned} V & = \\{ 1, 2, 3, 4, 5 \\} \\newline E & = \\{ (1,2), (1,3), (1,5), (2,3), (2,4), (2,5), (4,5) \\} \\newline G & = \\{ V, E \\} \\newline \\end{aligned} \\]

    \u5982\u679c\u5c06\u9876\u70b9\u770b\u4f5c\u8282\u70b9\uff0c\u5c06\u8fb9\u770b\u4f5c\u8fde\u63a5\u5404\u4e2a\u8282\u70b9\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5c06\u56fe\u770b\u4f5c\u4e00\u79cd\u4ece\u94fe\u8868\u62d3\u5c55\u800c\u6765\u7684\u6570\u636e\u7ed3\u6784\u3002\u5982\u56fe 9-1 \u6240\u793a\uff0c\u76f8\u8f83\u4e8e\u7ebf\u6027\u5173\u7cfb\uff08\u94fe\u8868\uff09\u548c\u5206\u6cbb\u5173\u7cfb\uff08\u6811\uff09\uff0c\u7f51\u7edc\u5173\u7cfb\uff08\u56fe\uff09\u7684\u81ea\u7531\u5ea6\u66f4\u9ad8\uff0c\u56e0\u800c\u66f4\u4e3a\u590d\u6742\u3002

    \u56fe 9-1 \u00a0 \u94fe\u8868\u3001\u6811\u3001\u56fe\u4e4b\u95f4\u7684\u5173\u7cfb

    "},{"location":"chapter_graph/graph/#911","title":"9.1.1 \u00a0 \u56fe\u7684\u5e38\u89c1\u7c7b\u578b\u4e0e\u672f\u8bed","text":"

    \u6839\u636e\u8fb9\u662f\u5426\u5177\u6709\u65b9\u5411\uff0c\u53ef\u5206\u4e3a\u65e0\u5411\u56fe\uff08undirected graph\uff09\u548c\u6709\u5411\u56fe\uff08directed graph\uff09\uff0c\u5982\u56fe 9-2 \u6240\u793a\u3002

    • \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u8fb9\u8868\u793a\u4e24\u9876\u70b9\u4e4b\u95f4\u7684\u201c\u53cc\u5411\u201d\u8fde\u63a5\u5173\u7cfb\uff0c\u4f8b\u5982\u5fae\u4fe1\u6216 QQ \u4e2d\u7684\u201c\u597d\u53cb\u5173\u7cfb\u201d\u3002
    • \u5728\u6709\u5411\u56fe\u4e2d\uff0c\u8fb9\u5177\u6709\u65b9\u5411\u6027\uff0c\u5373 \\(A \\rightarrow B\\) \u548c \\(A \\leftarrow B\\) \u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u662f\u76f8\u4e92\u72ec\u7acb\u7684\uff0c\u4f8b\u5982\u5fae\u535a\u6216\u6296\u97f3\u4e0a\u7684\u201c\u5173\u6ce8\u201d\u4e0e\u201c\u88ab\u5173\u6ce8\u201d\u5173\u7cfb\u3002

    \u56fe 9-2 \u00a0 \u6709\u5411\u56fe\u4e0e\u65e0\u5411\u56fe

    \u6839\u636e\u6240\u6709\u9876\u70b9\u662f\u5426\u8fde\u901a\uff0c\u53ef\u5206\u4e3a\u8fde\u901a\u56fe\uff08connected graph\uff09\u548c\u975e\u8fde\u901a\u56fe\uff08disconnected graph\uff09\uff0c\u5982\u56fe 9-3 \u6240\u793a\u3002

    • \u5bf9\u4e8e\u8fde\u901a\u56fe\uff0c\u4ece\u67d0\u4e2a\u9876\u70b9\u51fa\u53d1\uff0c\u53ef\u4ee5\u5230\u8fbe\u5176\u4f59\u4efb\u610f\u9876\u70b9\u3002
    • \u5bf9\u4e8e\u975e\u8fde\u901a\u56fe\uff0c\u4ece\u67d0\u4e2a\u9876\u70b9\u51fa\u53d1\uff0c\u81f3\u5c11\u6709\u4e00\u4e2a\u9876\u70b9\u65e0\u6cd5\u5230\u8fbe\u3002

    \u56fe 9-3 \u00a0 \u8fde\u901a\u56fe\u4e0e\u975e\u8fde\u901a\u56fe

    \u6211\u4eec\u8fd8\u53ef\u4ee5\u4e3a\u8fb9\u6dfb\u52a0\u201c\u6743\u91cd\u201d\u53d8\u91cf\uff0c\u4ece\u800c\u5f97\u5230\u5982\u56fe 9-4 \u6240\u793a\u7684\u6709\u6743\u56fe\uff08weighted graph\uff09\u3002\u4f8b\u5982\u5728\u300a\u738b\u8005\u8363\u8000\u300b\u7b49\u624b\u6e38\u4e2d\uff0c\u7cfb\u7edf\u4f1a\u6839\u636e\u5171\u540c\u6e38\u620f\u65f6\u95f4\u6765\u8ba1\u7b97\u73a9\u5bb6\u4e4b\u95f4\u7684\u201c\u4eb2\u5bc6\u5ea6\u201d\uff0c\u8fd9\u79cd\u4eb2\u5bc6\u5ea6\u7f51\u7edc\u5c31\u53ef\u4ee5\u7528\u6709\u6743\u56fe\u6765\u8868\u793a\u3002

    \u56fe 9-4 \u00a0 \u6709\u6743\u56fe\u4e0e\u65e0\u6743\u56fe

    \u56fe\u6570\u636e\u7ed3\u6784\u5305\u542b\u4ee5\u4e0b\u5e38\u7528\u672f\u8bed\u3002

    • \u90bb\u63a5\uff08adjacency\uff09\uff1a\u5f53\u4e24\u9876\u70b9\u4e4b\u95f4\u5b58\u5728\u8fb9\u76f8\u8fde\u65f6\uff0c\u79f0\u8fd9\u4e24\u9876\u70b9\u201c\u90bb\u63a5\u201d\u3002\u5728\u56fe 9-4 \u4e2d\uff0c\u9876\u70b9 1 \u7684\u90bb\u63a5\u9876\u70b9\u4e3a\u9876\u70b9 2\u30013\u30015\u3002
    • \u8def\u5f84\uff08path\uff09\uff1a\u4ece\u9876\u70b9 A \u5230\u9876\u70b9 B \u7ecf\u8fc7\u7684\u8fb9\u6784\u6210\u7684\u5e8f\u5217\u88ab\u79f0\u4e3a\u4ece A \u5230 B \u7684\u201c\u8def\u5f84\u201d\u3002\u5728\u56fe 9-4 \u4e2d\uff0c\u8fb9\u5e8f\u5217 1-5-2-4 \u662f\u9876\u70b9 1 \u5230\u9876\u70b9 4 \u7684\u4e00\u6761\u8def\u5f84\u3002
    • \u5ea6\uff08degree\uff09\uff1a\u4e00\u4e2a\u9876\u70b9\u62e5\u6709\u7684\u8fb9\u6570\u3002\u5bf9\u4e8e\u6709\u5411\u56fe\uff0c\u5165\u5ea6\uff08in-degree\uff09\u8868\u793a\u6709\u591a\u5c11\u6761\u8fb9\u6307\u5411\u8be5\u9876\u70b9\uff0c\u51fa\u5ea6\uff08out-degree\uff09\u8868\u793a\u6709\u591a\u5c11\u6761\u8fb9\u4ece\u8be5\u9876\u70b9\u6307\u51fa\u3002
    "},{"location":"chapter_graph/graph/#912","title":"9.1.2 \u00a0 \u56fe\u7684\u8868\u793a","text":"

    \u56fe\u7684\u5e38\u7528\u8868\u793a\u65b9\u5f0f\u5305\u62ec\u201c\u90bb\u63a5\u77e9\u9635\u201d\u548c\u201c\u90bb\u63a5\u8868\u201d\u3002\u4ee5\u4e0b\u4f7f\u7528\u65e0\u5411\u56fe\u8fdb\u884c\u4e3e\u4f8b\u3002

    "},{"location":"chapter_graph/graph/#1","title":"1. \u00a0 \u90bb\u63a5\u77e9\u9635","text":"

    \u8bbe\u56fe\u7684\u9876\u70b9\u6570\u91cf\u4e3a \\(n\\) \uff0c\u90bb\u63a5\u77e9\u9635\uff08adjacency matrix\uff09\u4f7f\u7528\u4e00\u4e2a \\(n \\times n\\) \u5927\u5c0f\u7684\u77e9\u9635\u6765\u8868\u793a\u56fe\uff0c\u6bcf\u4e00\u884c\uff08\u5217\uff09\u4ee3\u8868\u4e00\u4e2a\u9876\u70b9\uff0c\u77e9\u9635\u5143\u7d20\u4ee3\u8868\u8fb9\uff0c\u7528 \\(1\\) \u6216 \\(0\\) \u8868\u793a\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u662f\u5426\u5b58\u5728\u8fb9\u3002

    \u5982\u56fe 9-5 \u6240\u793a\uff0c\u8bbe\u90bb\u63a5\u77e9\u9635\u4e3a \\(M\\)\u3001\u9876\u70b9\u5217\u8868\u4e3a \\(V\\) \uff0c\u90a3\u4e48\u77e9\u9635\u5143\u7d20 \\(M[i, j] = 1\\) \u8868\u793a\u9876\u70b9 \\(V[i]\\) \u5230\u9876\u70b9 \\(V[j]\\) \u4e4b\u95f4\u5b58\u5728\u8fb9\uff0c\u53cd\u4e4b \\(M[i, j] = 0\\) \u8868\u793a\u4e24\u9876\u70b9\u4e4b\u95f4\u65e0\u8fb9\u3002

    \u56fe 9-5 \u00a0 \u56fe\u7684\u90bb\u63a5\u77e9\u9635\u8868\u793a

    \u90bb\u63a5\u77e9\u9635\u5177\u6709\u4ee5\u4e0b\u7279\u6027\u3002

    • \u9876\u70b9\u4e0d\u80fd\u4e0e\u81ea\u8eab\u76f8\u8fde\uff0c\u56e0\u6b64\u90bb\u63a5\u77e9\u9635\u4e3b\u5bf9\u89d2\u7ebf\u5143\u7d20\u6ca1\u6709\u610f\u4e49\u3002
    • \u5bf9\u4e8e\u65e0\u5411\u56fe\uff0c\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u7b49\u4ef7\uff0c\u6b64\u65f6\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\u3002
    • \u5c06\u90bb\u63a5\u77e9\u9635\u7684\u5143\u7d20\u4ece \\(1\\) \u548c \\(0\\) \u66ff\u6362\u4e3a\u6743\u91cd\uff0c\u5219\u53ef\u8868\u793a\u6709\u6743\u56fe\u3002

    \u4f7f\u7528\u90bb\u63a5\u77e9\u9635\u8868\u793a\u56fe\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee\u77e9\u9635\u5143\u7d20\u4ee5\u83b7\u53d6\u8fb9\uff0c\u56e0\u6b64\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u7684\u6548\u7387\u5f88\u9ad8\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(1)\\) \u3002\u7136\u800c\uff0c\u77e9\u9635\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u5185\u5b58\u5360\u7528\u8f83\u591a\u3002

    "},{"location":"chapter_graph/graph/#2","title":"2. \u00a0 \u90bb\u63a5\u8868","text":"

    \u90bb\u63a5\u8868\uff08adjacency list\uff09\u4f7f\u7528 \\(n\\) \u4e2a\u94fe\u8868\u6765\u8868\u793a\u56fe\uff0c\u94fe\u8868\u8282\u70b9\u8868\u793a\u9876\u70b9\u3002\u7b2c \\(i\\) \u4e2a\u94fe\u8868\u5bf9\u5e94\u9876\u70b9 \\(i\\) \uff0c\u5176\u4e2d\u5b58\u50a8\u4e86\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\uff08\u4e0e\u8be5\u9876\u70b9\u76f8\u8fde\u7684\u9876\u70b9\uff09\u3002\u56fe 9-6 \u5c55\u793a\u4e86\u4e00\u4e2a\u4f7f\u7528\u90bb\u63a5\u8868\u5b58\u50a8\u7684\u56fe\u7684\u793a\u4f8b\u3002

    \u56fe 9-6 \u00a0 \u56fe\u7684\u90bb\u63a5\u8868\u8868\u793a

    \u90bb\u63a5\u8868\u4ec5\u5b58\u50a8\u5b9e\u9645\u5b58\u5728\u7684\u8fb9\uff0c\u800c\u8fb9\u7684\u603b\u6570\u901a\u5e38\u8fdc\u5c0f\u4e8e \\(n^2\\) \uff0c\u56e0\u6b64\u5b83\u66f4\u52a0\u8282\u7701\u7a7a\u95f4\u3002\u7136\u800c\uff0c\u5728\u90bb\u63a5\u8868\u4e2d\u9700\u8981\u901a\u8fc7\u904d\u5386\u94fe\u8868\u6765\u67e5\u627e\u8fb9\uff0c\u56e0\u6b64\u5176\u65f6\u95f4\u6548\u7387\u4e0d\u5982\u90bb\u63a5\u77e9\u9635\u3002

    \u89c2\u5bdf\u56fe 9-6 \uff0c\u90bb\u63a5\u8868\u7ed3\u6784\u4e0e\u54c8\u5e0c\u8868\u4e2d\u7684\u201c\u94fe\u5f0f\u5730\u5740\u201d\u975e\u5e38\u76f8\u4f3c\uff0c\u56e0\u6b64\u6211\u4eec\u4e5f\u53ef\u4ee5\u91c7\u7528\u7c7b\u4f3c\u7684\u65b9\u6cd5\u6765\u4f18\u5316\u6548\u7387\u3002\u6bd4\u5982\u5f53\u94fe\u8868\u8f83\u957f\u65f6\uff0c\u53ef\u4ee5\u5c06\u94fe\u8868\u8f6c\u5316\u4e3a AVL \u6811\u6216\u7ea2\u9ed1\u6811\uff0c\u4ece\u800c\u5c06\u65f6\u95f4\u6548\u7387\u4ece \\(O(n)\\) \u4f18\u5316\u81f3 \\(O(\\log n)\\) \uff1b\u8fd8\u53ef\u4ee5\u628a\u94fe\u8868\u8f6c\u6362\u4e3a\u54c8\u5e0c\u8868\uff0c\u4ece\u800c\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u964d\u81f3 \\(O(1)\\) \u3002

    "},{"location":"chapter_graph/graph/#913","title":"9.1.3 \u00a0 \u56fe\u7684\u5e38\u89c1\u5e94\u7528","text":"

    \u5982\u8868 9-1 \u6240\u793a\uff0c\u8bb8\u591a\u73b0\u5b9e\u7cfb\u7edf\u53ef\u4ee5\u7528\u56fe\u6765\u5efa\u6a21\uff0c\u76f8\u5e94\u7684\u95ee\u9898\u4e5f\u53ef\u4ee5\u7ea6\u5316\u4e3a\u56fe\u8ba1\u7b97\u95ee\u9898\u3002

    \u8868 9-1 \u00a0 \u73b0\u5b9e\u751f\u6d3b\u4e2d\u5e38\u89c1\u7684\u56fe

    \u9876\u70b9 \u8fb9 \u56fe\u8ba1\u7b97\u95ee\u9898 \u793e\u4ea4\u7f51\u7edc \u7528\u6237 \u597d\u53cb\u5173\u7cfb \u6f5c\u5728\u597d\u53cb\u63a8\u8350 \u5730\u94c1\u7ebf\u8def \u7ad9\u70b9 \u7ad9\u70b9\u95f4\u7684\u8fde\u901a\u6027 \u6700\u77ed\u8def\u7ebf\u63a8\u8350 \u592a\u9633\u7cfb \u661f\u4f53 \u661f\u4f53\u95f4\u7684\u4e07\u6709\u5f15\u529b\u4f5c\u7528 \u884c\u661f\u8f68\u9053\u8ba1\u7b97"},{"location":"chapter_graph/graph_operations/","title":"9.2 \u00a0 \u56fe\u7684\u57fa\u7840\u64cd\u4f5c","text":"

    \u56fe\u7684\u57fa\u7840\u64cd\u4f5c\u53ef\u5206\u4e3a\u5bf9\u201c\u8fb9\u201d\u7684\u64cd\u4f5c\u548c\u5bf9\u201c\u9876\u70b9\u201d\u7684\u64cd\u4f5c\u3002\u5728\u201c\u90bb\u63a5\u77e9\u9635\u201d\u548c\u201c\u90bb\u63a5\u8868\u201d\u4e24\u79cd\u8868\u793a\u65b9\u6cd5\u4e0b\uff0c\u5b9e\u73b0\u65b9\u5f0f\u6709\u6240\u4e0d\u540c\u3002

    "},{"location":"chapter_graph/graph_operations/#921","title":"9.2.1 \u00a0 \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u7684\u5b9e\u73b0","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u9876\u70b9\u6570\u91cf\u4e3a \\(n\\) \u7684\u65e0\u5411\u56fe\uff0c\u5219\u5404\u79cd\u64cd\u4f5c\u7684\u5b9e\u73b0\u65b9\u5f0f\u5982\u56fe 9-7 \u6240\u793a\u3002

    • \u6dfb\u52a0\u6216\u5220\u9664\u8fb9\uff1a\u76f4\u63a5\u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u4fee\u6539\u6307\u5b9a\u7684\u8fb9\u5373\u53ef\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002\u800c\u7531\u4e8e\u662f\u65e0\u5411\u56fe\uff0c\u56e0\u6b64\u9700\u8981\u540c\u65f6\u66f4\u65b0\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u3002
    • \u6dfb\u52a0\u9876\u70b9\uff1a\u5728\u90bb\u63a5\u77e9\u9635\u7684\u5c3e\u90e8\u6dfb\u52a0\u4e00\u884c\u4e00\u5217\uff0c\u5e76\u5168\u90e8\u586b \\(0\\) \u5373\u53ef\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002
    • \u5220\u9664\u9876\u70b9\uff1a\u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u4e00\u884c\u4e00\u5217\u3002\u5f53\u5220\u9664\u9996\u884c\u9996\u5217\u65f6\u8fbe\u5230\u6700\u5dee\u60c5\u51b5\uff0c\u9700\u8981\u5c06 \\((n-1)^2\\) \u4e2a\u5143\u7d20\u201c\u5411\u5de6\u4e0a\u79fb\u52a8\u201d\uff0c\u4ece\u800c\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    • \u521d\u59cb\u5316\uff1a\u4f20\u5165 \\(n\\) \u4e2a\u9876\u70b9\uff0c\u521d\u59cb\u5316\u957f\u5ea6\u4e3a \\(n\\) \u7684\u9876\u70b9\u5217\u8868 vertices \uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\uff1b\u521d\u59cb\u5316 \\(n \\times n\\) \u5927\u5c0f\u7684\u90bb\u63a5\u77e9\u9635 adjMat \uff0c\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    \u521d\u59cb\u5316\u90bb\u63a5\u77e9\u9635\u6dfb\u52a0\u8fb9\u5220\u9664\u8fb9\u6dfb\u52a0\u9876\u70b9\u5220\u9664\u9876\u70b9

    \u56fe 9-7 \u00a0 \u90bb\u63a5\u77e9\u9635\u7684\u521d\u59cb\u5316\u3001\u589e\u5220\u8fb9\u3001\u589e\u5220\u9876\u70b9

    \u4ee5\u4e0b\u662f\u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u8868\u793a\u56fe\u7684\u5b9e\u73b0\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_matrix.py
    class GraphAdjMat:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, vertices: list[int], edges: list[list[int]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.vertices: list[int] = []\n        # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n        self.adj_mat: list[list[int]] = []\n        # \u6dfb\u52a0\u9876\u70b9\n        for val in vertices:\n            self.add_vertex(val)\n        # \u6dfb\u52a0\u8fb9\n        # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges:\n            self.add_edge(e[0], e[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.vertices)\n\n    def add_vertex(self, val: int):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        n = self.size()\n        # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.append(val)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        new_row = [0] * n\n        self.adj_mat.append(new_row)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in self.adj_mat:\n            row.append(0)\n\n    def remove_vertex(self, index: int):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if index >= self.size():\n            raise IndexError()\n        # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.pop(index)\n        # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in self.adj_mat:\n            row.pop(index)\n\n    def add_edge(self, i: int, j: int):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1\n        self.adj_mat[j][i] = 1\n\n    def remove_edge(self, i: int, j: int):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:\n            raise IndexError()\n        self.adj_mat[i][j] = 0\n        self.adj_mat[j][i] = 0\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u77e9\u9635\"\"\"\n        print(\"\u9876\u70b9\u5217\u8868 =\", self.vertices)\n        print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        print_matrix(self.adj_mat)\n
    graph_adjacency_matrix.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vector<int> vertices;       // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vector<vector<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjMat(const vector<int> &vertices, const vector<vector<int>> &edges) {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const vector<int> &edge : edges) {\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() const {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.push_back(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        adjMat.emplace_back(vector<int>(n, 0));\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (vector<int> &row : adjMat) {\n            row.push_back(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(int index) {\n        if (index >= size()) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.erase(vertices.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.erase(adjMat.begin() + index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (vector<int> &row : adjMat) {\n            row.erase(row.begin() + index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n            throw out_of_range(\"\u9876\u70b9\u4e0d\u5b58\u5728\");\n        }\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    void print() {\n        cout << \"\u9876\u70b9\u5217\u8868 = \";\n        printVector(vertices);\n        cout << \"\u90bb\u63a5\u77e9\u9635 =\" << endl;\n        printVectorMatrix(adjMat);\n    }\n};\n
    graph_adjacency_matrix.java
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<Integer> vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<Integer>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = new ArrayList<>();\n        this.adjMat = new ArrayList<>();\n        // \u6dfb\u52a0\u9876\u70b9\n        for (int val : vertices) {\n            addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (int[] e : edges) {\n            addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return vertices.size();\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(int val) {\n        int n = size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<Integer> newRow = new ArrayList<>(n);\n        for (int j = 0; j < n; j++) {\n            newRow.add(0);\n        }\n        adjMat.add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (List<Integer> row : adjMat) {\n            row.add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(int index) {\n        if (index >= size())\n            throw new IndexOutOfBoundsException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (List<Integer> row : adjMat) {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void addEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat.get(i).set(j, 1);\n        adjMat.get(j).set(i, 1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void removeEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw new IndexOutOfBoundsException();\n        adjMat.get(i).set(j, 0);\n        adjMat.get(j).set(i, 0);\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void print() {\n        System.out.print(\"\u9876\u70b9\u5217\u8868 = \");\n        System.out.println(vertices);\n        System.out.println(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.printMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    List<int> vertices;     // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    List<List<int>> adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjMat(int[] vertices, int[][] edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        foreach (int val in vertices) {\n            AddVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        foreach (int[] e in edges) {\n            AddEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return vertices.Count;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(int val) {\n        int n = Size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.Add(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        List<int> newRow = new(n);\n        for (int j = 0; j < n; j++) {\n            newRow.Add(0);\n        }\n        adjMat.Add(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        foreach (List<int> row in adjMat) {\n            row.Add(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(int index) {\n        if (index >= Size())\n            throw new IndexOutOfRangeException();\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.RemoveAt(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        foreach (List<int> row in adjMat) {\n            row.RemoveAt(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void AddEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1;\n        adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    public void RemoveEdge(int i, int j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j)\n            throw new IndexOutOfRangeException();\n        adjMat[i][j] = 0;\n        adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    public void Print() {\n        Console.Write(\"\u9876\u70b9\u5217\u8868 = \");\n        PrintUtil.PrintList(vertices);\n        Console.WriteLine(\"\u90bb\u63a5\u77e9\u9635 =\");\n        PrintUtil.PrintMatrix(adjMat);\n    }\n}\n
    graph_adjacency_matrix.go
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjMat struct {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    vertices []int\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat [][]int\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjMat(vertices []int, edges [][]int) *graphAdjMat {\n    // \u6dfb\u52a0\u9876\u70b9\n    n := len(vertices)\n    adjMat := make([][]int, n)\n    for i := range adjMat {\n        adjMat[i] = make([]int, n)\n    }\n    // \u521d\u59cb\u5316\u56fe\n    g := &graphAdjMat{\n        vertices: vertices,\n        adjMat:   adjMat,\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for i := range edges {\n        g.addEdge(edges[i][0], edges[i][1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjMat) size() int {\n    return len(g.vertices)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjMat) addVertex(val int) {\n    n := g.size()\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    g.vertices = append(g.vertices, val)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    newRow := make([]int, n)\n    g.adjMat = append(g.adjMat, newRow)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i], 0)\n    }\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjMat) removeVertex(index int) {\n    if index >= g.size() {\n        return\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    g.vertices = append(g.vertices[:index], g.vertices[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    g.adjMat = append(g.adjMat[:index], g.adjMat[index+1:]...)\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for i := range g.adjMat {\n        g.adjMat[i] = append(g.adjMat[i][:index], g.adjMat[i][index+1:]...)\n    }\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) addEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    g.adjMat[i][j] = 1\n    g.adjMat[j][i] = 1\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nfunc (g *graphAdjMat) removeEdge(i, j int) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= g.size() || j >= g.size() || i == j {\n        fmt.Errorf(\"%s\", \"Index Out Of Bounds Exception\")\n    }\n    g.adjMat[i][j] = 0\n    g.adjMat[j][i] = 0\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nfunc (g *graphAdjMat) print() {\n    fmt.Printf(\"\\t\u9876\u70b9\u5217\u8868 = %v\\n\", g.vertices)\n    fmt.Printf(\"\\t\u90bb\u63a5\u77e9\u9635 = \\n\")\n    for i := range g.adjMat {\n        fmt.Printf(\"\\t\\t\\t%v\\n\", g.adjMat[i])\n    }\n}\n
    graph_adjacency_matrix.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    private var vertices: [Int] // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    private var adjMat: [[Int]] // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(vertices: [Int], edges: [[Int]]) {\n        self.vertices = []\n        adjMat = []\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            addVertex(val: val)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for e in edges {\n            addEdge(i: e[0], j: e[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    func size() -> Int {\n        vertices.count\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    func addVertex(val: Int) {\n        let n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.append(val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        let newRow = Array(repeating: 0, count: n)\n        adjMat.append(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for i in adjMat.indices {\n            adjMat[i].append(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    func removeVertex(index: Int) {\n        if index >= size() {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.remove(at: index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for i in adjMat.indices {\n            adjMat[i].remove(at: index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    func removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i < 0 || j < 0 || i >= size() || j >= size() || i == j {\n            fatalError(\"\u8d8a\u754c\")\n        }\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    func print() {\n        Swift.print(\"\u9876\u70b9\u5217\u8868 = \", terminator: \"\")\n        Swift.print(vertices)\n        Swift.print(\"\u90bb\u63a5\u77e9\u9635 =\")\n        PrintUtil.printMatrix(matrix: adjMat)\n    }\n}\n
    graph_adjacency_matrix.js
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices, edges) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val) {\n        const n = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow = [];\n        for (let j = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index) {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i, j) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print() {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n    vertices: number[]; // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    adjMat: number[][]; // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u51fd\u6570 */\n    constructor(vertices: number[], edges: number[][]) {\n        this.vertices = [];\n        this.adjMat = [];\n        // \u6dfb\u52a0\u9876\u70b9\n        for (const val of vertices) {\n            this.addVertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (const e of edges) {\n            this.addEdge(e[0], e[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.vertices.length;\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(val: number): void {\n        const n: number = this.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        this.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        const newRow: number[] = [];\n        for (let j: number = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(index: number): void {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        this.vertices.splice(index, 1);\n\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        this.adjMat.splice(index, 1);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    addEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) === (j, i)\n        this.adjMat[i][j] = 1;\n        this.adjMat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    removeEdge(i: number, j: number): void {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        this.adjMat[i][j] = 0;\n        this.adjMat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    print(): void {\n        console.log('\u9876\u70b9\u5217\u8868 = ', this.vertices);\n        console.log('\u90bb\u63a5\u77e9\u9635 =', this.adjMat);\n    }\n}\n
    graph_adjacency_matrix.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat {\n  List<int> vertices = []; // \u9876\u70b9\u5143\u7d20\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n  List<List<int>> adjMat = []; //\u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjMat(List<int> vertices, List<List<int>> edges) {\n    this.vertices = [];\n    this.adjMat = [];\n    // \u6dfb\u52a0\u9876\u70b9\n    for (int val in vertices) {\n      addVertex(val);\n    }\n    // \u6dfb\u52a0\u8fb9\n    // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    for (List<int> e in edges) {\n      addEdge(e[0], e[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return vertices.length;\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(int val) {\n    int n = size();\n    // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    vertices.add(val);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    List<int> newRow = List.filled(n, 0, growable: true);\n    adjMat.add(newRow);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    for (List<int> row in adjMat) {\n      row.add(0);\n    }\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(int index) {\n    if (index >= size()) {\n      throw IndexError;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    vertices.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    adjMat.removeAt(index);\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (List<int> row in adjMat) {\n      row.removeAt(index);\n    }\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void addEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    adjMat[i][j] = 1;\n    adjMat[j][i] = 1;\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n  void removeEdge(int i, int j) {\n    // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) {\n      throw IndexError;\n    }\n    adjMat[i][j] = 0;\n    adjMat[j][i] = 0;\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n  void printAdjMat() {\n    print(\"\u9876\u70b9\u5217\u8868 = $vertices\");\n    print(\"\u90bb\u63a5\u77e9\u9635 = \");\n    printMatrix(adjMat);\n  }\n}\n
    graph_adjacency_matrix.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjMat {\n    // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub vertices: Vec<i32>,\n    // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    pub adj_mat: Vec<Vec<i32>>,\n}\n\nimpl GraphAdjMat {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(vertices: Vec<i32>, edges: Vec<[usize; 2]>) -> Self {\n        let mut graph = GraphAdjMat {\n            vertices: vec![],\n            adj_mat: vec![],\n        };\n        // \u6dfb\u52a0\u9876\u70b9\n        for val in vertices {\n            graph.add_vertex(val);\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for edge in edges {\n            graph.add_edge(edge[0], edge[1])\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    pub fn size(&self) -> usize {\n        self.vertices.len()\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, val: i32) {\n        let n = self.size();\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        self.vertices.push(val);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        self.adj_mat.push(vec![0; n]);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for row in &mut self.adj_mat {\n            row.push(0);\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    pub fn remove_vertex(&mut self, index: usize) {\n        if index >= self.size() {\n            panic!(\"index error\")\n        }\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        self.vertices.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        self.adj_mat.remove(index);\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for row in &mut self.adj_mat {\n            row.remove(index);\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        self.adj_mat[i][j] = 1;\n        self.adj_mat[j][i] = 1;\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    pub fn remove_edge(&mut self, i: usize, j: usize) {\n        // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if i >= self.size() || j >= self.size() || i == j {\n            panic!(\"index error\")\n        }\n        self.adj_mat[i][j] = 0;\n        self.adj_mat[j][i] = 0;\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    pub fn print(&self) {\n        println!(\"\u9876\u70b9\u5217\u8868 = {:?}\", self.vertices);\n        println!(\"\u90bb\u63a5\u77e9\u9635 =\");\n        println!(\"[\");\n        for row in &self.adj_mat {\n            println!(\"  {:?},\", row);\n        }\n        println!(\"]\")\n    }\n}\n
    graph_adjacency_matrix.c
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int vertices[MAX_SIZE];\n    int adjMat[MAX_SIZE][MAX_SIZE];\n    int size;\n} GraphAdjMat;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjMat *newGraphAdjMat() {\n    GraphAdjMat *graph = (GraphAdjMat *)malloc(sizeof(GraphAdjMat));\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        for (int j = 0; j < MAX_SIZE; j++) {\n            graph->adjMat[i][j] = 0;\n        }\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjMat(GraphAdjMat *graph) {\n    free(graph);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjMat *graph, int val) {\n    if (graph->size == MAX_SIZE) {\n        fprintf(stderr, \"\u56fe\u7684\u9876\u70b9\u6570\u91cf\u5df2\u8fbe\u6700\u5927\u503c\\n\");\n        return;\n    }\n    // \u6dfb\u52a0\u7b2c n \u4e2a\u9876\u70b9\uff0c\u5e76\u5c06\u7b2c n \u884c\u548c\u5217\u7f6e\u96f6\n    int n = graph->size;\n    graph->vertices[n] = val;\n    for (int i = 0; i <= n; i++) {\n        graph->adjMat[n][i] = graph->adjMat[i][n] = 0;\n    }\n    graph->size++;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjMat *graph, int index) {\n    if (index < 0 || index >= graph->size) {\n        fprintf(stderr, \"\u9876\u70b9\u7d22\u5f15\u8d8a\u754c\\n\");\n        return;\n    }\n    // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    for (int i = index; i < graph->size - 1; i++) {\n        graph->vertices[i] = graph->vertices[i + 1];\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    for (int i = index; i < graph->size - 1; i++) {\n        for (int j = 0; j < graph->size; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i + 1][j];\n        }\n    }\n    // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    for (int i = 0; i < graph->size; i++) {\n        for (int j = index; j < graph->size - 1; j++) {\n            graph->adjMat[i][j] = graph->adjMat[i][j + 1];\n        }\n    }\n    graph->size--;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid addEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 1;\n    graph->adjMat[j][i] = 1;\n}\n\n/* \u5220\u9664\u8fb9 */\n// \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\nvoid removeEdge(GraphAdjMat *graph, int i, int j) {\n    if (i < 0 || j < 0 || i >= graph->size || j >= graph->size || i == j) {\n        fprintf(stderr, \"\u8fb9\u7d22\u5f15\u8d8a\u754c\u6216\u76f8\u7b49\\n\");\n        return;\n    }\n    graph->adjMat[i][j] = 0;\n    graph->adjMat[j][i] = 0;\n}\n\n/* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\nvoid printGraphAdjMat(GraphAdjMat *graph) {\n    printf(\"\u9876\u70b9\u5217\u8868 = \");\n    printArray(graph->vertices, graph->size);\n    printf(\"\u90bb\u63a5\u77e9\u9635 =\\n\");\n    for (int i = 0; i < graph->size; i++) {\n        printArray(graph->adjMat[i], graph->size);\n    }\n}\n
    graph_adjacency_matrix.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjMat(vertices: IntArray, edges: Array<IntArray>) {\n    val vertices = mutableListOf<Int>() // \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    val adjMat = mutableListOf<MutableList<Int>>() // \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u9876\u70b9\n        for (vertex in vertices) {\n            addVertex(vertex)\n        }\n        // \u6dfb\u52a0\u8fb9\n        // \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n        for (edge in edges) {\n            addEdge(edge[0], edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return vertices.size\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(_val: Int) {\n        val n = size()\n        // \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n        vertices.add(_val)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n        val newRow = mutableListOf<Int>()\n        for (j in 0..<n) {\n            newRow.add(0)\n        }\n        adjMat.add(newRow)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n        for (row in adjMat) {\n            row.add(0)\n        }\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(index: Int) {\n        if (index >= size())\n            throw IndexOutOfBoundsException()\n        // \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n        vertices.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n        adjMat.removeAt(index)\n        // \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n        for (row in adjMat) {\n            row.removeAt(index)\n        }\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun addEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        // \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n        adjMat[i][j] = 1\n        adjMat[j][i] = 1\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    // \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    fun removeEdge(i: Int, j: Int) {\n        // \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n        if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)\n            throw IndexOutOfBoundsException()\n        adjMat[i][j] = 0\n        adjMat[j][i] = 0\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u77e9\u9635 */\n    fun print() {\n        print(\"\u9876\u70b9\u5217\u8868 = \")\n        println(vertices)\n        println(\"\u90bb\u63a5\u77e9\u9635 =\")\n        printMatrix(adjMat)\n    }\n}\n
    graph_adjacency_matrix.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u77e9\u9635\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjMat\n  def initialize(vertices, edges)\n    ### \u6784\u9020\u65b9\u6cd5 ###\n    # \u9876\u70b9\u5217\u8868\uff0c\u5143\u7d20\u4ee3\u8868\u201c\u9876\u70b9\u503c\u201d\uff0c\u7d22\u5f15\u4ee3\u8868\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @vertices = []\n    # \u90bb\u63a5\u77e9\u9635\uff0c\u884c\u5217\u7d22\u5f15\u5bf9\u5e94\u201c\u9876\u70b9\u7d22\u5f15\u201d\n    @adj_mat = []\n    # \u6dfb\u52a0\u9876\u70b9\n    vertices.each { |val| add_vertex(val) }\n    # \u6dfb\u52a0\u8fb9\n    # \u8bf7\u6ce8\u610f\uff0cedges \u5143\u7d20\u4ee3\u8868\u9876\u70b9\u7d22\u5f15\uff0c\u5373\u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    edges.each { |e| add_edge(e[0], e[1]) }\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @vertices.length\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(val)\n    n = size\n    # \u5411\u9876\u70b9\u5217\u8868\u4e2d\u6dfb\u52a0\u65b0\u9876\u70b9\u7684\u503c\n    @vertices << val\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u884c\n    new_row = Array.new(n, 0)\n    @adj_mat << new_row\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u6dfb\u52a0\u4e00\u5217\n    @adj_mat.each { |row| row << 0 }\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(index)\n    raise IndexError if index >= size\n\n    # \u5728\u9876\u70b9\u5217\u8868\u4e2d\u79fb\u9664\u7d22\u5f15 index \u7684\u9876\u70b9\n    @vertices.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u884c\n    @adj_mat.delete_at(index)\n    # \u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u5220\u9664\u7d22\u5f15 index \u7684\u5217\n    @adj_mat.each { |row| row.delete_at(index) }\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    # \u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u90bb\u63a5\u77e9\u9635\u5173\u4e8e\u4e3b\u5bf9\u89d2\u7ebf\u5bf9\u79f0\uff0c\u5373\u6ee1\u8db3 (i, j) == (j, i)\n    @adj_mat[i][j] = 1\n    @adj_mat[j][i] = 1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(i, j)\n    # \u53c2\u6570 i, j \u5bf9\u5e94 vertices \u5143\u7d20\u7d22\u5f15\n    # \u7d22\u5f15\u8d8a\u754c\u4e0e\u76f8\u7b49\u5904\u7406\n    if i < 0 || j < 0 || i >= size || j >= size || i == j\n      raise IndexError\n    end\n    @adj_mat[i][j] = 0\n    @adj_mat[j][i] = 0\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u77e9\u9635 ###\n  def __print__\n    puts \"\u9876\u70b9\u5217\u8868 = #{@vertices}\"\n    puts '\u90bb\u63a5\u77e9\u9635 ='\n    print_matrix(@adj_mat)\n  end\nend\n
    graph_adjacency_matrix.zig
    [class]{GraphAdjMat}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_graph/graph_operations/#922","title":"9.2.2 \u00a0 \u57fa\u4e8e\u90bb\u63a5\u8868\u7684\u5b9e\u73b0","text":"

    \u8bbe\u65e0\u5411\u56fe\u7684\u9876\u70b9\u603b\u6570\u4e3a \\(n\\)\u3001\u8fb9\u603b\u6570\u4e3a \\(m\\) \uff0c\u5219\u53ef\u6839\u636e\u56fe 9-8 \u6240\u793a\u7684\u65b9\u6cd5\u5b9e\u73b0\u5404\u79cd\u64cd\u4f5c\u3002

    • \u6dfb\u52a0\u8fb9\uff1a\u5728\u9876\u70b9\u5bf9\u5e94\u94fe\u8868\u7684\u672b\u5c3e\u6dfb\u52a0\u8fb9\u5373\u53ef\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002\u56e0\u4e3a\u662f\u65e0\u5411\u56fe\uff0c\u6240\u4ee5\u9700\u8981\u540c\u65f6\u6dfb\u52a0\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u3002
    • \u5220\u9664\u8fb9\uff1a\u5728\u9876\u70b9\u5bf9\u5e94\u94fe\u8868\u4e2d\u67e5\u627e\u5e76\u5220\u9664\u6307\u5b9a\u8fb9\uff0c\u4f7f\u7528 \\(O(m)\\) \u65f6\u95f4\u3002\u5728\u65e0\u5411\u56fe\u4e2d\uff0c\u9700\u8981\u540c\u65f6\u5220\u9664\u4e24\u4e2a\u65b9\u5411\u7684\u8fb9\u3002
    • \u6dfb\u52a0\u9876\u70b9\uff1a\u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u94fe\u8868\uff0c\u5e76\u5c06\u65b0\u589e\u9876\u70b9\u4f5c\u4e3a\u94fe\u8868\u5934\u8282\u70b9\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002
    • \u5220\u9664\u9876\u70b9\uff1a\u9700\u904d\u5386\u6574\u4e2a\u90bb\u63a5\u8868\uff0c\u5220\u9664\u5305\u542b\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u8fb9\uff0c\u4f7f\u7528 \\(O(n + m)\\) \u65f6\u95f4\u3002
    • \u521d\u59cb\u5316\uff1a\u5728\u90bb\u63a5\u8868\u4e2d\u521b\u5efa \\(n\\) \u4e2a\u9876\u70b9\u548c \\(2m\\) \u6761\u8fb9\uff0c\u4f7f\u7528 \\(O(n + m)\\) \u65f6\u95f4\u3002
    \u521d\u59cb\u5316\u90bb\u63a5\u8868\u6dfb\u52a0\u8fb9\u5220\u9664\u8fb9\u6dfb\u52a0\u9876\u70b9\u5220\u9664\u9876\u70b9

    \u56fe 9-8 \u00a0 \u90bb\u63a5\u8868\u7684\u521d\u59cb\u5316\u3001\u589e\u5220\u8fb9\u3001\u589e\u5220\u9876\u70b9

    \u4ee5\u4e0b\u662f\u90bb\u63a5\u8868\u7684\u4ee3\u7801\u5b9e\u73b0\u3002\u5bf9\u6bd4\u56fe 9-8 \uff0c\u5b9e\u9645\u4ee3\u7801\u6709\u4ee5\u4e0b\u4e0d\u540c\u3002

    • \u4e3a\u4e86\u65b9\u4fbf\u6dfb\u52a0\u4e0e\u5220\u9664\u9876\u70b9\uff0c\u4ee5\u53ca\u7b80\u5316\u4ee3\u7801\uff0c\u6211\u4eec\u4f7f\u7528\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\u6765\u4ee3\u66ff\u94fe\u8868\u3002
    • \u4f7f\u7528\u54c8\u5e0c\u8868\u6765\u5b58\u50a8\u90bb\u63a5\u8868\uff0ckey \u4e3a\u9876\u70b9\u5b9e\u4f8b\uff0cvalue \u4e3a\u8be5\u9876\u70b9\u7684\u90bb\u63a5\u9876\u70b9\u5217\u8868\uff08\u94fe\u8868\uff09\u3002

    \u53e6\u5916\uff0c\u6211\u4eec\u5728\u90bb\u63a5\u8868\u4e2d\u4f7f\u7528 Vertex \u7c7b\u6765\u8868\u793a\u9876\u70b9\uff0c\u8fd9\u6837\u505a\u7684\u539f\u56e0\u662f\uff1a\u5982\u679c\u4e0e\u90bb\u63a5\u77e9\u9635\u4e00\u6837\uff0c\u7528\u5217\u8868\u7d22\u5f15\u6765\u533a\u5206\u4e0d\u540c\u9876\u70b9\uff0c\u90a3\u4e48\u5047\u8bbe\u8981\u5220\u9664\u7d22\u5f15\u4e3a \\(i\\) \u7684\u9876\u70b9\uff0c\u5219\u9700\u904d\u5386\u6574\u4e2a\u90bb\u63a5\u8868\uff0c\u5c06\u6240\u6709\u5927\u4e8e \\(i\\) \u7684\u7d22\u5f15\u5168\u90e8\u51cf \\(1\\) \uff0c\u6548\u7387\u5f88\u4f4e\u3002\u800c\u5982\u679c\u6bcf\u4e2a\u9876\u70b9\u90fd\u662f\u552f\u4e00\u7684 Vertex \u5b9e\u4f8b\uff0c\u5220\u9664\u67d0\u4e00\u9876\u70b9\u4e4b\u540e\u5c31\u65e0\u987b\u6539\u52a8\u5176\u4ed6\u9876\u70b9\u4e86\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_adjacency_list.py
    class GraphAdjList:\n    \"\"\"\u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\"\"\"\n\n    def __init__(self, edges: list[list[Vertex]]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        self.adj_list = dict[Vertex, list[Vertex]]()\n        # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges:\n            self.add_vertex(edge[0])\n            self.add_vertex(edge[1])\n            self.add_edge(edge[0], edge[1])\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u9876\u70b9\u6570\u91cf\"\"\"\n        return len(self.adj_list)\n\n    def add_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u6dfb\u52a0\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list[vet1].append(vet2)\n        self.adj_list[vet2].append(vet1)\n\n    def remove_edge(self, vet1: Vertex, vet2: Vertex):\n        \"\"\"\u5220\u9664\u8fb9\"\"\"\n        if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:\n            raise ValueError()\n        # \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list[vet1].remove(vet2)\n        self.adj_list[vet2].remove(vet1)\n\n    def add_vertex(self, vet: Vertex):\n        \"\"\"\u6dfb\u52a0\u9876\u70b9\"\"\"\n        if vet in self.adj_list:\n            return\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list[vet] = []\n\n    def remove_vertex(self, vet: Vertex):\n        \"\"\"\u5220\u9664\u9876\u70b9\"\"\"\n        if vet not in self.adj_list:\n            raise ValueError()\n        # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.pop(vet)\n        # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for vertex in self.adj_list:\n            if vet in self.adj_list[vertex]:\n                self.adj_list[vertex].remove(vet)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u90bb\u63a5\u8868\"\"\"\n        print(\"\u90bb\u63a5\u8868 =\")\n        for vertex in self.adj_list:\n            tmp = [v.val for v in self.adj_list[vertex]]\n            print(f\"{vertex.val}: {tmp},\")\n
    graph_adjacency_list.cpp
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  public:\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    unordered_map<Vertex *, vector<Vertex *>> adjList;\n\n    /* \u5728 vector \u4e2d\u5220\u9664\u6307\u5b9a\u8282\u70b9 */\n    void remove(vector<Vertex *> &vec, Vertex *vet) {\n        for (int i = 0; i < vec.size(); i++) {\n            if (vec[i] == vet) {\n                vec.erase(vec.begin() + i);\n                break;\n            }\n        }\n    }\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    GraphAdjList(const vector<vector<Vertex *>> &edges) {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const vector<Vertex *> &edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    void addEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].push_back(vet2);\n        adjList[vet2].push_back(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    void removeEdge(Vertex *vet1, Vertex *vet2) {\n        if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        remove(adjList[vet1], vet2);\n        remove(adjList[vet2], vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    void addVertex(Vertex *vet) {\n        if (adjList.count(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = vector<Vertex *>();\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    void removeVertex(Vertex *vet) {\n        if (!adjList.count(vet))\n            throw invalid_argument(\"\u4e0d\u5b58\u5728\u9876\u70b9\");\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.erase(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (auto &adj : adjList) {\n            remove(adj.second, vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    void print() {\n        cout << \"\u90bb\u63a5\u8868 =\" << endl;\n        for (auto &adj : adjList) {\n            const auto &key = adj.first;\n            const auto &vec = adj.second;\n            cout << key->val << \": \";\n            printVector(vetsToVals(vec));\n        }\n    }\n};\n
    graph_adjacency_list.java
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    Map<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public GraphAdjList(Vertex[][] edges) {\n        this.adjList = new HashMap<>();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (Vertex[] edge : edges) {\n            addVertex(edge[0]);\n            addVertex(edge[1]);\n            addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public int size() {\n        return adjList.size();\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void addEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList.get(vet1).add(vet2);\n        adjList.get(vet2).add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void removeEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw new IllegalArgumentException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList.get(vet1).remove(vet2);\n        adjList.get(vet2).remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void addVertex(Vertex vet) {\n        if (adjList.containsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.put(vet, new ArrayList<>());\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void removeVertex(Vertex vet) {\n        if (!adjList.containsKey(vet))\n            throw new IllegalArgumentException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (List<Vertex> list : adjList.values()) {\n            list.remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void print() {\n        System.out.println(\"\u90bb\u63a5\u8868 =\");\n        for (Map.Entry<Vertex, List<Vertex>> pair : adjList.entrySet()) {\n            List<Integer> tmp = new ArrayList<>();\n            for (Vertex vertex : pair.getValue())\n                tmp.add(vertex.val);\n            System.out.println(pair.getKey().val + \": \" + tmp + \",\");\n        }\n    }\n}\n
    graph_adjacency_list.cs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public Dictionary<Vertex, List<Vertex>> adjList;\n\n    /* \u6784\u9020\u51fd\u6570 */\n    public GraphAdjList(Vertex[][] edges) {\n        adjList = [];\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        foreach (Vertex[] edge in edges) {\n            AddVertex(edge[0]);\n            AddVertex(edge[1]);\n            AddEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    int Size() {\n        return adjList.Count;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public void AddEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1].Add(vet2);\n        adjList[vet2].Add(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public void RemoveEdge(Vertex vet1, Vertex vet2) {\n        if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2)\n            throw new InvalidOperationException();\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1].Remove(vet2);\n        adjList[vet2].Remove(vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public void AddVertex(Vertex vet) {\n        if (adjList.ContainsKey(vet))\n            return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList.Add(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public void RemoveVertex(Vertex vet) {\n        if (!adjList.ContainsKey(vet))\n            throw new InvalidOperationException();\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.Remove(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        foreach (List<Vertex> list in adjList.Values) {\n            list.Remove(vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public void Print() {\n        Console.WriteLine(\"\u90bb\u63a5\u8868 =\");\n        foreach (KeyValuePair<Vertex, List<Vertex>> pair in adjList) {\n            List<int> tmp = [];\n            foreach (Vertex vertex in pair.Value)\n                tmp.Add(vertex.val);\n            Console.WriteLine(pair.Key.val + \": [\" + string.Join(\", \", tmp) + \"],\");\n        }\n    }\n}\n
    graph_adjacency_list.go
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntype graphAdjList struct {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList map[Vertex][]Vertex\n}\n\n/* \u6784\u9020\u51fd\u6570 */\nfunc newGraphAdjList(edges [][]Vertex) *graphAdjList {\n    g := &graphAdjList{\n        adjList: make(map[Vertex][]Vertex),\n    }\n    // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for _, edge := range edges {\n        g.addVertex(edge[0])\n        g.addVertex(edge[1])\n        g.addEdge(edge[0], edge[1])\n    }\n    return g\n}\n\n/* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\nfunc (g *graphAdjList) size() int {\n    return len(g.adjList)\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nfunc (g *graphAdjList) addEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2, \u6dfb\u52a0\u533f\u540d struct{},\n    g.adjList[vet1] = append(g.adjList[vet1], vet2)\n    g.adjList[vet2] = append(g.adjList[vet2], vet1)\n}\n\n/* \u5220\u9664\u8fb9 */\nfunc (g *graphAdjList) removeEdge(vet1 Vertex, vet2 Vertex) {\n    _, ok1 := g.adjList[vet1]\n    _, ok2 := g.adjList[vet2]\n    if !ok1 || !ok2 || vet1 == vet2 {\n        panic(\"error\")\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    g.adjList[vet1] = DeleteSliceElms(g.adjList[vet1], vet2)\n    g.adjList[vet2] = DeleteSliceElms(g.adjList[vet2], vet1)\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nfunc (g *graphAdjList) addVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if ok {\n        return\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    g.adjList[vet] = make([]Vertex, 0)\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nfunc (g *graphAdjList) removeVertex(vet Vertex) {\n    _, ok := g.adjList[vet]\n    if !ok {\n        panic(\"error\")\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    delete(g.adjList, vet)\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for v, list := range g.adjList {\n        g.adjList[v] = DeleteSliceElms(list, vet)\n    }\n}\n\n/* \u6253\u5370\u90bb\u63a5\u8868 */\nfunc (g *graphAdjList) print() {\n    var builder strings.Builder\n    fmt.Printf(\"\u90bb\u63a5\u8868 = \\n\")\n    for k, v := range g.adjList {\n        builder.WriteString(\"\\t\\t\" + strconv.Itoa(k.Val) + \": \")\n        for _, vet := range v {\n            builder.WriteString(strconv.Itoa(vet.Val) + \" \")\n        }\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    graph_adjacency_list.swift
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    public private(set) var adjList: [Vertex: [Vertex]]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public init(edges: [[Vertex]]) {\n        adjList = [:]\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            addVertex(vet: edge[0])\n            addVertex(vet: edge[1])\n            addEdge(vet1: edge[0], vet2: edge[1])\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    public func size() -> Int {\n        adjList.count\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    public func addEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.append(vet2)\n        adjList[vet2]?.append(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    public func removeEdge(vet1: Vertex, vet2: Vertex) {\n        if adjList[vet1] == nil || adjList[vet2] == nil || vet1 == vet2 {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.removeAll { $0 == vet2 }\n        adjList[vet2]?.removeAll { $0 == vet1 }\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    public func addVertex(vet: Vertex) {\n        if adjList[vet] != nil {\n            return\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = []\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    public func removeVertex(vet: Vertex) {\n        if adjList[vet] == nil {\n            fatalError(\"\u53c2\u6570\u9519\u8bef\")\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.removeValue(forKey: vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for key in adjList.keys {\n            adjList[key]?.removeAll { $0 == vet }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    public func print() {\n        Swift.print(\"\u90bb\u63a5\u8868 =\")\n        for (vertex, list) in adjList {\n            let list = list.map { $0.val }\n            Swift.print(\"\\(vertex.val): \\(list),\")\n        }\n    }\n}\n
    graph_adjacency_list.js
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size() {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1, vet2) {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet) {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet) {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print() {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.ts
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    adjList: Map<Vertex, Vertex[]>;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(edges: Vertex[][]) {\n        this.adjList = new Map();\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (const edge of edges) {\n            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    size(): number {\n        return this.adjList.size;\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    addEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    removeEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);\n        this.adjList.get(vet2).splice(this.adjList.get(vet2).indexOf(vet1), 1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    addVertex(vet: Vertex): void {\n        if (this.adjList.has(vet)) return;\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        this.adjList.set(vet, []);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    removeVertex(vet: Vertex): void {\n        if (!this.adjList.has(vet)) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        this.adjList.delete(vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (const set of this.adjList.values()) {\n            const index: number = set.indexOf(vet);\n            if (index > -1) {\n                set.splice(index, 1);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    print(): void {\n        console.log('\u90bb\u63a5\u8868 =');\n        for (const [key, value] of this.adjList.entries()) {\n            const tmp = [];\n            for (const vertex of value) {\n                tmp.push(vertex.val);\n            }\n            console.log(key.val + ': ' + tmp.join());\n        }\n    }\n}\n
    graph_adjacency_list.dart
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList {\n  // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  Map<Vertex, List<Vertex>> adjList = {};\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  GraphAdjList(List<List<Vertex>> edges) {\n    for (List<Vertex> edge in edges) {\n      addVertex(edge[0]);\n      addVertex(edge[1]);\n      addEdge(edge[0], edge[1]);\n    }\n  }\n\n  /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n  int size() {\n    return adjList.length;\n  }\n\n  /* \u6dfb\u52a0\u8fb9 */\n  void addEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    adjList[vet1]!.add(vet2);\n    adjList[vet2]!.add(vet1);\n  }\n\n  /* \u5220\u9664\u8fb9 */\n  void removeEdge(Vertex vet1, Vertex vet2) {\n    if (!adjList.containsKey(vet1) ||\n        !adjList.containsKey(vet2) ||\n        vet1 == vet2) {\n      throw ArgumentError;\n    }\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    adjList[vet1]!.remove(vet2);\n    adjList[vet2]!.remove(vet1);\n  }\n\n  /* \u6dfb\u52a0\u9876\u70b9 */\n  void addVertex(Vertex vet) {\n    if (adjList.containsKey(vet)) return;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    adjList[vet] = [];\n  }\n\n  /* \u5220\u9664\u9876\u70b9 */\n  void removeVertex(Vertex vet) {\n    if (!adjList.containsKey(vet)) {\n      throw ArgumentError;\n    }\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    adjList.remove(vet);\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    adjList.forEach((key, value) {\n      value.remove(vet);\n    });\n  }\n\n  /* \u6253\u5370\u90bb\u63a5\u8868 */\n  void printAdjList() {\n    print(\"\u90bb\u63a5\u8868 =\");\n    adjList.forEach((key, value) {\n      List<int> tmp = [];\n      for (Vertex vertex in value) {\n        tmp.add(vertex.val);\n      }\n      print(\"${key.val}: $tmp,\");\n    });\n  }\n}\n
    graph_adjacency_list.rs
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b\u578b */\npub struct GraphAdjList {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    pub adj_list: HashMap<Vertex, Vec<Vertex>>,\n}\n\nimpl GraphAdjList {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(edges: Vec<[Vertex; 2]>) -> Self {\n        let mut graph = GraphAdjList {\n            adj_list: HashMap::new(),\n        };\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for edge in edges {\n            graph.add_vertex(edge[0]);\n            graph.add_vertex(edge[1]);\n            graph.add_edge(edge[0], edge[1]);\n        }\n\n        graph\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    #[allow(unused)]\n    pub fn size(&self) -> usize {\n        self.adj_list.len()\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    pub fn add_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        self.adj_list.get_mut(&vet1).unwrap().push(vet2);\n        self.adj_list.get_mut(&vet2).unwrap().push(vet1);\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    #[allow(unused)]\n    pub fn remove_edge(&mut self, vet1: Vertex, vet2: Vertex) {\n        if !self.adj_list.contains_key(&vet1) || !self.adj_list.contains_key(&vet2) || vet1 == vet2\n        {\n            panic!(\"value error\");\n        }\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        self.adj_list\n            .get_mut(&vet1)\n            .unwrap()\n            .retain(|&vet| vet != vet2);\n        self.adj_list\n            .get_mut(&vet2)\n            .unwrap()\n            .retain(|&vet| vet != vet1);\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    pub fn add_vertex(&mut self, vet: Vertex) {\n        if self.adj_list.contains_key(&vet) {\n            return;\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        self.adj_list.insert(vet, vec![]);\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    #[allow(unused)]\n    pub fn remove_vertex(&mut self, vet: Vertex) {\n        if !self.adj_list.contains_key(&vet) {\n            panic!(\"value error\");\n        }\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        self.adj_list.remove(&vet);\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for list in self.adj_list.values_mut() {\n            list.retain(|&v| v != vet);\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    pub fn print(&self) {\n        println!(\"\u90bb\u63a5\u8868 =\");\n        for (vertex, list) in &self.adj_list {\n            let list = list.iter().map(|vertex| vertex.val).collect::<Vec<i32>>();\n            println!(\"{}: {:?},\", vertex.val, list);\n        }\n    }\n}\n
    graph_adjacency_list.c
    /* \u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct AdjListNode {\n    Vertex *vertex;           // \u9876\u70b9\n    struct AdjListNode *next; // \u540e\u7ee7\u8282\u70b9\n} AdjListNode;\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid addEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *node = (AdjListNode *)malloc(sizeof(AdjListNode));\n    node->vertex = vet;\n    // \u5934\u63d2\u6cd5\n    node->next = head->next;\n    head->next = node;\n}\n\n/* \u5220\u9664\u8fb9\u8f85\u52a9\u51fd\u6570 */\nvoid removeEdgeHelper(AdjListNode *head, Vertex *vet) {\n    AdjListNode *pre = head;\n    AdjListNode *cur = head->next;\n    // \u5728\u94fe\u8868\u4e2d\u641c\u7d22 vet \u5bf9\u5e94\u8282\u70b9\n    while (cur != NULL && cur->vertex != vet) {\n        pre = cur;\n        cur = cur->next;\n    }\n    if (cur == NULL)\n        return;\n    // \u5c06 vet \u5bf9\u5e94\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u5220\u9664\n    pre->next = cur->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(cur);\n}\n\n/* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\ntypedef struct {\n    AdjListNode *heads[MAX_SIZE]; // \u8282\u70b9\u6570\u7ec4\n    int size;                     // \u8282\u70b9\u6570\u91cf\n} GraphAdjList;\n\n/* \u6784\u9020\u51fd\u6570 */\nGraphAdjList *newGraphAdjList() {\n    GraphAdjList *graph = (GraphAdjList *)malloc(sizeof(GraphAdjList));\n    if (!graph) {\n        return NULL;\n    }\n    graph->size = 0;\n    for (int i = 0; i < MAX_SIZE; i++) {\n        graph->heads[i] = NULL;\n    }\n    return graph;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delGraphAdjList(GraphAdjList *graph) {\n    for (int i = 0; i < graph->size; i++) {\n        AdjListNode *cur = graph->heads[i];\n        while (cur != NULL) {\n            AdjListNode *next = cur->next;\n            if (cur != graph->heads[i]) {\n                free(cur);\n            }\n            cur = next;\n        }\n        free(graph->heads[i]->vertex);\n        free(graph->heads[i]);\n    }\n    free(graph);\n}\n\n/* \u67e5\u627e\u9876\u70b9\u5bf9\u5e94\u7684\u8282\u70b9 */\nAdjListNode *findNode(GraphAdjList *graph, Vertex *vet) {\n    for (int i = 0; i < graph->size; i++) {\n        if (graph->heads[i]->vertex == vet) {\n            return graph->heads[i];\n        }\n    }\n    return NULL;\n}\n\n/* \u6dfb\u52a0\u8fb9 */\nvoid addEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL && head1 != head2);\n    // \u6dfb\u52a0\u8fb9 vet1 - vet2\n    addEdgeHelper(head1, vet2);\n    addEdgeHelper(head2, vet1);\n}\n\n/* \u5220\u9664\u8fb9 */\nvoid removeEdge(GraphAdjList *graph, Vertex *vet1, Vertex *vet2) {\n    AdjListNode *head1 = findNode(graph, vet1);\n    AdjListNode *head2 = findNode(graph, vet2);\n    assert(head1 != NULL && head2 != NULL);\n    // \u5220\u9664\u8fb9 vet1 - vet2\n    removeEdgeHelper(head1, head2->vertex);\n    removeEdgeHelper(head2, head1->vertex);\n}\n\n/* \u6dfb\u52a0\u9876\u70b9 */\nvoid addVertex(GraphAdjList *graph, Vertex *vet) {\n    assert(graph != NULL && graph->size < MAX_SIZE);\n    AdjListNode *head = (AdjListNode *)malloc(sizeof(AdjListNode));\n    head->vertex = vet;\n    head->next = NULL;\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    graph->heads[graph->size++] = head;\n}\n\n/* \u5220\u9664\u9876\u70b9 */\nvoid removeVertex(GraphAdjList *graph, Vertex *vet) {\n    AdjListNode *node = findNode(graph, vet);\n    assert(node != NULL);\n    // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    AdjListNode *cur = node, *pre = NULL;\n    while (cur) {\n        pre = cur;\n        cur = cur->next;\n        free(pre);\n    }\n    // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for (int i = 0; i < graph->size; i++) {\n        cur = graph->heads[i];\n        pre = NULL;\n        while (cur) {\n            pre = cur;\n            cur = cur->next;\n            if (cur && cur->vertex == vet) {\n                pre->next = cur->next;\n                free(cur);\n                break;\n            }\n        }\n    }\n    // \u5c06\u8be5\u9876\u70b9\u4e4b\u540e\u7684\u9876\u70b9\u5411\u524d\u79fb\u52a8\uff0c\u4ee5\u586b\u8865\u7a7a\u7f3a\n    int i;\n    for (i = 0; i < graph->size; i++) {\n        if (graph->heads[i] == node)\n            break;\n    }\n    for (int j = i; j < graph->size - 1; j++) {\n        graph->heads[j] = graph->heads[j + 1];\n    }\n    graph->size--;\n    free(vet);\n}\n
    graph_adjacency_list.kt
    /* \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b */\nclass GraphAdjList(edges: Array<Array<Vertex?>>) {\n    // \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    val adjList = HashMap<Vertex, MutableList<Vertex>>()\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        // \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n        for (edge in edges) {\n            addVertex(edge[0]!!)\n            addVertex(edge[1]!!)\n            addEdge(edge[0]!!, edge[1]!!)\n        }\n    }\n\n    /* \u83b7\u53d6\u9876\u70b9\u6570\u91cf */\n    fun size(): Int {\n        return adjList.size\n    }\n\n    /* \u6dfb\u52a0\u8fb9 */\n    fun addEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u6dfb\u52a0\u8fb9 vet1 - vet2\n        adjList[vet1]?.add(vet2)\n        adjList[vet2]?.add(vet1)\n    }\n\n    /* \u5220\u9664\u8fb9 */\n    fun removeEdge(vet1: Vertex, vet2: Vertex) {\n        if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)\n            throw IllegalArgumentException()\n        // \u5220\u9664\u8fb9 vet1 - vet2\n        adjList[vet1]?.remove(vet2)\n        adjList[vet2]?.remove(vet1)\n    }\n\n    /* \u6dfb\u52a0\u9876\u70b9 */\n    fun addVertex(vet: Vertex) {\n        if (adjList.containsKey(vet))\n            return\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n        adjList[vet] = mutableListOf()\n    }\n\n    /* \u5220\u9664\u9876\u70b9 */\n    fun removeVertex(vet: Vertex) {\n        if (!adjList.containsKey(vet))\n            throw IllegalArgumentException()\n        // \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n        adjList.remove(vet)\n        // \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n        for (list in adjList.values) {\n            list.remove(vet)\n        }\n    }\n\n    /* \u6253\u5370\u90bb\u63a5\u8868 */\n    fun print() {\n        println(\"\u90bb\u63a5\u8868 =\")\n        for (pair in adjList.entries) {\n            val tmp = mutableListOf<Int>()\n            for (vertex in pair.value) {\n                tmp.add(vertex._val)\n            }\n            println(\"${pair.key._val}: $tmp,\")\n        }\n    }\n}\n
    graph_adjacency_list.rb
    ### \u57fa\u4e8e\u90bb\u63a5\u8868\u5b9e\u73b0\u7684\u65e0\u5411\u56fe\u7c7b ###\nclass GraphAdjList\n  attr_reader :adj_list\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(edges)\n    # \u90bb\u63a5\u8868\uff0ckey\uff1a\u9876\u70b9\uff0cvalue\uff1a\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    @adj_list = {}\n    # \u6dfb\u52a0\u6240\u6709\u9876\u70b9\u548c\u8fb9\n    for edge in edges\n      add_vertex(edge[0])\n      add_vertex(edge[1])\n      add_edge(edge[0], edge[1])\n    end\n  end\n\n  ### \u83b7\u53d6\u9876\u70b9\u6570\u91cf ###\n  def size\n    @adj_list.length\n  end\n\n  ### \u6dfb\u52a0\u8fb9 ###\n  def add_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    @adj_list[vet1] << vet2\n    @adj_list[vet2] << vet1\n  end\n\n  ### \u5220\u9664\u8fb9 ###\n  def remove_edge(vet1, vet2)\n    raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)\n\n    # \u5220\u9664\u8fb9 vet1 - vet2\n    @adj_list[vet1].delete(vet2)\n    @adj_list[vet2].delete(vet1)\n  end\n\n  ### \u6dfb\u52a0\u9876\u70b9 ###\n  def add_vertex(vet)\n    return if @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u65b0\u94fe\u8868\n    @adj_list[vet] = []\n  end\n\n  ### \u5220\u9664\u9876\u70b9 ###\n  def remove_vertex(vet)\n    raise ArgumentError unless @adj_list.include?(vet)\n\n    # \u5728\u90bb\u63a5\u8868\u4e2d\u5220\u9664\u9876\u70b9 vet \u5bf9\u5e94\u7684\u94fe\u8868\n    @adj_list.delete(vet)\n    # \u904d\u5386\u5176\u4ed6\u9876\u70b9\u7684\u94fe\u8868\uff0c\u5220\u9664\u6240\u6709\u5305\u542b vet \u7684\u8fb9\n    for vertex in @adj_list\n      @adj_list[vertex.first].delete(vet) if @adj_list[vertex.first].include?(vet)\n    end\n  end\n\n  ### \u6253\u5370\u90bb\u63a5\u8868 ###\n  def __print__\n    puts '\u90bb\u63a5\u8868 ='\n    for vertex in @adj_list\n      tmp = @adj_list[vertex.first].map { |v| v.val }\n      puts \"#{vertex.first.val}: #{tmp},\"\n    end\n  end\nend\n
    graph_adjacency_list.zig
    [class]{GraphAdjList}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_graph/graph_operations/#923","title":"9.2.3 \u00a0 \u6548\u7387\u5bf9\u6bd4","text":"

    \u8bbe\u56fe\u4e2d\u5171\u6709 \\(n\\) \u4e2a\u9876\u70b9\u548c \\(m\\) \u6761\u8fb9\uff0c\u8868 9-2 \u5bf9\u6bd4\u4e86\u90bb\u63a5\u77e9\u9635\u548c\u90bb\u63a5\u8868\u7684\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u3002

    \u8868 9-2 \u00a0 \u90bb\u63a5\u77e9\u9635\u4e0e\u90bb\u63a5\u8868\u5bf9\u6bd4

    \u90bb\u63a5\u77e9\u9635 \u90bb\u63a5\u8868\uff08\u94fe\u8868\uff09 \u90bb\u63a5\u8868\uff08\u54c8\u5e0c\u8868\uff09 \u5224\u65ad\u662f\u5426\u90bb\u63a5 \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) \u6dfb\u52a0\u8fb9 \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) \u5220\u9664\u8fb9 \\(O(1)\\) \\(O(m)\\) \\(O(1)\\) \u6dfb\u52a0\u9876\u70b9 \\(O(n)\\) \\(O(1)\\) \\(O(1)\\) \u5220\u9664\u9876\u70b9 \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n)\\) \u5185\u5b58\u7a7a\u95f4\u5360\u7528 \\(O(n^2)\\) \\(O(n + m)\\) \\(O(n + m)\\)

    \u89c2\u5bdf\u8868 9-2 \uff0c\u4f3c\u4e4e\u90bb\u63a5\u8868\uff08\u54c8\u5e0c\u8868\uff09\u7684\u65f6\u95f4\u6548\u7387\u4e0e\u7a7a\u95f4\u6548\u7387\u6700\u4f18\u3002\u4f46\u5b9e\u9645\u4e0a\uff0c\u5728\u90bb\u63a5\u77e9\u9635\u4e2d\u64cd\u4f5c\u8fb9\u7684\u6548\u7387\u66f4\u9ad8\uff0c\u53ea\u9700\u4e00\u6b21\u6570\u7ec4\u8bbf\u95ee\u6216\u8d4b\u503c\u64cd\u4f5c\u5373\u53ef\u3002\u7efc\u5408\u6765\u770b\uff0c\u90bb\u63a5\u77e9\u9635\u4f53\u73b0\u4e86\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\u7684\u539f\u5219\uff0c\u800c\u90bb\u63a5\u8868\u4f53\u73b0\u4e86\u201c\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4\u201d\u7684\u539f\u5219\u3002

    "},{"location":"chapter_graph/graph_traversal/","title":"9.3 \u00a0 \u56fe\u7684\u904d\u5386","text":"

    \u6811\u4ee3\u8868\u7684\u662f\u201c\u4e00\u5bf9\u591a\u201d\u7684\u5173\u7cfb\uff0c\u800c\u56fe\u5219\u5177\u6709\u66f4\u9ad8\u7684\u81ea\u7531\u5ea6\uff0c\u53ef\u4ee5\u8868\u793a\u4efb\u610f\u7684\u201c\u591a\u5bf9\u591a\u201d\u5173\u7cfb\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u6811\u770b\u4f5c\u56fe\u7684\u4e00\u79cd\u7279\u4f8b\u3002\u663e\u7136\uff0c\u6811\u7684\u904d\u5386\u64cd\u4f5c\u4e5f\u662f\u56fe\u7684\u904d\u5386\u64cd\u4f5c\u7684\u4e00\u79cd\u7279\u4f8b\u3002

    \u56fe\u548c\u6811\u90fd\u9700\u8981\u5e94\u7528\u641c\u7d22\u7b97\u6cd5\u6765\u5b9e\u73b0\u904d\u5386\u64cd\u4f5c\u3002\u56fe\u7684\u904d\u5386\u65b9\u5f0f\u4e5f\u53ef\u5206\u4e3a\u4e24\u79cd\uff1a\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u548c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u3002

    "},{"location":"chapter_graph/graph_traversal/#931","title":"9.3.1 \u00a0 \u5e7f\u5ea6\u4f18\u5148\u904d\u5386","text":"

    \u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u7531\u8fd1\u53ca\u8fdc\u7684\u904d\u5386\u65b9\u5f0f\uff0c\u4ece\u67d0\u4e2a\u8282\u70b9\u51fa\u53d1\uff0c\u59cb\u7ec8\u4f18\u5148\u8bbf\u95ee\u8ddd\u79bb\u6700\u8fd1\u7684\u9876\u70b9\uff0c\u5e76\u4e00\u5c42\u5c42\u5411\u5916\u6269\u5f20\u3002\u5982\u56fe 9-9 \u6240\u793a\uff0c\u4ece\u5de6\u4e0a\u89d2\u9876\u70b9\u51fa\u53d1\uff0c\u9996\u5148\u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\uff0c\u7136\u540e\u904d\u5386\u4e0b\u4e00\u4e2a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u6240\u6709\u9876\u70b9\u8bbf\u95ee\u5b8c\u6bd5\u3002

    \u56fe 9-9 \u00a0 \u56fe\u7684\u5e7f\u5ea6\u4f18\u5148\u904d\u5386

    "},{"location":"chapter_graph/graph_traversal/#1","title":"1. \u00a0 \u7b97\u6cd5\u5b9e\u73b0","text":"

    BFS \u901a\u5e38\u501f\u52a9\u961f\u5217\u6765\u5b9e\u73b0\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\u3002\u961f\u5217\u5177\u6709\u201c\u5148\u5165\u5148\u51fa\u201d\u7684\u6027\u8d28\uff0c\u8fd9\u4e0e BFS \u7684\u201c\u7531\u8fd1\u53ca\u8fdc\u201d\u7684\u601d\u60f3\u5f02\u66f2\u540c\u5de5\u3002

    1. \u5c06\u904d\u5386\u8d77\u59cb\u9876\u70b9 startVet \u52a0\u5165\u961f\u5217\uff0c\u5e76\u5f00\u542f\u5faa\u73af\u3002
    2. \u5728\u5faa\u73af\u7684\u6bcf\u8f6e\u8fed\u4ee3\u4e2d\uff0c\u5f39\u51fa\u961f\u9996\u9876\u70b9\u5e76\u8bb0\u5f55\u8bbf\u95ee\uff0c\u7136\u540e\u5c06\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\u52a0\u5165\u5230\u961f\u5217\u5c3e\u90e8\u3002
    3. \u5faa\u73af\u6b65\u9aa4 2. \uff0c\u76f4\u5230\u6240\u6709\u9876\u70b9\u88ab\u8bbf\u95ee\u5b8c\u6bd5\u540e\u7ed3\u675f\u3002

    \u4e3a\u4e86\u9632\u6b62\u91cd\u590d\u904d\u5386\u9876\u70b9\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408 visited \u6765\u8bb0\u5f55\u54ea\u4e9b\u8282\u70b9\u5df2\u88ab\u8bbf\u95ee\u3002

    Tip

    \u54c8\u5e0c\u96c6\u5408\u53ef\u4ee5\u770b\u4f5c\u4e00\u4e2a\u53ea\u5b58\u50a8 key \u800c\u4e0d\u5b58\u50a8 value \u7684\u54c8\u5e0c\u8868\uff0c\u5b83\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u590d\u6742\u5ea6\u4e0b\u8fdb\u884c key \u7684\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u3002\u6839\u636e key \u7684\u552f\u4e00\u6027\uff0c\u54c8\u5e0c\u96c6\u5408\u901a\u5e38\u7528\u4e8e\u6570\u636e\u53bb\u91cd\u7b49\u573a\u666f\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_bfs.py
    def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]([start_vet])\n    # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    que = deque[Vertex]([start_vet])\n    # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while len(que) > 0:\n        vet = que.popleft()  # \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adj_vet in graph.adj_list[vet]:\n            if adj_vet in visited:\n                continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.append(adj_vet)  # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adj_vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n
    graph_bfs.cpp
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphBFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited = {startVet};\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    queue<Vertex *> que;\n    que.push(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.empty()) {\n        Vertex *vet = que.front();\n        que.pop();          // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push_back(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (auto adjVet : graph.adjList[vet]) {\n            if (visited.count(adjVet))\n                continue;            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.push(adjVet);        // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.emplace(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.java
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new LinkedList<>();\n    que.offer(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        Vertex vet = que.poll(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet);            // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (Vertex adjVet : graph.adjList.get(vet)) {\n            if (visited.contains(adjVet))\n                continue;        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.cs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphBFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [startVet];\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue<Vertex> que = new();\n    que.Enqueue(startVet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.Count > 0) {\n        Vertex vet = que.Dequeue(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.Add(vet);               // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        foreach (Vertex adjVet in graph.adjList[vet]) {\n            if (visited.Contains(adjVet)) {\n                continue;          // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.Enqueue(adjVet);   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.Add(adjVet);   // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.go
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    visited[startVet] = struct{}{}\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS, \u4f7f\u7528\u5207\u7247\u6a21\u62df\u961f\u5217\n    queue := make([]Vertex, 0)\n    queue = append(queue, startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    for len(queue) > 0 {\n        // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        vet := queue[0]\n        queue = queue[1:]\n        // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        res = append(res, vet)\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for _, adjVet := range g.adjList[vet] {\n            _, isExist := visited[adjVet]\n            // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            if !isExist {\n                queue = append(queue, adjVet)\n                visited[adjVet] = struct{}{}\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.swift
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphBFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = [startVet]\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    var que: [Vertex] = [startVet]\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.isEmpty {\n        let vet = que.removeFirst() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for adjVet in graph.adjList[vet] ?? [] {\n            if visited.contains(adjVet) {\n                continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.append(adjVet) // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.insert(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.js
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.ts
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphBFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    visited.add(startVet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    const que = [startVet];\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (que.length) {\n        const vet = que.shift(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (const adjVet of graph.adjList.get(vet) ?? []) {\n            if (visited.has(adjVet)) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            que.push(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\n            visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res;\n}\n
    graph_bfs.dart
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {\n  // \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  visited.add(startVet);\n  // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  Queue<Vertex> que = Queue();\n  que.add(startVet);\n  // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while (que.isNotEmpty) {\n    Vertex vet = que.removeFirst(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet in graph.adjList[vet]!) {\n      if (visited.contains(adjVet)) {\n        continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      }\n      que.add(adjVet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adjVet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    }\n  }\n  // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  return res;\n}\n
    graph_bfs.rs
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    visited.insert(start_vet);\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    let mut que = VecDeque::new();\n    que.push_back(start_vet);\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while !que.is_empty() {\n        let vet = que.pop_front().unwrap(); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        if let Some(adj_vets) = graph.adj_list.get(&vet) {\n            for &adj_vet in adj_vets {\n                if visited.contains(&adj_vet) {\n                    continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n                }\n                que.push_back(adj_vet); // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited.insert(adj_vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res\n}\n
    graph_bfs.c
    /* \u8282\u70b9\u961f\u5217\u7ed3\u6784\u4f53 */\ntypedef struct {\n    Vertex *vertices[MAX_SIZE];\n    int front, rear, size;\n} Queue;\n\n/* \u6784\u9020\u51fd\u6570 */\nQueue *newQueue() {\n    Queue *q = (Queue *)malloc(sizeof(Queue));\n    q->front = q->rear = q->size = 0;\n    return q;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nint isEmpty(Queue *q) {\n    return q->size == 0;\n}\n\n/* \u5165\u961f\u64cd\u4f5c */\nvoid enqueue(Queue *q, Vertex *vet) {\n    q->vertices[q->rear] = vet;\n    q->rear = (q->rear + 1) % MAX_SIZE;\n    q->size++;\n}\n\n/* \u51fa\u961f\u64cd\u4f5c */\nVertex *dequeue(Queue *q) {\n    Vertex *vet = q->vertices[q->front];\n    q->front = (q->front + 1) % MAX_SIZE;\n    q->size--;\n    return vet;\n}\n\n/* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **visited, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (visited[i] == vet)\n            return 1;\n    }\n    return 0;\n}\n\n/* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphBFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize, Vertex **visited, int *visitedSize) {\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    Queue *queue = newQueue();\n    enqueue(queue, startVet);\n    visited[(*visitedSize)++] = startVet;\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!isEmpty(queue)) {\n        Vertex *vet = dequeue(queue); // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res[(*resSize)++] = vet;      // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        AdjListNode *node = findNode(graph, vet);\n        while (node != NULL) {\n            // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            if (!isVisited(visited, *visitedSize, node->vertex)) {\n                enqueue(queue, node->vertex);             // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n                visited[(*visitedSize)++] = node->vertex; // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n            }\n            node = node->next;\n        }\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(queue);\n}\n
    graph_bfs.kt
    /* \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphBFS(graph: GraphAdjList, startVet: Vertex): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex>()\n    visited.add(startVet)\n    // \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n    val que = LinkedList<Vertex>()\n    que.offer(startVet)\n    // \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n    while (!que.isEmpty()) {\n        val vet = que.poll() // \u961f\u9996\u9876\u70b9\u51fa\u961f\n        res.add(vet)         // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n        // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n        for (adjVet in graph.adjList[vet]!!) {\n            if (visited.contains(adjVet))\n                continue        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            que.offer(adjVet)   // \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n            visited.add(adjVet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n        }\n    }\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_bfs.rb
    ### \u5e7f\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_bfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new([start_vet])\n  # \u961f\u5217\u7528\u4e8e\u5b9e\u73b0 BFS\n  que = [start_vet]\n  # \u4ee5\u9876\u70b9 vet \u4e3a\u8d77\u70b9\uff0c\u5faa\u73af\u76f4\u81f3\u8bbf\u95ee\u5b8c\u6240\u6709\u9876\u70b9\n  while que.length > 0\n    vet = que.shift # \u961f\u9996\u9876\u70b9\u51fa\u961f\n    res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adj_vet in graph.adj_list[vet]\n      next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n      que << adj_vet # \u53ea\u5165\u961f\u672a\u8bbf\u95ee\u7684\u9876\u70b9\n      visited.add(adj_vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    end\n  end\n  # \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res\nend\n
    graph_bfs.zig
    [class]{}-[func]{graphBFS}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4ee3\u7801\u76f8\u5bf9\u62bd\u8c61\uff0c\u5efa\u8bae\u5bf9\u7167\u56fe 9-10 \u6765\u52a0\u6df1\u7406\u89e3\u3002

    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 9-10 \u00a0 \u56fe\u7684\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u6b65\u9aa4

    \u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u7684\u5e8f\u5217\u662f\u5426\u552f\u4e00\uff1f

    \u4e0d\u552f\u4e00\u3002\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u53ea\u8981\u6c42\u6309\u201c\u7531\u8fd1\u53ca\u8fdc\u201d\u7684\u987a\u5e8f\u904d\u5386\uff0c\u800c\u591a\u4e2a\u76f8\u540c\u8ddd\u79bb\u7684\u9876\u70b9\u7684\u904d\u5386\u987a\u5e8f\u5141\u8bb8\u88ab\u4efb\u610f\u6253\u4e71\u3002\u4ee5\u56fe 9-10 \u4e3a\u4f8b\uff0c\u9876\u70b9 \\(1\\)\u3001\\(3\\) \u7684\u8bbf\u95ee\u987a\u5e8f\u53ef\u4ee5\u4ea4\u6362\uff0c\u9876\u70b9 \\(2\\)\u3001\\(4\\)\u3001\\(6\\) \u7684\u8bbf\u95ee\u987a\u5e8f\u4e5f\u53ef\u4ee5\u4efb\u610f\u4ea4\u6362\u3002

    "},{"location":"chapter_graph/graph_traversal/#2","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u6240\u6709\u9876\u70b9\u90fd\u4f1a\u5165\u961f\u5e76\u51fa\u961f\u4e00\u6b21\uff0c\u4f7f\u7528 \\(O(|V|)\\) \u65f6\u95f4\uff1b\u5728\u904d\u5386\u90bb\u63a5\u9876\u70b9\u7684\u8fc7\u7a0b\u4e2d\uff0c\u7531\u4e8e\u662f\u65e0\u5411\u56fe\uff0c\u56e0\u6b64\u6240\u6709\u8fb9\u90fd\u4f1a\u88ab\u8bbf\u95ee \\(2\\) \u6b21\uff0c\u4f7f\u7528 \\(O(2|E|)\\) \u65f6\u95f4\uff1b\u603b\u4f53\u4f7f\u7528 \\(O(|V| + |E|)\\) \u65f6\u95f4\u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5217\u8868 res \uff0c\u54c8\u5e0c\u96c6\u5408 visited \uff0c\u961f\u5217 que \u4e2d\u7684\u9876\u70b9\u6570\u91cf\u6700\u591a\u4e3a \\(|V|\\) \uff0c\u4f7f\u7528 \\(O(|V|)\\) \u7a7a\u95f4\u3002

    "},{"location":"chapter_graph/graph_traversal/#932","title":"9.3.2 \u00a0 \u6df1\u5ea6\u4f18\u5148\u904d\u5386","text":"

    \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u4f18\u5148\u8d70\u5230\u5e95\u3001\u65e0\u8def\u53ef\u8d70\u518d\u56de\u5934\u7684\u904d\u5386\u65b9\u5f0f\u3002\u5982\u56fe 9-11 \u6240\u793a\uff0c\u4ece\u5de6\u4e0a\u89d2\u9876\u70b9\u51fa\u53d1\uff0c\u8bbf\u95ee\u5f53\u524d\u9876\u70b9\u7684\u67d0\u4e2a\u90bb\u63a5\u9876\u70b9\uff0c\u76f4\u5230\u8d70\u5230\u5c3d\u5934\u65f6\u8fd4\u56de\uff0c\u518d\u7ee7\u7eed\u8d70\u5230\u5c3d\u5934\u5e76\u8fd4\u56de\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u81f3\u6240\u6709\u9876\u70b9\u904d\u5386\u5b8c\u6210\u3002

    \u56fe 9-11 \u00a0 \u56fe\u7684\u6df1\u5ea6\u4f18\u5148\u904d\u5386

    "},{"location":"chapter_graph/graph_traversal/#1_1","title":"1. \u00a0 \u7b97\u6cd5\u5b9e\u73b0","text":"

    \u8fd9\u79cd\u201c\u8d70\u5230\u5c3d\u5934\u518d\u8fd4\u56de\u201d\u7684\u7b97\u6cd5\u8303\u5f0f\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u6765\u5b9e\u73b0\u3002\u4e0e\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u7c7b\u4f3c\uff0c\u5728\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u4e2d\uff0c\u6211\u4eec\u4e5f\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u96c6\u5408 visited \u6765\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\uff0c\u4ee5\u907f\u514d\u91cd\u590d\u8bbf\u95ee\u9876\u70b9\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig graph_dfs.py
    def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570\"\"\"\n    res.append(vet)  # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet)  # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adj_list[vet]:\n        if adjVet in visited:\n            continue  # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n\ndef graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:\n    \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n    # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res = []\n    # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited = set[Vertex]()\n    dfs(graph, visited, res, start_vet)\n    return res\n
    graph_dfs.cpp
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList &graph, unordered_set<Vertex *> &visited, vector<Vertex *> &res, Vertex *vet) {\n    res.push_back(vet);   // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.emplace(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex *adjVet : graph.adjList[vet]) {\n        if (visited.count(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvector<Vertex *> graphDFS(GraphAdjList &graph, Vertex *startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    vector<Vertex *> res;\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    unordered_set<Vertex *> visited;\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.java
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList graph, Set<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (Vertex adjVet : graph.adjList.get(vet)) {\n        if (visited.contains(adjVet))\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = new ArrayList<>();\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    Set<Vertex> visited = new HashSet<>();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.cs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid DFS(GraphAdjList graph, HashSet<Vertex> visited, List<Vertex> res, Vertex vet) {\n    res.Add(vet);     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.Add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    foreach (Vertex adjVet in graph.adjList[vet]) {\n        if (visited.Contains(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9                             \n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        DFS(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nList<Vertex> GraphDFS(GraphAdjList graph, Vertex startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    List<Vertex> res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    HashSet<Vertex> visited = [];\n    DFS(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.go
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(g *graphAdjList, visited map[Vertex]struct{}, res *[]Vertex, vet Vertex) {\n    // append \u64cd\u4f5c\u4f1a\u8fd4\u56de\u65b0\u7684\u7684\u5f15\u7528\uff0c\u5fc5\u987b\u8ba9\u539f\u5f15\u7528\u91cd\u65b0\u8d4b\u503c\u4e3a\u65b0slice\u7684\u5f15\u7528\n    *res = append(*res, vet)\n    visited[vet] = struct{}{}\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for _, adjVet := range g.adjList[vet] {\n        _, isExist := visited[adjVet]\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        if !isExist {\n            dfs(g, visited, res, adjVet)\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(g *graphAdjList, startVet Vertex) []Vertex {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    res := make([]Vertex, 0)\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    visited := make(map[Vertex]struct{})\n    dfs(g, visited, &res, startVet)\n    // \u8fd4\u56de\u9876\u70b9\u904d\u5386\u5e8f\u5217\n    return res\n}\n
    graph_dfs.swift
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunc dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], vet: Vertex) {\n    res.append(vet) // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for adjVet in graph.adjList[vet] ?? [] {\n        if visited.contains(adjVet) {\n            continue // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph: graph, visited: &visited, res: &res, vet: adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunc graphDFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    var res: [Vertex] = []\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    var visited: Set<Vertex> = []\n    dfs(graph: graph, visited: &visited, res: &res, vet: startVet)\n    return res\n}\n
    graph_dfs.js
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction dfs(graph, visited, res, vet) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph, startVet) {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.ts
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfunction dfs(\n    graph: GraphAdjList,\n    visited: Set<Vertex>,\n    res: Vertex[],\n    vet: Vertex\n): void {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (const adjVet of graph.adjList.get(vet)) {\n        if (visited.has(adjVet)) {\n            continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        }\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet);\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfunction graphDFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    const res: Vertex[] = [];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    const visited: Set<Vertex> = new Set();\n    dfs(graph, visited, res, startVet);\n    return res;\n}\n
    graph_dfs.dart
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(\n  GraphAdjList graph,\n  Set<Vertex> visited,\n  List<Vertex> res,\n  Vertex vet,\n) {\n  res.add(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for (Vertex adjVet in graph.adjList[vet]!) {\n    if (visited.contains(adjVet)) {\n      continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    }\n    // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adjVet);\n  }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nList<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {\n  // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  List<Vertex> res = [];\n  // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  Set<Vertex> visited = {};\n  dfs(graph, visited, res, startVet);\n  return res;\n}\n
    graph_dfs.rs
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex>, vet: Vertex) {\n    res.push(vet); // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.insert(vet); // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n                         // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    if let Some(adj_vets) = graph.adj_list.get(&vet) {\n        for &adj_vet in adj_vets {\n            if visited.contains(&adj_vet) {\n                continue; // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n            }\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, visited, res, adj_vet);\n        }\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfn graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    let mut res = vec![];\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    let mut visited = HashSet::new();\n    dfs(&graph, &mut visited, &mut res, start_vet);\n\n    res\n}\n
    graph_dfs.c
    /* \u68c0\u67e5\u9876\u70b9\u662f\u5426\u5df2\u88ab\u8bbf\u95ee */\nint isVisited(Vertex **res, int size, Vertex *vet) {\n    // \u904d\u5386\u67e5\u627e\u8282\u70b9\uff0c\u4f7f\u7528 O(n) \u65f6\u95f4\n    for (int i = 0; i < size; i++) {\n        if (res[i] == vet) {\n            return 1;\n        }\n    }\n    return 0;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nvoid dfs(GraphAdjList *graph, Vertex **res, int *resSize, Vertex *vet) {\n    // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    res[(*resSize)++] = vet;\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    AdjListNode *node = findNode(graph, vet);\n    while (node != NULL) {\n        // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        if (!isVisited(res, *resSize, node->vertex)) {\n            // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n            dfs(graph, res, resSize, node->vertex);\n        }\n        node = node->next;\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nvoid graphDFS(GraphAdjList *graph, Vertex *startVet, Vertex **res, int *resSize) {\n    dfs(graph, res, resSize, startVet);\n}\n
    graph_dfs.kt
    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 */\nfun dfs(\n    graph: GraphAdjList,\n    visited: MutableSet<Vertex?>,\n    res: MutableList<Vertex?>,\n    vet: Vertex?\n) {\n    res.add(vet)     // \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n    visited.add(vet) // \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n    // \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n    for (adjVet in graph.adjList[vet]!!) {\n        if (visited.contains(adjVet))\n            continue  // \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n        // \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n        dfs(graph, visited, res, adjVet)\n    }\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n// \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\nfun graphDFS(graph: GraphAdjList, startVet: Vertex?): MutableList<Vertex?> {\n    // \u9876\u70b9\u904d\u5386\u5e8f\u5217\n    val res = mutableListOf<Vertex?>()\n    // \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n    val visited = HashSet<Vertex?>()\n    dfs(graph, visited, res, startVet)\n    return res\n}\n
    graph_dfs.rb
    ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u8f85\u52a9\u51fd\u6570 ###\ndef dfs(graph, visited, res, vet)\n  res << vet # \u8bb0\u5f55\u8bbf\u95ee\u9876\u70b9\n  visited.add(vet) # \u6807\u8bb0\u8be5\u9876\u70b9\u5df2\u88ab\u8bbf\u95ee\n  # \u904d\u5386\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  for adj_vet in graph.adj_list[vet]\n    next if visited.include?(adj_vet) # \u8df3\u8fc7\u5df2\u88ab\u8bbf\u95ee\u7684\u9876\u70b9\n    # \u9012\u5f52\u8bbf\u95ee\u90bb\u63a5\u9876\u70b9\n    dfs(graph, visited, res, adj_vet)\n  end\nend\n\n### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\ndef graph_dfs(graph, start_vet)\n  # \u4f7f\u7528\u90bb\u63a5\u8868\u6765\u8868\u793a\u56fe\uff0c\u4ee5\u4fbf\u83b7\u53d6\u6307\u5b9a\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\n  # \u9876\u70b9\u904d\u5386\u5e8f\u5217\n  res = []\n  # \u54c8\u5e0c\u96c6\u5408\uff0c\u7528\u4e8e\u8bb0\u5f55\u5df2\u88ab\u8bbf\u95ee\u8fc7\u7684\u9876\u70b9\n  visited = Set.new\n  dfs(graph, visited, res, start_vet)\n  res\nend\n
    graph_dfs.zig
    [class]{}-[func]{dfs}\n\n[class]{}-[func]{graphDFS}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u7684\u7b97\u6cd5\u6d41\u7a0b\u5982\u56fe 9-12 \u6240\u793a\u3002

    • \u76f4\u865a\u7ebf\u4ee3\u8868\u5411\u4e0b\u9012\u63a8\uff0c\u8868\u793a\u5f00\u542f\u4e86\u4e00\u4e2a\u65b0\u7684\u9012\u5f52\u65b9\u6cd5\u6765\u8bbf\u95ee\u65b0\u9876\u70b9\u3002
    • \u66f2\u865a\u7ebf\u4ee3\u8868\u5411\u4e0a\u56de\u6eaf\uff0c\u8868\u793a\u6b64\u9012\u5f52\u65b9\u6cd5\u5df2\u7ecf\u8fd4\u56de\uff0c\u56de\u6eaf\u5230\u4e86\u5f00\u542f\u6b64\u65b9\u6cd5\u7684\u4f4d\u7f6e\u3002

    \u4e3a\u4e86\u52a0\u6df1\u7406\u89e3\uff0c\u5efa\u8bae\u5c06\u56fe 9-12 \u4e0e\u4ee3\u7801\u7ed3\u5408\u8d77\u6765\uff0c\u5728\u8111\u4e2d\u6a21\u62df\uff08\u6216\u8005\u7528\u7b14\u753b\u4e0b\u6765\uff09\u6574\u4e2a DFS \u8fc7\u7a0b\uff0c\u5305\u62ec\u6bcf\u4e2a\u9012\u5f52\u65b9\u6cd5\u4f55\u65f6\u5f00\u542f\u3001\u4f55\u65f6\u8fd4\u56de\u3002

    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 9-12 \u00a0 \u56fe\u7684\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u6b65\u9aa4

    \u6df1\u5ea6\u4f18\u5148\u904d\u5386\u7684\u5e8f\u5217\u662f\u5426\u552f\u4e00\uff1f

    \u4e0e\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u7c7b\u4f3c\uff0c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u5e8f\u5217\u7684\u987a\u5e8f\u4e5f\u4e0d\u662f\u552f\u4e00\u7684\u3002\u7ed9\u5b9a\u67d0\u9876\u70b9\uff0c\u5148\u5f80\u54ea\u4e2a\u65b9\u5411\u63a2\u7d22\u90fd\u53ef\u4ee5\uff0c\u5373\u90bb\u63a5\u9876\u70b9\u7684\u987a\u5e8f\u53ef\u4ee5\u4efb\u610f\u6253\u4e71\uff0c\u90fd\u662f\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u3002

    \u4ee5\u6811\u7684\u904d\u5386\u4e3a\u4f8b\uff0c\u201c\u6839 \\(\\rightarrow\\) \u5de6 \\(\\rightarrow\\) \u53f3\u201d\u201c\u5de6 \\(\\rightarrow\\) \u6839 \\(\\rightarrow\\) \u53f3\u201d\u201c\u5de6 \\(\\rightarrow\\) \u53f3 \\(\\rightarrow\\) \u6839\u201d\u5206\u522b\u5bf9\u5e94\u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386\uff0c\u5b83\u4eec\u5c55\u793a\u4e86\u4e09\u79cd\u904d\u5386\u4f18\u5148\u7ea7\uff0c\u7136\u800c\u8fd9\u4e09\u8005\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u3002

    "},{"location":"chapter_graph/graph_traversal/#2_1","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    \u65f6\u95f4\u590d\u6742\u5ea6\uff1a\u6240\u6709\u9876\u70b9\u90fd\u4f1a\u88ab\u8bbf\u95ee \\(1\\) \u6b21\uff0c\u4f7f\u7528 \\(O(|V|)\\) \u65f6\u95f4\uff1b\u6240\u6709\u8fb9\u90fd\u4f1a\u88ab\u8bbf\u95ee \\(2\\) \u6b21\uff0c\u4f7f\u7528 \\(O(2|E|)\\) \u65f6\u95f4\uff1b\u603b\u4f53\u4f7f\u7528 \\(O(|V| + |E|)\\) \u65f6\u95f4\u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6\uff1a\u5217\u8868 res \uff0c\u54c8\u5e0c\u96c6\u5408 visited \u9876\u70b9\u6570\u91cf\u6700\u591a\u4e3a \\(|V|\\) \uff0c\u9012\u5f52\u6df1\u5ea6\u6700\u5927\u4e3a \\(|V|\\) \uff0c\u56e0\u6b64\u4f7f\u7528 \\(O(|V|)\\) \u7a7a\u95f4\u3002

    "},{"location":"chapter_graph/summary/","title":"9.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_graph/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u56fe\u7531\u9876\u70b9\u548c\u8fb9\u7ec4\u6210\uff0c\u53ef\u4ee5\u8868\u793a\u4e3a\u4e00\u7ec4\u9876\u70b9\u548c\u4e00\u7ec4\u8fb9\u6784\u6210\u7684\u96c6\u5408\u3002
    • \u76f8\u8f83\u4e8e\u7ebf\u6027\u5173\u7cfb\uff08\u94fe\u8868\uff09\u548c\u5206\u6cbb\u5173\u7cfb\uff08\u6811\uff09\uff0c\u7f51\u7edc\u5173\u7cfb\uff08\u56fe\uff09\u5177\u6709\u66f4\u9ad8\u7684\u81ea\u7531\u5ea6\uff0c\u56e0\u800c\u66f4\u4e3a\u590d\u6742\u3002
    • \u6709\u5411\u56fe\u7684\u8fb9\u5177\u6709\u65b9\u5411\u6027\uff0c\u8fde\u901a\u56fe\u4e2d\u7684\u4efb\u610f\u9876\u70b9\u5747\u53ef\u8fbe\uff0c\u6709\u6743\u56fe\u7684\u6bcf\u6761\u8fb9\u90fd\u5305\u542b\u6743\u91cd\u53d8\u91cf\u3002
    • \u90bb\u63a5\u77e9\u9635\u5229\u7528\u77e9\u9635\u6765\u8868\u793a\u56fe\uff0c\u6bcf\u4e00\u884c\uff08\u5217\uff09\u4ee3\u8868\u4e00\u4e2a\u9876\u70b9\uff0c\u77e9\u9635\u5143\u7d20\u4ee3\u8868\u8fb9\uff0c\u7528 \\(1\\) \u6216 \\(0\\) \u8868\u793a\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u6709\u8fb9\u6216\u65e0\u8fb9\u3002\u90bb\u63a5\u77e9\u9635\u5728\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u4e0a\u6548\u7387\u5f88\u9ad8\uff0c\u4f46\u7a7a\u95f4\u5360\u7528\u8f83\u591a\u3002
    • \u90bb\u63a5\u8868\u4f7f\u7528\u591a\u4e2a\u94fe\u8868\u6765\u8868\u793a\u56fe\uff0c\u7b2c \\(i\\) \u4e2a\u94fe\u8868\u5bf9\u5e94\u9876\u70b9 \\(i\\) \uff0c\u5176\u4e2d\u5b58\u50a8\u4e86\u8be5\u9876\u70b9\u7684\u6240\u6709\u90bb\u63a5\u9876\u70b9\u3002\u90bb\u63a5\u8868\u76f8\u5bf9\u4e8e\u90bb\u63a5\u77e9\u9635\u66f4\u52a0\u8282\u7701\u7a7a\u95f4\uff0c\u4f46\u7531\u4e8e\u9700\u8981\u904d\u5386\u94fe\u8868\u6765\u67e5\u627e\u8fb9\uff0c\u56e0\u6b64\u65f6\u95f4\u6548\u7387\u8f83\u4f4e\u3002
    • \u5f53\u90bb\u63a5\u8868\u4e2d\u7684\u94fe\u8868\u8fc7\u957f\u65f6\uff0c\u53ef\u4ee5\u5c06\u5176\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u6216\u54c8\u5e0c\u8868\uff0c\u4ece\u800c\u63d0\u5347\u67e5\u8be2\u6548\u7387\u3002
    • \u4ece\u7b97\u6cd5\u601d\u60f3\u7684\u89d2\u5ea6\u5206\u6790\uff0c\u90bb\u63a5\u77e9\u9635\u4f53\u73b0\u4e86\u201c\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4\u201d\uff0c\u90bb\u63a5\u8868\u4f53\u73b0\u4e86\u201c\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4\u201d\u3002
    • \u56fe\u53ef\u7528\u4e8e\u5efa\u6a21\u5404\u7c7b\u73b0\u5b9e\u7cfb\u7edf\uff0c\u5982\u793e\u4ea4\u7f51\u7edc\u3001\u5730\u94c1\u7ebf\u8def\u7b49\u3002
    • \u6811\u662f\u56fe\u7684\u4e00\u79cd\u7279\u4f8b\uff0c\u6811\u7684\u904d\u5386\u4e5f\u662f\u56fe\u7684\u904d\u5386\u7684\u4e00\u79cd\u7279\u4f8b\u3002
    • \u56fe\u7684\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u7531\u8fd1\u53ca\u8fdc\u3001\u5c42\u5c42\u6269\u5f20\u7684\u641c\u7d22\u65b9\u5f0f\uff0c\u901a\u5e38\u501f\u52a9\u961f\u5217\u5b9e\u73b0\u3002
    • \u56fe\u7684\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u662f\u4e00\u79cd\u4f18\u5148\u8d70\u5230\u5e95\u3001\u65e0\u8def\u53ef\u8d70\u65f6\u518d\u56de\u6eaf\u7684\u641c\u7d22\u65b9\u5f0f\uff0c\u5e38\u57fa\u4e8e\u9012\u5f52\u6765\u5b9e\u73b0\u3002
    "},{"location":"chapter_graph/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u8def\u5f84\u7684\u5b9a\u4e49\u662f\u9876\u70b9\u5e8f\u5217\u8fd8\u662f\u8fb9\u5e8f\u5217\uff1f

    \u7ef4\u57fa\u767e\u79d1\u4e0a\u4e0d\u540c\u8bed\u8a00\u7248\u672c\u7684\u5b9a\u4e49\u4e0d\u4e00\u81f4\uff1a\u82f1\u6587\u7248\u662f\u201c\u8def\u5f84\u662f\u4e00\u4e2a\u8fb9\u5e8f\u5217\u201d\uff0c\u800c\u4e2d\u6587\u7248\u662f\u201c\u8def\u5f84\u662f\u4e00\u4e2a\u9876\u70b9\u5e8f\u5217\u201d\u3002\u4ee5\u4e0b\u662f\u82f1\u6587\u7248\u539f\u6587\uff1aIn graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices.

    \u5728\u672c\u6587\u4e2d\uff0c\u8def\u5f84\u88ab\u89c6\u4e3a\u4e00\u4e2a\u8fb9\u5e8f\u5217\uff0c\u800c\u4e0d\u662f\u4e00\u4e2a\u9876\u70b9\u5e8f\u5217\u3002\u8fd9\u662f\u56e0\u4e3a\u4e24\u4e2a\u9876\u70b9\u4e4b\u95f4\u53ef\u80fd\u5b58\u5728\u591a\u6761\u8fb9\u8fde\u63a5\uff0c\u6b64\u65f6\u6bcf\u6761\u8fb9\u90fd\u5bf9\u5e94\u4e00\u6761\u8def\u5f84\u3002

    Q\uff1a\u975e\u8fde\u901a\u56fe\u4e2d\u662f\u5426\u4f1a\u6709\u65e0\u6cd5\u904d\u5386\u5230\u7684\u70b9\uff1f

    \u5728\u975e\u8fde\u901a\u56fe\u4e2d\uff0c\u4ece\u67d0\u4e2a\u9876\u70b9\u51fa\u53d1\uff0c\u81f3\u5c11\u6709\u4e00\u4e2a\u9876\u70b9\u65e0\u6cd5\u5230\u8fbe\u3002\u904d\u5386\u975e\u8fde\u901a\u56fe\u9700\u8981\u8bbe\u7f6e\u591a\u4e2a\u8d77\u70b9\uff0c\u4ee5\u904d\u5386\u5230\u56fe\u7684\u6240\u6709\u8fde\u901a\u5206\u91cf\u3002

    Q\uff1a\u5728\u90bb\u63a5\u8868\u4e2d\uff0c\u201c\u4e0e\u8be5\u9876\u70b9\u76f8\u8fde\u7684\u6240\u6709\u9876\u70b9\u201d\u7684\u9876\u70b9\u987a\u5e8f\u662f\u5426\u6709\u8981\u6c42\uff1f

    \u53ef\u4ee5\u662f\u4efb\u610f\u987a\u5e8f\u3002\u4f46\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u53ef\u80fd\u9700\u8981\u6309\u7167\u6307\u5b9a\u89c4\u5219\u6765\u6392\u5e8f\uff0c\u6bd4\u5982\u6309\u7167\u9876\u70b9\u6dfb\u52a0\u7684\u6b21\u5e8f\uff0c\u6216\u8005\u6309\u7167\u9876\u70b9\u503c\u5927\u5c0f\u7684\u987a\u5e8f\u7b49\uff0c\u8fd9\u6837\u6709\u52a9\u4e8e\u5feb\u901f\u67e5\u627e\u201c\u5e26\u6709\u67d0\u79cd\u6781\u503c\u201d\u7684\u9876\u70b9\u3002

    "},{"location":"chapter_greedy/","title":"\u7b2c 15 \u7ae0 \u00a0 \u8d2a\u5fc3","text":"

    Abstract

    \u5411\u65e5\u8475\u671d\u7740\u592a\u9633\u8f6c\u52a8\uff0c\u65f6\u523b\u8ffd\u6c42\u81ea\u8eab\u6210\u957f\u7684\u6700\u5927\u53ef\u80fd\u3002

    \u8d2a\u5fc3\u7b56\u7565\u5728\u4e00\u8f6e\u8f6e\u7684\u7b80\u5355\u9009\u62e9\u4e2d\uff0c\u9010\u6b65\u5bfc\u5411\u6700\u4f73\u7b54\u6848\u3002

    "},{"location":"chapter_greedy/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 15.1 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5
    • 15.2 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898
    • 15.3 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898
    • 15.4 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u95ee\u9898
    • 15.5 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_greedy/fractional_knapsack_problem/","title":"15.2 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a \\(n\\) \u4e2a\u7269\u54c1\uff0c\u7b2c \\(i\\) \u4e2a\u7269\u54c1\u7684\u91cd\u91cf\u4e3a \\(wgt[i-1]\\)\u3001\u4ef7\u503c\u4e3a \\(val[i-1]\\) \uff0c\u548c\u4e00\u4e2a\u5bb9\u91cf\u4e3a \\(cap\\) \u7684\u80cc\u5305\u3002\u6bcf\u4e2a\u7269\u54c1\u53ea\u80fd\u9009\u62e9\u4e00\u6b21\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u7269\u54c1\u7684\u4e00\u90e8\u5206\uff0c\u4ef7\u503c\u6839\u636e\u9009\u62e9\u7684\u91cd\u91cf\u6bd4\u4f8b\u8ba1\u7b97\uff0c\u95ee\u5728\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u80cc\u5305\u4e2d\u7269\u54c1\u7684\u6700\u5927\u4ef7\u503c\u3002\u793a\u4f8b\u5982\u56fe 15-3 \u6240\u793a\u3002

    \u56fe 15-3 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    \u5206\u6570\u80cc\u5305\u95ee\u9898\u548c 0-1 \u80cc\u5305\u95ee\u9898\u6574\u4f53\u4e0a\u975e\u5e38\u76f8\u4f3c\uff0c\u72b6\u6001\u5305\u542b\u5f53\u524d\u7269\u54c1 \\(i\\) \u548c\u5bb9\u91cf \\(c\\) \uff0c\u76ee\u6807\u662f\u6c42\u9650\u5b9a\u80cc\u5305\u5bb9\u91cf\u4e0b\u7684\u6700\u5927\u4ef7\u503c\u3002

    \u4e0d\u540c\u70b9\u5728\u4e8e\uff0c\u672c\u9898\u5141\u8bb8\u53ea\u9009\u62e9\u7269\u54c1\u7684\u4e00\u90e8\u5206\u3002\u5982\u56fe 15-4 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u7269\u54c1\u4efb\u610f\u5730\u8fdb\u884c\u5207\u5206\uff0c\u5e76\u6309\u7167\u91cd\u91cf\u6bd4\u4f8b\u6765\u8ba1\u7b97\u76f8\u5e94\u4ef7\u503c\u3002

    1. \u5bf9\u4e8e\u7269\u54c1 \\(i\\) \uff0c\u5b83\u5728\u5355\u4f4d\u91cd\u91cf\u4e0b\u7684\u4ef7\u503c\u4e3a \\(val[i-1] / wgt[i-1]\\) \uff0c\u7b80\u79f0\u5355\u4f4d\u4ef7\u503c\u3002
    2. \u5047\u8bbe\u653e\u5165\u4e00\u90e8\u5206\u7269\u54c1 \\(i\\) \uff0c\u91cd\u91cf\u4e3a \\(w\\) \uff0c\u5219\u80cc\u5305\u589e\u52a0\u7684\u4ef7\u503c\u4e3a \\(w \\times val[i-1] / wgt[i-1]\\) \u3002

    \u56fe 15-4 \u00a0 \u7269\u54c1\u5728\u5355\u4f4d\u91cd\u91cf\u4e0b\u7684\u4ef7\u503c

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#1","title":"1. \u00a0 \u8d2a\u5fc3\u7b56\u7565\u786e\u5b9a","text":"

    \u6700\u5927\u5316\u80cc\u5305\u5185\u7269\u54c1\u603b\u4ef7\u503c\uff0c\u672c\u8d28\u4e0a\u662f\u6700\u5927\u5316\u5355\u4f4d\u91cd\u91cf\u4e0b\u7684\u7269\u54c1\u4ef7\u503c\u3002\u7531\u6b64\u4fbf\u53ef\u63a8\u7406\u51fa\u56fe 15-5 \u6240\u793a\u7684\u8d2a\u5fc3\u7b56\u7565\u3002

    1. \u5c06\u7269\u54c1\u6309\u7167\u5355\u4f4d\u4ef7\u503c\u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\u3002
    2. \u904d\u5386\u6240\u6709\u7269\u54c1\uff0c\u6bcf\u8f6e\u8d2a\u5fc3\u5730\u9009\u62e9\u5355\u4f4d\u4ef7\u503c\u6700\u9ad8\u7684\u7269\u54c1\u3002
    3. \u82e5\u5269\u4f59\u80cc\u5305\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u4f7f\u7528\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u586b\u6ee1\u80cc\u5305\u3002

    \u56fe 15-5 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898\u7684\u8d2a\u5fc3\u7b56\u7565

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u6211\u4eec\u5efa\u7acb\u4e86\u4e00\u4e2a\u7269\u54c1\u7c7b Item \uff0c\u4ee5\u4fbf\u5c06\u7269\u54c1\u6309\u7167\u5355\u4f4d\u4ef7\u503c\u8fdb\u884c\u6392\u5e8f\u3002\u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u5f53\u80cc\u5305\u5df2\u6ee1\u65f6\u8df3\u51fa\u5e76\u8fd4\u56de\u89e3\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig fractional_knapsack.py
    class Item:\n    \"\"\"\u7269\u54c1\"\"\"\n\n    def __init__(self, w: int, v: int):\n        self.w = w  # \u7269\u54c1\u91cd\u91cf\n        self.v = v  # \u7269\u54c1\u4ef7\u503c\n\ndef fractional_knapsack(wgt: list[int], val: list[int], cap: int) -> int:\n    \"\"\"\u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3\"\"\"\n    # \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    items = [Item(w, v) for w, v in zip(wgt, val)]\n    # \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort(key=lambda item: item.v / item.w, reverse=True)\n    # \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    res = 0\n    for item in items:\n        if item.w <= cap:\n            # \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v\n            cap -= item.w\n        else:\n            # \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap\n            # \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n    return res\n
    fractional_knapsack.cpp
    /* \u7269\u54c1 */\nclass Item {\n  public:\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n\n    Item(int w, int v) : w(w), v(v) {\n    }\n};\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(vector<int> &wgt, vector<int> &val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    vector<Item> items;\n    for (int i = 0; i < wgt.size(); i++) {\n        items.push_back(Item(wgt[i], val[i]));\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    sort(items.begin(), items.end(), [](Item &a, Item &b) { return (double)a.v / a.w > (double)b.v / b.w; });\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    for (auto &item : items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double)item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.java
    /* \u7269\u54c1 */\nclass Item {\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n\n    public Item(int w, int v) {\n        this.w = w;\n        this.v = v;\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(int[] wgt, int[] val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item[] items = new Item[wgt.length];\n    for (int i = 0; i < wgt.length; i++) {\n        items[i] = new Item(wgt[i], val[i]);\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    Arrays.sort(items, Comparator.comparingDouble(item -> -((double) item.v / item.w)));\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    for (Item item : items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double) item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.cs
    /* \u7269\u54c1 */\nclass Item(int w, int v) {\n    public int w = w; // \u7269\u54c1\u91cd\u91cf\n    public int v = v; // \u7269\u54c1\u4ef7\u503c\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble FractionalKnapsack(int[] wgt, int[] val, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item[] items = new Item[wgt.Length];\n    for (int i = 0; i < wgt.Length; i++) {\n        items[i] = new Item(wgt[i], val[i]);\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    Array.Sort(items, (x, y) => (y.v / y.w).CompareTo(x.v / x.w));\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    double res = 0;\n    foreach (Item item in items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (double)item.v / item.w * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.go
    /* \u7269\u54c1 */\ntype Item struct {\n    w int // \u7269\u54c1\u91cd\u91cf\n    v int // \u7269\u54c1\u4ef7\u503c\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunc fractionalKnapsack(wgt []int, val []int, cap int) float64 {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    items := make([]Item, len(wgt))\n    for i := 0; i < len(wgt); i++ {\n        items[i] = Item{wgt[i], val[i]}\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    sort.Slice(items, func(i, j int) bool {\n        return float64(items[i].v)/float64(items[i].w) > float64(items[j].v)/float64(items[j].w)\n    })\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    res := 0.0\n    for _, item := range items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += float64(item.v)\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += float64(item.v) / float64(item.w) * float64(cap)\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.swift
    /* \u7269\u54c1 */\nclass Item {\n    var w: Int // \u7269\u54c1\u91cd\u91cf\n    var v: Int // \u7269\u54c1\u4ef7\u503c\n\n    init(w: Int, v: Int) {\n        self.w = w\n        self.v = v\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunc fractionalKnapsack(wgt: [Int], val: [Int], cap: Int) -> Double {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    var items = zip(wgt, val).map { Item(w: $0, v: $1) }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    var res = 0.0\n    var cap = cap\n    for item in items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += Double(item.v)\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += Double(item.v) / Double(item.w) * Double(cap)\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.js
    /* \u7269\u54c1 */\nclass Item {\n    constructor(w, v) {\n        this.w = w; // \u7269\u54c1\u91cd\u91cf\n        this.v = v; // \u7269\u54c1\u4ef7\u503c\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunction fractionalKnapsack(wgt, val, cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    const items = wgt.map((w, i) => new Item(w, val[i]));\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort((a, b) => b.v / b.w - a.v / a.w);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let res = 0;\n    for (const item of items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.ts
    /* \u7269\u54c1 */\nclass Item {\n    w: number; // \u7269\u54c1\u91cd\u91cf\n    v: number; // \u7269\u54c1\u4ef7\u503c\n\n    constructor(w: number, v: number) {\n        this.w = w;\n        this.v = v;\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfunction fractionalKnapsack(wgt: number[], val: number[], cap: number): number {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    const items: Item[] = wgt.map((w, i) => new Item(w, val[i]));\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort((a, b) => b.v / b.w - a.v / a.w);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let res = 0;\n    for (const item of items) {\n        if (item.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (item.v / item.w) * cap;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    return res;\n}\n
    fractional_knapsack.dart
    /* \u7269\u54c1 */\nclass Item {\n  int w; // \u7269\u54c1\u91cd\u91cf\n  int v; // \u7269\u54c1\u4ef7\u503c\n\n  Item(this.w, this.v);\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\ndouble fractionalKnapsack(List<int> wgt, List<int> val, int cap) {\n  // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n  List<Item> items = List.generate(wgt.length, (i) => Item(wgt[i], val[i]));\n  // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n  items.sort((a, b) => (b.v / b.w).compareTo(a.v / a.w));\n  // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n  double res = 0;\n  for (Item item in items) {\n    if (item.w <= cap) {\n      // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n      res += item.v;\n      cap -= item.w;\n    } else {\n      // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n      res += item.v / item.w * cap;\n      // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n      break;\n    }\n  }\n  return res;\n}\n
    fractional_knapsack.rs
    /* \u7269\u54c1 */\nstruct Item {\n    w: i32, // \u7269\u54c1\u91cd\u91cf\n    v: i32, // \u7269\u54c1\u4ef7\u503c\n}\n\nimpl Item {\n    fn new(w: i32, v: i32) -> Self {\n        Self { w, v }\n    }\n}\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfn fractional_knapsack(wgt: &[i32], val: &[i32], mut cap: i32) -> f64 {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    let mut items = wgt\n        .iter()\n        .zip(val.iter())\n        .map(|(&w, &v)| Item::new(w, v))\n        .collect::<Vec<Item>>();\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sort_by(|a, b| {\n        (b.v as f64 / b.w as f64)\n            .partial_cmp(&(a.v as f64 / a.w as f64))\n            .unwrap()\n    });\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    let mut res = 0.0;\n    for item in &items {\n        if item.w <= cap {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v as f64;\n            cap -= item.w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += item.v as f64 / item.w as f64 * cap as f64;\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    res\n}\n
    fractional_knapsack.c
    /* \u7269\u54c1 */\ntypedef struct {\n    int w; // \u7269\u54c1\u91cd\u91cf\n    int v; // \u7269\u54c1\u4ef7\u503c\n} Item;\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfloat fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    Item *items = malloc(sizeof(Item) * itemCount);\n    for (int i = 0; i < itemCount; i++) {\n        items[i] = (Item){.w = wgt[i], .v = val[i]};\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    qsort(items, (size_t)itemCount, sizeof(Item), sortByValueDensity);\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    float res = 0.0;\n    for (int i = 0; i < itemCount; i++) {\n        if (items[i].w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += items[i].v;\n            cap -= items[i].w;\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += (float)cap / items[i].w * items[i].v;\n            cap = 0;\n            break;\n        }\n    }\n    free(items);\n    return res;\n}\n
    fractional_knapsack.kt
    /* \u7269\u54c1 */\nclass Item(\n    val w: Int, // \u7269\u54c1\n    val v: Int  // \u7269\u54c1\u4ef7\u503c\n)\n\n/* \u5206\u6570\u80cc\u5305\uff1a\u8d2a\u5fc3 */\nfun fractionalKnapsack(wgt: IntArray, _val: IntArray, c: Int): Double {\n    // \u521b\u5efa\u7269\u54c1\u5217\u8868\uff0c\u5305\u542b\u4e24\u4e2a\u5c5e\u6027\uff1a\u91cd\u91cf\u3001\u4ef7\u503c\n    var cap = c\n    val items = arrayOfNulls<Item>(wgt.size)\n    for (i in wgt.indices) {\n        items[i] = Item(wgt[i], _val[i])\n    }\n    // \u6309\u7167\u5355\u4f4d\u4ef7\u503c item.v / item.w \u4ece\u9ad8\u5230\u4f4e\u8fdb\u884c\u6392\u5e8f\n    items.sortBy { item: Item? -> -(item!!.v.toDouble() / item.w) }\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\n    var res = 0.0\n    for (item in items) {\n        if (item!!.w <= cap) {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u5145\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u6574\u4e2a\u88c5\u8fdb\u80cc\u5305\n            res += item.v\n            cap -= item.w\n        } else {\n            // \u82e5\u5269\u4f59\u5bb9\u91cf\u4e0d\u8db3\uff0c\u5219\u5c06\u5f53\u524d\u7269\u54c1\u7684\u4e00\u90e8\u5206\u88c5\u8fdb\u80cc\u5305\n            res += item.v.toDouble() / item.w * cap\n            // \u5df2\u65e0\u5269\u4f59\u5bb9\u91cf\uff0c\u56e0\u6b64\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    return res\n}\n
    fractional_knapsack.rb
    [class]{Item}-[func]{}\n\n[class]{}-[func]{fractional_knapsack}\n
    fractional_knapsack.zig
    [class]{Item}-[func]{}\n\n[class]{}-[func]{fractionalKnapsack}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u9664\u6392\u5e8f\u4e4b\u5916\uff0c\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u9700\u8981\u904d\u5386\u6574\u4e2a\u7269\u54c1\u5217\u8868\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u7269\u54c1\u6570\u91cf\u3002

    \u7531\u4e8e\u521d\u59cb\u5316\u4e86\u4e00\u4e2a Item \u5bf9\u8c61\u5217\u8868\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    "},{"location":"chapter_greedy/fractional_knapsack_problem/#3","title":"3. \u00a0 \u6b63\u786e\u6027\u8bc1\u660e","text":"

    \u91c7\u7528\u53cd\u8bc1\u6cd5\u3002\u5047\u8bbe\u7269\u54c1 \\(x\\) \u662f\u5355\u4f4d\u4ef7\u503c\u6700\u9ad8\u7684\u7269\u54c1\uff0c\u4f7f\u7528\u67d0\u7b97\u6cd5\u6c42\u5f97\u6700\u5927\u4ef7\u503c\u4e3a res \uff0c\u4f46\u8be5\u89e3\u4e2d\u4e0d\u5305\u542b\u7269\u54c1 \\(x\\) \u3002

    \u73b0\u5728\u4ece\u80cc\u5305\u4e2d\u62ff\u51fa\u5355\u4f4d\u91cd\u91cf\u7684\u4efb\u610f\u7269\u54c1\uff0c\u5e76\u66ff\u6362\u4e3a\u5355\u4f4d\u91cd\u91cf\u7684\u7269\u54c1 \\(x\\) \u3002\u7531\u4e8e\u7269\u54c1 \\(x\\) \u7684\u5355\u4f4d\u4ef7\u503c\u6700\u9ad8\uff0c\u56e0\u6b64\u66ff\u6362\u540e\u7684\u603b\u4ef7\u503c\u4e00\u5b9a\u5927\u4e8e res \u3002\u8fd9\u4e0e res \u662f\u6700\u4f18\u89e3\u77db\u76fe\uff0c\u8bf4\u660e\u6700\u4f18\u89e3\u4e2d\u5fc5\u987b\u5305\u542b\u7269\u54c1 \\(x\\) \u3002

    \u5bf9\u4e8e\u8be5\u89e3\u4e2d\u7684\u5176\u4ed6\u7269\u54c1\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u6784\u5efa\u51fa\u4e0a\u8ff0\u77db\u76fe\u3002\u603b\u800c\u8a00\u4e4b\uff0c\u5355\u4f4d\u4ef7\u503c\u66f4\u5927\u7684\u7269\u54c1\u603b\u662f\u66f4\u4f18\u9009\u62e9\uff0c\u8fd9\u8bf4\u660e\u8d2a\u5fc3\u7b56\u7565\u662f\u6709\u6548\u7684\u3002

    \u5982\u56fe 15-6 \u6240\u793a\uff0c\u5982\u679c\u5c06\u7269\u54c1\u91cd\u91cf\u548c\u7269\u54c1\u5355\u4f4d\u4ef7\u503c\u5206\u522b\u770b\u4f5c\u4e00\u5f20\u4e8c\u7ef4\u56fe\u8868\u7684\u6a2a\u8f74\u548c\u7eb5\u8f74\uff0c\u5219\u5206\u6570\u80cc\u5305\u95ee\u9898\u53ef\u8f6c\u5316\u4e3a\u201c\u6c42\u5728\u6709\u9650\u6a2a\u8f74\u533a\u95f4\u4e0b\u56f4\u6210\u7684\u6700\u5927\u9762\u79ef\u201d\u3002\u8fd9\u4e2a\u7c7b\u6bd4\u53ef\u4ee5\u5e2e\u52a9\u6211\u4eec\u4ece\u51e0\u4f55\u89d2\u5ea6\u7406\u89e3\u8d2a\u5fc3\u7b56\u7565\u7684\u6709\u6548\u6027\u3002

    \u56fe 15-6 \u00a0 \u5206\u6570\u80cc\u5305\u95ee\u9898\u7684\u51e0\u4f55\u8868\u793a

    "},{"location":"chapter_greedy/greedy_algorithm/","title":"15.1 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5","text":"

    \u8d2a\u5fc3\u7b97\u6cd5\uff08greedy algorithm\uff09\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u89e3\u51b3\u4f18\u5316\u95ee\u9898\u7684\u7b97\u6cd5\uff0c\u5176\u57fa\u672c\u601d\u60f3\u662f\u5728\u95ee\u9898\u7684\u6bcf\u4e2a\u51b3\u7b56\u9636\u6bb5\uff0c\u90fd\u9009\u62e9\u5f53\u524d\u770b\u8d77\u6765\u6700\u4f18\u7684\u9009\u62e9\uff0c\u5373\u8d2a\u5fc3\u5730\u505a\u51fa\u5c40\u90e8\u6700\u4f18\u7684\u51b3\u7b56\uff0c\u4ee5\u671f\u83b7\u5f97\u5168\u5c40\u6700\u4f18\u89e3\u3002\u8d2a\u5fc3\u7b97\u6cd5\u7b80\u6d01\u4e14\u9ad8\u6548\uff0c\u5728\u8bb8\u591a\u5b9e\u9645\u95ee\u9898\u4e2d\u6709\u7740\u5e7f\u6cdb\u7684\u5e94\u7528\u3002

    \u8d2a\u5fc3\u7b97\u6cd5\u548c\u52a8\u6001\u89c4\u5212\u90fd\u5e38\u7528\u4e8e\u89e3\u51b3\u4f18\u5316\u95ee\u9898\u3002\u5b83\u4eec\u4e4b\u95f4\u5b58\u5728\u4e00\u4e9b\u76f8\u4f3c\u4e4b\u5904\uff0c\u6bd4\u5982\u90fd\u4f9d\u8d56\u6700\u4f18\u5b50\u7ed3\u6784\u6027\u8d28\uff0c\u4f46\u5de5\u4f5c\u539f\u7406\u4e0d\u540c\u3002

    • \u52a8\u6001\u89c4\u5212\u4f1a\u6839\u636e\u4e4b\u524d\u9636\u6bb5\u7684\u6240\u6709\u51b3\u7b56\u6765\u8003\u8651\u5f53\u524d\u51b3\u7b56\uff0c\u5e76\u4f7f\u7528\u8fc7\u53bb\u5b50\u95ee\u9898\u7684\u89e3\u6765\u6784\u5efa\u5f53\u524d\u5b50\u95ee\u9898\u7684\u89e3\u3002
    • \u8d2a\u5fc3\u7b97\u6cd5\u4e0d\u4f1a\u8003\u8651\u8fc7\u53bb\u7684\u51b3\u7b56\uff0c\u800c\u662f\u4e00\u8def\u5411\u524d\u5730\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u4e0d\u65ad\u7f29\u5c0f\u95ee\u9898\u8303\u56f4\uff0c\u76f4\u81f3\u95ee\u9898\u88ab\u89e3\u51b3\u3002

    \u6211\u4eec\u5148\u901a\u8fc7\u4f8b\u9898\u201c\u96f6\u94b1\u5151\u6362\u201d\u4e86\u89e3\u8d2a\u5fc3\u7b97\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u3002\u8fd9\u9053\u9898\u5df2\u7ecf\u5728\u201c\u5b8c\u5168\u80cc\u5305\u95ee\u9898\u201d\u7ae0\u8282\u4e2d\u4ecb\u7ecd\u8fc7\uff0c\u76f8\u4fe1\u4f60\u5bf9\u5b83\u5e76\u4e0d\u964c\u751f\u3002

    Question

    \u7ed9\u5b9a \\(n\\) \u79cd\u786c\u5e01\uff0c\u7b2c \\(i\\) \u79cd\u786c\u5e01\u7684\u9762\u503c\u4e3a \\(coins[i - 1]\\) \uff0c\u76ee\u6807\u91d1\u989d\u4e3a \\(amt\\) \uff0c\u6bcf\u79cd\u786c\u5e01\u53ef\u4ee5\u91cd\u590d\u9009\u53d6\uff0c\u95ee\u80fd\u591f\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u7684\u6700\u5c11\u786c\u5e01\u6570\u91cf\u3002\u5982\u679c\u65e0\u6cd5\u51d1\u51fa\u76ee\u6807\u91d1\u989d\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002

    \u672c\u9898\u91c7\u53d6\u7684\u8d2a\u5fc3\u7b56\u7565\u5982\u56fe 15-1 \u6240\u793a\u3002\u7ed9\u5b9a\u76ee\u6807\u91d1\u989d\uff0c\u6211\u4eec\u8d2a\u5fc3\u5730\u9009\u62e9\u4e0d\u5927\u4e8e\u4e14\u6700\u63a5\u8fd1\u5b83\u7684\u786c\u5e01\uff0c\u4e0d\u65ad\u5faa\u73af\u8be5\u6b65\u9aa4\uff0c\u76f4\u81f3\u51d1\u51fa\u76ee\u6807\u91d1\u989d\u4e3a\u6b62\u3002

    \u56fe 15-1 \u00a0 \u96f6\u94b1\u5151\u6362\u7684\u8d2a\u5fc3\u7b56\u7565

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig coin_change_greedy.py
    def coin_change_greedy(coins: list[int], amt: int) -> int:\n    \"\"\"\u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3\"\"\"\n    # \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    i = len(coins) - 1\n    count = 0\n    # \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0:\n        # \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 and coins[i] > amt:\n            i -= 1\n        # \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count += 1\n    # \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return count if amt == 0 else -1\n
    coin_change_greedy.cpp
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(vector<int> &coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.size() - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.java
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(int[] coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.length - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.cs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint CoinChangeGreedy(int[] coins, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = coins.Length - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.go
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunc coinChangeGreedy(coins []int, amt int) int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    i := len(coins) - 1\n    count := 0\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    for amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        for i > 0 && coins[i] > amt {\n            i--\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count++\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    if amt != 0 {\n        return -1\n    }\n    return count\n}\n
    coin_change_greedy.swift
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunc coinChangeGreedy(coins: [Int], amt: Int) -> Int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    var i = coins.count - 1\n    var count = 0\n    var amt = amt\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 && coins[i] > amt {\n            i -= 1\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i]\n        count += 1\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1\n}\n
    coin_change_greedy.js
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunction coinChangeGreedy(coins, amt) {\n    // \u5047\u8bbe coins \u6570\u7ec4\u6709\u5e8f\n    let i = coins.length - 1;\n    let count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt === 0 ? count : -1;\n}\n
    coin_change_greedy.ts
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfunction coinChangeGreedy(coins: number[], amt: number): number {\n    // \u5047\u8bbe coins \u6570\u7ec4\u6709\u5e8f\n    let i = coins.length - 1;\n    let count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt === 0 ? count : -1;\n}\n
    coin_change_greedy.dart
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(List<int> coins, int amt) {\n  // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n  int i = coins.length - 1;\n  int count = 0;\n  // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n  while (amt > 0) {\n    // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n    while (i > 0 && coins[i] > amt) {\n      i--;\n    }\n    // \u9009\u62e9 coins[i]\n    amt -= coins[i];\n    count++;\n  }\n  // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n  return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.rs
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfn coin_change_greedy(coins: &[i32], mut amt: i32) -> i32 {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    let mut i = coins.len() - 1;\n    let mut count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while amt > 0 {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while i > 0 && coins[i] > amt {\n            i -= 1;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count += 1;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    if amt == 0 {\n        count\n    } else {\n        -1\n    }\n}\n
    coin_change_greedy.c
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nint coinChangeGreedy(int *coins, int size, int amt) {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    int i = size - 1;\n    int count = 0;\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (amt > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > amt) {\n            i--;\n        }\n        // \u9009\u62e9 coins[i]\n        amt -= coins[i];\n        count++;\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return amt == 0 ? count : -1;\n}\n
    coin_change_greedy.kt
    /* \u96f6\u94b1\u5151\u6362\uff1a\u8d2a\u5fc3 */\nfun coinChangeGreedy(coins: IntArray, amt: Int): Int {\n    // \u5047\u8bbe coins \u5217\u8868\u6709\u5e8f\n    var am = amt\n    var i = coins.size - 1\n    var count = 0\n    // \u5faa\u73af\u8fdb\u884c\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u5230\u65e0\u5269\u4f59\u91d1\u989d\n    while (am > 0) {\n        // \u627e\u5230\u5c0f\u4e8e\u4e14\u6700\u63a5\u8fd1\u5269\u4f59\u91d1\u989d\u7684\u786c\u5e01\n        while (i > 0 && coins[i] > am) {\n            i--\n        }\n        // \u9009\u62e9 coins[i]\n        am -= coins[i]\n        count++\n    }\n    // \u82e5\u672a\u627e\u5230\u53ef\u884c\u65b9\u6848\uff0c\u5219\u8fd4\u56de -1\n    return if (am == 0) count else -1\n}\n
    coin_change_greedy.rb
    [class]{}-[func]{coin_change_greedy}\n
    coin_change_greedy.zig
    [class]{}-[func]{coinChangeGreedy}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4f60\u53ef\u80fd\u4f1a\u4e0d\u7531\u5730\u53d1\u51fa\u611f\u53f9\uff1aSo clean \uff01\u8d2a\u5fc3\u7b97\u6cd5\u4ec5\u7528\u7ea6\u5341\u884c\u4ee3\u7801\u5c31\u89e3\u51b3\u4e86\u96f6\u94b1\u5151\u6362\u95ee\u9898\u3002

    "},{"location":"chapter_greedy/greedy_algorithm/#1511","title":"15.1.1 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u7684\u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u8d2a\u5fc3\u7b97\u6cd5\u4e0d\u4ec5\u64cd\u4f5c\u76f4\u63a5\u3001\u5b9e\u73b0\u7b80\u5355\uff0c\u800c\u4e14\u901a\u5e38\u6548\u7387\u4e5f\u5f88\u9ad8\u3002\u5728\u4ee5\u4e0a\u4ee3\u7801\u4e2d\uff0c\u8bb0\u786c\u5e01\u6700\u5c0f\u9762\u503c\u4e3a \\(\\min(coins)\\) \uff0c\u5219\u8d2a\u5fc3\u9009\u62e9\u6700\u591a\u5faa\u73af \\(amt / \\min(coins)\\) \u6b21\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(amt / \\min(coins))\\) \u3002\u8fd9\u6bd4\u52a8\u6001\u89c4\u5212\u89e3\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n \\times amt)\\) \u5c0f\u4e86\u4e00\u4e2a\u6570\u91cf\u7ea7\u3002

    \u7136\u800c\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u786c\u5e01\u9762\u503c\u7ec4\u5408\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u5e76\u4e0d\u80fd\u627e\u5230\u6700\u4f18\u89e3\u3002\u56fe 15-2 \u7ed9\u51fa\u4e86\u4e24\u4e2a\u793a\u4f8b\u3002

    • \u6b63\u4f8b \\(coins = [1, 5, 10, 20, 50, 100]\\)\uff1a\u5728\u8be5\u786c\u5e01\u7ec4\u5408\u4e0b\uff0c\u7ed9\u5b9a\u4efb\u610f \\(amt\\) \uff0c\u8d2a\u5fc3\u7b97\u6cd5\u90fd\u53ef\u4ee5\u627e\u5230\u6700\u4f18\u89e3\u3002
    • \u53cd\u4f8b \\(coins = [1, 20, 50]\\)\uff1a\u5047\u8bbe \\(amt = 60\\) \uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ea\u80fd\u627e\u5230 \\(50 + 1 \\times 10\\) \u7684\u5151\u6362\u7ec4\u5408\uff0c\u5171\u8ba1 \\(11\\) \u679a\u786c\u5e01\uff0c\u4f46\u52a8\u6001\u89c4\u5212\u53ef\u4ee5\u627e\u5230\u6700\u4f18\u89e3 \\(20 + 20 + 20\\) \uff0c\u4ec5\u9700 \\(3\\) \u679a\u786c\u5e01\u3002
    • \u53cd\u4f8b \\(coins = [1, 49, 50]\\)\uff1a\u5047\u8bbe \\(amt = 98\\) \uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ea\u80fd\u627e\u5230 \\(50 + 1 \\times 48\\) \u7684\u5151\u6362\u7ec4\u5408\uff0c\u5171\u8ba1 \\(49\\) \u679a\u786c\u5e01\uff0c\u4f46\u52a8\u6001\u89c4\u5212\u53ef\u4ee5\u627e\u5230\u6700\u4f18\u89e3 \\(49 + 49\\) \uff0c\u4ec5\u9700 \\(2\\) \u679a\u786c\u5e01\u3002

    \u56fe 15-2 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u65e0\u6cd5\u627e\u51fa\u6700\u4f18\u89e3\u7684\u793a\u4f8b

    \u4e5f\u5c31\u662f\u8bf4\uff0c\u5bf9\u4e8e\u96f6\u94b1\u5151\u6362\u95ee\u9898\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u65e0\u6cd5\u4fdd\u8bc1\u627e\u5230\u5168\u5c40\u6700\u4f18\u89e3\uff0c\u5e76\u4e14\u6709\u53ef\u80fd\u627e\u5230\u975e\u5e38\u5dee\u7684\u89e3\u3002\u5b83\u66f4\u9002\u5408\u7528\u52a8\u6001\u89c4\u5212\u89e3\u51b3\u3002

    \u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u7684\u9002\u7528\u60c5\u51b5\u5206\u4ee5\u4e0b\u4e24\u79cd\u3002

    1. \u53ef\u4ee5\u4fdd\u8bc1\u627e\u5230\u6700\u4f18\u89e3\uff1a\u8d2a\u5fc3\u7b97\u6cd5\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5f80\u5f80\u662f\u6700\u4f18\u9009\u62e9\uff0c\u56e0\u4e3a\u5b83\u5f80\u5f80\u6bd4\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\u66f4\u9ad8\u6548\u3002
    2. \u53ef\u4ee5\u627e\u5230\u8fd1\u4f3c\u6700\u4f18\u89e3\uff1a\u8d2a\u5fc3\u7b97\u6cd5\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u4e5f\u662f\u53ef\u7528\u7684\u3002\u5bf9\u4e8e\u5f88\u591a\u590d\u6742\u95ee\u9898\u6765\u8bf4\uff0c\u5bfb\u627e\u5168\u5c40\u6700\u4f18\u89e3\u975e\u5e38\u56f0\u96be\uff0c\u80fd\u4ee5\u8f83\u9ad8\u6548\u7387\u627e\u5230\u6b21\u4f18\u89e3\u4e5f\u662f\u975e\u5e38\u4e0d\u9519\u7684\u3002
    "},{"location":"chapter_greedy/greedy_algorithm/#1512","title":"15.1.2 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u7279\u6027","text":"

    \u90a3\u4e48\u95ee\u9898\u6765\u4e86\uff0c\u4ec0\u4e48\u6837\u7684\u95ee\u9898\u9002\u5408\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\u5462\uff1f\u6216\u8005\u8bf4\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u53ef\u4ee5\u4fdd\u8bc1\u627e\u5230\u6700\u4f18\u89e3\uff1f

    \u76f8\u8f83\u4e8e\u52a8\u6001\u89c4\u5212\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u7684\u4f7f\u7528\u6761\u4ef6\u66f4\u52a0\u82db\u523b\uff0c\u5176\u4e3b\u8981\u5173\u6ce8\u95ee\u9898\u7684\u4e24\u4e2a\u6027\u8d28\u3002

    • \u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\uff1a\u53ea\u6709\u5f53\u5c40\u90e8\u6700\u4f18\u9009\u62e9\u59cb\u7ec8\u53ef\u4ee5\u5bfc\u81f4\u5168\u5c40\u6700\u4f18\u89e3\u65f6\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u624d\u80fd\u4fdd\u8bc1\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u6700\u4f18\u5b50\u7ed3\u6784\uff1a\u539f\u95ee\u9898\u7684\u6700\u4f18\u89e3\u5305\u542b\u5b50\u95ee\u9898\u7684\u6700\u4f18\u89e3\u3002

    \u6700\u4f18\u5b50\u7ed3\u6784\u5df2\u7ecf\u5728\u201c\u52a8\u6001\u89c4\u5212\u201d\u7ae0\u8282\u4e2d\u4ecb\u7ecd\u8fc7\uff0c\u8fd9\u91cc\u4e0d\u518d\u8d58\u8ff0\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u4e00\u4e9b\u95ee\u9898\u7684\u6700\u4f18\u5b50\u7ed3\u6784\u5e76\u4e0d\u660e\u663e\uff0c\u4f46\u4ecd\u7136\u53ef\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u89e3\u51b3\u3002

    \u6211\u4eec\u4e3b\u8981\u63a2\u7a76\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u7684\u5224\u65ad\u65b9\u6cd5\u3002\u867d\u7136\u5b83\u7684\u63cf\u8ff0\u770b\u4e0a\u53bb\u6bd4\u8f83\u7b80\u5355\uff0c\u4f46\u5b9e\u9645\u4e0a\u5bf9\u4e8e\u8bb8\u591a\u95ee\u9898\uff0c\u8bc1\u660e\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u5e76\u975e\u6613\u4e8b\u3002

    \u4f8b\u5982\u96f6\u94b1\u5151\u6362\u95ee\u9898\uff0c\u6211\u4eec\u867d\u7136\u80fd\u591f\u5bb9\u6613\u5730\u4e3e\u51fa\u53cd\u4f8b\uff0c\u5bf9\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u8fdb\u884c\u8bc1\u4f2a\uff0c\u4f46\u8bc1\u5b9e\u7684\u96be\u5ea6\u8f83\u5927\u3002\u5982\u679c\u95ee\uff1a\u6ee1\u8db3\u4ec0\u4e48\u6761\u4ef6\u7684\u786c\u5e01\u7ec4\u5408\u53ef\u4ee5\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\uff1f\u6211\u4eec\u5f80\u5f80\u53ea\u80fd\u51ed\u501f\u76f4\u89c9\u6216\u4e3e\u4f8b\u5b50\u6765\u7ed9\u51fa\u4e00\u4e2a\u6a21\u68f1\u4e24\u53ef\u7684\u7b54\u6848\uff0c\u800c\u96be\u4ee5\u7ed9\u51fa\u4e25\u8c28\u7684\u6570\u5b66\u8bc1\u660e\u3002

    Quote

    \u6709\u4e00\u7bc7\u8bba\u6587\u7ed9\u51fa\u4e86\u4e00\u4e2a \\(O(n^3)\\) \u65f6\u95f4\u590d\u6742\u5ea6\u7684\u7b97\u6cd5\uff0c\u7528\u4e8e\u5224\u65ad\u4e00\u4e2a\u786c\u5e01\u7ec4\u5408\u80fd\u5426\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u627e\u51fa\u4efb\u610f\u91d1\u989d\u7684\u6700\u4f18\u89e3\u3002

    Pearson, D. A polynomial-time algorithm for the change-making problem[J]. Operations Research Letters, 2005, 33(3): 231-234.

    "},{"location":"chapter_greedy/greedy_algorithm/#1513","title":"15.1.3 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u89e3\u9898\u6b65\u9aa4","text":"

    \u8d2a\u5fc3\u95ee\u9898\u7684\u89e3\u51b3\u6d41\u7a0b\u5927\u4f53\u53ef\u5206\u4e3a\u4ee5\u4e0b\u4e09\u6b65\u3002

    1. \u95ee\u9898\u5206\u6790\uff1a\u68b3\u7406\u4e0e\u7406\u89e3\u95ee\u9898\u7279\u6027\uff0c\u5305\u62ec\u72b6\u6001\u5b9a\u4e49\u3001\u4f18\u5316\u76ee\u6807\u548c\u7ea6\u675f\u6761\u4ef6\u7b49\u3002\u8fd9\u4e00\u6b65\u5728\u56de\u6eaf\u548c\u52a8\u6001\u89c4\u5212\u4e2d\u90fd\u6709\u6d89\u53ca\u3002
    2. \u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\uff1a\u786e\u5b9a\u5982\u4f55\u5728\u6bcf\u4e00\u6b65\u4e2d\u505a\u51fa\u8d2a\u5fc3\u9009\u62e9\u3002\u8fd9\u4e2a\u7b56\u7565\u80fd\u591f\u5728\u6bcf\u4e00\u6b65\u51cf\u5c0f\u95ee\u9898\u7684\u89c4\u6a21\uff0c\u5e76\u6700\u7ec8\u89e3\u51b3\u6574\u4e2a\u95ee\u9898\u3002
    3. \u6b63\u786e\u6027\u8bc1\u660e\uff1a\u901a\u5e38\u9700\u8981\u8bc1\u660e\u95ee\u9898\u5177\u6709\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u548c\u6700\u4f18\u5b50\u7ed3\u6784\u3002\u8fd9\u4e2a\u6b65\u9aa4\u53ef\u80fd\u9700\u8981\u7528\u5230\u6570\u5b66\u8bc1\u660e\uff0c\u4f8b\u5982\u5f52\u7eb3\u6cd5\u6216\u53cd\u8bc1\u6cd5\u7b49\u3002

    \u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\u662f\u6c42\u89e3\u95ee\u9898\u7684\u6838\u5fc3\u6b65\u9aa4\uff0c\u4f46\u5b9e\u65bd\u8d77\u6765\u53ef\u80fd\u5e76\u4e0d\u5bb9\u6613\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u4e0d\u540c\u95ee\u9898\u7684\u8d2a\u5fc3\u7b56\u7565\u7684\u5dee\u5f02\u8f83\u5927\u3002\u5bf9\u4e8e\u8bb8\u591a\u95ee\u9898\u6765\u8bf4\uff0c\u8d2a\u5fc3\u7b56\u7565\u6bd4\u8f83\u6d45\u663e\uff0c\u6211\u4eec\u901a\u8fc7\u4e00\u4e9b\u5927\u6982\u7684\u601d\u8003\u4e0e\u5c1d\u8bd5\u5c31\u80fd\u5f97\u51fa\u3002\u800c\u5bf9\u4e8e\u4e00\u4e9b\u590d\u6742\u95ee\u9898\uff0c\u8d2a\u5fc3\u7b56\u7565\u53ef\u80fd\u975e\u5e38\u9690\u853d\uff0c\u8fd9\u79cd\u60c5\u51b5\u5c31\u975e\u5e38\u8003\u9a8c\u4e2a\u4eba\u7684\u89e3\u9898\u7ecf\u9a8c\u4e0e\u7b97\u6cd5\u80fd\u529b\u4e86\u3002
    • \u67d0\u4e9b\u8d2a\u5fc3\u7b56\u7565\u5177\u6709\u8f83\u5f3a\u7684\u8ff7\u60d1\u6027\u3002\u5f53\u6211\u4eec\u6ee1\u6000\u4fe1\u5fc3\u8bbe\u8ba1\u597d\u8d2a\u5fc3\u7b56\u7565\uff0c\u5199\u51fa\u89e3\u9898\u4ee3\u7801\u5e76\u63d0\u4ea4\u8fd0\u884c\uff0c\u5f88\u53ef\u80fd\u53d1\u73b0\u90e8\u5206\u6d4b\u8bd5\u6837\u4f8b\u65e0\u6cd5\u901a\u8fc7\u3002\u8fd9\u662f\u56e0\u4e3a\u8bbe\u8ba1\u7684\u8d2a\u5fc3\u7b56\u7565\u53ea\u662f\u201c\u90e8\u5206\u6b63\u786e\u201d\u7684\uff0c\u4e0a\u6587\u4ecb\u7ecd\u7684\u96f6\u94b1\u5151\u6362\u5c31\u662f\u4e00\u4e2a\u5178\u578b\u6848\u4f8b\u3002

    \u4e3a\u4e86\u4fdd\u8bc1\u6b63\u786e\u6027\uff0c\u6211\u4eec\u5e94\u8be5\u5bf9\u8d2a\u5fc3\u7b56\u7565\u8fdb\u884c\u4e25\u8c28\u7684\u6570\u5b66\u8bc1\u660e\uff0c\u901a\u5e38\u9700\u8981\u7528\u5230\u53cd\u8bc1\u6cd5\u6216\u6570\u5b66\u5f52\u7eb3\u6cd5\u3002

    \u7136\u800c\uff0c\u6b63\u786e\u6027\u8bc1\u660e\u4e5f\u5f88\u53ef\u80fd\u4e0d\u662f\u4e00\u4ef6\u6613\u4e8b\u3002\u5982\u82e5\u6ca1\u6709\u5934\u7eea\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u9009\u62e9\u9762\u5411\u6d4b\u8bd5\u7528\u4f8b\u8fdb\u884c\u4ee3\u7801\u8c03\u8bd5\uff0c\u4e00\u6b65\u6b65\u4fee\u6539\u4e0e\u9a8c\u8bc1\u8d2a\u5fc3\u7b56\u7565\u3002

    "},{"location":"chapter_greedy/greedy_algorithm/#1514","title":"15.1.4 \u00a0 \u8d2a\u5fc3\u7b97\u6cd5\u5178\u578b\u4f8b\u9898","text":"

    \u8d2a\u5fc3\u7b97\u6cd5\u5e38\u5e38\u5e94\u7528\u5728\u6ee1\u8db3\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u548c\u6700\u4f18\u5b50\u7ed3\u6784\u7684\u4f18\u5316\u95ee\u9898\u4e2d\uff0c\u4ee5\u4e0b\u5217\u4e3e\u4e86\u4e00\u4e9b\u5178\u578b\u7684\u8d2a\u5fc3\u7b97\u6cd5\u95ee\u9898\u3002

    • \u786c\u5e01\u627e\u96f6\u95ee\u9898\uff1a\u5728\u67d0\u4e9b\u786c\u5e01\u7ec4\u5408\u4e0b\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u603b\u662f\u53ef\u4ee5\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u533a\u95f4\u8c03\u5ea6\u95ee\u9898\uff1a\u5047\u8bbe\u4f60\u6709\u4e00\u4e9b\u4efb\u52a1\uff0c\u6bcf\u4e2a\u4efb\u52a1\u5728\u4e00\u6bb5\u65f6\u95f4\u5185\u8fdb\u884c\uff0c\u4f60\u7684\u76ee\u6807\u662f\u5b8c\u6210\u5c3d\u53ef\u80fd\u591a\u7684\u4efb\u52a1\u3002\u5982\u679c\u6bcf\u6b21\u90fd\u9009\u62e9\u7ed3\u675f\u65f6\u95f4\u6700\u65e9\u7684\u4efb\u52a1\uff0c\u90a3\u4e48\u8d2a\u5fc3\u7b97\u6cd5\u5c31\u53ef\u4ee5\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u5206\u6570\u80cc\u5305\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u7269\u54c1\u548c\u4e00\u4e2a\u8f7d\u91cd\u91cf\uff0c\u4f60\u7684\u76ee\u6807\u662f\u9009\u62e9\u4e00\u7ec4\u7269\u54c1\uff0c\u4f7f\u5f97\u603b\u91cd\u91cf\u4e0d\u8d85\u8fc7\u8f7d\u91cd\u91cf\uff0c\u4e14\u603b\u4ef7\u503c\u6700\u5927\u3002\u5982\u679c\u6bcf\u6b21\u90fd\u9009\u62e9\u6027\u4ef7\u6bd4\u6700\u9ad8\uff08\u4ef7\u503c / \u91cd\u91cf\uff09\u7684\u7269\u54c1\uff0c\u90a3\u4e48\u8d2a\u5fc3\u7b97\u6cd5\u5728\u4e00\u4e9b\u60c5\u51b5\u4e0b\u53ef\u4ee5\u5f97\u5230\u6700\u4f18\u89e3\u3002
    • \u80a1\u7968\u4e70\u5356\u95ee\u9898\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u80a1\u7968\u7684\u5386\u53f2\u4ef7\u683c\uff0c\u4f60\u53ef\u4ee5\u8fdb\u884c\u591a\u6b21\u4e70\u5356\uff0c\u4f46\u5982\u679c\u4f60\u5df2\u7ecf\u6301\u6709\u80a1\u7968\uff0c\u90a3\u4e48\u5728\u5356\u51fa\u4e4b\u524d\u4e0d\u80fd\u518d\u4e70\uff0c\u76ee\u6807\u662f\u83b7\u53d6\u6700\u5927\u5229\u6da6\u3002
    • \u970d\u592b\u66fc\u7f16\u7801\uff1a\u970d\u592b\u66fc\u7f16\u7801\u662f\u4e00\u79cd\u7528\u4e8e\u65e0\u635f\u6570\u636e\u538b\u7f29\u7684\u8d2a\u5fc3\u7b97\u6cd5\u3002\u901a\u8fc7\u6784\u5efa\u970d\u592b\u66fc\u6811\uff0c\u6bcf\u6b21\u9009\u62e9\u51fa\u73b0\u9891\u7387\u6700\u4f4e\u7684\u4e24\u4e2a\u8282\u70b9\u5408\u5e76\uff0c\u6700\u540e\u5f97\u5230\u7684\u970d\u592b\u66fc\u6811\u7684\u5e26\u6743\u8def\u5f84\u957f\u5ea6\uff08\u7f16\u7801\u957f\u5ea6\uff09\u6700\u5c0f\u3002
    • Dijkstra \u7b97\u6cd5\uff1a\u5b83\u662f\u4e00\u79cd\u89e3\u51b3\u7ed9\u5b9a\u6e90\u9876\u70b9\u5230\u5176\u4f59\u5404\u9876\u70b9\u7684\u6700\u77ed\u8def\u5f84\u95ee\u9898\u7684\u8d2a\u5fc3\u7b97\u6cd5\u3002
    "},{"location":"chapter_greedy/max_capacity_problem/","title":"15.3 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898","text":"

    Question

    \u8f93\u5165\u4e00\u4e2a\u6570\u7ec4 \\(ht\\) \uff0c\u5176\u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u4ee3\u8868\u4e00\u4e2a\u5782\u76f4\u9694\u677f\u7684\u9ad8\u5ea6\u3002\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u4e24\u4e2a\u9694\u677f\uff0c\u4ee5\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u7a7a\u95f4\u53ef\u4ee5\u7ec4\u6210\u4e00\u4e2a\u5bb9\u5668\u3002

    \u5bb9\u5668\u7684\u5bb9\u91cf\u7b49\u4e8e\u9ad8\u5ea6\u548c\u5bbd\u5ea6\u7684\u4e58\u79ef\uff08\u9762\u79ef\uff09\uff0c\u5176\u4e2d\u9ad8\u5ea6\u7531\u8f83\u77ed\u7684\u9694\u677f\u51b3\u5b9a\uff0c\u5bbd\u5ea6\u662f\u4e24\u4e2a\u9694\u677f\u7684\u6570\u7ec4\u7d22\u5f15\u4e4b\u5dee\u3002

    \u8bf7\u5728\u6570\u7ec4\u4e2d\u9009\u62e9\u4e24\u4e2a\u9694\u677f\uff0c\u4f7f\u5f97\u7ec4\u6210\u7684\u5bb9\u5668\u7684\u5bb9\u91cf\u6700\u5927\uff0c\u8fd4\u56de\u6700\u5927\u5bb9\u91cf\u3002\u793a\u4f8b\u5982\u56fe 15-7 \u6240\u793a\u3002

    \u56fe 15-7 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898\u7684\u793a\u4f8b\u6570\u636e

    \u5bb9\u5668\u7531\u4efb\u610f\u4e24\u4e2a\u9694\u677f\u56f4\u6210\uff0c\u56e0\u6b64\u672c\u9898\u7684\u72b6\u6001\u4e3a\u4e24\u4e2a\u9694\u677f\u7684\u7d22\u5f15\uff0c\u8bb0\u4e3a \\([i, j]\\) \u3002

    \u6839\u636e\u9898\u610f\uff0c\u5bb9\u91cf\u7b49\u4e8e\u9ad8\u5ea6\u4e58\u4ee5\u5bbd\u5ea6\uff0c\u5176\u4e2d\u9ad8\u5ea6\u7531\u77ed\u677f\u51b3\u5b9a\uff0c\u5bbd\u5ea6\u662f\u4e24\u9694\u677f\u7684\u6570\u7ec4\u7d22\u5f15\u4e4b\u5dee\u3002\u8bbe\u5bb9\u91cf\u4e3a \\(cap[i, j]\\) \uff0c\u5219\u53ef\u5f97\u8ba1\u7b97\u516c\u5f0f\uff1a

    \\[ cap[i, j] = \\min(ht[i], ht[j]) \\times (j - i) \\]

    \u8bbe\u6570\u7ec4\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u4e24\u4e2a\u9694\u677f\u7684\u7ec4\u5408\u6570\u91cf\uff08\u72b6\u6001\u603b\u6570\uff09\u4e3a \\(C_n^2 = \\frac{n(n - 1)}{2}\\) \u4e2a\u3002\u6700\u76f4\u63a5\u5730\uff0c\u6211\u4eec\u53ef\u4ee5\u7a77\u4e3e\u6240\u6709\u72b6\u6001\uff0c\u4ece\u800c\u6c42\u5f97\u6700\u5927\u5bb9\u91cf\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_greedy/max_capacity_problem/#1","title":"1. \u00a0 \u8d2a\u5fc3\u7b56\u7565\u786e\u5b9a","text":"

    \u8fd9\u9053\u9898\u8fd8\u6709\u66f4\u9ad8\u6548\u7387\u7684\u89e3\u6cd5\u3002\u5982\u56fe 15-8 \u6240\u793a\uff0c\u73b0\u9009\u53d6\u4e00\u4e2a\u72b6\u6001 \\([i, j]\\) \uff0c\u5176\u6ee1\u8db3\u7d22\u5f15 \\(i < j\\) \u4e14\u9ad8\u5ea6 \\(ht[i] < ht[j]\\) \uff0c\u5373 \\(i\\) \u4e3a\u77ed\u677f\u3001\\(j\\) \u4e3a\u957f\u677f\u3002

    \u56fe 15-8 \u00a0 \u521d\u59cb\u72b6\u6001

    \u5982\u56fe 15-9 \u6240\u793a\uff0c\u82e5\u6b64\u65f6\u5c06\u957f\u677f \\(j\\) \u5411\u77ed\u677f \\(i\\) \u9760\u8fd1\uff0c\u5219\u5bb9\u91cf\u4e00\u5b9a\u53d8\u5c0f\u3002

    \u8fd9\u662f\u56e0\u4e3a\u5728\u79fb\u52a8\u957f\u677f \\(j\\) \u540e\uff0c\u5bbd\u5ea6 \\(j-i\\) \u80af\u5b9a\u53d8\u5c0f\uff1b\u800c\u9ad8\u5ea6\u7531\u77ed\u677f\u51b3\u5b9a\uff0c\u56e0\u6b64\u9ad8\u5ea6\u53ea\u53ef\u80fd\u4e0d\u53d8\uff08 \\(i\\) \u4ecd\u4e3a\u77ed\u677f\uff09\u6216\u53d8\u5c0f\uff08\u79fb\u52a8\u540e\u7684 \\(j\\) \u6210\u4e3a\u77ed\u677f\uff09\u3002

    \u56fe 15-9 \u00a0 \u5411\u5185\u79fb\u52a8\u957f\u677f\u540e\u7684\u72b6\u6001

    \u53cd\u5411\u601d\u8003\uff0c\u6211\u4eec\u53ea\u6709\u5411\u5185\u6536\u7f29\u77ed\u677f \\(i\\) \uff0c\u624d\u6709\u53ef\u80fd\u4f7f\u5bb9\u91cf\u53d8\u5927\u3002\u56e0\u4e3a\u867d\u7136\u5bbd\u5ea6\u4e00\u5b9a\u53d8\u5c0f\uff0c\u4f46\u9ad8\u5ea6\u53ef\u80fd\u4f1a\u53d8\u5927\uff08\u79fb\u52a8\u540e\u7684\u77ed\u677f \\(i\\) \u53ef\u80fd\u4f1a\u53d8\u957f\uff09\u3002\u4f8b\u5982\u5728\u56fe 15-10 \u4e2d\uff0c\u79fb\u52a8\u77ed\u677f\u540e\u9762\u79ef\u53d8\u5927\u3002

    \u56fe 15-10 \u00a0 \u5411\u5185\u79fb\u52a8\u77ed\u677f\u540e\u7684\u72b6\u6001

    \u7531\u6b64\u4fbf\u53ef\u63a8\u51fa\u672c\u9898\u7684\u8d2a\u5fc3\u7b56\u7565\uff1a\u521d\u59cb\u5316\u4e24\u6307\u9488\uff0c\u4f7f\u5176\u5206\u5217\u5bb9\u5668\u4e24\u7aef\uff0c\u6bcf\u8f6e\u5411\u5185\u6536\u7f29\u77ed\u677f\u5bf9\u5e94\u7684\u6307\u9488\uff0c\u76f4\u81f3\u4e24\u6307\u9488\u76f8\u9047\u3002

    \u56fe 15-11 \u5c55\u793a\u4e86\u8d2a\u5fc3\u7b56\u7565\u7684\u6267\u884c\u8fc7\u7a0b\u3002

    1. \u521d\u59cb\u72b6\u6001\u4e0b\uff0c\u6307\u9488 \\(i\\) \u548c \\(j\\) \u5206\u5217\u6570\u7ec4\u4e24\u7aef\u3002
    2. \u8ba1\u7b97\u5f53\u524d\u72b6\u6001\u7684\u5bb9\u91cf \\(cap[i, j]\\) \uff0c\u5e76\u66f4\u65b0\u6700\u5927\u5bb9\u91cf\u3002
    3. \u6bd4\u8f83\u677f \\(i\\) \u548c \u677f \\(j\\) \u7684\u9ad8\u5ea6\uff0c\u5e76\u5c06\u77ed\u677f\u5411\u5185\u79fb\u52a8\u4e00\u683c\u3002
    4. \u5faa\u73af\u6267\u884c\u7b2c 2. \u6b65\u548c\u7b2c 3. \u6b65\uff0c\u76f4\u81f3 \\(i\\) \u548c \\(j\\) \u76f8\u9047\u65f6\u7ed3\u675f\u3002
    <1><2><3><4><5><6><7><8><9>

    \u56fe 15-11 \u00a0 \u6700\u5927\u5bb9\u91cf\u95ee\u9898\u7684\u8d2a\u5fc3\u8fc7\u7a0b

    "},{"location":"chapter_greedy/max_capacity_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u4ee3\u7801\u5faa\u73af\u6700\u591a \\(n\\) \u8f6e\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002

    \u53d8\u91cf \\(i\\)\u3001\\(j\\)\u3001\\(res\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig max_capacity.py
    def max_capacity(ht: list[int]) -> int:\n    \"\"\"\u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3\"\"\"\n    # \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    i, j = 0, len(ht) - 1\n    # \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    res = 0\n    # \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j:\n        # \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        # \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j]:\n            i += 1\n        else:\n            j -= 1\n    return res\n
    max_capacity.cpp
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(vector<int> &ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.size() - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = min(ht[i], ht[j]) * (j - i);\n        res = max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.java
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(int[] ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.cs
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint MaxCapacity(int[] ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0, j = ht.Length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int cap = Math.Min(ht[i], ht[j]) * (j - i);\n        res = Math.Max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.go
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunc maxCapacity(ht []int) int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    i, j := 0, len(ht)-1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    res := 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    for i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        capacity := int(math.Min(float64(ht[i]), float64(ht[j]))) * (j - i)\n        res = int(math.Max(float64(res), float64(capacity)))\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i++\n        } else {\n            j--\n        }\n    }\n    return res\n}\n
    max_capacity.swift
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunc maxCapacity(ht: [Int]) -> Int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    var i = ht.startIndex, j = ht.endIndex - 1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    var res = 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        let cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i += 1\n        } else {\n            j -= 1\n        }\n    }\n    return res\n}\n
    max_capacity.js
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunction maxCapacity(ht) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let i = 0,\n        j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        const cap = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    return res;\n}\n
    max_capacity.ts
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfunction maxCapacity(ht: number[]): number {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let i = 0,\n        j = ht.length - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        const cap: number = Math.min(ht[i], ht[j]) * (j - i);\n        res = Math.max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    return res;\n}\n
    max_capacity.dart
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(List<int> ht) {\n  // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n  int i = 0, j = ht.length - 1;\n  // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n  int res = 0;\n  // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n  while (i < j) {\n    // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n    int cap = min(ht[i], ht[j]) * (j - i);\n    res = max(res, cap);\n    // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n    if (ht[i] < ht[j]) {\n      i++;\n    } else {\n      j--;\n    }\n  }\n  return res;\n}\n
    max_capacity.rs
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfn max_capacity(ht: &[i32]) -> i32 {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    let mut i = 0;\n    let mut j = ht.len() - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    let mut res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while i < j {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        let cap = std::cmp::min(ht[i], ht[j]) * (j - i) as i32;\n        res = std::cmp::max(res, cap);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if ht[i] < ht[j] {\n            i += 1;\n        } else {\n            j -= 1;\n        }\n    }\n    res\n}\n
    max_capacity.c
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nint maxCapacity(int ht[], int htLength) {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    int i = 0;\n    int j = htLength - 1;\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    int res = 0;\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        int capacity = myMin(ht[i], ht[j]) * (j - i);\n        res = myMax(res, capacity);\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++;\n        } else {\n            j--;\n        }\n    }\n    return res;\n}\n
    max_capacity.kt
    /* \u6700\u5927\u5bb9\u91cf\uff1a\u8d2a\u5fc3 */\nfun maxCapacity(ht: IntArray): Int {\n    // \u521d\u59cb\u5316 i, j\uff0c\u4f7f\u5176\u5206\u5217\u6570\u7ec4\u4e24\u7aef\n    var i = 0\n    var j = ht.size - 1\n    // \u521d\u59cb\u6700\u5927\u5bb9\u91cf\u4e3a 0\n    var res = 0\n    // \u5faa\u73af\u8d2a\u5fc3\u9009\u62e9\uff0c\u76f4\u81f3\u4e24\u677f\u76f8\u9047\n    while (i < j) {\n        // \u66f4\u65b0\u6700\u5927\u5bb9\u91cf\n        val cap = min(ht[i], ht[j]) * (j - i)\n        res = max(res, cap)\n        // \u5411\u5185\u79fb\u52a8\u77ed\u677f\n        if (ht[i] < ht[j]) {\n            i++\n        } else {\n            j--\n        }\n    }\n    return res\n}\n
    max_capacity.rb
    [class]{}-[func]{max_capacity}\n
    max_capacity.zig
    [class]{}-[func]{maxCapacity}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_greedy/max_capacity_problem/#3","title":"3. \u00a0 \u6b63\u786e\u6027\u8bc1\u660e","text":"

    \u4e4b\u6240\u4ee5\u8d2a\u5fc3\u6bd4\u7a77\u4e3e\u66f4\u5feb\uff0c\u662f\u56e0\u4e3a\u6bcf\u8f6e\u7684\u8d2a\u5fc3\u9009\u62e9\u90fd\u4f1a\u201c\u8df3\u8fc7\u201d\u4e00\u4e9b\u72b6\u6001\u3002

    \u6bd4\u5982\u5728\u72b6\u6001 \\(cap[i, j]\\) \u4e0b\uff0c\\(i\\) \u4e3a\u77ed\u677f\u3001\\(j\\) \u4e3a\u957f\u677f\u3002\u82e5\u8d2a\u5fc3\u5730\u5c06\u77ed\u677f \\(i\\) \u5411\u5185\u79fb\u52a8\u4e00\u683c\uff0c\u4f1a\u5bfc\u81f4\u56fe 15-12 \u6240\u793a\u7684\u72b6\u6001\u88ab\u201c\u8df3\u8fc7\u201d\u3002\u8fd9\u610f\u5473\u7740\u4e4b\u540e\u65e0\u6cd5\u9a8c\u8bc1\u8fd9\u4e9b\u72b6\u6001\u7684\u5bb9\u91cf\u5927\u5c0f\u3002

    \\[ cap[i, i+1], cap[i, i+2], \\dots, cap[i, j-2], cap[i, j-1] \\]

    \u56fe 15-12 \u00a0 \u79fb\u52a8\u77ed\u677f\u5bfc\u81f4\u88ab\u8df3\u8fc7\u7684\u72b6\u6001

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u8fd9\u4e9b\u88ab\u8df3\u8fc7\u7684\u72b6\u6001\u5b9e\u9645\u4e0a\u5c31\u662f\u5c06\u957f\u677f \\(j\\) \u5411\u5185\u79fb\u52a8\u7684\u6240\u6709\u72b6\u6001\u3002\u524d\u9762\u6211\u4eec\u5df2\u7ecf\u8bc1\u660e\u5185\u79fb\u957f\u677f\u4e00\u5b9a\u4f1a\u5bfc\u81f4\u5bb9\u91cf\u53d8\u5c0f\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u88ab\u8df3\u8fc7\u7684\u72b6\u6001\u90fd\u4e0d\u53ef\u80fd\u662f\u6700\u4f18\u89e3\uff0c\u8df3\u8fc7\u5b83\u4eec\u4e0d\u4f1a\u5bfc\u81f4\u9519\u8fc7\u6700\u4f18\u89e3\u3002

    \u4ee5\u4e0a\u5206\u6790\u8bf4\u660e\uff0c\u79fb\u52a8\u77ed\u677f\u7684\u64cd\u4f5c\u662f\u201c\u5b89\u5168\u201d\u7684\uff0c\u8d2a\u5fc3\u7b56\u7565\u662f\u6709\u6548\u7684\u3002

    "},{"location":"chapter_greedy/max_product_cutting_problem/","title":"15.4 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6b63\u6574\u6570 \\(n\\) \uff0c\u5c06\u5176\u5207\u5206\u4e3a\u81f3\u5c11\u4e24\u4e2a\u6b63\u6574\u6570\u7684\u548c\uff0c\u6c42\u5207\u5206\u540e\u6240\u6709\u6574\u6570\u7684\u4e58\u79ef\u6700\u5927\u662f\u591a\u5c11\uff0c\u5982\u56fe 15-13 \u6240\u793a\u3002

    \u56fe 15-13 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u7684\u95ee\u9898\u5b9a\u4e49

    \u5047\u8bbe\u6211\u4eec\u5c06 \\(n\\) \u5207\u5206\u4e3a \\(m\\) \u4e2a\u6574\u6570\u56e0\u5b50\uff0c\u5176\u4e2d\u7b2c \\(i\\) \u4e2a\u56e0\u5b50\u8bb0\u4e3a \\(n_i\\) \uff0c\u5373

    \\[ n = \\sum_{i=1}^{m}n_i \\]

    \u672c\u9898\u7684\u76ee\u6807\u662f\u6c42\u5f97\u6240\u6709\u6574\u6570\u56e0\u5b50\u7684\u6700\u5927\u4e58\u79ef\uff0c\u5373

    \\[ \\max(\\prod_{i=1}^{m}n_i) \\]

    \u6211\u4eec\u9700\u8981\u601d\u8003\u7684\u662f\uff1a\u5207\u5206\u6570\u91cf \\(m\\) \u5e94\u8be5\u591a\u5927\uff0c\u6bcf\u4e2a \\(n_i\\) \u5e94\u8be5\u662f\u591a\u5c11\uff1f

    "},{"location":"chapter_greedy/max_product_cutting_problem/#1","title":"1. \u00a0 \u8d2a\u5fc3\u7b56\u7565\u786e\u5b9a","text":"

    \u6839\u636e\u7ecf\u9a8c\uff0c\u4e24\u4e2a\u6574\u6570\u7684\u4e58\u79ef\u5f80\u5f80\u6bd4\u5b83\u4eec\u7684\u52a0\u548c\u66f4\u5927\u3002\u5047\u8bbe\u4ece \\(n\\) \u4e2d\u5206\u51fa\u4e00\u4e2a\u56e0\u5b50 \\(2\\) \uff0c\u5219\u5b83\u4eec\u7684\u4e58\u79ef\u4e3a \\(2(n-2)\\) \u3002\u6211\u4eec\u5c06\u8be5\u4e58\u79ef\u4e0e \\(n\\) \u4f5c\u6bd4\u8f83\uff1a

    \\[ \\begin{aligned} 2(n-2) & \\geq n \\newline 2n - n - 4 & \\geq 0 \\newline n & \\geq 4 \\end{aligned} \\]

    \u5982\u56fe 15-14 \u6240\u793a\uff0c\u5f53 \\(n \\geq 4\\) \u65f6\uff0c\u5207\u5206\u51fa\u4e00\u4e2a \\(2\\) \u540e\u4e58\u79ef\u4f1a\u53d8\u5927\uff0c\u8fd9\u8bf4\u660e\u5927\u4e8e\u7b49\u4e8e \\(4\\) \u7684\u6574\u6570\u90fd\u5e94\u8be5\u88ab\u5207\u5206\u3002

    \u8d2a\u5fc3\u7b56\u7565\u4e00\uff1a\u5982\u679c\u5207\u5206\u65b9\u6848\u4e2d\u5305\u542b \\(\\geq 4\\) \u7684\u56e0\u5b50\uff0c\u90a3\u4e48\u5b83\u5c31\u5e94\u8be5\u88ab\u7ee7\u7eed\u5207\u5206\u3002\u6700\u7ec8\u7684\u5207\u5206\u65b9\u6848\u53ea\u5e94\u51fa\u73b0 \\(1\\)\u3001\\(2\\)\u3001\\(3\\) \u8fd9\u4e09\u79cd\u56e0\u5b50\u3002

    \u56fe 15-14 \u00a0 \u5207\u5206\u5bfc\u81f4\u4e58\u79ef\u53d8\u5927

    \u63a5\u4e0b\u6765\u601d\u8003\u54ea\u4e2a\u56e0\u5b50\u662f\u6700\u4f18\u7684\u3002\u5728 \\(1\\)\u3001\\(2\\)\u3001\\(3\\) \u8fd9\u4e09\u4e2a\u56e0\u5b50\u4e2d\uff0c\u663e\u7136 \\(1\\) \u662f\u6700\u5dee\u7684\uff0c\u56e0\u4e3a \\(1 \\times (n-1) < n\\) \u6052\u6210\u7acb\uff0c\u5373\u5207\u5206\u51fa \\(1\\) \u53cd\u800c\u4f1a\u5bfc\u81f4\u4e58\u79ef\u51cf\u5c0f\u3002

    \u5982\u56fe 15-15 \u6240\u793a\uff0c\u5f53 \\(n = 6\\) \u65f6\uff0c\u6709 \\(3 \\times 3 > 2 \\times 2 \\times 2\\) \u3002\u8fd9\u610f\u5473\u7740\u5207\u5206\u51fa \\(3\\) \u6bd4\u5207\u5206\u51fa \\(2\\) \u66f4\u4f18\u3002

    \u8d2a\u5fc3\u7b56\u7565\u4e8c\uff1a\u5728\u5207\u5206\u65b9\u6848\u4e2d\uff0c\u6700\u591a\u53ea\u5e94\u5b58\u5728\u4e24\u4e2a \\(2\\) \u3002\u56e0\u4e3a\u4e09\u4e2a \\(2\\) \u603b\u662f\u53ef\u4ee5\u66ff\u6362\u4e3a\u4e24\u4e2a \\(3\\) \uff0c\u4ece\u800c\u83b7\u5f97\u66f4\u5927\u7684\u4e58\u79ef\u3002

    \u56fe 15-15 \u00a0 \u6700\u4f18\u5207\u5206\u56e0\u5b50

    \u7efc\u4e0a\u6240\u8ff0\uff0c\u53ef\u63a8\u7406\u51fa\u4ee5\u4e0b\u8d2a\u5fc3\u7b56\u7565\u3002

    1. \u8f93\u5165\u6574\u6570 \\(n\\) \uff0c\u4ece\u5176\u4e0d\u65ad\u5730\u5207\u5206\u51fa\u56e0\u5b50 \\(3\\) \uff0c\u76f4\u81f3\u4f59\u6570\u4e3a \\(0\\)\u3001\\(1\\)\u3001\\(2\\) \u3002
    2. \u5f53\u4f59\u6570\u4e3a \\(0\\) \u65f6\uff0c\u4ee3\u8868 \\(n\\) \u662f \\(3\\) \u7684\u500d\u6570\uff0c\u56e0\u6b64\u4e0d\u505a\u4efb\u4f55\u5904\u7406\u3002
    3. \u5f53\u4f59\u6570\u4e3a \\(2\\) \u65f6\uff0c\u4e0d\u7ee7\u7eed\u5212\u5206\uff0c\u4fdd\u7559\u3002
    4. \u5f53\u4f59\u6570\u4e3a \\(1\\) \u65f6\uff0c\u7531\u4e8e \\(2 \\times 2 > 1 \\times 3\\) \uff0c\u56e0\u6b64\u5e94\u5c06\u6700\u540e\u4e00\u4e2a \\(3\\) \u66ff\u6362\u4e3a \\(2\\) \u3002
    "},{"location":"chapter_greedy/max_product_cutting_problem/#2","title":"2. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5982\u56fe 15-16 \u6240\u793a\uff0c\u6211\u4eec\u65e0\u987b\u901a\u8fc7\u5faa\u73af\u6765\u5207\u5206\u6574\u6570\uff0c\u800c\u53ef\u4ee5\u5229\u7528\u5411\u4e0b\u6574\u9664\u8fd0\u7b97\u5f97\u5230 \\(3\\) \u7684\u4e2a\u6570 \\(a\\) \uff0c\u7528\u53d6\u6a21\u8fd0\u7b97\u5f97\u5230\u4f59\u6570 \\(b\\) \uff0c\u6b64\u65f6\u6709\uff1a

    \\[ n = 3 a + b \\]

    \u8bf7\u6ce8\u610f\uff0c\u5bf9\u4e8e \\(n \\leq 3\\) \u7684\u8fb9\u754c\u60c5\u51b5\uff0c\u5fc5\u987b\u62c6\u5206\u51fa\u4e00\u4e2a \\(1\\) \uff0c\u4e58\u79ef\u4e3a \\(1 \\times (n - 1)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig max_product_cutting.py
    def max_product_cutting(n: int) -> int:\n    \"\"\"\u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3\"\"\"\n    # \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3:\n        return 1 * (n - 1)\n    # \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    a, b = n // 3, n % 3\n    if b == 1:\n        # \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return int(math.pow(3, a - 1)) * 2 * 2\n    if b == 2:\n        # \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return int(math.pow(3, a)) * 2\n    # \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return int(math.pow(3, a))\n
    max_product_cutting.cpp
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int)pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int)pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int)pow(3, a);\n}\n
    max_product_cutting.java
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int) Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int) Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int) Math.pow(3, a);\n}\n
    max_product_cutting.cs
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint MaxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return (int)Math.Pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return (int)Math.Pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (int)Math.Pow(3, a);\n}\n
    max_product_cutting.go
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunc maxProductCutting(n int) int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    a := n / 3\n    b := n % 3\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return int(math.Pow(3, float64(a-1))) * 2 * 2\n    }\n    if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return int(math.Pow(3, float64(a))) * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return int(math.Pow(3, float64(a)))\n}\n
    max_product_cutting.swift
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunc maxProductCutting(n: Int) -> Int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = n / 3\n    let b = n % 3\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return pow(3, a - 1) * 2 * 2\n    }\n    if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return pow(3, a) * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return pow(3, a)\n}\n
    max_product_cutting.js
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunction maxProductCutting(n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = Math.floor(n / 3);\n    let b = n % 3;\n    if (b === 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b === 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return Math.pow(3, a);\n}\n
    max_product_cutting.ts
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfunction maxProductCutting(n: number): number {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a: number = Math.floor(n / 3);\n    let b: number = n % 3;\n    if (b === 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return Math.pow(3, a - 1) * 2 * 2;\n    }\n    if (b === 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return Math.pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return Math.pow(3, a);\n}\n
    max_product_cutting.dart
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n  // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n  if (n <= 3) {\n    return 1 * (n - 1);\n  }\n  // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n  int a = n ~/ 3;\n  int b = n % 3;\n  if (b == 1) {\n    // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n    return (pow(3, a - 1) * 2 * 2).toInt();\n  }\n  if (b == 2) {\n    // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return (pow(3, a) * 2).toInt();\n  }\n  // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n  return pow(3, a).toInt();\n}\n
    max_product_cutting.rs
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfn max_product_cutting(n: i32) -> i32 {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if n <= 3 {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    let a = n / 3;\n    let b = n % 3;\n    if b == 1 {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        3_i32.pow(a as u32 - 1) * 2 * 2\n    } else if b == 2 {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        3_i32.pow(a as u32) * 2\n    } else {\n        // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        3_i32.pow(a as u32)\n    }\n}\n
    max_product_cutting.c
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nint maxProductCutting(int n) {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1);\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    int a = n / 3;\n    int b = n % 3;\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return pow(3, a - 1) * 2 * 2;\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return pow(3, a) * 2;\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return pow(3, a);\n}\n
    max_product_cutting.kt
    /* \u6700\u5927\u5207\u5206\u4e58\u79ef\uff1a\u8d2a\u5fc3 */\nfun maxProductCutting(n: Int): Int {\n    // \u5f53 n <= 3 \u65f6\uff0c\u5fc5\u987b\u5207\u5206\u51fa\u4e00\u4e2a 1\n    if (n <= 3) {\n        return 1 * (n - 1)\n    }\n    // \u8d2a\u5fc3\u5730\u5207\u5206\u51fa 3 \uff0ca \u4e3a 3 \u7684\u4e2a\u6570\uff0cb \u4e3a\u4f59\u6570\n    val a = n / 3\n    val b = n % 3\n    if (b == 1) {\n        // \u5f53\u4f59\u6570\u4e3a 1 \u65f6\uff0c\u5c06\u4e00\u5bf9 1 * 3 \u8f6c\u5316\u4e3a 2 * 2\n        return 3.0.pow((a - 1)).toInt() * 2 * 2\n    }\n    if (b == 2) {\n        // \u5f53\u4f59\u6570\u4e3a 2 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n        return 3.0.pow(a).toInt() * 2 * 2\n    }\n    // \u5f53\u4f59\u6570\u4e3a 0 \u65f6\uff0c\u4e0d\u505a\u5904\u7406\n    return 3.0.pow(a).toInt()\n}\n
    max_product_cutting.rb
    [class]{}-[func]{max_product_cutting}\n
    max_product_cutting.zig
    [class]{}-[func]{maxProductCutting}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u56fe 15-16 \u00a0 \u6700\u5927\u5207\u5206\u4e58\u79ef\u7684\u8ba1\u7b97\u65b9\u6cd5

    \u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u7f16\u7a0b\u8bed\u8a00\u7684\u5e42\u8fd0\u7b97\u7684\u5b9e\u73b0\u65b9\u6cd5\u3002\u4ee5 Python \u4e3a\u4f8b\uff0c\u5e38\u7528\u7684\u5e42\u8ba1\u7b97\u51fd\u6570\u6709\u4e09\u79cd\u3002

    • \u8fd0\u7b97\u7b26 ** \u548c\u51fd\u6570 pow() \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(\\log\u2061 a)\\) \u3002
    • \u51fd\u6570 math.pow() \u5185\u90e8\u8c03\u7528 C \u8bed\u8a00\u5e93\u7684 pow() \u51fd\u6570\uff0c\u5176\u6267\u884c\u6d6e\u70b9\u53d6\u5e42\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    \u53d8\u91cf \\(a\\) \u548c \\(b\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002

    "},{"location":"chapter_greedy/max_product_cutting_problem/#3","title":"3. \u00a0 \u6b63\u786e\u6027\u8bc1\u660e","text":"

    \u4f7f\u7528\u53cd\u8bc1\u6cd5\uff0c\u53ea\u5206\u6790 \\(n \\geq 3\\) \u7684\u60c5\u51b5\u3002

    1. \u6240\u6709\u56e0\u5b50 \\(\\leq 3\\) \uff1a\u5047\u8bbe\u6700\u4f18\u5207\u5206\u65b9\u6848\u4e2d\u5b58\u5728 \\(\\geq 4\\) \u7684\u56e0\u5b50 \\(x\\) \uff0c\u90a3\u4e48\u4e00\u5b9a\u53ef\u4ee5\u5c06\u5176\u7ee7\u7eed\u5212\u5206\u4e3a \\(2(x-2)\\) \uff0c\u4ece\u800c\u83b7\u5f97\u66f4\u5927\u7684\u4e58\u79ef\u3002\u8fd9\u4e0e\u5047\u8bbe\u77db\u76fe\u3002
    2. \u5207\u5206\u65b9\u6848\u4e0d\u5305\u542b \\(1\\) \uff1a\u5047\u8bbe\u6700\u4f18\u5207\u5206\u65b9\u6848\u4e2d\u5b58\u5728\u4e00\u4e2a\u56e0\u5b50 \\(1\\) \uff0c\u90a3\u4e48\u5b83\u4e00\u5b9a\u53ef\u4ee5\u5408\u5e76\u5165\u53e6\u5916\u4e00\u4e2a\u56e0\u5b50\u4e2d\uff0c\u4ee5\u83b7\u5f97\u66f4\u5927\u7684\u4e58\u79ef\u3002\u8fd9\u4e0e\u5047\u8bbe\u77db\u76fe\u3002
    3. \u5207\u5206\u65b9\u6848\u6700\u591a\u5305\u542b\u4e24\u4e2a \\(2\\) \uff1a\u5047\u8bbe\u6700\u4f18\u5207\u5206\u65b9\u6848\u4e2d\u5305\u542b\u4e09\u4e2a \\(2\\) \uff0c\u90a3\u4e48\u4e00\u5b9a\u53ef\u4ee5\u66ff\u6362\u4e3a\u4e24\u4e2a \\(3\\) \uff0c\u4e58\u79ef\u66f4\u5927\u3002\u8fd9\u4e0e\u5047\u8bbe\u77db\u76fe\u3002
    "},{"location":"chapter_greedy/summary/","title":"15.5 \u00a0 \u5c0f\u7ed3","text":"
    • \u8d2a\u5fc3\u7b97\u6cd5\u901a\u5e38\u7528\u4e8e\u89e3\u51b3\u6700\u4f18\u5316\u95ee\u9898\uff0c\u5176\u539f\u7406\u662f\u5728\u6bcf\u4e2a\u51b3\u7b56\u9636\u6bb5\u90fd\u505a\u51fa\u5c40\u90e8\u6700\u4f18\u7684\u51b3\u7b56\uff0c\u4ee5\u671f\u83b7\u5f97\u5168\u5c40\u6700\u4f18\u89e3\u3002
    • \u8d2a\u5fc3\u7b97\u6cd5\u4f1a\u8fed\u4ee3\u5730\u505a\u51fa\u4e00\u4e2a\u53c8\u4e00\u4e2a\u7684\u8d2a\u5fc3\u9009\u62e9\uff0c\u6bcf\u8f6e\u90fd\u5c06\u95ee\u9898\u8f6c\u5316\u6210\u4e00\u4e2a\u89c4\u6a21\u66f4\u5c0f\u7684\u5b50\u95ee\u9898\uff0c\u76f4\u5230\u95ee\u9898\u88ab\u89e3\u51b3\u3002
    • \u8d2a\u5fc3\u7b97\u6cd5\u4e0d\u4ec5\u5b9e\u73b0\u7b80\u5355\uff0c\u8fd8\u5177\u6709\u5f88\u9ad8\u7684\u89e3\u9898\u6548\u7387\u3002\u76f8\u6bd4\u4e8e\u52a8\u6001\u89c4\u5212\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u66f4\u4f4e\u3002
    • \u5728\u96f6\u94b1\u5151\u6362\u95ee\u9898\u4e2d\uff0c\u5bf9\u4e8e\u67d0\u4e9b\u786c\u5e01\u7ec4\u5408\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ef\u4ee5\u4fdd\u8bc1\u627e\u5230\u6700\u4f18\u89e3\uff1b\u5bf9\u4e8e\u53e6\u5916\u4e00\u4e9b\u786c\u5e01\u7ec4\u5408\u5219\u4e0d\u7136\uff0c\u8d2a\u5fc3\u7b97\u6cd5\u53ef\u80fd\u627e\u5230\u5f88\u5dee\u7684\u89e3\u3002
    • \u9002\u5408\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\u7684\u95ee\u9898\u5177\u6709\u4e24\u5927\u6027\u8d28\uff1a\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u548c\u6700\u4f18\u5b50\u7ed3\u6784\u3002\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u4ee3\u8868\u8d2a\u5fc3\u7b56\u7565\u7684\u6709\u6548\u6027\u3002
    • \u5bf9\u4e8e\u67d0\u4e9b\u590d\u6742\u95ee\u9898\uff0c\u8d2a\u5fc3\u9009\u62e9\u6027\u8d28\u7684\u8bc1\u660e\u5e76\u4e0d\u7b80\u5355\u3002\u76f8\u5bf9\u6765\u8bf4\uff0c\u8bc1\u4f2a\u66f4\u52a0\u5bb9\u6613\uff0c\u4f8b\u5982\u96f6\u94b1\u5151\u6362\u95ee\u9898\u3002
    • \u6c42\u89e3\u8d2a\u5fc3\u95ee\u9898\u4e3b\u8981\u5206\u4e3a\u4e09\u6b65\uff1a\u95ee\u9898\u5206\u6790\u3001\u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\u3001\u6b63\u786e\u6027\u8bc1\u660e\u3002\u5176\u4e2d\uff0c\u786e\u5b9a\u8d2a\u5fc3\u7b56\u7565\u662f\u6838\u5fc3\u6b65\u9aa4\uff0c\u6b63\u786e\u6027\u8bc1\u660e\u5f80\u5f80\u662f\u96be\u70b9\u3002
    • \u5206\u6570\u80cc\u5305\u95ee\u9898\u5728 0-1 \u80cc\u5305\u7684\u57fa\u7840\u4e0a\uff0c\u5141\u8bb8\u9009\u62e9\u7269\u54c1\u7684\u4e00\u90e8\u5206\uff0c\u56e0\u6b64\u53ef\u4f7f\u7528\u8d2a\u5fc3\u7b97\u6cd5\u6c42\u89e3\u3002\u8d2a\u5fc3\u7b56\u7565\u7684\u6b63\u786e\u6027\u53ef\u4ee5\u4f7f\u7528\u53cd\u8bc1\u6cd5\u6765\u8bc1\u660e\u3002
    • \u6700\u5927\u5bb9\u91cf\u95ee\u9898\u53ef\u4f7f\u7528\u7a77\u4e3e\u6cd5\u6c42\u89e3\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002\u901a\u8fc7\u8bbe\u8ba1\u8d2a\u5fc3\u7b56\u7565\uff0c\u6bcf\u8f6e\u5411\u5185\u79fb\u52a8\u77ed\u677f\uff0c\u53ef\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(n)\\) \u3002
    • \u5728\u6700\u5927\u5207\u5206\u4e58\u79ef\u95ee\u9898\u4e2d\uff0c\u6211\u4eec\u5148\u540e\u63a8\u7406\u51fa\u4e24\u4e2a\u8d2a\u5fc3\u7b56\u7565\uff1a\\(\\geq 4\\) \u7684\u6574\u6570\u90fd\u5e94\u8be5\u7ee7\u7eed\u5207\u5206\uff0c\u6700\u4f18\u5207\u5206\u56e0\u5b50\u4e3a \\(3\\) \u3002\u4ee3\u7801\u4e2d\u5305\u542b\u5e42\u8fd0\u7b97\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53d6\u51b3\u4e8e\u5e42\u8fd0\u7b97\u5b9e\u73b0\u65b9\u6cd5\uff0c\u901a\u5e38\u4e3a \\(O(1)\\) \u6216 \\(O(\\log n)\\) \u3002
    "},{"location":"chapter_hashing/","title":"\u7b2c 6 \u7ae0 \u00a0 \u54c8\u5e0c\u8868","text":"

    Abstract

    \u5728\u8ba1\u7b97\u673a\u4e16\u754c\u4e2d\uff0c\u54c8\u5e0c\u8868\u5982\u540c\u4e00\u4f4d\u806a\u6167\u7684\u56fe\u4e66\u7ba1\u7406\u5458\u3002

    \u4ed6\u77e5\u9053\u5982\u4f55\u8ba1\u7b97\u7d22\u4e66\u53f7\uff0c\u4ece\u800c\u53ef\u4ee5\u5feb\u901f\u627e\u5230\u76ee\u6807\u56fe\u4e66\u3002

    "},{"location":"chapter_hashing/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 6.1 \u00a0 \u54c8\u5e0c\u8868
    • 6.2 \u00a0 \u54c8\u5e0c\u51b2\u7a81
    • 6.3 \u00a0 \u54c8\u5e0c\u7b97\u6cd5
    • 6.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_hashing/hash_algorithm/","title":"6.3 \u00a0 \u54c8\u5e0c\u7b97\u6cd5","text":"

    \u524d\u4e24\u8282\u4ecb\u7ecd\u4e86\u54c8\u5e0c\u8868\u7684\u5de5\u4f5c\u539f\u7406\u548c\u54c8\u5e0c\u51b2\u7a81\u7684\u5904\u7406\u65b9\u6cd5\u3002\u7136\u800c\u65e0\u8bba\u662f\u5f00\u653e\u5bfb\u5740\u8fd8\u662f\u94fe\u5f0f\u5730\u5740\uff0c\u5b83\u4eec\u53ea\u80fd\u4fdd\u8bc1\u54c8\u5e0c\u8868\u53ef\u4ee5\u5728\u53d1\u751f\u51b2\u7a81\u65f6\u6b63\u5e38\u5de5\u4f5c\uff0c\u800c\u65e0\u6cd5\u51cf\u5c11\u54c8\u5e0c\u51b2\u7a81\u7684\u53d1\u751f\u3002

    \u5982\u679c\u54c8\u5e0c\u51b2\u7a81\u8fc7\u4e8e\u9891\u7e41\uff0c\u54c8\u5e0c\u8868\u7684\u6027\u80fd\u5219\u4f1a\u6025\u5267\u52a3\u5316\u3002\u5982\u56fe 6-8 \u6240\u793a\uff0c\u5bf9\u4e8e\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\uff0c\u7406\u60f3\u60c5\u51b5\u4e0b\u952e\u503c\u5bf9\u5747\u5300\u5206\u5e03\u5728\u5404\u4e2a\u6876\u4e2d\uff0c\u8fbe\u5230\u6700\u4f73\u67e5\u8be2\u6548\u7387\uff1b\u6700\u5dee\u60c5\u51b5\u4e0b\u6240\u6709\u952e\u503c\u5bf9\u90fd\u5b58\u50a8\u5230\u540c\u4e00\u4e2a\u6876\u4e2d\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u9000\u5316\u81f3 \\(O(n)\\) \u3002

    \u56fe 6-8 \u00a0 \u54c8\u5e0c\u51b2\u7a81\u7684\u6700\u4f73\u60c5\u51b5\u4e0e\u6700\u5dee\u60c5\u51b5

    \u952e\u503c\u5bf9\u7684\u5206\u5e03\u60c5\u51b5\u7531\u54c8\u5e0c\u51fd\u6570\u51b3\u5b9a\u3002\u56de\u5fc6\u54c8\u5e0c\u51fd\u6570\u7684\u8ba1\u7b97\u6b65\u9aa4\uff0c\u5148\u8ba1\u7b97\u54c8\u5e0c\u503c\uff0c\u518d\u5bf9\u6570\u7ec4\u957f\u5ea6\u53d6\u6a21\uff1a

    index = hash(key) % capacity\n

    \u89c2\u5bdf\u4ee5\u4e0a\u516c\u5f0f\uff0c\u5f53\u54c8\u5e0c\u8868\u5bb9\u91cf capacity \u56fa\u5b9a\u65f6\uff0c\u54c8\u5e0c\u7b97\u6cd5 hash() \u51b3\u5b9a\u4e86\u8f93\u51fa\u503c\uff0c\u8fdb\u800c\u51b3\u5b9a\u4e86\u952e\u503c\u5bf9\u5728\u54c8\u5e0c\u8868\u4e2d\u7684\u5206\u5e03\u60c5\u51b5\u3002

    \u8fd9\u610f\u5473\u7740\uff0c\u4e3a\u4e86\u964d\u4f4e\u54c8\u5e0c\u51b2\u7a81\u7684\u53d1\u751f\u6982\u7387\uff0c\u6211\u4eec\u5e94\u5f53\u5c06\u6ce8\u610f\u529b\u96c6\u4e2d\u5728\u54c8\u5e0c\u7b97\u6cd5 hash() \u7684\u8bbe\u8ba1\u4e0a\u3002

    "},{"location":"chapter_hashing/hash_algorithm/#631","title":"6.3.1 \u00a0 \u54c8\u5e0c\u7b97\u6cd5\u7684\u76ee\u6807","text":"

    \u4e3a\u4e86\u5b9e\u73b0\u201c\u65e2\u5feb\u53c8\u7a33\u201d\u7684\u54c8\u5e0c\u8868\u6570\u636e\u7ed3\u6784\uff0c\u54c8\u5e0c\u7b97\u6cd5\u5e94\u5177\u5907\u4ee5\u4e0b\u7279\u70b9\u3002

    • \u786e\u5b9a\u6027\uff1a\u5bf9\u4e8e\u76f8\u540c\u7684\u8f93\u5165\uff0c\u54c8\u5e0c\u7b97\u6cd5\u5e94\u59cb\u7ec8\u4ea7\u751f\u76f8\u540c\u7684\u8f93\u51fa\u3002\u8fd9\u6837\u624d\u80fd\u786e\u4fdd\u54c8\u5e0c\u8868\u662f\u53ef\u9760\u7684\u3002
    • \u6548\u7387\u9ad8\uff1a\u8ba1\u7b97\u54c8\u5e0c\u503c\u7684\u8fc7\u7a0b\u5e94\u8be5\u8db3\u591f\u5feb\u3002\u8ba1\u7b97\u5f00\u9500\u8d8a\u5c0f\uff0c\u54c8\u5e0c\u8868\u7684\u5b9e\u7528\u6027\u8d8a\u9ad8\u3002
    • \u5747\u5300\u5206\u5e03\uff1a\u54c8\u5e0c\u7b97\u6cd5\u5e94\u4f7f\u5f97\u952e\u503c\u5bf9\u5747\u5300\u5206\u5e03\u5728\u54c8\u5e0c\u8868\u4e2d\u3002\u5206\u5e03\u8d8a\u5747\u5300\uff0c\u54c8\u5e0c\u51b2\u7a81\u7684\u6982\u7387\u5c31\u8d8a\u4f4e\u3002

    \u5b9e\u9645\u4e0a\uff0c\u54c8\u5e0c\u7b97\u6cd5\u9664\u4e86\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u54c8\u5e0c\u8868\uff0c\u8fd8\u5e7f\u6cdb\u5e94\u7528\u4e8e\u5176\u4ed6\u9886\u57df\u4e2d\u3002

    • \u5bc6\u7801\u5b58\u50a8\uff1a\u4e3a\u4e86\u4fdd\u62a4\u7528\u6237\u5bc6\u7801\u7684\u5b89\u5168\uff0c\u7cfb\u7edf\u901a\u5e38\u4e0d\u4f1a\u76f4\u63a5\u5b58\u50a8\u7528\u6237\u7684\u660e\u6587\u5bc6\u7801\uff0c\u800c\u662f\u5b58\u50a8\u5bc6\u7801\u7684\u54c8\u5e0c\u503c\u3002\u5f53\u7528\u6237\u8f93\u5165\u5bc6\u7801\u65f6\uff0c\u7cfb\u7edf\u4f1a\u5bf9\u8f93\u5165\u7684\u5bc6\u7801\u8ba1\u7b97\u54c8\u5e0c\u503c\uff0c\u7136\u540e\u4e0e\u5b58\u50a8\u7684\u54c8\u5e0c\u503c\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u8005\u5339\u914d\uff0c\u90a3\u4e48\u5bc6\u7801\u5c31\u88ab\u89c6\u4e3a\u6b63\u786e\u3002
    • \u6570\u636e\u5b8c\u6574\u6027\u68c0\u67e5\uff1a\u6570\u636e\u53d1\u9001\u65b9\u53ef\u4ee5\u8ba1\u7b97\u6570\u636e\u7684\u54c8\u5e0c\u503c\u5e76\u5c06\u5176\u4e00\u540c\u53d1\u9001\uff1b\u63a5\u6536\u65b9\u53ef\u4ee5\u91cd\u65b0\u8ba1\u7b97\u63a5\u6536\u5230\u7684\u6570\u636e\u7684\u54c8\u5e0c\u503c\uff0c\u5e76\u4e0e\u63a5\u6536\u5230\u7684\u54c8\u5e0c\u503c\u8fdb\u884c\u6bd4\u8f83\u3002\u5982\u679c\u4e24\u8005\u5339\u914d\uff0c\u90a3\u4e48\u6570\u636e\u5c31\u88ab\u89c6\u4e3a\u5b8c\u6574\u3002

    \u5bf9\u4e8e\u5bc6\u7801\u5b66\u7684\u76f8\u5173\u5e94\u7528\uff0c\u4e3a\u4e86\u9632\u6b62\u4ece\u54c8\u5e0c\u503c\u63a8\u5bfc\u51fa\u539f\u59cb\u5bc6\u7801\u7b49\u9006\u5411\u5de5\u7a0b\uff0c\u54c8\u5e0c\u7b97\u6cd5\u9700\u8981\u5177\u5907\u66f4\u9ad8\u7b49\u7ea7\u7684\u5b89\u5168\u7279\u6027\u3002

    • \u5355\u5411\u6027\uff1a\u65e0\u6cd5\u901a\u8fc7\u54c8\u5e0c\u503c\u53cd\u63a8\u51fa\u5173\u4e8e\u8f93\u5165\u6570\u636e\u7684\u4efb\u4f55\u4fe1\u606f\u3002
    • \u6297\u78b0\u649e\u6027\uff1a\u5e94\u5f53\u6781\u96be\u627e\u5230\u4e24\u4e2a\u4e0d\u540c\u7684\u8f93\u5165\uff0c\u4f7f\u5f97\u5b83\u4eec\u7684\u54c8\u5e0c\u503c\u76f8\u540c\u3002
    • \u96ea\u5d29\u6548\u5e94\uff1a\u8f93\u5165\u7684\u5fae\u5c0f\u53d8\u5316\u5e94\u5f53\u5bfc\u81f4\u8f93\u51fa\u7684\u663e\u8457\u4e14\u4e0d\u53ef\u9884\u6d4b\u7684\u53d8\u5316\u3002

    \u8bf7\u6ce8\u610f\uff0c\u201c\u5747\u5300\u5206\u5e03\u201d\u4e0e\u201c\u6297\u78b0\u649e\u6027\u201d\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u6982\u5ff5\uff0c\u6ee1\u8db3\u5747\u5300\u5206\u5e03\u4e0d\u4e00\u5b9a\u6ee1\u8db3\u6297\u78b0\u649e\u6027\u3002\u4f8b\u5982\uff0c\u5728\u968f\u673a\u8f93\u5165 key \u4e0b\uff0c\u54c8\u5e0c\u51fd\u6570 key % 100 \u53ef\u4ee5\u4ea7\u751f\u5747\u5300\u5206\u5e03\u7684\u8f93\u51fa\u3002\u7136\u800c\u8be5\u54c8\u5e0c\u7b97\u6cd5\u8fc7\u4e8e\u7b80\u5355\uff0c\u6240\u6709\u540e\u4e24\u4f4d\u76f8\u7b49\u7684 key \u7684\u8f93\u51fa\u90fd\u76f8\u540c\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u4ece\u54c8\u5e0c\u503c\u53cd\u63a8\u51fa\u53ef\u7528\u7684 key \uff0c\u4ece\u800c\u7834\u89e3\u5bc6\u7801\u3002

    "},{"location":"chapter_hashing/hash_algorithm/#632","title":"6.3.2 \u00a0 \u54c8\u5e0c\u7b97\u6cd5\u7684\u8bbe\u8ba1","text":"

    \u54c8\u5e0c\u7b97\u6cd5\u7684\u8bbe\u8ba1\u662f\u4e00\u4e2a\u9700\u8981\u8003\u8651\u8bb8\u591a\u56e0\u7d20\u7684\u590d\u6742\u95ee\u9898\u3002\u7136\u800c\u5bf9\u4e8e\u67d0\u4e9b\u8981\u6c42\u4e0d\u9ad8\u7684\u573a\u666f\uff0c\u6211\u4eec\u4e5f\u80fd\u8bbe\u8ba1\u4e00\u4e9b\u7b80\u5355\u7684\u54c8\u5e0c\u7b97\u6cd5\u3002

    • \u52a0\u6cd5\u54c8\u5e0c\uff1a\u5bf9\u8f93\u5165\u7684\u6bcf\u4e2a\u5b57\u7b26\u7684 ASCII \u7801\u8fdb\u884c\u76f8\u52a0\uff0c\u5c06\u5f97\u5230\u7684\u603b\u548c\u4f5c\u4e3a\u54c8\u5e0c\u503c\u3002
    • \u4e58\u6cd5\u54c8\u5e0c\uff1a\u5229\u7528\u4e58\u6cd5\u7684\u4e0d\u76f8\u5173\u6027\uff0c\u6bcf\u8f6e\u4e58\u4ee5\u4e00\u4e2a\u5e38\u6570\uff0c\u5c06\u5404\u4e2a\u5b57\u7b26\u7684 ASCII \u7801\u7d2f\u79ef\u5230\u54c8\u5e0c\u503c\u4e2d\u3002
    • \u5f02\u6216\u54c8\u5e0c\uff1a\u5c06\u8f93\u5165\u6570\u636e\u7684\u6bcf\u4e2a\u5143\u7d20\u901a\u8fc7\u5f02\u6216\u64cd\u4f5c\u7d2f\u79ef\u5230\u4e00\u4e2a\u54c8\u5e0c\u503c\u4e2d\u3002
    • \u65cb\u8f6c\u54c8\u5e0c\uff1a\u5c06\u6bcf\u4e2a\u5b57\u7b26\u7684 ASCII \u7801\u7d2f\u79ef\u5230\u4e00\u4e2a\u54c8\u5e0c\u503c\u4e2d\uff0c\u6bcf\u6b21\u7d2f\u79ef\u4e4b\u524d\u90fd\u4f1a\u5bf9\u54c8\u5e0c\u503c\u8fdb\u884c\u65cb\u8f6c\u64cd\u4f5c\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig simple_hash.py
    def add_hash(key: str) -> int:\n    \"\"\"\u52a0\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash += ord(c)\n    return hash % modulus\n\ndef mul_hash(key: str) -> int:\n    \"\"\"\u4e58\u6cd5\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = 31 * hash + ord(c)\n    return hash % modulus\n\ndef xor_hash(key: str) -> int:\n    \"\"\"\u5f02\u6216\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash ^= ord(c)\n    return hash % modulus\n\ndef rot_hash(key: str) -> int:\n    \"\"\"\u65cb\u8f6c\u54c8\u5e0c\"\"\"\n    hash = 0\n    modulus = 1000000007\n    for c in key:\n        hash = (hash << 4) ^ (hash >> 28) ^ ord(c)\n    return hash % modulus\n
    simple_hash.cpp
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = (31 * hash + (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash ^= (int)c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(string key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (unsigned char c : key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int)c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.java
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = (31 * hash + (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n    int hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash ^= (int) c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n    long hash = 0;\n    final int MODULUS = 1000000007;\n    for (char c : key.toCharArray()) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (int) c) % MODULUS;\n    }\n    return (int) hash;\n}\n
    simple_hash.cs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint AddHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint MulHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = (31 * hash + c) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint XorHash(string key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash ^= c;\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint RotHash(string key) {\n    long hash = 0;\n    const int MODULUS = 1000000007;\n    foreach (char c in key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c) % MODULUS;\n    }\n    return (int)hash;\n}\n
    simple_hash.go
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = (31*hash + int64(b)) % modulus\n    }\n    return int(hash)\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key string) int {\n    hash := 0\n    modulus := 1000000007\n    for _, b := range []byte(key) {\n        fmt.Println(int(b))\n        hash ^= int(b)\n        hash = (31*hash + int(b)) % modulus\n    }\n    return hash & modulus\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key string) int {\n    var hash int64\n    var modulus int64\n\n    modulus = 1000000007\n    for _, b := range []byte(key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ int64(b)) % modulus\n    }\n    return int(hash)\n}\n
    simple_hash.swift
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunc addHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunc mulHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = (31 * hash + Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunc xorHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash ^= Int(scalar.value)\n        }\n    }\n    return hash & MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunc rotHash(key: String) -> Int {\n    var hash = 0\n    let MODULUS = 1_000_000_007\n    for c in key {\n        for scalar in c.unicodeScalars {\n            hash = ((hash << 4) ^ (hash >> 28) ^ Int(scalar.value)) % MODULUS\n        }\n    }\n    return hash\n}\n
    simple_hash.js
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key) {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.ts
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfunction addHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfunction mulHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = (31 * hash + c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfunction xorHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash ^= c.charCodeAt(0);\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfunction rotHash(key: string): number {\n    let hash = 0;\n    const MODULUS = 1000000007;\n    for (const c of key) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c.charCodeAt(0)) % MODULUS;\n    }\n    return hash;\n}\n
    simple_hash.dart
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = (31 * hash + key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash ^= key.codeUnitAt(i);\n  }\n  return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(String key) {\n  int hash = 0;\n  final int MODULUS = 1000000007;\n  for (int i = 0; i < key.length; i++) {\n    hash = ((hash << 4) ^ (hash >> 28) ^ key.codeUnitAt(i)) % MODULUS;\n  }\n  return hash;\n}\n
    simple_hash.rs
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfn add_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfn mul_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = (31 * hash + c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfn xor_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash ^= c as i64;\n    }\n\n    (hash & MODULUS) as i32\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfn rot_hash(key: &str) -> i32 {\n    let mut hash = 0_i64;\n    const MODULUS: i64 = 1000000007;\n\n    for c in key.chars() {\n        hash = ((hash << 4) ^ (hash >> 28) ^ c as i64) % MODULUS;\n    }\n\n    hash as i32\n}\n
    simple_hash.c
    /* \u52a0\u6cd5\u54c8\u5e0c */\nint addHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nint mulHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = (31 * hash + (unsigned char)key[i]) % MODULUS;\n    }\n    return (int)hash;\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nint xorHash(char *key) {\n    int hash = 0;\n    const int MODULUS = 1000000007;\n\n    for (int i = 0; i < strlen(key); i++) {\n        hash ^= (unsigned char)key[i];\n    }\n    return hash & MODULUS;\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nint rotHash(char *key) {\n    long long hash = 0;\n    const int MODULUS = 1000000007;\n    for (int i = 0; i < strlen(key); i++) {\n        hash = ((hash << 4) ^ (hash >> 28) ^ (unsigned char)key[i]) % MODULUS;\n    }\n\n    return (int)hash;\n}\n
    simple_hash.kt
    /* \u52a0\u6cd5\u54c8\u5e0c */\nfun addHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u4e58\u6cd5\u54c8\u5e0c */\nfun mulHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = (31 * hash + c.code) % MODULUS\n    }\n    return hash.toInt()\n}\n\n/* \u5f02\u6216\u54c8\u5e0c */\nfun xorHash(key: String): Int {\n    var hash = 0\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = hash xor c.code\n    }\n    return hash and MODULUS\n}\n\n/* \u65cb\u8f6c\u54c8\u5e0c */\nfun rotHash(key: String): Int {\n    var hash = 0L\n    val MODULUS = 1000000007\n    for (c in key.toCharArray()) {\n        hash = ((hash shl 4) xor (hash shr 28) xor c.code.toLong()) % MODULUS\n    }\n    return hash.toInt()\n}\n
    simple_hash.rb
    ### \u52a0\u6cd5\u54c8\u5e0c ###\ndef add_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash += c.ord }\n\n  hash % modulus\nend\n\n### \u4e58\u6cd5\u54c8\u5e0c ###\ndef mul_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = 31 * hash + c.ord }\n\n  hash % modulus\nend\n\n### \u5f02\u6216\u54c8\u5e0c ###\ndef xor_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash ^= c.ord }\n\n  hash % modulus\nend\n\n### \u65cb\u8f6c\u54c8\u5e0c ###\ndef rot_hash(key)\n  hash = 0\n  modulus = 1_000_000_007\n\n  key.each_char { |c| hash = (hash << 4) ^ (hash >> 28) ^ c.ord }\n\n  hash % modulus\nend\n
    simple_hash.zig
    [class]{}-[func]{addHash}\n\n[class]{}-[func]{mulHash}\n\n[class]{}-[func]{xorHash}\n\n[class]{}-[func]{rotHash}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u6bcf\u79cd\u54c8\u5e0c\u7b97\u6cd5\u7684\u6700\u540e\u4e00\u6b65\u90fd\u662f\u5bf9\u5927\u8d28\u6570 \\(1000000007\\) \u53d6\u6a21\uff0c\u4ee5\u786e\u4fdd\u54c8\u5e0c\u503c\u5728\u5408\u9002\u7684\u8303\u56f4\u5185\u3002\u503c\u5f97\u601d\u8003\u7684\u662f\uff0c\u4e3a\u4ec0\u4e48\u8981\u5f3a\u8c03\u5bf9\u8d28\u6570\u53d6\u6a21\uff0c\u6216\u8005\u8bf4\u5bf9\u5408\u6570\u53d6\u6a21\u7684\u5f0a\u7aef\u662f\u4ec0\u4e48\uff1f\u8fd9\u662f\u4e00\u4e2a\u6709\u8da3\u7684\u95ee\u9898\u3002

    \u5148\u629b\u51fa\u7ed3\u8bba\uff1a\u4f7f\u7528\u5927\u8d28\u6570\u4f5c\u4e3a\u6a21\u6570\uff0c\u53ef\u4ee5\u6700\u5927\u5316\u5730\u4fdd\u8bc1\u54c8\u5e0c\u503c\u7684\u5747\u5300\u5206\u5e03\u3002\u56e0\u4e3a\u8d28\u6570\u4e0d\u4e0e\u5176\u4ed6\u6570\u5b57\u5b58\u5728\u516c\u7ea6\u6570\uff0c\u53ef\u4ee5\u51cf\u5c11\u56e0\u53d6\u6a21\u64cd\u4f5c\u800c\u4ea7\u751f\u7684\u5468\u671f\u6027\u6a21\u5f0f\uff0c\u4ece\u800c\u907f\u514d\u54c8\u5e0c\u51b2\u7a81\u3002

    \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5047\u8bbe\u6211\u4eec\u9009\u62e9\u5408\u6570 \\(9\\) \u4f5c\u4e3a\u6a21\u6570\uff0c\u5b83\u53ef\u4ee5\u88ab \\(3\\) \u6574\u9664\uff0c\u90a3\u4e48\u6240\u6709\u53ef\u4ee5\u88ab \\(3\\) \u6574\u9664\u7684 key \u90fd\u4f1a\u88ab\u6620\u5c04\u5230 \\(0\\)\u3001\\(3\\)\u3001\\(6\\) \u8fd9\u4e09\u4e2a\u54c8\u5e0c\u503c\u3002

    \\[ \\begin{aligned} \\text{modulus} & = 9 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 0, 3, 6, 0, 3, 6, 0, 3, 6,\\dots \\} \\end{aligned} \\]

    \u5982\u679c\u8f93\u5165 key \u6070\u597d\u6ee1\u8db3\u8fd9\u79cd\u7b49\u5dee\u6570\u5217\u7684\u6570\u636e\u5206\u5e03\uff0c\u90a3\u4e48\u54c8\u5e0c\u503c\u5c31\u4f1a\u51fa\u73b0\u805a\u5806\uff0c\u4ece\u800c\u52a0\u91cd\u54c8\u5e0c\u51b2\u7a81\u3002\u73b0\u5728\uff0c\u5047\u8bbe\u5c06 modulus \u66ff\u6362\u4e3a\u8d28\u6570 \\(13\\) \uff0c\u7531\u4e8e key \u548c modulus \u4e4b\u95f4\u4e0d\u5b58\u5728\u516c\u7ea6\u6570\uff0c\u56e0\u6b64\u8f93\u51fa\u7684\u54c8\u5e0c\u503c\u7684\u5747\u5300\u6027\u4f1a\u660e\u663e\u63d0\u5347\u3002

    \\[ \\begin{aligned} \\text{modulus} & = 13 \\newline \\text{key} & = \\{ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, \\dots \\} \\newline \\text{hash} & = \\{ 0, 3, 6, 9, 12, 2, 5, 8, 11, 1, 4, 7, \\dots \\} \\end{aligned} \\]

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u5982\u679c\u80fd\u591f\u4fdd\u8bc1 key \u662f\u968f\u673a\u5747\u5300\u5206\u5e03\u7684\uff0c\u90a3\u4e48\u9009\u62e9\u8d28\u6570\u6216\u8005\u5408\u6570\u4f5c\u4e3a\u6a21\u6570\u90fd\u53ef\u4ee5\uff0c\u5b83\u4eec\u90fd\u80fd\u8f93\u51fa\u5747\u5300\u5206\u5e03\u7684\u54c8\u5e0c\u503c\u3002\u800c\u5f53 key \u7684\u5206\u5e03\u5b58\u5728\u67d0\u79cd\u5468\u671f\u6027\u65f6\uff0c\u5bf9\u5408\u6570\u53d6\u6a21\u66f4\u5bb9\u6613\u51fa\u73b0\u805a\u96c6\u73b0\u8c61\u3002

    \u603b\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u901a\u5e38\u9009\u53d6\u8d28\u6570\u4f5c\u4e3a\u6a21\u6570\uff0c\u5e76\u4e14\u8fd9\u4e2a\u8d28\u6570\u6700\u597d\u8db3\u591f\u5927\uff0c\u4ee5\u5c3d\u53ef\u80fd\u6d88\u9664\u5468\u671f\u6027\u6a21\u5f0f\uff0c\u63d0\u5347\u54c8\u5e0c\u7b97\u6cd5\u7684\u7a33\u5065\u6027\u3002

    "},{"location":"chapter_hashing/hash_algorithm/#633","title":"6.3.3 \u00a0 \u5e38\u89c1\u54c8\u5e0c\u7b97\u6cd5","text":"

    \u4e0d\u96be\u53d1\u73b0\uff0c\u4ee5\u4e0a\u4ecb\u7ecd\u7684\u7b80\u5355\u54c8\u5e0c\u7b97\u6cd5\u90fd\u6bd4\u8f83\u201c\u8106\u5f31\u201d\uff0c\u8fdc\u8fdc\u6ca1\u6709\u8fbe\u5230\u54c8\u5e0c\u7b97\u6cd5\u7684\u8bbe\u8ba1\u76ee\u6807\u3002\u4f8b\u5982\uff0c\u7531\u4e8e\u52a0\u6cd5\u548c\u5f02\u6216\u6ee1\u8db3\u4ea4\u6362\u5f8b\uff0c\u56e0\u6b64\u52a0\u6cd5\u54c8\u5e0c\u548c\u5f02\u6216\u54c8\u5e0c\u65e0\u6cd5\u533a\u5206\u5185\u5bb9\u76f8\u540c\u4f46\u987a\u5e8f\u4e0d\u540c\u7684\u5b57\u7b26\u4e32\uff0c\u8fd9\u53ef\u80fd\u4f1a\u52a0\u5267\u54c8\u5e0c\u51b2\u7a81\uff0c\u5e76\u5f15\u8d77\u4e00\u4e9b\u5b89\u5168\u95ee\u9898\u3002

    \u5728\u5b9e\u9645\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u7528\u4e00\u4e9b\u6807\u51c6\u54c8\u5e0c\u7b97\u6cd5\uff0c\u4f8b\u5982 MD5\u3001SHA-1\u3001SHA-2 \u548c SHA-3 \u7b49\u3002\u5b83\u4eec\u53ef\u4ee5\u5c06\u4efb\u610f\u957f\u5ea6\u7684\u8f93\u5165\u6570\u636e\u6620\u5c04\u5230\u6052\u5b9a\u957f\u5ea6\u7684\u54c8\u5e0c\u503c\u3002

    \u8fd1\u4e00\u4e2a\u4e16\u7eaa\u4ee5\u6765\uff0c\u54c8\u5e0c\u7b97\u6cd5\u5904\u5728\u4e0d\u65ad\u5347\u7ea7\u4e0e\u4f18\u5316\u7684\u8fc7\u7a0b\u4e2d\u3002\u4e00\u90e8\u5206\u7814\u7a76\u4eba\u5458\u52aa\u529b\u63d0\u5347\u54c8\u5e0c\u7b97\u6cd5\u7684\u6027\u80fd\uff0c\u53e6\u4e00\u90e8\u5206\u7814\u7a76\u4eba\u5458\u548c\u9ed1\u5ba2\u5219\u81f4\u529b\u4e8e\u5bfb\u627e\u54c8\u5e0c\u7b97\u6cd5\u7684\u5b89\u5168\u6027\u95ee\u9898\u3002\u8868 6-2 \u5c55\u793a\u4e86\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u5e38\u89c1\u7684\u54c8\u5e0c\u7b97\u6cd5\u3002

    • MD5 \u548c SHA-1 \u5df2\u591a\u6b21\u88ab\u6210\u529f\u653b\u51fb\uff0c\u56e0\u6b64\u5b83\u4eec\u88ab\u5404\u7c7b\u5b89\u5168\u5e94\u7528\u5f03\u7528\u3002
    • SHA-2 \u7cfb\u5217\u4e2d\u7684 SHA-256 \u662f\u6700\u5b89\u5168\u7684\u54c8\u5e0c\u7b97\u6cd5\u4e4b\u4e00\uff0c\u4ecd\u672a\u51fa\u73b0\u6210\u529f\u7684\u653b\u51fb\u6848\u4f8b\uff0c\u56e0\u6b64\u5e38\u7528\u5728\u5404\u7c7b\u5b89\u5168\u5e94\u7528\u4e0e\u534f\u8bae\u4e2d\u3002
    • SHA-3 \u76f8\u8f83 SHA-2 \u7684\u5b9e\u73b0\u5f00\u9500\u66f4\u4f4e\u3001\u8ba1\u7b97\u6548\u7387\u66f4\u9ad8\uff0c\u4f46\u76ee\u524d\u4f7f\u7528\u8986\u76d6\u5ea6\u4e0d\u5982 SHA-2 \u7cfb\u5217\u3002

    \u8868 6-2 \u00a0 \u5e38\u89c1\u7684\u54c8\u5e0c\u7b97\u6cd5

    MD5 SHA-1 SHA-2 SHA-3 \u63a8\u51fa\u65f6\u95f4 1992 1995 2002 2008 \u8f93\u51fa\u957f\u5ea6 128 bit 160 bit 256/512 bit 224/256/384/512 bit \u54c8\u5e0c\u51b2\u7a81 \u8f83\u591a \u8f83\u591a \u5f88\u5c11 \u5f88\u5c11 \u5b89\u5168\u7b49\u7ea7 \u4f4e\uff0c\u5df2\u88ab\u6210\u529f\u653b\u51fb \u4f4e\uff0c\u5df2\u88ab\u6210\u529f\u653b\u51fb \u9ad8 \u9ad8 \u5e94\u7528 \u5df2\u88ab\u5f03\u7528\uff0c\u4ecd\u7528\u4e8e\u6570\u636e\u5b8c\u6574\u6027\u68c0\u67e5 \u5df2\u88ab\u5f03\u7528 \u52a0\u5bc6\u8d27\u5e01\u4ea4\u6613\u9a8c\u8bc1\u3001\u6570\u5b57\u7b7e\u540d\u7b49 \u53ef\u7528\u4e8e\u66ff\u4ee3 SHA-2"},{"location":"chapter_hashing/hash_algorithm/#634","title":"6.3.4 \u00a0 \u6570\u636e\u7ed3\u6784\u7684\u54c8\u5e0c\u503c","text":"

    \u6211\u4eec\u77e5\u9053\uff0c\u54c8\u5e0c\u8868\u7684 key \u53ef\u4ee5\u662f\u6574\u6570\u3001\u5c0f\u6570\u6216\u5b57\u7b26\u4e32\u7b49\u6570\u636e\u7c7b\u578b\u3002\u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u4f1a\u4e3a\u8fd9\u4e9b\u6570\u636e\u7c7b\u578b\u63d0\u4f9b\u5185\u7f6e\u7684\u54c8\u5e0c\u7b97\u6cd5\uff0c\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u8868\u4e2d\u7684\u6876\u7d22\u5f15\u3002\u4ee5 Python \u4e3a\u4f8b\uff0c\u6211\u4eec\u53ef\u4ee5\u8c03\u7528 hash() \u51fd\u6570\u6765\u8ba1\u7b97\u5404\u79cd\u6570\u636e\u7c7b\u578b\u7684\u54c8\u5e0c\u503c\u3002

    • \u6574\u6570\u548c\u5e03\u5c14\u91cf\u7684\u54c8\u5e0c\u503c\u5c31\u662f\u5176\u672c\u8eab\u3002
    • \u6d6e\u70b9\u6570\u548c\u5b57\u7b26\u4e32\u7684\u54c8\u5e0c\u503c\u8ba1\u7b97\u8f83\u4e3a\u590d\u6742\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u8bf7\u81ea\u884c\u5b66\u4e60\u3002
    • \u5143\u7ec4\u7684\u54c8\u5e0c\u503c\u662f\u5bf9\u5176\u4e2d\u6bcf\u4e00\u4e2a\u5143\u7d20\u8fdb\u884c\u54c8\u5e0c\uff0c\u7136\u540e\u5c06\u8fd9\u4e9b\u54c8\u5e0c\u503c\u7ec4\u5408\u8d77\u6765\uff0c\u5f97\u5230\u5355\u4e00\u7684\u54c8\u5e0c\u503c\u3002
    • \u5bf9\u8c61\u7684\u54c8\u5e0c\u503c\u57fa\u4e8e\u5176\u5185\u5b58\u5730\u5740\u751f\u6210\u3002\u901a\u8fc7\u91cd\u5199\u5bf9\u8c61\u7684\u54c8\u5e0c\u65b9\u6cd5\uff0c\u53ef\u5b9e\u73b0\u57fa\u4e8e\u5185\u5bb9\u751f\u6210\u54c8\u5e0c\u503c\u3002

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u7684\u5185\u7f6e\u54c8\u5e0c\u503c\u8ba1\u7b97\u51fd\u6570\u7684\u5b9a\u4e49\u548c\u65b9\u6cd5\u4e0d\u540c\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig built_in_hash.py
    num = 3\nhash_num = hash(num)\n# \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nbol = True\nhash_bol = hash(bol)\n# \u5e03\u5c14\u91cf True \u7684\u54c8\u5e0c\u503c\u4e3a 1\n\ndec = 3.14159\nhash_dec = hash(dec)\n# \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 326484311674566659\n\nstr = \"Hello \u7b97\u6cd5\"\nhash_str = hash(str)\n# \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 4617003410720528961\n\ntup = (12836, \"\u5c0f\u54c8\")\nhash_tup = hash(tup)\n# \u5143\u7ec4 (12836, '\u5c0f\u54c8') \u7684\u54c8\u5e0c\u503c\u4e3a 1029005403108185979\n\nobj = ListNode(0)\nhash_obj = hash(obj)\n# \u8282\u70b9\u5bf9\u8c61 <ListNode object at 0x1058fd810> \u7684\u54c8\u5e0c\u503c\u4e3a 274267521\n
    built_in_hash.cpp
    int num = 3;\nsize_t hashNum = hash<int>()(num);\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nbool bol = true;\nsize_t hashBol = hash<bool>()(bol);\n// \u5e03\u5c14\u91cf 1 \u7684\u54c8\u5e0c\u503c\u4e3a 1\n\ndouble dec = 3.14159;\nsize_t hashDec = hash<double>()(dec);\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 4614256650576692846\n\nstring str = \"Hello \u7b97\u6cd5\";\nsize_t hashStr = hash<string>()(str);\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 15466937326284535026\n\n// \u5728 C++ \u4e2d\uff0c\u5185\u7f6e std:hash() \u4ec5\u63d0\u4f9b\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u54c8\u5e0c\u503c\u8ba1\u7b97\n// \u6570\u7ec4\u3001\u5bf9\u8c61\u7684\u54c8\u5e0c\u503c\u8ba1\u7b97\u9700\u8981\u81ea\u884c\u5b9e\u73b0\n
    built_in_hash.java
    int num = 3;\nint hashNum = Integer.hashCode(num);\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nboolean bol = true;\nint hashBol = Boolean.hashCode(bol);\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 1231\n\ndouble dec = 3.14159;\nint hashDec = Double.hashCode(dec);\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1340954729\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode();\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -727081396\n\nObject[] arr = { 12836, \"\u5c0f\u54c8\" };\nint hashTup = Arrays.hashCode(arr);\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 1151158\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode();\n// \u8282\u70b9\u5bf9\u8c61 utils.ListNode@7dc5e7b4 \u7684\u54c8\u5e0c\u503c\u4e3a 2110121908\n
    built_in_hash.cs
    int num = 3;\nint hashNum = num.GetHashCode();\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3;\n\nbool bol = true;\nint hashBol = bol.GetHashCode();\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 1;\n\ndouble dec = 3.14159;\nint hashDec = dec.GetHashCode();\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1340954729;\n\nstring str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.GetHashCode();\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -586107568;\n\nobject[] arr = [12836, \"\u5c0f\u54c8\"];\nint hashTup = arr.GetHashCode();\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 42931033;\n\nListNode obj = new(0);\nint hashObj = obj.GetHashCode();\n// \u8282\u70b9\u5bf9\u8c61 0 \u7684\u54c8\u5e0c\u503c\u4e3a 39053774;\n
    built_in_hash.go
    // Go \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.swift
    let num = 3\nlet hashNum = num.hashValue\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 9047044699613009734\n\nlet bol = true\nlet hashBol = bol.hashValue\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a -4431640247352757451\n\nlet dec = 3.14159\nlet hashDec = dec.hashValue\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -2465384235396674631\n\nlet str = \"Hello \u7b97\u6cd5\"\nlet hashStr = str.hashValue\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -7850626797806988787\n\nlet arr = [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")]\nlet hashTup = arr.hashValue\n// \u6570\u7ec4 [AnyHashable(12836), AnyHashable(\"\u5c0f\u54c8\")] \u7684\u54c8\u5e0c\u503c\u4e3a -2308633508154532996\n\nlet obj = ListNode(x: 0)\nlet hashObj = obj.hashValue\n// \u8282\u70b9\u5bf9\u8c61 utils.ListNode \u7684\u54c8\u5e0c\u503c\u4e3a -2434780518035996159\n
    built_in_hash.js
    // JavaScript \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.ts
    // TypeScript \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.dart
    int num = 3;\nint hashNum = num.hashCode;\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 34803\n\nbool bol = true;\nint hashBol = bol.hashCode;\n// \u5e03\u5c14\u503c true \u7684\u54c8\u5e0c\u503c\u4e3a 1231\n\ndouble dec = 3.14159;\nint hashDec = dec.hashCode;\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 2570631074981783\n\nString str = \"Hello \u7b97\u6cd5\";\nint hashStr = str.hashCode;\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 468167534\n\nList arr = [12836, \"\u5c0f\u54c8\"];\nint hashArr = arr.hashCode;\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 976512528\n\nListNode obj = new ListNode(0);\nint hashObj = obj.hashCode;\n// \u8282\u70b9\u5bf9\u8c61 Instance of 'ListNode' \u7684\u54c8\u5e0c\u503c\u4e3a 1033450432\n
    built_in_hash.rs
    use std::collections::hash_map::DefaultHasher;\nuse std::hash::{Hash, Hasher};\n\nlet num = 3;\nlet mut num_hasher = DefaultHasher::new();\nnum.hash(&mut num_hasher);\nlet hash_num = num_hasher.finish();\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 568126464209439262\n\nlet bol = true;\nlet mut bol_hasher = DefaultHasher::new();\nbol.hash(&mut bol_hasher);\nlet hash_bol = bol_hasher.finish();\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 4952851536318644461\n\nlet dec: f32 = 3.14159;\nlet mut dec_hasher = DefaultHasher::new();\ndec.to_bits().hash(&mut dec_hasher);\nlet hash_dec = dec_hasher.finish();\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a 2566941990314602357\n\nlet str = \"Hello \u7b97\u6cd5\";\nlet mut str_hasher = DefaultHasher::new();\nstr.hash(&mut str_hasher);\nlet hash_str = str_hasher.finish();\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a 16092673739211250988\n\nlet arr = (&12836, &\"\u5c0f\u54c8\");\nlet mut tup_hasher = DefaultHasher::new();\narr.hash(&mut tup_hasher);\nlet hash_tup = tup_hasher.finish();\n// \u5143\u7ec4 (12836, \"\u5c0f\u54c8\") \u7684\u54c8\u5e0c\u503c\u4e3a 1885128010422702749\n\nlet node = ListNode::new(42);\nlet mut hasher = DefaultHasher::new();\nnode.borrow().val.hash(&mut hasher);\nlet hash = hasher.finish();\n// \u8282\u70b9\u5bf9\u8c61 RefCell { value: ListNode { val: 42, next: None } } \u7684\u54c8\u5e0c\u503c\u4e3a15387811073369036852\n
    built_in_hash.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e hash code \u51fd\u6570\n
    built_in_hash.kt
    val num = 3\nval hashNum = num.hashCode()\n// \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a 3\n\nval bol = true\nval hashBol = bol.hashCode()\n// \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a 1231\n\nval dec = 3.14159\nval hashDec = dec.hashCode()\n// \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1340954729\n\nval str = \"Hello \u7b97\u6cd5\"\nval hashStr = str.hashCode()\n// \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -727081396\n\nval arr = arrayOf<Any>(12836, \"\u5c0f\u54c8\")\nval hashTup = arr.hashCode()\n// \u6570\u7ec4 [12836, \u5c0f\u54c8] \u7684\u54c8\u5e0c\u503c\u4e3a 189568618\n\nval obj = ListNode(0)\nval hashObj = obj.hashCode()\n// \u8282\u70b9\u5bf9\u8c61 utils.ListNode@1d81eb93 \u7684\u54c8\u5e0c\u503c\u4e3a 495053715\n
    built_in_hash.rb
    num = 3\nhash_num = num.hash\n# \u6574\u6570 3 \u7684\u54c8\u5e0c\u503c\u4e3a -4385856518450339636\n\nbol = true\nhash_bol = bol.hash\n# \u5e03\u5c14\u91cf true \u7684\u54c8\u5e0c\u503c\u4e3a -1617938112149317027\n\ndec = 3.14159\nhash_dec = dec.hash\n# \u5c0f\u6570 3.14159 \u7684\u54c8\u5e0c\u503c\u4e3a -1479186995943067893\n\nstr = \"Hello \u7b97\u6cd5\"\nhash_str = str.hash\n# \u5b57\u7b26\u4e32\u201cHello \u7b97\u6cd5\u201d\u7684\u54c8\u5e0c\u503c\u4e3a -4075943250025831763\n\ntup = [12836, '\u5c0f\u54c8']\nhash_tup = tup.hash\n# \u5143\u7ec4 (12836, '\u5c0f\u54c8') \u7684\u54c8\u5e0c\u503c\u4e3a 1999544809202288822\n\nobj = ListNode.new(0)\nhash_obj = obj.hash\n# \u8282\u70b9\u5bf9\u8c61 #<ListNode:0x000078133140ab70> \u7684\u54c8\u5e0c\u503c\u4e3a 4302940560806366381\n
    built_in_hash.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5728\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0c\u53ea\u6709\u4e0d\u53ef\u53d8\u5bf9\u8c61\u624d\u53ef\u4f5c\u4e3a\u54c8\u5e0c\u8868\u7684 key \u3002\u5047\u5982\u6211\u4eec\u5c06\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\u4f5c\u4e3a key \uff0c\u5f53\u5217\u8868\u7684\u5185\u5bb9\u53d1\u751f\u53d8\u5316\u65f6\uff0c\u5b83\u7684\u54c8\u5e0c\u503c\u4e5f\u968f\u4e4b\u6539\u53d8\uff0c\u6211\u4eec\u5c31\u65e0\u6cd5\u5728\u54c8\u5e0c\u8868\u4e2d\u67e5\u8be2\u5230\u539f\u5148\u7684 value \u4e86\u3002

    \u867d\u7136\u81ea\u5b9a\u4e49\u5bf9\u8c61\uff08\u6bd4\u5982\u94fe\u8868\u8282\u70b9\uff09\u7684\u6210\u5458\u53d8\u91cf\u662f\u53ef\u53d8\u7684\uff0c\u4f46\u5b83\u662f\u53ef\u54c8\u5e0c\u7684\u3002\u8fd9\u662f\u56e0\u4e3a\u5bf9\u8c61\u7684\u54c8\u5e0c\u503c\u901a\u5e38\u662f\u57fa\u4e8e\u5185\u5b58\u5730\u5740\u751f\u6210\u7684\uff0c\u5373\u4f7f\u5bf9\u8c61\u7684\u5185\u5bb9\u53d1\u751f\u4e86\u53d8\u5316\uff0c\u4f46\u5b83\u7684\u5185\u5b58\u5730\u5740\u4e0d\u53d8\uff0c\u54c8\u5e0c\u503c\u4ecd\u7136\u662f\u4e0d\u53d8\u7684\u3002

    \u7ec6\u5fc3\u7684\u4f60\u53ef\u80fd\u53d1\u73b0\u5728\u4e0d\u540c\u63a7\u5236\u53f0\u4e2d\u8fd0\u884c\u7a0b\u5e8f\u65f6\uff0c\u8f93\u51fa\u7684\u54c8\u5e0c\u503c\u662f\u4e0d\u540c\u7684\u3002\u8fd9\u662f\u56e0\u4e3a Python \u89e3\u91ca\u5668\u5728\u6bcf\u6b21\u542f\u52a8\u65f6\uff0c\u90fd\u4f1a\u4e3a\u5b57\u7b26\u4e32\u54c8\u5e0c\u51fd\u6570\u52a0\u5165\u4e00\u4e2a\u968f\u673a\u7684\u76d0\uff08salt\uff09\u503c\u3002\u8fd9\u79cd\u505a\u6cd5\u53ef\u4ee5\u6709\u6548\u9632\u6b62 HashDoS \u653b\u51fb\uff0c\u63d0\u5347\u54c8\u5e0c\u7b97\u6cd5\u7684\u5b89\u5168\u6027\u3002

    "},{"location":"chapter_hashing/hash_collision/","title":"6.2 \u00a0 \u54c8\u5e0c\u51b2\u7a81","text":"

    \u4e0a\u4e00\u8282\u63d0\u5230\uff0c\u901a\u5e38\u60c5\u51b5\u4e0b\u54c8\u5e0c\u51fd\u6570\u7684\u8f93\u5165\u7a7a\u95f4\u8fdc\u5927\u4e8e\u8f93\u51fa\u7a7a\u95f4\uff0c\u56e0\u6b64\u7406\u8bba\u4e0a\u54c8\u5e0c\u51b2\u7a81\u662f\u4e0d\u53ef\u907f\u514d\u7684\u3002\u6bd4\u5982\uff0c\u8f93\u5165\u7a7a\u95f4\u4e3a\u5168\u4f53\u6574\u6570\uff0c\u8f93\u51fa\u7a7a\u95f4\u4e3a\u6570\u7ec4\u5bb9\u91cf\u5927\u5c0f\uff0c\u5219\u5fc5\u7136\u6709\u591a\u4e2a\u6574\u6570\u6620\u5c04\u81f3\u540c\u4e00\u6876\u7d22\u5f15\u3002

    \u54c8\u5e0c\u51b2\u7a81\u4f1a\u5bfc\u81f4\u67e5\u8be2\u7ed3\u679c\u9519\u8bef\uff0c\u4e25\u91cd\u5f71\u54cd\u54c8\u5e0c\u8868\u7684\u53ef\u7528\u6027\u3002\u4e3a\u4e86\u89e3\u51b3\u8be5\u95ee\u9898\uff0c\u6bcf\u5f53\u9047\u5230\u54c8\u5e0c\u51b2\u7a81\u65f6\uff0c\u6211\u4eec\u5c31\u8fdb\u884c\u54c8\u5e0c\u8868\u6269\u5bb9\uff0c\u76f4\u81f3\u51b2\u7a81\u6d88\u5931\u4e3a\u6b62\u3002\u6b64\u65b9\u6cd5\u7b80\u5355\u7c97\u66b4\u4e14\u6709\u6548\uff0c\u4f46\u6548\u7387\u592a\u4f4e\uff0c\u56e0\u4e3a\u54c8\u5e0c\u8868\u6269\u5bb9\u9700\u8981\u8fdb\u884c\u5927\u91cf\u7684\u6570\u636e\u642c\u8fd0\u4e0e\u54c8\u5e0c\u503c\u8ba1\u7b97\u3002\u4e3a\u4e86\u63d0\u5347\u6548\u7387\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u4ee5\u4e0b\u7b56\u7565\u3002

    1. \u6539\u826f\u54c8\u5e0c\u8868\u6570\u636e\u7ed3\u6784\uff0c\u4f7f\u5f97\u54c8\u5e0c\u8868\u53ef\u4ee5\u5728\u51fa\u73b0\u54c8\u5e0c\u51b2\u7a81\u65f6\u6b63\u5e38\u5de5\u4f5c\u3002
    2. \u4ec5\u5728\u5fc5\u8981\u65f6\uff0c\u5373\u5f53\u54c8\u5e0c\u51b2\u7a81\u6bd4\u8f83\u4e25\u91cd\u65f6\uff0c\u624d\u6267\u884c\u6269\u5bb9\u64cd\u4f5c\u3002

    \u54c8\u5e0c\u8868\u7684\u7ed3\u6784\u6539\u826f\u65b9\u6cd5\u4e3b\u8981\u5305\u62ec\u201c\u94fe\u5f0f\u5730\u5740\u201d\u548c\u201c\u5f00\u653e\u5bfb\u5740\u201d\u3002

    "},{"location":"chapter_hashing/hash_collision/#621","title":"6.2.1 \u00a0 \u94fe\u5f0f\u5730\u5740","text":"

    \u5728\u539f\u59cb\u54c8\u5e0c\u8868\u4e2d\uff0c\u6bcf\u4e2a\u6876\u4ec5\u80fd\u5b58\u50a8\u4e00\u4e2a\u952e\u503c\u5bf9\u3002\u94fe\u5f0f\u5730\u5740\uff08separate chaining\uff09\u5c06\u5355\u4e2a\u5143\u7d20\u8f6c\u6362\u4e3a\u94fe\u8868\uff0c\u5c06\u952e\u503c\u5bf9\u4f5c\u4e3a\u94fe\u8868\u8282\u70b9\uff0c\u5c06\u6240\u6709\u53d1\u751f\u51b2\u7a81\u7684\u952e\u503c\u5bf9\u90fd\u5b58\u50a8\u5728\u540c\u4e00\u94fe\u8868\u4e2d\u3002\u56fe 6-5 \u5c55\u793a\u4e86\u4e00\u4e2a\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\u7684\u4f8b\u5b50\u3002

    \u56fe 6-5 \u00a0 \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868

    \u57fa\u4e8e\u94fe\u5f0f\u5730\u5740\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\u7684\u64cd\u4f5c\u65b9\u6cd5\u53d1\u751f\u4e86\u4ee5\u4e0b\u53d8\u5316\u3002

    • \u67e5\u8be2\u5143\u7d20\uff1a\u8f93\u5165 key \uff0c\u7ecf\u8fc7\u54c8\u5e0c\u51fd\u6570\u5f97\u5230\u6876\u7d22\u5f15\uff0c\u5373\u53ef\u8bbf\u95ee\u94fe\u8868\u5934\u8282\u70b9\uff0c\u7136\u540e\u904d\u5386\u94fe\u8868\u5e76\u5bf9\u6bd4 key \u4ee5\u67e5\u627e\u76ee\u6807\u952e\u503c\u5bf9\u3002
    • \u6dfb\u52a0\u5143\u7d20\uff1a\u9996\u5148\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u8bbf\u95ee\u94fe\u8868\u5934\u8282\u70b9\uff0c\u7136\u540e\u5c06\u8282\u70b9\uff08\u952e\u503c\u5bf9\uff09\u6dfb\u52a0\u5230\u94fe\u8868\u4e2d\u3002
    • \u5220\u9664\u5143\u7d20\uff1a\u6839\u636e\u54c8\u5e0c\u51fd\u6570\u7684\u7ed3\u679c\u8bbf\u95ee\u94fe\u8868\u5934\u90e8\uff0c\u63a5\u7740\u904d\u5386\u94fe\u8868\u4ee5\u67e5\u627e\u76ee\u6807\u8282\u70b9\u5e76\u5c06\u5176\u5220\u9664\u3002

    \u94fe\u5f0f\u5730\u5740\u5b58\u5728\u4ee5\u4e0b\u5c40\u9650\u6027\u3002

    • \u5360\u7528\u7a7a\u95f4\u589e\u5927\uff1a\u94fe\u8868\u5305\u542b\u8282\u70b9\u6307\u9488\uff0c\u5b83\u76f8\u6bd4\u6570\u7ec4\u66f4\u52a0\u8017\u8d39\u5185\u5b58\u7a7a\u95f4\u3002
    • \u67e5\u8be2\u6548\u7387\u964d\u4f4e\uff1a\u56e0\u4e3a\u9700\u8981\u7ebf\u6027\u904d\u5386\u94fe\u8868\u6765\u67e5\u627e\u5bf9\u5e94\u5143\u7d20\u3002

    \u4ee5\u4e0b\u4ee3\u7801\u7ed9\u51fa\u4e86\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\u7684\u7b80\u5355\u5b9e\u73b0\uff0c\u9700\u8981\u6ce8\u610f\u4e24\u70b9\u3002

    • \u4f7f\u7528\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\u4ee3\u66ff\u94fe\u8868\uff0c\u4ece\u800c\u7b80\u5316\u4ee3\u7801\u3002\u5728\u8fd9\u79cd\u8bbe\u5b9a\u4e0b\uff0c\u54c8\u5e0c\u8868\uff08\u6570\u7ec4\uff09\u5305\u542b\u591a\u4e2a\u6876\uff0c\u6bcf\u4e2a\u6876\u90fd\u662f\u4e00\u4e2a\u5217\u8868\u3002
    • \u4ee5\u4e0b\u5b9e\u73b0\u5305\u542b\u54c8\u5e0c\u8868\u6269\u5bb9\u65b9\u6cd5\u3002\u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7 \\(\\frac{2}{3}\\) \u65f6\uff0c\u6211\u4eec\u5c06\u54c8\u5e0c\u8868\u6269\u5bb9\u81f3\u539f\u5148\u7684 \\(2\\) \u500d\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_chaining.py
    class HashMapChaining:\n    \"\"\"\u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets = [[] for _ in range(self.capacity)]  # \u6876\u6570\u7ec4\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def get(self, key: int) -> str | None:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket:\n            if pair.key == key:\n                return pair.val\n        # \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket:\n            if pair.key == key:\n                pair.val = val\n                return\n        # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        pair = Pair(key, val)\n        bucket.append(pair)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index = self.hash_func(key)\n        bucket = self.buckets[index]\n        # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for pair in bucket:\n            if pair.key == key:\n                bucket.remove(pair)\n                self.size -= 1\n                break\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [[] for _ in range(self.capacity)]\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets:\n            for pair in bucket:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for bucket in self.buckets:\n            res = []\n            for pair in bucket:\n                res.append(str(pair.key) + \" -> \" + pair.val)\n            print(res)\n
    hash_map_chaining.cpp
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  private:\n    int size;                       // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;                   // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres;               // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;                // \u6269\u5bb9\u500d\u6570\n    vector<vector<Pair *>> buckets; // \u6876\u6570\u7ec4\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapChaining() : size(0), capacity(4), loadThres(2.0 / 3.0), extendRatio(2) {\n        buckets.resize(capacity);\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapChaining() {\n        for (auto &bucket : buckets) {\n            for (Pair *pair : bucket) {\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / (double)capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                return pair->val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair *pair : buckets[index]) {\n            if (pair->key == key) {\n                pair->val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].push_back(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        auto &bucket = buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (int i = 0; i < bucket.size(); i++) {\n            if (bucket[i]->key == key) {\n                Pair *tmp = bucket[i];\n                bucket.erase(bucket.begin() + i); // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n                delete tmp;                       // \u91ca\u653e\u5185\u5b58\n                size--;\n                return;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<vector<Pair *>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets.clear();\n        buckets.resize(capacity);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (auto &bucket : bucketsTmp) {\n            for (Pair *pair : bucket) {\n                put(pair->key, pair->val);\n                // \u91ca\u653e\u5185\u5b58\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (auto &bucket : buckets) {\n            cout << \"[\";\n            for (Pair *pair : bucket) {\n                cout << pair->key << \" -> \" << pair->val << \", \";\n            }\n            cout << \"]\\n\";\n        }\n    }\n};\n
    hash_map_chaining.java
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    String get(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        Pair pair = new Pair(key, val);\n        bucket.add(pair);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        List<Pair> bucket = buckets.get(index);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (Pair pair : bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new ArrayList<>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.add(new ArrayList<>());\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (List<Pair> bucket : bucketsTmp) {\n            for (Pair pair : bucket) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (List<Pair> bucket : buckets) {\n            List<String> res = new ArrayList<>();\n            for (Pair pair : bucket) {\n                res.add(pair.key + \" -> \" + pair.val);\n            }\n            System.out.println(res);\n        }\n    }\n}\n
    hash_map_chaining.cs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio; // \u6269\u5bb9\u500d\u6570\n    List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapChaining() {\n        size = 0;\n        capacity = 4;\n        loadThres = 2.0 / 3.0;\n        extendRatio = 2;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        foreach (Pair pair in buckets[index]) {\n            if (pair.key == key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        buckets[index].Add(new Pair(key, val));\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        foreach (Pair pair in buckets[index].ToList()) {\n            if (pair.key == key) {\n                buckets[index].Remove(pair);\n                size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        List<List<Pair>> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new List<List<Pair>>(capacity);\n        for (int i = 0; i < capacity; i++) {\n            buckets.Add([]);\n        }\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (List<Pair> bucket in bucketsTmp) {\n            foreach (Pair pair in bucket) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (List<Pair> bucket in buckets) {\n            List<string> res = [];\n            foreach (Pair pair in bucket) {\n                res.Add(pair.key + \" -> \" + pair.val);\n            }\n            foreach (string kv in res) {\n                Console.WriteLine(kv);\n            }\n        }\n    }\n}\n
    hash_map_chaining.go
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntype hashMapChaining struct {\n    size        int      // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int      // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64  // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int      // \u6269\u5bb9\u500d\u6570\n    buckets     [][]pair // \u6876\u6570\u7ec4\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapChaining() *hashMapChaining {\n    buckets := make([][]pair, 4)\n    for i := 0; i < 4; i++ {\n        buckets[i] = make([]pair, 0)\n    }\n    return &hashMapChaining{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     buckets,\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (m *hashMapChaining) hashFunc(key int) int {\n    return key % m.capacity\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (m *hashMapChaining) loadFactor() float64 {\n    return float64(m.size) / float64(m.capacity)\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (m *hashMapChaining) get(key int) string {\n    idx := m.hashFunc(key)\n    bucket := m.buckets[idx]\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for _, p := range bucket {\n        if p.key == key {\n            return p.val\n        }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (m *hashMapChaining) put(key int, val string) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if m.loadFactor() > m.loadThres {\n        m.extend()\n    }\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for i := range m.buckets[idx] {\n        if m.buckets[idx][i].key == key {\n            m.buckets[idx][i].val = val\n            return\n        }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    p := pair{\n        key: key,\n        val: val,\n    }\n    m.buckets[idx] = append(m.buckets[idx], p)\n    m.size += 1\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (m *hashMapChaining) remove(key int) {\n    idx := m.hashFunc(key)\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for i, p := range m.buckets[idx] {\n        if p.key == key {\n            // \u5207\u7247\u5220\u9664\n            m.buckets[idx] = append(m.buckets[idx][:i], m.buckets[idx][i+1:]...)\n            m.size -= 1\n            break\n        }\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    tmpBuckets := make([][]pair, len(m.buckets))\n    for i := 0; i < len(m.buckets); i++ {\n        tmpBuckets[i] = make([]pair, len(m.buckets[i]))\n        copy(tmpBuckets[i], m.buckets[i])\n    }\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    m.capacity *= m.extendRatio\n    m.buckets = make([][]pair, m.capacity)\n    for i := 0; i < m.capacity; i++ {\n        m.buckets[i] = make([]pair, 0)\n    }\n    m.size = 0\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, bucket := range tmpBuckets {\n        for _, p := range bucket {\n            m.put(p.key, p.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (m *hashMapChaining) print() {\n    var builder strings.Builder\n\n    for _, bucket := range m.buckets {\n        builder.WriteString(\"[\")\n        for _, p := range bucket {\n            builder.WriteString(strconv.Itoa(p.key) + \" -> \" + p.val + \" \")\n        }\n        builder.WriteString(\"]\")\n        fmt.Println(builder.String())\n        builder.Reset()\n    }\n}\n
    hash_map_chaining.swift
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [[Pair]] // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: [], count: capacity)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return pair.val\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de nil\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair(key: key, val: val)\n        buckets[index].append(pair)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        let bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pairIndex, pair) in bucket.enumerated() {\n            if pair.key == key {\n                buckets[index].remove(at: pairIndex)\n                size -= 1\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: [], count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in bucketsTmp {\n            for pair in bucket {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for bucket in buckets {\n            let res = bucket.map { \"\\($0.key) -> \\($0.val)\" }\n            Swift.print(res)\n        }\n    }\n}\n
    hash_map_chaining.js
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.ts
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    #size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    #buckets: Pair[][]; // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0;\n        this.#capacity = 4;\n        this.#loadThres = 2.0 / 3.0;\n        this.#extendRatio = 2;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key: number): number {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor(): number {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                return pair.val;\n            }\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        const index = this.#hashFunc(key);\n        const bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (const pair of bucket) {\n            if (pair.key === key) {\n                pair.val = val;\n                return;\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        const pair = new Pair(key, val);\n        bucket.push(pair);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        const index = this.#hashFunc(key);\n        let bucket = this.#buckets[index];\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (let i = 0; i < bucket.length; i++) {\n            if (bucket[i].key === key) {\n                bucket.splice(i, 1);\n                this.#size--;\n                break;\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = new Array(this.#capacity).fill(null).map((x) => []);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const bucket of bucketsTmp) {\n            for (const pair of bucket) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const bucket of this.#buckets) {\n            let res = [];\n            for (const pair of bucket) {\n                res.push(pair.key + ' -> ' + pair.val);\n            }\n            console.log(res);\n        }\n    }\n}\n
    hash_map_chaining.dart
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n  late int size; // \u952e\u503c\u5bf9\u6570\u91cf\n  late int capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  late double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  late int extendRatio; // \u6269\u5bb9\u500d\u6570\n  late List<List<Pair>> buckets; // \u6876\u6570\u7ec4\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapChaining() {\n    size = 0;\n    capacity = 4;\n    loadThres = 2.0 / 3.0;\n    extendRatio = 2;\n    buckets = List.generate(capacity, (_) => []);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return size / capacity;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        return pair.val;\n      }\n    }\n    // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > loadThres) {\n      extend();\n    }\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        pair.val = val;\n        return;\n      }\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    Pair pair = Pair(key, val);\n    bucket.add(pair);\n    size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    int index = hashFunc(key);\n    List<Pair> bucket = buckets[index];\n    // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for (Pair pair in bucket) {\n      if (pair.key == key) {\n        bucket.remove(pair);\n        size--;\n        break;\n      }\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<List<Pair>> bucketsTmp = buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    capacity *= extendRatio;\n    buckets = List.generate(capacity, (_) => []);\n    size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (List<Pair> bucket in bucketsTmp) {\n      for (Pair pair in bucket) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (List<Pair> bucket in buckets) {\n      List<String> res = [];\n      for (Pair pair in bucket) {\n        res.add(\"${pair.key} -> ${pair.val}\");\n      }\n      print(res);\n    }\n  }\n}\n
    hash_map_chaining.rs
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapChaining {\n    size: i32,\n    capacity: i32,\n    load_thres: f32,\n    extend_ratio: i32,\n    buckets: Vec<Vec<Pair>>,\n}\n\nimpl HashMapChaining {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![vec![]; 4],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % self.capacity as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f32 {\n        self.size as f32 / self.capacity as f32\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) -> Option<String> {\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for i in 0..bucket.len() {\n            if bucket[i].key == key {\n                let pair = bucket.remove(i);\n                self.size -= 1;\n                return Some(pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = std::mem::replace(&mut self.buckets, vec![]);\n\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![Vec::new(); self.capacity as usize];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for bucket in buckets_tmp {\n            for pair in bucket {\n                self.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for bucket in &self.buckets {\n            let mut res = Vec::new();\n            for pair in bucket {\n                res.push(format!(\"{} -> {}\", pair.key, pair.val));\n            }\n            println!(\"{:?}\", res);\n        }\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n\n        let index = self.hash_func(key);\n        let bucket = &mut self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for pair in bucket {\n            if pair.key == key {\n                pair.val = val;\n                return;\n            }\n        }\n        let bucket = &mut self.buckets[index];\n\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        let pair = Pair { key, val };\n        bucket.push(pair);\n        self.size += 1;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&self, key: i32) -> Option<&str> {\n        let index = self.hash_func(key);\n        let bucket = &self.buckets[index];\n\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for pair in bucket {\n            if pair.key == key {\n                return Some(&pair.val);\n            }\n        }\n\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de None\n        None\n    }\n}\n
    hash_map_chaining.c
    /* \u94fe\u8868\u8282\u70b9 */\ntypedef struct Node {\n    Pair *pair;\n    struct Node *next;\n} Node;\n\n/* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Node **buckets;   // \u6876\u6570\u7ec4\n} HashMapChaining;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapChaining *newHashMapChaining() {\n    HashMapChaining *hashMap = (HashMapChaining *)malloc(sizeof(HashMapChaining));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapChaining(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        while (cur) {\n            Node *tmp = cur;\n            cur = cur->next;\n            free(tmp->pair);\n            free(tmp);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapChaining *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapChaining *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            return cur->pair->val;\n        }\n        cur = cur->next;\n    }\n    return \"\"; // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapChaining *hashMap, int key, const char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    int index = hashFunc(hashMap, key);\n    // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    Node *cur = hashMap->buckets[index];\n    while (cur) {\n        if (cur->pair->key == key) {\n            strcpy(cur->pair->val, val); // \u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n            return;\n        }\n        cur = cur->next;\n    }\n    // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n    Pair *newPair = (Pair *)malloc(sizeof(Pair));\n    newPair->key = key;\n    strcpy(newPair->val, val);\n    Node *newNode = (Node *)malloc(sizeof(Node));\n    newNode->pair = newPair;\n    newNode->next = hashMap->buckets[index];\n    hashMap->buckets[index] = newNode;\n    hashMap->size++;\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapChaining *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    int oldCapacity = hashMap->capacity;\n    Node **oldBuckets = hashMap->buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Node **)malloc(hashMap->capacity * sizeof(Node *));\n    for (int i = 0; i < hashMap->capacity; i++) {\n        hashMap->buckets[i] = NULL;\n    }\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Node *cur = oldBuckets[i];\n        while (cur) {\n            put(hashMap, cur->pair->key, cur->pair->val);\n            Node *temp = cur;\n            cur = cur->next;\n            // \u91ca\u653e\u5185\u5b58\n            free(temp->pair);\n            free(temp);\n        }\n    }\n\n    free(oldBuckets);\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapChaining *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    Node *cur = hashMap->buckets[index];\n    Node *pre = NULL;\n    while (cur) {\n        if (cur->pair->key == key) {\n            // \u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n            if (pre) {\n                pre->next = cur->next;\n            } else {\n                hashMap->buckets[index] = cur->next;\n            }\n            // \u91ca\u653e\u5185\u5b58\n            free(cur->pair);\n            free(cur);\n            hashMap->size--;\n            return;\n        }\n        pre = cur;\n        cur = cur->next;\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapChaining *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Node *cur = hashMap->buckets[i];\n        printf(\"[\");\n        while (cur) {\n            printf(\"%d -> %s, \", cur->pair->key, cur->pair->val);\n            cur = cur->next;\n        }\n        printf(\"]\\n\");\n    }\n}\n
    hash_map_chaining.kt
    /* \u94fe\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 */\nclass HashMapChaining {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    val loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    val extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: MutableList<MutableList<Pair>> // \u6876\u6570\u7ec4\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        for (pair in bucket) {\n            if (pair.key == key) return pair._val\n        }\n        // \u82e5\u672a\u627e\u5230 key \uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n        for (pair in bucket) {\n            if (pair.key == key) {\n                pair._val = _val\n                return\n            }\n        }\n        // \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n        val pair = Pair(key, _val)\n        bucket.add(pair)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        val bucket = buckets[index]\n        // \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n        for (pair in bucket) {\n            if (pair.key == key) {\n                bucket.remove(pair)\n                size--\n                break\n            }\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        // mutablelist \u65e0\u56fa\u5b9a\u5927\u5c0f\n        buckets = mutableListOf()\n        for (i in 0..<capacity) {\n            buckets.add(mutableListOf())\n        }\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (bucket in bucketsTmp) {\n            for (pair in bucket) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (bucket in buckets) {\n            val res = mutableListOf<String>()\n            for (pair in bucket) {\n                val k = pair.key\n                val v = pair._val\n                res.add(\"$k -> $v\")\n            }\n            println(res)\n        }\n    }\n}\n
    hash_map_chaining.rb
    ### \u952e\u5f0f\u5730\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapChaining\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) { [] } # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u627e\u5230 key \uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    for pair in bucket\n      return pair.val if pair.key == key\n    end\n    # \u82e5\u672a\u627e\u5230 key , \u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u82e5\u9047\u5230\u6307\u5b9a key \uff0c\u5219\u66f4\u65b0\u5bf9\u5e94 val \u5e76\u8fd4\u56de\n    for pair in bucket\n      if pair.key == key\n        pair.val = val\n        return\n      end\n    end\n    # \u82e5\u65e0\u8be5 key \uff0c\u5219\u5c06\u952e\u503c\u5bf9\u6dfb\u52a0\u81f3\u5c3e\u90e8\n    pair = Pair.new(key, val)\n    bucket << pair\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    bucket = @buckets[index]\n    # \u904d\u5386\u6876\uff0c\u4ece\u4e2d\u5220\u9664\u952e\u503c\u5bf9\n    for pair in bucket\n      if pair.key == key\n        bucket.delete(pair)\n        @size -= 1\n        break\n      end\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u66ab\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity) { [] }\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for bucket in buckets\n      for pair in bucket\n        put(pair.key, pair.val)\n      end\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for bucket in @buckets\n      res = []\n      for pair in bucket\n        res << \"#{pair.key} -> #{pair.val}\"\n      end\n      pp res\n    end\n  end\nend\n
    hash_map_chaining.zig
    [class]{HashMapChaining}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u5f53\u94fe\u8868\u5f88\u957f\u65f6\uff0c\u67e5\u8be2\u6548\u7387 \\(O(n)\\) \u5f88\u5dee\u3002\u6b64\u65f6\u53ef\u4ee5\u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u201cAVL \u6811\u201d\u6216\u201c\u7ea2\u9ed1\u6811\u201d\uff0c\u4ece\u800c\u5c06\u67e5\u8be2\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(\\log n)\\) \u3002

    "},{"location":"chapter_hashing/hash_collision/#622","title":"6.2.2 \u00a0 \u5f00\u653e\u5bfb\u5740","text":"

    \u5f00\u653e\u5bfb\u5740\uff08open addressing\uff09\u4e0d\u5f15\u5165\u989d\u5916\u7684\u6570\u636e\u7ed3\u6784\uff0c\u800c\u662f\u901a\u8fc7\u201c\u591a\u6b21\u63a2\u6d4b\u201d\u6765\u5904\u7406\u54c8\u5e0c\u51b2\u7a81\uff0c\u63a2\u6d4b\u65b9\u5f0f\u4e3b\u8981\u5305\u62ec\u7ebf\u6027\u63a2\u6d4b\u3001\u5e73\u65b9\u63a2\u6d4b\u548c\u591a\u6b21\u54c8\u5e0c\u7b49\u3002

    \u4e0b\u9762\u4ee5\u7ebf\u6027\u63a2\u6d4b\u4e3a\u4f8b\uff0c\u4ecb\u7ecd\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\u7684\u5de5\u4f5c\u673a\u5236\u3002

    "},{"location":"chapter_hashing/hash_collision/#1","title":"1. \u00a0 \u7ebf\u6027\u63a2\u6d4b","text":"

    \u7ebf\u6027\u63a2\u6d4b\u91c7\u7528\u56fa\u5b9a\u6b65\u957f\u7684\u7ebf\u6027\u641c\u7d22\u6765\u8fdb\u884c\u63a2\u6d4b\uff0c\u5176\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u666e\u901a\u54c8\u5e0c\u8868\u6709\u6240\u4e0d\u540c\u3002

    • \u63d2\u5165\u5143\u7d20\uff1a\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u82e5\u53d1\u73b0\u6876\u5185\u5df2\u6709\u5143\u7d20\uff0c\u5219\u4ece\u51b2\u7a81\u4f4d\u7f6e\u5411\u540e\u7ebf\u6027\u904d\u5386\uff08\u6b65\u957f\u901a\u5e38\u4e3a \\(1\\) \uff09\uff0c\u76f4\u81f3\u627e\u5230\u7a7a\u6876\uff0c\u5c06\u5143\u7d20\u63d2\u5165\u5176\u4e2d\u3002
    • \u67e5\u627e\u5143\u7d20\uff1a\u82e5\u53d1\u73b0\u54c8\u5e0c\u51b2\u7a81\uff0c\u5219\u4f7f\u7528\u76f8\u540c\u6b65\u957f\u5411\u540e\u8fdb\u884c\u7ebf\u6027\u904d\u5386\uff0c\u76f4\u5230\u627e\u5230\u5bf9\u5e94\u5143\u7d20\uff0c\u8fd4\u56de value \u5373\u53ef\uff1b\u5982\u679c\u9047\u5230\u7a7a\u6876\uff0c\u8bf4\u660e\u76ee\u6807\u5143\u7d20\u4e0d\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u8fd4\u56de None \u3002

    \u56fe 6-6 \u5c55\u793a\u4e86\u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\uff09\u54c8\u5e0c\u8868\u7684\u952e\u503c\u5bf9\u5206\u5e03\u3002\u6839\u636e\u6b64\u54c8\u5e0c\u51fd\u6570\uff0c\u6700\u540e\u4e24\u4f4d\u76f8\u540c\u7684 key \u90fd\u4f1a\u88ab\u6620\u5c04\u5230\u76f8\u540c\u7684\u6876\u3002\u800c\u901a\u8fc7\u7ebf\u6027\u63a2\u6d4b\uff0c\u5b83\u4eec\u88ab\u4f9d\u6b21\u5b58\u50a8\u5728\u8be5\u6876\u4ee5\u53ca\u4e4b\u4e0b\u7684\u6876\u4e2d\u3002

    \u56fe 6-6 \u00a0 \u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\uff09\u54c8\u5e0c\u8868\u7684\u952e\u503c\u5bf9\u5206\u5e03

    \u7136\u800c\uff0c\u7ebf\u6027\u63a2\u6d4b\u5bb9\u6613\u4ea7\u751f\u201c\u805a\u96c6\u73b0\u8c61\u201d\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u6570\u7ec4\u4e2d\u8fde\u7eed\u88ab\u5360\u7528\u7684\u4f4d\u7f6e\u8d8a\u957f\uff0c\u8fd9\u4e9b\u8fde\u7eed\u4f4d\u7f6e\u53d1\u751f\u54c8\u5e0c\u51b2\u7a81\u7684\u53ef\u80fd\u6027\u8d8a\u5927\uff0c\u4ece\u800c\u8fdb\u4e00\u6b65\u4fc3\u4f7f\u8be5\u4f4d\u7f6e\u7684\u805a\u5806\u751f\u957f\uff0c\u5f62\u6210\u6076\u6027\u5faa\u73af\uff0c\u6700\u7ec8\u5bfc\u81f4\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u6548\u7387\u52a3\u5316\u3002

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6211\u4eec\u4e0d\u80fd\u5728\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\u4e2d\u76f4\u63a5\u5220\u9664\u5143\u7d20\u3002\u8fd9\u662f\u56e0\u4e3a\u5220\u9664\u5143\u7d20\u4f1a\u5728\u6570\u7ec4\u5185\u4ea7\u751f\u4e00\u4e2a\u7a7a\u6876 None \uff0c\u800c\u5f53\u67e5\u8be2\u5143\u7d20\u65f6\uff0c\u7ebf\u6027\u63a2\u6d4b\u5230\u8be5\u7a7a\u6876\u5c31\u4f1a\u8fd4\u56de\uff0c\u56e0\u6b64\u5728\u8be5\u7a7a\u6876\u4e4b\u4e0b\u7684\u5143\u7d20\u90fd\u65e0\u6cd5\u518d\u88ab\u8bbf\u95ee\u5230\uff0c\u7a0b\u5e8f\u53ef\u80fd\u8bef\u5224\u8fd9\u4e9b\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u5982\u56fe 6-7 \u6240\u793a\u3002

    \u56fe 6-7 \u00a0 \u5728\u5f00\u653e\u5bfb\u5740\u4e2d\u5220\u9664\u5143\u7d20\u5bfc\u81f4\u7684\u67e5\u8be2\u95ee\u9898

    \u4e3a\u4e86\u89e3\u51b3\u8be5\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u61d2\u5220\u9664\uff08lazy deletion\uff09\u673a\u5236\uff1a\u5b83\u4e0d\u76f4\u63a5\u4ece\u54c8\u5e0c\u8868\u4e2d\u79fb\u9664\u5143\u7d20\uff0c\u800c\u662f\u5229\u7528\u4e00\u4e2a\u5e38\u91cf TOMBSTONE \u6765\u6807\u8bb0\u8fd9\u4e2a\u6876\u3002\u5728\u8be5\u673a\u5236\u4e0b\uff0cNone \u548c TOMBSTONE \u90fd\u4ee3\u8868\u7a7a\u6876\uff0c\u90fd\u53ef\u4ee5\u653e\u7f6e\u952e\u503c\u5bf9\u3002\u4f46\u4e0d\u540c\u7684\u662f\uff0c\u7ebf\u6027\u63a2\u6d4b\u5230 TOMBSTONE \u65f6\u5e94\u8be5\u7ee7\u7eed\u904d\u5386\uff0c\u56e0\u4e3a\u5176\u4e4b\u4e0b\u53ef\u80fd\u8fd8\u5b58\u5728\u952e\u503c\u5bf9\u3002

    \u7136\u800c\uff0c\u61d2\u5220\u9664\u53ef\u80fd\u4f1a\u52a0\u901f\u54c8\u5e0c\u8868\u7684\u6027\u80fd\u9000\u5316\u3002\u8fd9\u662f\u56e0\u4e3a\u6bcf\u6b21\u5220\u9664\u64cd\u4f5c\u90fd\u4f1a\u4ea7\u751f\u4e00\u4e2a\u5220\u9664\u6807\u8bb0\uff0c\u968f\u7740 TOMBSTONE \u7684\u589e\u52a0\uff0c\u641c\u7d22\u65f6\u95f4\u4e5f\u4f1a\u589e\u52a0\uff0c\u56e0\u4e3a\u7ebf\u6027\u63a2\u6d4b\u53ef\u80fd\u9700\u8981\u8df3\u8fc7\u591a\u4e2a TOMBSTONE \u624d\u80fd\u627e\u5230\u76ee\u6807\u5143\u7d20\u3002

    \u4e3a\u6b64\uff0c\u8003\u8651\u5728\u7ebf\u6027\u63a2\u6d4b\u4e2d\u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a TOMBSTONE \u7684\u7d22\u5f15\uff0c\u5e76\u5c06\u641c\u7d22\u5230\u7684\u76ee\u6807\u5143\u7d20\u4e0e\u8be5 TOMBSTONE \u4ea4\u6362\u4f4d\u7f6e\u3002\u8fd9\u6837\u505a\u7684\u597d\u5904\u662f\u5f53\u6bcf\u6b21\u67e5\u8be2\u6216\u6dfb\u52a0\u5143\u7d20\u65f6\uff0c\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u81f3\u8ddd\u79bb\u7406\u60f3\u4f4d\u7f6e\uff08\u63a2\u6d4b\u8d77\u59cb\u70b9\uff09\u66f4\u8fd1\u7684\u6876\uff0c\u4ece\u800c\u4f18\u5316\u67e5\u8be2\u6548\u7387\u3002

    \u4ee5\u4e0b\u4ee3\u7801\u5b9e\u73b0\u4e86\u4e00\u4e2a\u5305\u542b\u61d2\u5220\u9664\u7684\u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\uff09\u54c8\u5e0c\u8868\u3002\u4e3a\u4e86\u66f4\u52a0\u5145\u5206\u5730\u4f7f\u7528\u54c8\u5e0c\u8868\u7684\u7a7a\u95f4\uff0c\u6211\u4eec\u5c06\u54c8\u5e0c\u8868\u770b\u4f5c\u4e00\u4e2a\u201c\u73af\u5f62\u6570\u7ec4\u201d\uff0c\u5f53\u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u56de\u5230\u5934\u90e8\u7ee7\u7eed\u904d\u5386\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map_open_addressing.py
    class HashMapOpenAddressing:\n    \"\"\"\u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.size = 0  # \u952e\u503c\u5bf9\u6570\u91cf\n        self.capacity = 4  # \u54c8\u5e0c\u8868\u5bb9\u91cf\n        self.load_thres = 2.0 / 3.0  # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        self.extend_ratio = 2  # \u6269\u5bb9\u500d\u6570\n        self.buckets: list[Pair | None] = [None] * self.capacity  # \u6876\u6570\u7ec4\n        self.TOMBSTONE = Pair(-1, \"-1\")  # \u5220\u9664\u6807\u8bb0\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        return key % self.capacity\n\n    def load_factor(self) -> float:\n        \"\"\"\u8d1f\u8f7d\u56e0\u5b50\"\"\"\n        return self.size / self.capacity\n\n    def find_bucket(self, key: int) -> int:\n        \"\"\"\u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\"\"\"\n        index = self.hash_func(key)\n        first_tombstone = -1\n        # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index] is not None:\n            # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].key == key:\n                # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if first_tombstone != -1:\n                    self.buckets[first_tombstone] = self.buckets[index]\n                    self.buckets[index] = self.TOMBSTONE\n                    return first_tombstone  # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                return index  # \u8fd4\u56de\u6876\u7d22\u5f15\n            # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 and self.buckets[index] is self.TOMBSTONE:\n                first_tombstone = index\n            # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity\n        # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return index if first_tombstone == -1 else first_tombstone\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            return self.buckets[index].val\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de None\n        return None\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres:\n            self.extend()\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index].val = val\n            return\n        # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Pair(key, val)\n        self.size += 1\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        index = self.find_bucket(key)\n        # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index] not in [None, self.TOMBSTONE]:\n            self.buckets[index] = self.TOMBSTONE\n            self.size -= 1\n\n    def extend(self):\n        \"\"\"\u6269\u5bb9\u54c8\u5e0c\u8868\"\"\"\n        # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        buckets_tmp = self.buckets\n        # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio\n        self.buckets = [None] * self.capacity\n        self.size = 0\n        # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp:\n            if pair not in [None, self.TOMBSTONE]:\n                self.put(pair.key, pair.val)\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is None:\n                print(\"None\")\n            elif pair is self.TOMBSTONE:\n                print(\"TOMBSTONE\")\n            else:\n                print(pair.key, \"->\", pair.val)\n
    hash_map_open_addressing.cpp
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  private:\n    int size;                             // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4;                     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    const double loadThres = 2.0 / 3.0;     // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    const int extendRatio = 2;            // \u6269\u5bb9\u500d\u6570\n    vector<Pair *> buckets;               // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    HashMapOpenAddressing() : size(0), buckets(capacity, nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~HashMapOpenAddressing() {\n        for (Pair *pair : buckets) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                delete pair;\n            }\n        }\n        delete TOMBSTONE;\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double loadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != nullptr) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]->key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            return buckets[index]->val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n        return \"\";\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            buckets[index]->val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != nullptr && buckets[index] != TOMBSTONE) {\n            delete buckets[index];\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        vector<Pair *> bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = vector<Pair *>(capacity, nullptr);\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair *pair : bucketsTmp) {\n            if (pair != nullptr && pair != TOMBSTONE) {\n                put(pair->key, pair->val);\n                delete pair;\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *pair : buckets) {\n            if (pair == nullptr) {\n                cout << \"nullptr\" << endl;\n            } else if (pair == TOMBSTONE) {\n                cout << \"TOMBSTONE\" << endl;\n            } else {\n                cout << pair->key << \" -> \" << pair->val << endl;\n            }\n        }\n    }\n};\n
    hash_map_open_addressing.java
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    private int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private final double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private final int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    private Pair[] buckets; // \u6876\u6570\u7ec4\n    private final Pair TOMBSTONE = new Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private double loadFactor() {\n        return (double) size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private int findBucket(int key) {\n        int index = hashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private void extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (Pair pair : bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair pair : buckets) {\n            if (pair == null) {\n                System.out.println(\"null\");\n            } else if (pair == TOMBSTONE) {\n                System.out.println(\"TOMBSTONE\");\n            } else {\n                System.out.println(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.cs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    int size; // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n    Pair[] buckets; // \u6876\u6570\u7ec4\n    Pair TOMBSTONE = new(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public HashMapOpenAddressing() {\n        size = 0;\n        buckets = new Pair[capacity];\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        return key % capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    double LoadFactor() {\n        return (double)size / capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    int FindBucket(int key) {\n        int index = HashFunc(key);\n        int firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index].key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index];\n                    buckets[index] = TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (LoadFactor() > loadThres) {\n            Extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = new Pair(key, val);\n        size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        int index = FindBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE;\n            size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    void Extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        Pair[] bucketsTmp = buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio;\n        buckets = new Pair[capacity];\n        size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        foreach (Pair pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                Put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair pair in buckets) {\n            if (pair == null) {\n                Console.WriteLine(\"null\");\n            } else if (pair == TOMBSTONE) {\n                Console.WriteLine(\"TOMBSTONE\");\n            } else {\n                Console.WriteLine(pair.key + \" -> \" + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.go
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntype hashMapOpenAddressing struct {\n    size        int     // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity    int     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    loadThres   float64 // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extendRatio int     // \u6269\u5bb9\u500d\u6570\n    buckets     []*pair // \u6876\u6570\u7ec4\n    TOMBSTONE   *pair   // \u5220\u9664\u6807\u8bb0\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newHashMapOpenAddressing() *hashMapOpenAddressing {\n    return &hashMapOpenAddressing{\n        size:        0,\n        capacity:    4,\n        loadThres:   2.0 / 3.0,\n        extendRatio: 2,\n        buckets:     make([]*pair, 4),\n        TOMBSTONE:   &pair{-1, \"-1\"},\n    }\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (h *hashMapOpenAddressing) hashFunc(key int) int {\n    return key % h.capacity // \u6839\u636e\u952e\u8ba1\u7b97\u54c8\u5e0c\u503c\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\nfunc (h *hashMapOpenAddressing) loadFactor() float64 {\n    return float64(h.size) / float64(h.capacity) // \u8ba1\u7b97\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nfunc (h *hashMapOpenAddressing) findBucket(key int) int {\n    index := h.hashFunc(key) // \u83b7\u53d6\u521d\u59cb\u7d22\u5f15\n    firstTombstone := -1     // \u8bb0\u5f55\u9047\u5230\u7684\u7b2c\u4e00\u4e2aTOMBSTONE\u7684\u4f4d\u7f6e\n    for h.buckets[index] != nil {\n        if h.buckets[index].key == key {\n            if firstTombstone != -1 {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                h.buckets[firstTombstone] = h.buckets[index]\n                h.buckets[index] = h.TOMBSTONE\n                return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index // \u8fd4\u56de\u627e\u5230\u7684\u7d22\u5f15\n        }\n        if firstTombstone == -1 && h.buckets[index] == h.TOMBSTONE {\n            firstTombstone = index // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\u7684\u4f4d\u7f6e\n        }\n        index = (index + 1) % h.capacity // \u7ebf\u6027\u63a2\u6d4b\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    if firstTombstone != -1 {\n        return firstTombstone\n    }\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) get(key int) string {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        return h.buckets[index].val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    }\n    return \"\" // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de \"\"\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) put(key int, val string) {\n    if h.loadFactor() > h.loadThres {\n        h.extend() // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    }\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] == nil || h.buckets[index] == h.TOMBSTONE {\n        h.buckets[index] = &pair{key, val} // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        h.size++\n    } else {\n        h.buckets[index].val = val // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val\n    }\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (h *hashMapOpenAddressing) remove(key int) {\n    index := h.findBucket(key) // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    if h.buckets[index] != nil && h.buckets[index] != h.TOMBSTONE {\n        h.buckets[index] = h.TOMBSTONE // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        h.size--\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) extend() {\n    oldBuckets := h.buckets               // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    h.capacity *= h.extendRatio           // \u66f4\u65b0\u5bb9\u91cf\n    h.buckets = make([]*pair, h.capacity) // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    h.size = 0                            // \u91cd\u7f6e\u5927\u5c0f\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for _, pair := range oldBuckets {\n        if pair != nil && pair != h.TOMBSTONE {\n            h.put(pair.key, pair.val)\n        }\n    }\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (h *hashMapOpenAddressing) print() {\n    for _, pair := range h.buckets {\n        if pair == nil {\n            fmt.Println(\"nil\")\n        } else if pair == h.TOMBSTONE {\n            fmt.Println(\"TOMBSTONE\")\n        } else {\n            fmt.Printf(\"%d -> %s\\n\", pair.key, pair.val)\n        }\n    }\n}\n
    hash_map_open_addressing.swift
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    var size: Int // \u952e\u503c\u5bf9\u6570\u91cf\n    var capacity: Int // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    var loadThres: Double // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    var extendRatio: Int // \u6269\u5bb9\u500d\u6570\n    var buckets: [Pair?] // \u6876\u6570\u7ec4\n    var TOMBSTONE: Pair // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init() {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = Array(repeating: nil, count: capacity)\n        TOMBSTONE = Pair(key: -1, val: \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    func hashFunc(key: Int) -> Int {\n        key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    func loadFactor() -> Double {\n        Double(size) / Double(capacity)\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    func findBucket(key: Int) -> Int {\n        var index = hashFunc(key: key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while buckets[index] != nil {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if buckets[index]!.key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if firstTombstone != -1 {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if firstTombstone == -1 && buckets[index] == TOMBSTONE {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone == -1 ? index : firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            return buckets[index]!.val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return nil\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if loadFactor() > loadThres {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index]!.val = val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key: key, val: val)\n        size += 1\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = findBucket(key: key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if buckets[index] != nil, buckets[index] != TOMBSTONE {\n            buckets[index] = TOMBSTONE\n            size -= 1\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    func extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = Array(repeating: nil, count: capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in bucketsTmp {\n            if let pair, pair != TOMBSTONE {\n                put(key: pair.key, val: pair.val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in buckets {\n            if pair == nil {\n                Swift.print(\"null\")\n            } else if pair == TOMBSTONE {\n                Swift.print(\"TOMBSTONE\")\n            } else {\n                Swift.print(\"\\(pair!.key) -> \\(pair!.val)\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.js
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    #size; // \u952e\u503c\u5bf9\u6570\u91cf\n    #capacity; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    #loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    #extendRatio; // \u6269\u5bb9\u500d\u6570\n    #buckets; // \u6876\u6570\u7ec4\n    #TOMBSTONE; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.#size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.#capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.#loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.#extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.#buckets = Array(this.#capacity).fill(null); // \u6876\u6570\u7ec4\n        this.#TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % this.#capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    #loadFactor() {\n        return this.#size / this.#capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    #findBucket(key) {\n        let index = this.#hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.#buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.#buckets[index].key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.#buckets[firstTombstone] = this.#buckets[index];\n                    this.#buckets[index] = this.#TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.#buckets[index] === this.#TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.#capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            return this.#buckets[index].val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key, val) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.#loadFactor() > this.#loadThres) {\n            this.#extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index].val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.#buckets[index] = new Pair(key, val);\n        this.#size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.#findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.#buckets[index] !== null &&\n            this.#buckets[index] !== this.#TOMBSTONE\n        ) {\n            this.#buckets[index] = this.#TOMBSTONE;\n            this.#size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    #extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.#buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.#capacity *= this.#extendRatio;\n        this.#buckets = Array(this.#capacity).fill(null);\n        this.#size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.#TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        for (const pair of this.#buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.#TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.ts
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private size: number; // \u952e\u503c\u5bf9\u6570\u91cf\n    private capacity: number; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private loadThres: number; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private extendRatio: number; // \u6269\u5bb9\u500d\u6570\n    private buckets: Array<Pair | null>; // \u6876\u6570\u7ec4\n    private TOMBSTONE: Pair; // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor() {\n        this.size = 0; // \u952e\u503c\u5bf9\u6570\u91cf\n        this.capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n        this.loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n        this.extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n        this.buckets = Array(this.capacity).fill(null); // \u6876\u6570\u7ec4\n        this.TOMBSTONE = new Pair(-1, '-1'); // \u5220\u9664\u6807\u8bb0\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % this.capacity;\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    private loadFactor(): number {\n        return this.size / this.capacity;\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    private findBucket(key: number): number {\n        let index = this.hashFunc(key);\n        let firstTombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (this.buckets[index] !== null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (this.buckets[index]!.key === key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone !== -1) {\n                    this.buckets[firstTombstone] = this.buckets[index];\n                    this.buckets[index] = this.TOMBSTONE;\n                    return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (\n                firstTombstone === -1 &&\n                this.buckets[index] === this.TOMBSTONE\n            ) {\n                firstTombstone = index;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % this.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return firstTombstone === -1 ? index : firstTombstone;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key: number): string | null {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            return this.buckets[index]!.val;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    put(key: number, val: string): void {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (this.loadFactor() > this.loadThres) {\n            this.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index]!.val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        this.buckets[index] = new Pair(key, val);\n        this.size++;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    remove(key: number): void {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        const index = this.findBucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (\n            this.buckets[index] !== null &&\n            this.buckets[index] !== this.TOMBSTONE\n        ) {\n            this.buckets[index] = this.TOMBSTONE;\n            this.size--;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    private extend(): void {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        const bucketsTmp = this.buckets;\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        this.capacity *= this.extendRatio;\n        this.buckets = Array(this.capacity).fill(null);\n        this.size = 0;\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (const pair of bucketsTmp) {\n            if (pair !== null && pair !== this.TOMBSTONE) {\n                this.put(pair.key, pair.val);\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print(): void {\n        for (const pair of this.buckets) {\n            if (pair === null) {\n                console.log('null');\n            } else if (pair === this.TOMBSTONE) {\n                console.log('TOMBSTONE');\n            } else {\n                console.log(pair.key + ' -> ' + pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.dart
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n  late int _size; // \u952e\u503c\u5bf9\u6570\u91cf\n  int _capacity = 4; // \u54c8\u5e0c\u8868\u5bb9\u91cf\n  double _loadThres = 2.0 / 3.0; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n  int _extendRatio = 2; // \u6269\u5bb9\u500d\u6570\n  late List<Pair?> _buckets; // \u6876\u6570\u7ec4\n  Pair _TOMBSTONE = Pair(-1, \"-1\"); // \u5220\u9664\u6807\u8bb0\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  HashMapOpenAddressing() {\n    _size = 0;\n    _buckets = List.generate(_capacity, (index) => null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int hashFunc(int key) {\n    return key % _capacity;\n  }\n\n  /* \u8d1f\u8f7d\u56e0\u5b50 */\n  double loadFactor() {\n    return _size / _capacity;\n  }\n\n  /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n  int findBucket(int key) {\n    int index = hashFunc(key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (_buckets[index] != null) {\n      // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if (_buckets[index]!.key == key) {\n        // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if (firstTombstone != -1) {\n          _buckets[firstTombstone] = _buckets[index];\n          _buckets[index] = _TOMBSTONE;\n          return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        }\n        return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n      }\n      // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      if (firstTombstone == -1 && _buckets[index] == _TOMBSTONE) {\n        firstTombstone = index;\n      }\n      // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % _capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      return _buckets[index]!.val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n    return null;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor() > _loadThres) {\n      extend();\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index]!.val = val;\n      return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    _buckets[index] = new Pair(key, val);\n    _size++;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (_buckets[index] != null && _buckets[index] != _TOMBSTONE) {\n      _buckets[index] = _TOMBSTONE;\n      _size--;\n    }\n  }\n\n  /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n  void extend() {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    List<Pair?> bucketsTmp = _buckets;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    _capacity *= _extendRatio;\n    _buckets = List.generate(_capacity, (index) => null);\n    _size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (Pair? pair in bucketsTmp) {\n      if (pair != null && pair != _TOMBSTONE) {\n        put(pair.key, pair.val);\n      }\n    }\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (Pair? pair in _buckets) {\n      if (pair == null) {\n        print(\"null\");\n      } else if (pair == _TOMBSTONE) {\n        print(\"TOMBSTONE\");\n      } else {\n        print(\"${pair.key} -> ${pair.val}\");\n      }\n    }\n  }\n}\n
    hash_map_open_addressing.rs
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nstruct HashMapOpenAddressing {\n    size: usize,                // \u952e\u503c\u5bf9\u6570\u91cf\n    capacity: usize,            // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    load_thres: f64,            // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    extend_ratio: usize,        // \u6269\u5bb9\u500d\u6570\n    buckets: Vec<Option<Pair>>, // \u6876\u6570\u7ec4\n    TOMBSTONE: Option<Pair>,    // \u5220\u9664\u6807\u8bb0\n}\n\nimpl HashMapOpenAddressing {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new() -> Self {\n        Self {\n            size: 0,\n            capacity: 4,\n            load_thres: 2.0 / 3.0,\n            extend_ratio: 2,\n            buckets: vec![None; 4],\n            TOMBSTONE: Some(Pair {\n                key: -1,\n                val: \"-1\".to_string(),\n            }),\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        (key % self.capacity as i32) as usize\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fn load_factor(&self) -> f64 {\n        self.size as f64 / self.capacity as f64\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fn find_bucket(&mut self, key: i32) -> usize {\n        let mut index = self.hash_func(key);\n        let mut first_tombstone = -1;\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while self.buckets[index].is_some() {\n            // \u82e5\u9047\u5230 key\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if self.buckets[index].as_ref().unwrap().key == key {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u5efa\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\n                if first_tombstone != -1 {\n                    self.buckets[first_tombstone as usize] = self.buckets[index].take();\n                    self.buckets[index] = self.TOMBSTONE.clone();\n                    return first_tombstone as usize; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if first_tombstone == -1 && self.buckets[index] == self.TOMBSTONE {\n                first_tombstone = index as i32;\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % self.capacity;\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        if first_tombstone == -1 {\n            index\n        } else {\n            first_tombstone as usize\n        }\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fn get(&mut self, key: i32) -> Option<&str> {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            return self.buckets[index].as_ref().map(|pair| &pair.val as &str);\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        None\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fn put(&mut self, key: i32, val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if self.load_factor() > self.load_thres {\n            self.extend();\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index].as_mut().unwrap().val = val;\n            return;\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        self.buckets[index] = Some(Pair { key, val });\n        self.size += 1;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fn remove(&mut self, key: i32) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        let index = self.find_bucket(key);\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if self.buckets[index].is_some() && self.buckets[index] != self.TOMBSTONE {\n            self.buckets[index] = self.TOMBSTONE.clone();\n            self.size -= 1;\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fn extend(&mut self) {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        let buckets_tmp = self.buckets.clone();\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        self.capacity *= self.extend_ratio;\n        self.buckets = vec![None; self.capacity];\n        self.size = 0;\n\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for pair in buckets_tmp {\n            if pair.is_none() || pair == self.TOMBSTONE {\n                continue;\n            }\n            let pair = pair.unwrap();\n\n            self.put(pair.key, pair.val);\n        }\n    }\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fn print(&self) {\n        for pair in &self.buckets {\n            if pair.is_none() {\n                println!(\"null\");\n            } else if pair == &self.TOMBSTONE {\n                println!(\"TOMBSTONE\");\n            } else {\n                let pair = pair.as_ref().unwrap();\n                println!(\"{} -> {}\", pair.key, pair.val);\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.c
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\ntypedef struct {\n    int size;         // \u952e\u503c\u5bf9\u6570\u91cf\n    int capacity;     // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    double loadThres; // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    int extendRatio;  // \u6269\u5bb9\u500d\u6570\n    Pair **buckets;   // \u6876\u6570\u7ec4\n    Pair *TOMBSTONE;  // \u5220\u9664\u6807\u8bb0\n} HashMapOpenAddressing;\n\n/* \u6784\u9020\u51fd\u6570 */\nHashMapOpenAddressing *newHashMapOpenAddressing() {\n    HashMapOpenAddressing *hashMap = (HashMapOpenAddressing *)malloc(sizeof(HashMapOpenAddressing));\n    hashMap->size = 0;\n    hashMap->capacity = 4;\n    hashMap->loadThres = 2.0 / 3.0;\n    hashMap->extendRatio = 2;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->TOMBSTONE = (Pair *)malloc(sizeof(Pair));\n    hashMap->TOMBSTONE->key = -1;\n    hashMap->TOMBSTONE->val = \"-1\";\n\n    return hashMap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delHashMapOpenAddressing(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(hashMap->buckets);\n    free(hashMap->TOMBSTONE);\n    free(hashMap);\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nint hashFunc(HashMapOpenAddressing *hashMap, int key) {\n    return key % hashMap->capacity;\n}\n\n/* \u8d1f\u8f7d\u56e0\u5b50 */\ndouble loadFactor(HashMapOpenAddressing *hashMap) {\n    return (double)hashMap->size / (double)hashMap->capacity;\n}\n\n/* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\nint findBucket(HashMapOpenAddressing *hashMap, int key) {\n    int index = hashFunc(hashMap, key);\n    int firstTombstone = -1;\n    // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while (hashMap->buckets[index] != NULL) {\n        // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        if (hashMap->buckets[index]->key == key) {\n            // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n            if (firstTombstone != -1) {\n                hashMap->buckets[firstTombstone] = hashMap->buckets[index];\n                hashMap->buckets[index] = hashMap->TOMBSTONE;\n                return firstTombstone; // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n            }\n            return index; // \u8fd4\u56de\u6876\u7d22\u5f15\n        }\n        // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n        if (firstTombstone == -1 && hashMap->buckets[index] == hashMap->TOMBSTONE) {\n            firstTombstone = index;\n        }\n        // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n        index = (index + 1) % hashMap->capacity;\n    }\n    // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    return firstTombstone == -1 ? index : firstTombstone;\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nchar *get(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        return hashMap->buckets[index]->val;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u7a7a\u5b57\u7b26\u4e32\n    return \"\";\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(HashMapOpenAddressing *hashMap, int key, char *val) {\n    // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    if (loadFactor(hashMap) > hashMap->loadThres) {\n        extend(hashMap);\n    }\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        free(hashMap->buckets[index]->val);\n        hashMap->buckets[index]->val = (char *)malloc(sizeof(strlen(val) + 1));\n        strcpy(hashMap->buckets[index]->val, val);\n        hashMap->buckets[index]->val[strlen(val)] = '\\0';\n        return;\n    }\n    // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    Pair *pair = (Pair *)malloc(sizeof(Pair));\n    pair->key = key;\n    pair->val = (char *)malloc(sizeof(strlen(val) + 1));\n    strcpy(pair->val, val);\n    pair->val[strlen(val)] = '\\0';\n\n    hashMap->buckets[index] = pair;\n    hashMap->size++;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(HashMapOpenAddressing *hashMap, int key) {\n    // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    int index = findBucket(hashMap, key);\n    // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    if (hashMap->buckets[index] != NULL && hashMap->buckets[index] != hashMap->TOMBSTONE) {\n        Pair *pair = hashMap->buckets[index];\n        free(pair->val);\n        free(pair);\n        hashMap->buckets[index] = hashMap->TOMBSTONE;\n        hashMap->size--;\n    }\n}\n\n/* \u6269\u5bb9\u54c8\u5e0c\u8868 */\nvoid extend(HashMapOpenAddressing *hashMap) {\n    // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    Pair **bucketsTmp = hashMap->buckets;\n    int oldCapacity = hashMap->capacity;\n    // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    hashMap->capacity *= hashMap->extendRatio;\n    hashMap->buckets = (Pair **)malloc(sizeof(Pair *) * hashMap->capacity);\n    hashMap->size = 0;\n    // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for (int i = 0; i < oldCapacity; i++) {\n        Pair *pair = bucketsTmp[i];\n        if (pair != NULL && pair != hashMap->TOMBSTONE) {\n            put(hashMap, pair->key, pair->val);\n            free(pair->val);\n            free(pair);\n        }\n    }\n    free(bucketsTmp);\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(HashMapOpenAddressing *hashMap) {\n    for (int i = 0; i < hashMap->capacity; i++) {\n        Pair *pair = hashMap->buckets[i];\n        if (pair == NULL) {\n            printf(\"NULL\\n\");\n        } else if (pair == hashMap->TOMBSTONE) {\n            printf(\"TOMBSTONE\\n\");\n        } else {\n            printf(\"%d -> %s\\n\", pair->key, pair->val);\n        }\n    }\n}\n
    hash_map_open_addressing.kt
    /* \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 */\nclass HashMapOpenAddressing {\n    private var size: Int               // \u952e\u503c\u5bf9\u6570\u91cf\n    private var capacity: Int           // \u54c8\u5e0c\u8868\u5bb9\u91cf\n    private val loadThres: Double       // \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    private val extendRatio: Int        // \u6269\u5bb9\u500d\u6570\n    private var buckets: Array<Pair?>   // \u6876\u6570\u7ec4\n    private val TOMBSTONE: Pair         // \u5220\u9664\u6807\u8bb0\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init {\n        size = 0\n        capacity = 4\n        loadThres = 2.0 / 3.0\n        extendRatio = 2\n        buckets = arrayOfNulls(capacity)\n        TOMBSTONE = Pair(-1, \"-1\")\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        return key % capacity\n    }\n\n    /* \u8d1f\u8f7d\u56e0\u5b50 */\n    fun loadFactor(): Double {\n        return (size / capacity).toDouble()\n    }\n\n    /* \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 */\n    fun findBucket(key: Int): Int {\n        var index = hashFunc(key)\n        var firstTombstone = -1\n        // \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n        while (buckets[index] != null) {\n            // \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n            if (buckets[index]?.key == key) {\n                // \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n                if (firstTombstone != -1) {\n                    buckets[firstTombstone] = buckets[index]\n                    buckets[index] = TOMBSTONE\n                    return firstTombstone // \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n                }\n                return index // \u8fd4\u56de\u6876\u7d22\u5f15\n            }\n            // \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n            if (firstTombstone == -1 && buckets[index] == TOMBSTONE) {\n                firstTombstone = index\n            }\n            // \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n            index = (index + 1) % capacity\n        }\n        // \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n        return if (firstTombstone == -1) index else firstTombstone\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            return buckets[index]?._val\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de null\n        return null\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        // \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n        if (loadFactor() > loadThres) {\n            extend()\n        }\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5e76\u8fd4\u56de\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index]!!._val = _val\n            return\n        }\n        // \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n        buckets[index] = Pair(key, _val)\n        size++\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        // \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n        val index = findBucket(key)\n        // \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n        if (buckets[index] != null && buckets[index] != TOMBSTONE) {\n            buckets[index] = TOMBSTONE\n            size--\n        }\n    }\n\n    /* \u6269\u5bb9\u54c8\u5e0c\u8868 */\n    fun extend() {\n        // \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n        val bucketsTmp = buckets\n        // \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n        capacity *= extendRatio\n        buckets = arrayOfNulls(capacity)\n        size = 0\n        // \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n        for (pair in bucketsTmp) {\n            if (pair != null && pair != TOMBSTONE) {\n                put(pair.key, pair._val)\n            }\n        }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (pair in buckets) {\n            if (pair == null) {\n                println(\"null\")\n            } else if (pair == TOMBSTONE) {\n                println(\"TOMESTOME\")\n            } else {\n                println(\"${pair.key} -> ${pair._val}\")\n            }\n        }\n    }\n}\n
    hash_map_open_addressing.rb
    ### \u5f00\u653e\u5bfb\u5740\u54c8\u5e0c\u8868 ###\nclass HashMapOpenAddressing\n  TOMBSTONE = Pair.new(-1, '-1') # \u5220\u9664\u6807\u8bb0\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0 # \u952e\u503c\u5bf9\u6570\u91cf\n    @capacity = 4 # \u54c8\u5e0c\u8868\u5bb9\u91cf\n    @load_thres = 2.0 / 3.0 # \u89e6\u53d1\u6269\u5bb9\u7684\u8d1f\u8f7d\u56e0\u5b50\u9608\u503c\n    @extend_ratio = 2 # \u6269\u5bb9\u500d\u6570\n    @buckets = Array.new(@capacity) # \u6876\u6570\u7ec4\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    key % @capacity\n  end\n\n  ### \u8d1f\u8f7d\u56e0\u5b50 ###\n  def load_factor\n    @size / @capacity\n  end\n\n  ### \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15 ###\n  def find_bucket(key)\n    index = hash_func(key)\n    first_tombstone = -1\n    # \u7ebf\u6027\u63a2\u6d4b\uff0c\u5f53\u9047\u5230\u7a7a\u6876\u65f6\u8df3\u51fa\n    while !@buckets[index].nil?\n      # \u82e5\u9047\u5230 key \uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n      if @buckets[index].key == key\n        # \u82e5\u4e4b\u524d\u9047\u5230\u4e86\u5220\u9664\u6807\u8bb0\uff0c\u5219\u5c06\u952e\u503c\u5bf9\u79fb\u52a8\u81f3\u8be5\u7d22\u5f15\u5904\n        if first_tombstone != -1\n          @buckets[first_tombstone] = @buckets[index]\n          @buckets[index] = TOMBSTONE\n          return first_tombstone # \u8fd4\u56de\u79fb\u52a8\u540e\u7684\u6876\u7d22\u5f15\n        end\n        return index # \u8fd4\u56de\u6876\u7d22\u5f15\n      end\n      # \u8bb0\u5f55\u9047\u5230\u7684\u9996\u4e2a\u5220\u9664\u6807\u8bb0\n      first_tombstone = index if first_tombstone == -1 && @buckets[index] == TOMBSTONE\n      # \u8ba1\u7b97\u6876\u7d22\u5f15\uff0c\u8d8a\u8fc7\u5c3e\u90e8\u5219\u8fd4\u56de\u5934\u90e8\n      index = (index + 1) % @capacity\n    end\n    # \u82e5 key \u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de\u6dfb\u52a0\u70b9\u7684\u7d22\u5f15\n    first_tombstone == -1 ? index : first_tombstone\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8fd4\u56de\u5bf9\u5e94 val\n    return @buckets[index].val unless [nil, TOMBSTONE].include?(@buckets[index])\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u8fd4\u56de nil\n    nil\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    # \u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u9608\u503c\u65f6\uff0c\u6267\u884c\u6269\u5bb9\n    extend if load_factor > @load_thres\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u8986\u76d6 val \u5f00\u8fd4\u56de\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index].val = val\n      return\n    end\n    # \u82e5\u952e\u503c\u5bf9\u4e0d\u5b58\u5728\uff0c\u5219\u6dfb\u52a0\u8be5\u952e\u503c\u5bf9\n    @buckets[index] = Pair.new(key, val)\n    @size += 1\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    # \u641c\u7d22 key \u5bf9\u5e94\u7684\u6876\u7d22\u5f15\n    index = find_bucket(key)\n    # \u82e5\u627e\u5230\u952e\u503c\u5bf9\uff0c\u5219\u7528\u5220\u9664\u6807\u8bb0\u8986\u76d6\u5b83\n    unless [nil, TOMBSTONE].include?(@buckets[index])\n      @buckets[index] = TOMBSTONE\n      @size -= 1\n    end\n  end\n\n  ### \u6269\u5bb9\u54c8\u5e0c\u8868 ###\n  def extend\n    # \u6682\u5b58\u539f\u54c8\u5e0c\u8868\n    buckets_tmp = @buckets\n    # \u521d\u59cb\u5316\u6269\u5bb9\u540e\u7684\u65b0\u54c8\u5e0c\u8868\n    @capacity *= @extend_ratio\n    @buckets = Array.new(@capacity)\n    @size = 0\n    # \u5c06\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u642c\u8fd0\u81f3\u65b0\u54c8\u5e0c\u8868\n    for pair in buckets_tmp\n      put(pair.key, pair.val) unless [nil, TOMBSTONE].include?(pair)\n    end\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    for pair in @buckets\n      if pair.nil?\n        puts \"Nil\"\n      elsif pair == TOMBSTONE\n        puts \"TOMBSTONE\"\n      else\n        puts \"#{pair.key} -> #{pair.val}\"\n      end\n    end\n  end\nend\n
    hash_map_open_addressing.zig
    [class]{HashMapOpenAddressing}-[func]{}\n
    "},{"location":"chapter_hashing/hash_collision/#2","title":"2. \u00a0 \u5e73\u65b9\u63a2\u6d4b","text":"

    \u5e73\u65b9\u63a2\u6d4b\u4e0e\u7ebf\u6027\u63a2\u6d4b\u7c7b\u4f3c\uff0c\u90fd\u662f\u5f00\u653e\u5bfb\u5740\u7684\u5e38\u89c1\u7b56\u7565\u4e4b\u4e00\u3002\u5f53\u53d1\u751f\u51b2\u7a81\u65f6\uff0c\u5e73\u65b9\u63a2\u6d4b\u4e0d\u662f\u7b80\u5355\u5730\u8df3\u8fc7\u4e00\u4e2a\u56fa\u5b9a\u7684\u6b65\u6570\uff0c\u800c\u662f\u8df3\u8fc7\u201c\u63a2\u6d4b\u6b21\u6570\u7684\u5e73\u65b9\u201d\u7684\u6b65\u6570\uff0c\u5373 \\(1, 4, 9, \\dots\\) \u6b65\u3002

    \u5e73\u65b9\u63a2\u6d4b\u4e3b\u8981\u5177\u6709\u4ee5\u4e0b\u4f18\u52bf\u3002

    • \u5e73\u65b9\u63a2\u6d4b\u901a\u8fc7\u8df3\u8fc7\u63a2\u6d4b\u6b21\u6570\u5e73\u65b9\u7684\u8ddd\u79bb\uff0c\u8bd5\u56fe\u7f13\u89e3\u7ebf\u6027\u63a2\u6d4b\u7684\u805a\u96c6\u6548\u5e94\u3002
    • \u5e73\u65b9\u63a2\u6d4b\u4f1a\u8df3\u8fc7\u66f4\u5927\u7684\u8ddd\u79bb\u6765\u5bfb\u627e\u7a7a\u4f4d\u7f6e\uff0c\u6709\u52a9\u4e8e\u6570\u636e\u5206\u5e03\u5f97\u66f4\u52a0\u5747\u5300\u3002

    \u7136\u800c\uff0c\u5e73\u65b9\u63a2\u6d4b\u5e76\u4e0d\u662f\u5b8c\u7f8e\u7684\u3002

    • \u4ecd\u7136\u5b58\u5728\u805a\u96c6\u73b0\u8c61\uff0c\u5373\u67d0\u4e9b\u4f4d\u7f6e\u6bd4\u5176\u4ed6\u4f4d\u7f6e\u66f4\u5bb9\u6613\u88ab\u5360\u7528\u3002
    • \u7531\u4e8e\u5e73\u65b9\u7684\u589e\u957f\uff0c\u5e73\u65b9\u63a2\u6d4b\u53ef\u80fd\u4e0d\u4f1a\u63a2\u6d4b\u6574\u4e2a\u54c8\u5e0c\u8868\uff0c\u8fd9\u610f\u5473\u7740\u5373\u4f7f\u54c8\u5e0c\u8868\u4e2d\u6709\u7a7a\u6876\uff0c\u5e73\u65b9\u63a2\u6d4b\u4e5f\u53ef\u80fd\u65e0\u6cd5\u8bbf\u95ee\u5230\u5b83\u3002
    "},{"location":"chapter_hashing/hash_collision/#3","title":"3. \u00a0 \u591a\u6b21\u54c8\u5e0c","text":"

    \u987e\u540d\u601d\u4e49\uff0c\u591a\u6b21\u54c8\u5e0c\u65b9\u6cd5\u4f7f\u7528\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570 \\(f_1(x)\\)\u3001\\(f_2(x)\\)\u3001\\(f_3(x)\\)\u3001\\(\\dots\\) \u8fdb\u884c\u63a2\u6d4b\u3002

    • \u63d2\u5165\u5143\u7d20\uff1a\u82e5\u54c8\u5e0c\u51fd\u6570 \\(f_1(x)\\) \u51fa\u73b0\u51b2\u7a81\uff0c\u5219\u5c1d\u8bd5 \\(f_2(x)\\) \uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0c\u76f4\u5230\u627e\u5230\u7a7a\u4f4d\u540e\u63d2\u5165\u5143\u7d20\u3002
    • \u67e5\u627e\u5143\u7d20\uff1a\u5728\u76f8\u540c\u7684\u54c8\u5e0c\u51fd\u6570\u987a\u5e8f\u4e0b\u8fdb\u884c\u67e5\u627e\uff0c\u76f4\u5230\u627e\u5230\u76ee\u6807\u5143\u7d20\u65f6\u8fd4\u56de\uff1b\u82e5\u9047\u5230\u7a7a\u4f4d\u6216\u5df2\u5c1d\u8bd5\u6240\u6709\u54c8\u5e0c\u51fd\u6570\uff0c\u8bf4\u660e\u54c8\u5e0c\u8868\u4e2d\u4e0d\u5b58\u5728\u8be5\u5143\u7d20\uff0c\u5219\u8fd4\u56de None \u3002

    \u4e0e\u7ebf\u6027\u63a2\u6d4b\u76f8\u6bd4\uff0c\u591a\u6b21\u54c8\u5e0c\u65b9\u6cd5\u4e0d\u6613\u4ea7\u751f\u805a\u96c6\uff0c\u4f46\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570\u4f1a\u5e26\u6765\u989d\u5916\u7684\u8ba1\u7b97\u91cf\u3002

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u5f00\u653e\u5bfb\u5740\uff08\u7ebf\u6027\u63a2\u6d4b\u3001\u5e73\u65b9\u63a2\u6d4b\u548c\u591a\u6b21\u54c8\u5e0c\uff09\u54c8\u5e0c\u8868\u90fd\u5b58\u5728\u201c\u4e0d\u80fd\u76f4\u63a5\u5220\u9664\u5143\u7d20\u201d\u7684\u95ee\u9898\u3002

    "},{"location":"chapter_hashing/hash_collision/#623","title":"6.2.3 \u00a0 \u7f16\u7a0b\u8bed\u8a00\u7684\u9009\u62e9","text":"

    \u5404\u79cd\u7f16\u7a0b\u8bed\u8a00\u91c7\u53d6\u4e86\u4e0d\u540c\u7684\u54c8\u5e0c\u8868\u5b9e\u73b0\u7b56\u7565\uff0c\u4e0b\u9762\u4e3e\u51e0\u4e2a\u4f8b\u5b50\u3002

    • Python \u91c7\u7528\u5f00\u653e\u5bfb\u5740\u3002\u5b57\u5178 dict \u4f7f\u7528\u4f2a\u968f\u673a\u6570\u8fdb\u884c\u63a2\u6d4b\u3002
    • Java \u91c7\u7528\u94fe\u5f0f\u5730\u5740\u3002\u81ea JDK 1.8 \u4ee5\u6765\uff0c\u5f53 HashMap \u5185\u6570\u7ec4\u957f\u5ea6\u8fbe\u5230 64 \u4e14\u94fe\u8868\u957f\u5ea6\u8fbe\u5230 8 \u65f6\uff0c\u94fe\u8868\u4f1a\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u4ee5\u63d0\u5347\u67e5\u627e\u6027\u80fd\u3002
    • Go \u91c7\u7528\u94fe\u5f0f\u5730\u5740\u3002Go \u89c4\u5b9a\u6bcf\u4e2a\u6876\u6700\u591a\u5b58\u50a8 8 \u4e2a\u952e\u503c\u5bf9\uff0c\u8d85\u51fa\u5bb9\u91cf\u5219\u8fde\u63a5\u4e00\u4e2a\u6ea2\u51fa\u6876\uff1b\u5f53\u6ea2\u51fa\u6876\u8fc7\u591a\u65f6\uff0c\u4f1a\u6267\u884c\u4e00\u6b21\u7279\u6b8a\u7684\u7b49\u91cf\u6269\u5bb9\u64cd\u4f5c\uff0c\u4ee5\u786e\u4fdd\u6027\u80fd\u3002
    "},{"location":"chapter_hashing/hash_map/","title":"6.1 \u00a0 \u54c8\u5e0c\u8868","text":"

    \u54c8\u5e0c\u8868\uff08hash table\uff09\uff0c\u53c8\u79f0\u6563\u5217\u8868\uff0c\u5b83\u901a\u8fc7\u5efa\u7acb\u952e key \u4e0e\u503c value \u4e4b\u95f4\u7684\u6620\u5c04\uff0c\u5b9e\u73b0\u9ad8\u6548\u7684\u5143\u7d20\u67e5\u8be2\u3002\u5177\u4f53\u800c\u8a00\uff0c\u6211\u4eec\u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u4e00\u4e2a\u952e key \uff0c\u5219\u53ef\u4ee5\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u83b7\u53d6\u5bf9\u5e94\u7684\u503c value \u3002

    \u5982\u56fe 6-1 \u6240\u793a\uff0c\u7ed9\u5b9a \\(n\\) \u4e2a\u5b66\u751f\uff0c\u6bcf\u4e2a\u5b66\u751f\u90fd\u6709\u201c\u59d3\u540d\u201d\u548c\u201c\u5b66\u53f7\u201d\u4e24\u9879\u6570\u636e\u3002\u5047\u5982\u6211\u4eec\u5e0c\u671b\u5b9e\u73b0\u201c\u8f93\u5165\u4e00\u4e2a\u5b66\u53f7\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684\u59d3\u540d\u201d\u7684\u67e5\u8be2\u529f\u80fd\uff0c\u5219\u53ef\u4ee5\u91c7\u7528\u56fe 6-1 \u6240\u793a\u7684\u54c8\u5e0c\u8868\u6765\u5b9e\u73b0\u3002

    \u56fe 6-1 \u00a0 \u54c8\u5e0c\u8868\u7684\u62bd\u8c61\u8868\u793a

    \u9664\u54c8\u5e0c\u8868\u5916\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u67e5\u8be2\u529f\u80fd\uff0c\u5b83\u4eec\u7684\u6548\u7387\u5bf9\u6bd4\u5982\u8868 6-1 \u6240\u793a\u3002

    • \u6dfb\u52a0\u5143\u7d20\uff1a\u4ec5\u9700\u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u6570\u7ec4\uff08\u94fe\u8868\uff09\u7684\u5c3e\u90e8\u5373\u53ef\uff0c\u4f7f\u7528 \\(O(1)\\) \u65f6\u95f4\u3002
    • \u67e5\u8be2\u5143\u7d20\uff1a\u7531\u4e8e\u6570\u7ec4\uff08\u94fe\u8868\uff09\u662f\u4e71\u5e8f\u7684\uff0c\u56e0\u6b64\u9700\u8981\u904d\u5386\u5176\u4e2d\u7684\u6240\u6709\u5143\u7d20\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002
    • \u5220\u9664\u5143\u7d20\uff1a\u9700\u8981\u5148\u67e5\u8be2\u5230\u5143\u7d20\uff0c\u518d\u4ece\u6570\u7ec4\uff08\u94fe\u8868\uff09\u4e2d\u5220\u9664\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002

    \u8868 6-1 \u00a0 \u5143\u7d20\u67e5\u8be2\u6548\u7387\u5bf9\u6bd4

    \u6570\u7ec4 \u94fe\u8868 \u54c8\u5e0c\u8868 \u67e5\u627e\u5143\u7d20 \\(O(n)\\) \\(O(n)\\) \\(O(1)\\) \u6dfb\u52a0\u5143\u7d20 \\(O(1)\\) \\(O(1)\\) \\(O(1)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(n)\\) \\(O(1)\\)

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u5728\u54c8\u5e0c\u8868\u4e2d\u8fdb\u884c\u589e\u5220\u67e5\u6539\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f \\(O(1)\\) \uff0c\u975e\u5e38\u9ad8\u6548\u3002

    "},{"location":"chapter_hashing/hash_map/#611","title":"6.1.1 \u00a0 \u54c8\u5e0c\u8868\u5e38\u7528\u64cd\u4f5c","text":"

    \u54c8\u5e0c\u8868\u7684\u5e38\u89c1\u64cd\u4f5c\u5305\u62ec\uff1a\u521d\u59cb\u5316\u3001\u67e5\u8be2\u64cd\u4f5c\u3001\u6dfb\u52a0\u952e\u503c\u5bf9\u548c\u5220\u9664\u952e\u503c\u5bf9\u7b49\uff0c\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map.py
    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\nhmap: dict = {}\n\n# \u6dfb\u52a0\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nhmap[12836] = \"\u5c0f\u54c8\"\nhmap[15937] = \"\u5c0f\u5570\"\nhmap[16750] = \"\u5c0f\u7b97\"\nhmap[13276] = \"\u5c0f\u6cd5\"\nhmap[10583] = \"\u5c0f\u9e2d\"\n\n# \u67e5\u8be2\u64cd\u4f5c\n# \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nname: str = hmap[15937]\n\n# \u5220\u9664\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nhmap.pop(10583)\n
    hash_map.cpp
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nunordered_map<int, string> map;\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\";\nmap[15937] = \"\u5c0f\u5570\";\nmap[16750] = \"\u5c0f\u7b97\";\nmap[13276] = \"\u5c0f\u6cd5\";\nmap[10583] = \"\u5c0f\u9e2d\";\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nstring name = map[15937];\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.erase(10583);\n
    hash_map.java
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nMap<Integer, String> map = new HashMap<>();\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.put(12836, \"\u5c0f\u54c8\");\nmap.put(15937, \"\u5c0f\u5570\");\nmap.put(16750, \"\u5c0f\u7b97\");\nmap.put(13276, \"\u5c0f\u6cd5\");\nmap.put(10583, \"\u5c0f\u9e2d\");\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nString name = map.get(15937);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.remove(10583);\n
    hash_map.cs
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nDictionary<int, string> map = new() {\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    // \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\n    { 12836, \"\u5c0f\u54c8\" },\n    { 15937, \"\u5c0f\u5570\" },\n    { 16750, \"\u5c0f\u7b97\" },\n    { 13276, \"\u5c0f\u6cd5\" },\n    { 10583, \"\u5c0f\u9e2d\" }\n};\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nstring name = map[15937];\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.Remove(10583);\n
    hash_map_test.go
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nhmap := make(map[int]string)\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nhmap[12836] = \"\u5c0f\u54c8\"\nhmap[15937] = \"\u5c0f\u5570\"\nhmap[16750] = \"\u5c0f\u7b97\"\nhmap[13276] = \"\u5c0f\u6cd5\"\nhmap[10583] = \"\u5c0f\u9e2d\"\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nname := hmap[15937]\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\ndelete(hmap, 10583)\n
    hash_map.swift
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nvar map: [Int: String] = [:]\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\"\nmap[15937] = \"\u5c0f\u5570\"\nmap[16750] = \"\u5c0f\u7b97\"\nmap[13276] = \"\u5c0f\u6cd5\"\nmap[10583] = \"\u5c0f\u9e2d\"\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet name = map[15937]!\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.removeValue(forKey: 10583)\n
    hash_map.js
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nconst map = new Map();\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.set(12836, '\u5c0f\u54c8');\nmap.set(15937, '\u5c0f\u5570');\nmap.set(16750, '\u5c0f\u7b97');\nmap.set(13276, '\u5c0f\u6cd5');\nmap.set(10583, '\u5c0f\u9e2d');\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet name = map.get(15937);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.delete(10583);\n
    hash_map.ts
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nconst map = new Map<number, string>();\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.set(12836, '\u5c0f\u54c8');\nmap.set(15937, '\u5c0f\u5570');\nmap.set(16750, '\u5c0f\u7b97');\nmap.set(13276, '\u5c0f\u6cd5');\nmap.set(10583, '\u5c0f\u9e2d');\nconsole.info('\\n\u6dfb\u52a0\u5b8c\u6210\u540e\uff0c\u54c8\u5e0c\u8868\u4e3a\\nKey -> Value');\nconsole.info(map);\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet name = map.get(15937);\nconsole.info('\\n\u8f93\u5165\u5b66\u53f7 15937 \uff0c\u67e5\u8be2\u5230\u59d3\u540d ' + name);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.delete(10583);\nconsole.info('\\n\u5220\u9664 10583 \u540e\uff0c\u54c8\u5e0c\u8868\u4e3a\\nKey -> Value');\nconsole.info(map);\n
    hash_map.dart
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nMap<int, String> map = {};\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\";\nmap[15937] = \"\u5c0f\u5570\";\nmap[16750] = \"\u5c0f\u7b97\";\nmap[13276] = \"\u5c0f\u6cd5\";\nmap[10583] = \"\u5c0f\u9e2d\";\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nString name = map[15937];\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.remove(10583);\n
    hash_map.rs
    use std::collections::HashMap;\n\n/* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nlet mut map: HashMap<i32, String> = HashMap::new();\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap.insert(12836, \"\u5c0f\u54c8\".to_string());\nmap.insert(15937, \"\u5c0f\u5570\".to_string());\nmap.insert(16750, \"\u5c0f\u7b97\".to_string());\nmap.insert(13279, \"\u5c0f\u6cd5\".to_string());\nmap.insert(10583, \"\u5c0f\u9e2d\".to_string());\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nlet _name: Option<&String> = map.get(&15937);\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nlet _removed_value: Option<String> = map.remove(&10583);\n
    hash_map.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u54c8\u5e0c\u8868\n
    hash_map.kt
    /* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nval map = HashMap<Int,String>()\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nmap[12836] = \"\u5c0f\u54c8\"\nmap[15937] = \"\u5c0f\u5570\"\nmap[16750] = \"\u5c0f\u7b97\"\nmap[13276] = \"\u5c0f\u6cd5\"\nmap[10583] = \"\u5c0f\u9e2d\"\n\n/* \u67e5\u8be2\u64cd\u4f5c */\n// \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nval name = map[15937]\n\n/* \u5220\u9664\u64cd\u4f5c */\n// \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nmap.remove(10583)\n
    hash_map.rb
    # \u521d\u59cb\u5316\u54c8\u5e0c\u8868\nhmap = {}\n\n# \u6dfb\u52a0\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u6dfb\u52a0\u952e\u503c\u5bf9 (key, value)\nhmap[12836] = \"\u5c0f\u54c8\"\nhmap[15937] = \"\u5c0f\u5570\"\nhmap[16750] = \"\u5c0f\u7b97\"\nhmap[13276] = \"\u5c0f\u6cd5\"\nhmap[10583] = \"\u5c0f\u9e2d\"\n\n# \u67e5\u8be2\u64cd\u4f5c\n# \u5411\u54c8\u5e0c\u8868\u4e2d\u8f93\u5165\u952e key \uff0c\u5f97\u5230\u503c value\nname = hmap[15937]\n\n# \u5220\u9664\u64cd\u4f5c\n# \u5728\u54c8\u5e0c\u8868\u4e2d\u5220\u9664\u952e\u503c\u5bf9 (key, value)\nhmap.delete(10583)\n
    hash_map.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u54c8\u5e0c\u8868\u6709\u4e09\u79cd\u5e38\u7528\u7684\u904d\u5386\u65b9\u5f0f\uff1a\u904d\u5386\u952e\u503c\u5bf9\u3001\u904d\u5386\u952e\u548c\u904d\u5386\u503c\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig hash_map.py
    # \u904d\u5386\u54c8\u5e0c\u8868\n# \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor key, value in hmap.items():\n    print(key, \"->\", value)\n# \u5355\u72ec\u904d\u5386\u952e key\nfor key in hmap.keys():\n    print(key)\n# \u5355\u72ec\u904d\u5386\u503c value\nfor value in hmap.values():\n    print(value)\n
    hash_map.cpp
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor (auto kv: map) {\n    cout << kv.first << \" -> \" << kv.second << endl;\n}\n// \u4f7f\u7528\u8fed\u4ee3\u5668\u904d\u5386 key->value\nfor (auto iter = map.begin(); iter != map.end(); iter++) {\n    cout << iter->first << \"->\" << iter->second << endl;\n}\n
    hash_map.java
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor (Map.Entry <Integer, String> kv: map.entrySet()) {\n    System.out.println(kv.getKey() + \" -> \" + kv.getValue());\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nfor (int key: map.keySet()) {\n    System.out.println(key);\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nfor (String val: map.values()) {\n    System.out.println(val);\n}\n
    hash_map.cs
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nforeach (var kv in map) {\n    Console.WriteLine(kv.Key + \" -> \" + kv.Value);\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nforeach (int key in map.Keys) {\n    Console.WriteLine(key);\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nforeach (string val in map.Values) {\n    Console.WriteLine(val);\n}\n
    hash_map_test.go
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor key, value := range hmap {\n    fmt.Println(key, \"->\", value)\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nfor key := range hmap {\n    fmt.Println(key)\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nfor _, value := range hmap {\n    fmt.Println(value)\n}\n
    hash_map.swift
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nfor (key, value) in map {\n    print(\"\\(key) -> \\(value)\")\n}\n// \u5355\u72ec\u904d\u5386\u952e Key\nfor key in map.keys {\n    print(key)\n}\n// \u5355\u72ec\u904d\u5386\u503c Value\nfor value in map.values {\n    print(value)\n}\n
    hash_map.js
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\nconsole.info('\\n\u904d\u5386\u952e\u503c\u5bf9 Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u952e Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u503c Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.ts
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\nconsole.info('\\n\u904d\u5386\u952e\u503c\u5bf9 Key->Value');\nfor (const [k, v] of map.entries()) {\n    console.info(k + ' -> ' + v);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u952e Key');\nfor (const k of map.keys()) {\n    console.info(k);\n}\nconsole.info('\\n\u5355\u72ec\u904d\u5386\u503c Value');\nfor (const v of map.values()) {\n    console.info(v);\n}\n
    hash_map.dart
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nmap.forEach((key, value) {\n  print('$key -> $value');\n});\n\n// \u5355\u72ec\u904d\u5386\u952e Key\nmap.keys.forEach((key) {\n  print(key);\n});\n\n// \u5355\u72ec\u904d\u5386\u503c Value\nmap.values.forEach((value) {\n  print(value);\n});\n
    hash_map.rs
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 Key->Value\nfor (key, value) in &map {\n    println!(\"{key} -> {value}\");\n}\n\n// \u5355\u72ec\u904d\u5386\u952e Key\nfor key in map.keys() {\n    println!(\"{key}\");\n}\n\n// \u5355\u72ec\u904d\u5386\u503c Value\nfor value in map.values() {\n    println!(\"{value}\");\n}\n
    hash_map.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u54c8\u5e0c\u8868\n
    hash_map.kt
    /* \u904d\u5386\u54c8\u5e0c\u8868 */\n// \u904d\u5386\u952e\u503c\u5bf9 key->value\nfor ((key, value) in map) {\n    println(\"$key -> $value\")\n}\n// \u5355\u72ec\u904d\u5386\u952e key\nfor (key in map.keys) {\n    println(key)\n}\n// \u5355\u72ec\u904d\u5386\u503c value\nfor (_val in map.values) {\n    println(_val)\n}\n
    hash_map.rb
    # \u904d\u5386\u54c8\u5e0c\u8868\n# \u904d\u5386\u952e\u503c\u5bf9 key->value\nhmap.entries.each { |key, value| puts \"#{key} -> #{value}\" }\n\n# \u5355\u72ec\u904d\u5386\u952e key\nhmap.keys.each { |key| puts key }\n\n# \u5355\u72ec\u904d\u5386\u503c value\nhmap.values.each { |val| puts val }\n
    hash_map.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_hashing/hash_map/#612","title":"6.1.2 \u00a0 \u54c8\u5e0c\u8868\u7b80\u5355\u5b9e\u73b0","text":"

    \u6211\u4eec\u5148\u8003\u8651\u6700\u7b80\u5355\u7684\u60c5\u51b5\uff0c\u4ec5\u7528\u4e00\u4e2a\u6570\u7ec4\u6765\u5b9e\u73b0\u54c8\u5e0c\u8868\u3002\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u6211\u4eec\u5c06\u6570\u7ec4\u4e2d\u7684\u6bcf\u4e2a\u7a7a\u4f4d\u79f0\u4e3a\u6876\uff08bucket\uff09\uff0c\u6bcf\u4e2a\u6876\u53ef\u5b58\u50a8\u4e00\u4e2a\u952e\u503c\u5bf9\u3002\u56e0\u6b64\uff0c\u67e5\u8be2\u64cd\u4f5c\u5c31\u662f\u627e\u5230 key \u5bf9\u5e94\u7684\u6876\uff0c\u5e76\u5728\u6876\u4e2d\u83b7\u53d6 value \u3002

    \u90a3\u4e48\uff0c\u5982\u4f55\u57fa\u4e8e key \u5b9a\u4f4d\u5bf9\u5e94\u7684\u6876\u5462\uff1f\u8fd9\u662f\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\uff08hash function\uff09\u5b9e\u73b0\u7684\u3002\u54c8\u5e0c\u51fd\u6570\u7684\u4f5c\u7528\u662f\u5c06\u4e00\u4e2a\u8f83\u5927\u7684\u8f93\u5165\u7a7a\u95f4\u6620\u5c04\u5230\u4e00\u4e2a\u8f83\u5c0f\u7684\u8f93\u51fa\u7a7a\u95f4\u3002\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u8f93\u5165\u7a7a\u95f4\u662f\u6240\u6709 key \uff0c\u8f93\u51fa\u7a7a\u95f4\u662f\u6240\u6709\u6876\uff08\u6570\u7ec4\u7d22\u5f15\uff09\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u8f93\u5165\u4e00\u4e2a key \uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u5f97\u5230\u8be5 key \u5bf9\u5e94\u7684\u952e\u503c\u5bf9\u5728\u6570\u7ec4\u4e2d\u7684\u5b58\u50a8\u4f4d\u7f6e\u3002

    \u8f93\u5165\u4e00\u4e2a key \uff0c\u54c8\u5e0c\u51fd\u6570\u7684\u8ba1\u7b97\u8fc7\u7a0b\u5206\u4e3a\u4ee5\u4e0b\u4e24\u6b65\u3002

    1. \u901a\u8fc7\u67d0\u79cd\u54c8\u5e0c\u7b97\u6cd5 hash() \u8ba1\u7b97\u5f97\u5230\u54c8\u5e0c\u503c\u3002
    2. \u5c06\u54c8\u5e0c\u503c\u5bf9\u6876\u6570\u91cf\uff08\u6570\u7ec4\u957f\u5ea6\uff09capacity \u53d6\u6a21\uff0c\u4ece\u800c\u83b7\u53d6\u8be5 key \u5bf9\u5e94\u7684\u6570\u7ec4\u7d22\u5f15 index \u3002
    index = hash(key) % capacity\n

    \u968f\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5229\u7528 index \u5728\u54c8\u5e0c\u8868\u4e2d\u8bbf\u95ee\u5bf9\u5e94\u7684\u6876\uff0c\u4ece\u800c\u83b7\u53d6 value \u3002

    \u8bbe\u6570\u7ec4\u957f\u5ea6 capacity = 100\u3001\u54c8\u5e0c\u7b97\u6cd5 hash(key) = key \uff0c\u6613\u5f97\u54c8\u5e0c\u51fd\u6570\u4e3a key % 100 \u3002\u56fe 6-2 \u4ee5 key \u5b66\u53f7\u548c value \u59d3\u540d\u4e3a\u4f8b\uff0c\u5c55\u793a\u4e86\u54c8\u5e0c\u51fd\u6570\u7684\u5de5\u4f5c\u539f\u7406\u3002

    \u56fe 6-2 \u00a0 \u54c8\u5e0c\u51fd\u6570\u5de5\u4f5c\u539f\u7406

    \u4ee5\u4e0b\u4ee3\u7801\u5b9e\u73b0\u4e86\u4e00\u4e2a\u7b80\u5355\u54c8\u5e0c\u8868\u3002\u5176\u4e2d\uff0c\u6211\u4eec\u5c06 key \u548c value \u5c01\u88c5\u6210\u4e00\u4e2a\u7c7b Pair \uff0c\u4ee5\u8868\u793a\u952e\u503c\u5bf9\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_hash_map.py
    class Pair:\n    \"\"\"\u952e\u503c\u5bf9\"\"\"\n\n    def __init__(self, key: int, val: str):\n        self.key = key\n        self.val = val\n\nclass ArrayHashMap:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        self.buckets: list[Pair | None] = [None] * 100\n\n    def hash_func(self, key: int) -> int:\n        \"\"\"\u54c8\u5e0c\u51fd\u6570\"\"\"\n        index = key % 100\n        return index\n\n    def get(self, key: int) -> str:\n        \"\"\"\u67e5\u8be2\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        pair: Pair = self.buckets[index]\n        if pair is None:\n            return None\n        return pair.val\n\n    def put(self, key: int, val: str):\n        \"\"\"\u6dfb\u52a0\u64cd\u4f5c\"\"\"\n        pair = Pair(key, val)\n        index: int = self.hash_func(key)\n        self.buckets[index] = pair\n\n    def remove(self, key: int):\n        \"\"\"\u5220\u9664\u64cd\u4f5c\"\"\"\n        index: int = self.hash_func(key)\n        # \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None\n\n    def entry_set(self) -> list[Pair]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\"\"\"\n        result: list[Pair] = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair)\n        return result\n\n    def key_set(self) -> list[int]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u952e\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.key)\n        return result\n\n    def value_set(self) -> list[str]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u503c\"\"\"\n        result = []\n        for pair in self.buckets:\n            if pair is not None:\n                result.append(pair.val)\n        return result\n\n    def print(self):\n        \"\"\"\u6253\u5370\u54c8\u5e0c\u8868\"\"\"\n        for pair in self.buckets:\n            if pair is not None:\n                print(pair.key, \"->\", pair.val)\n
    array_hash_map.cpp
    /* \u952e\u503c\u5bf9 */\nstruct Pair {\n  public:\n    int key;\n    string val;\n    Pair(int key, string val) {\n        this->key = key;\n        this->val = val;\n    }\n};\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  private:\n    vector<Pair *> buckets;\n\n  public:\n    ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = vector<Pair *>(100);\n    }\n\n    ~ArrayHashMap() {\n        // \u91ca\u653e\u5185\u5b58\n        for (const auto &bucket : buckets) {\n            delete bucket;\n        }\n        buckets.clear();\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    string get(int key) {\n        int index = hashFunc(key);\n        Pair *pair = buckets[index];\n        if (pair == nullptr)\n            return \"\";\n        return pair->val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    void put(int key, string val) {\n        Pair *pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    void remove(int key) {\n        int index = hashFunc(key);\n        // \u91ca\u653e\u5185\u5b58\u5e76\u7f6e\u4e3a nullptr\n        delete buckets[index];\n        buckets[index] = nullptr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    vector<Pair *> pairSet() {\n        vector<Pair *> pairSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                pairSet.push_back(pair);\n            }\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    vector<int> keySet() {\n        vector<int> keySet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                keySet.push_back(pair->key);\n            }\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    vector<string> valueSet() {\n        vector<string> valueSet;\n        for (Pair *pair : buckets) {\n            if (pair != nullptr) {\n                valueSet.push_back(pair->val);\n            }\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    void print() {\n        for (Pair *kv : pairSet()) {\n            cout << kv->key << \" -> \" << kv->val << endl;\n        }\n    }\n};\n
    array_hash_map.java
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n    public int key;\n    public String val;\n\n    public Pair(int key, String val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private List<Pair> buckets;\n\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = new ArrayList<>();\n        for (int i = 0; i < 100; i++) {\n            buckets.add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private int hashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public String get(int key) {\n        int index = hashFunc(key);\n        Pair pair = buckets.get(index);\n        if (pair == null)\n            return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void put(int key, String val) {\n        Pair pair = new Pair(key, val);\n        int index = hashFunc(key);\n        buckets.set(index, pair);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void remove(int key) {\n        int index = hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets.set(index, null);\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> pairSet() {\n        List<Pair> pairSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                pairSet.add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<Integer> keySet() {\n        List<Integer> keySet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                keySet.add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<String> valueSet() {\n        List<String> valueSet = new ArrayList<>();\n        for (Pair pair : buckets) {\n            if (pair != null)\n                valueSet.add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void print() {\n        for (Pair kv : pairSet()) {\n            System.out.println(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.cs
    /* \u952e\u503c\u5bf9 int->string */\nclass Pair(int key, string val) {\n    public int key = key;\n    public string val = val;\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    List<Pair?> buckets;\n    public ArrayHashMap() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = [];\n        for (int i = 0; i < 100; i++) {\n            buckets.Add(null);\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    int HashFunc(int key) {\n        int index = key % 100;\n        return index;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public string? Get(int key) {\n        int index = HashFunc(key);\n        Pair? pair = buckets[index];\n        if (pair == null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public void Put(int key, string val) {\n        Pair pair = new(key, val);\n        int index = HashFunc(key);\n        buckets[index] = pair;\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public void Remove(int key) {\n        int index = HashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public List<Pair> PairSet() {\n        List<Pair> pairSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                pairSet.Add(pair);\n        }\n        return pairSet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public List<int> KeySet() {\n        List<int> keySet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                keySet.Add(pair.key);\n        }\n        return keySet;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public List<string> ValueSet() {\n        List<string> valueSet = [];\n        foreach (Pair? pair in buckets) {\n            if (pair != null)\n                valueSet.Add(pair.val);\n        }\n        return valueSet;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public void Print() {\n        foreach (Pair kv in PairSet()) {\n            Console.WriteLine(kv.key + \" -> \" + kv.val);\n        }\n    }\n}\n
    array_hash_map.go
    /* \u952e\u503c\u5bf9 */\ntype pair struct {\n    key int\n    val string\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntype arrayHashMap struct {\n    buckets []*pair\n}\n\n/* \u521d\u59cb\u5316\u54c8\u5e0c\u8868 */\nfunc newArrayHashMap() *arrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    buckets := make([]*pair, 100)\n    return &arrayHashMap{buckets: buckets}\n}\n\n/* \u54c8\u5e0c\u51fd\u6570 */\nfunc (a *arrayHashMap) hashFunc(key int) int {\n    index := key % 100\n    return index\n}\n\n/* \u67e5\u8be2\u64cd\u4f5c */\nfunc (a *arrayHashMap) get(key int) string {\n    index := a.hashFunc(key)\n    pair := a.buckets[index]\n    if pair == nil {\n        return \"Not Found\"\n    }\n    return pair.val\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nfunc (a *arrayHashMap) put(key int, val string) {\n    pair := &pair{key: key, val: val}\n    index := a.hashFunc(key)\n    a.buckets[index] = pair\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nfunc (a *arrayHashMap) remove(key int) {\n    index := a.hashFunc(key)\n    // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    a.buckets[index] = nil\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u5bf9 */\nfunc (a *arrayHashMap) pairSet() []*pair {\n    var pairs []*pair\n    for _, pair := range a.buckets {\n        if pair != nil {\n            pairs = append(pairs, pair)\n        }\n    }\n    return pairs\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nfunc (a *arrayHashMap) keySet() []int {\n    var keys []int\n    for _, pair := range a.buckets {\n        if pair != nil {\n            keys = append(keys, pair.key)\n        }\n    }\n    return keys\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nfunc (a *arrayHashMap) valueSet() []string {\n    var values []string\n    for _, pair := range a.buckets {\n        if pair != nil {\n            values = append(values, pair.val)\n        }\n    }\n    return values\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nfunc (a *arrayHashMap) print() {\n    for _, pair := range a.buckets {\n        if pair != nil {\n            fmt.Println(pair.key, \"->\", pair.val)\n        }\n    }\n}\n
    array_hash_map.swift
    /* \u952e\u503c\u5bf9 */\nclass Pair: Equatable {\n    public var key: Int\n    public var val: String\n\n    public init(key: Int, val: String) {\n        self.key = key\n        self.val = val\n    }\n\n    public static func == (lhs: Pair, rhs: Pair) -> Bool {\n        lhs.key == rhs.key && lhs.val == rhs.val\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private var buckets: [Pair?]\n\n    init() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        buckets = Array(repeating: nil, count: 100)\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private func hashFunc(key: Int) -> Int {\n        let index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    func get(key: Int) -> String? {\n        let index = hashFunc(key: key)\n        let pair = buckets[index]\n        return pair?.val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    func put(key: Int, val: String) {\n        let pair = Pair(key: key, val: val)\n        let index = hashFunc(key: key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    func remove(key: Int) {\n        let index = hashFunc(key: key)\n        // \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = nil\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    func pairSet() -> [Pair] {\n        buckets.compactMap { $0 }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    func keySet() -> [Int] {\n        buckets.compactMap { $0?.key }\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    func valueSet() -> [String] {\n        buckets.compactMap { $0?.val }\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    func print() {\n        for pair in pairSet() {\n            Swift.print(\"\\(pair.key) -> \\(pair.val)\")\n        }\n    }\n}\n
    array_hash_map.js
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    constructor(key, val) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    #buckets;\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.#buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    #hashFunc(key) {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    get(key) {\n        let index = this.#hashFunc(key);\n        let pair = this.#buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    set(key, val) {\n        let index = this.#hashFunc(key);\n        this.#buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    delete(key) {\n        let index = this.#hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.#buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    entries() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    keys() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    values() {\n        let arr = [];\n        for (let i = 0; i < this.#buckets.length; i++) {\n            if (this.#buckets[i]) {\n                arr.push(this.#buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.ts
    /* \u952e\u503c\u5bf9 Number -> String */\nclass Pair {\n    public key: number;\n    public val: string;\n\n    constructor(key: number, val: string) {\n        this.key = key;\n        this.val = val;\n    }\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    private readonly buckets: (Pair | null)[];\n\n    constructor() {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        this.buckets = new Array(100).fill(null);\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    private hashFunc(key: number): number {\n        return key % 100;\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    public get(key: number): string | null {\n        let index = this.hashFunc(key);\n        let pair = this.buckets[index];\n        if (pair === null) return null;\n        return pair.val;\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    public set(key: number, val: string) {\n        let index = this.hashFunc(key);\n        this.buckets[index] = new Pair(key, val);\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    public delete(key: number) {\n        let index = this.hashFunc(key);\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        this.buckets[index] = null;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    public entries(): (Pair | null)[] {\n        let arr: (Pair | null)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i]);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    public keys(): (number | undefined)[] {\n        let arr: (number | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].key);\n            }\n        }\n        return arr;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    public values(): (string | undefined)[] {\n        let arr: (string | undefined)[] = [];\n        for (let i = 0; i < this.buckets.length; i++) {\n            if (this.buckets[i]) {\n                arr.push(this.buckets[i].val);\n            }\n        }\n        return arr;\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    public print() {\n        let pairSet = this.entries();\n        for (const pair of pairSet) {\n            console.info(`${pair.key} -> ${pair.val}`);\n        }\n    }\n}\n
    array_hash_map.dart
    /* \u952e\u503c\u5bf9 */\nclass Pair {\n  int key;\n  String val;\n  Pair(this.key, this.val);\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n  late List<Pair?> _buckets;\n\n  ArrayHashMap() {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    _buckets = List.filled(100, null);\n  }\n\n  /* \u54c8\u5e0c\u51fd\u6570 */\n  int _hashFunc(int key) {\n    final int index = key % 100;\n    return index;\n  }\n\n  /* \u67e5\u8be2\u64cd\u4f5c */\n  String? get(int key) {\n    final int index = _hashFunc(key);\n    final Pair? pair = _buckets[index];\n    if (pair == null) {\n      return null;\n    }\n    return pair.val;\n  }\n\n  /* \u6dfb\u52a0\u64cd\u4f5c */\n  void put(int key, String val) {\n    final Pair pair = Pair(key, val);\n    final int index = _hashFunc(key);\n    _buckets[index] = pair;\n  }\n\n  /* \u5220\u9664\u64cd\u4f5c */\n  void remove(int key) {\n    final int index = _hashFunc(key);\n    _buckets[index] = null;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n  List<Pair> pairSet() {\n    List<Pair> pairSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        pairSet.add(pair);\n      }\n    }\n    return pairSet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u952e */\n  List<int> keySet() {\n    List<int> keySet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        keySet.add(pair.key);\n      }\n    }\n    return keySet;\n  }\n\n  /* \u83b7\u53d6\u6240\u6709\u503c */\n  List<String> values() {\n    List<String> valueSet = [];\n    for (final Pair? pair in _buckets) {\n      if (pair != null) {\n        valueSet.add(pair.val);\n      }\n    }\n    return valueSet;\n  }\n\n  /* \u6253\u5370\u54c8\u5e0c\u8868 */\n  void printHashMap() {\n    for (final Pair kv in pairSet()) {\n      print(\"${kv.key} -> ${kv.val}\");\n    }\n  }\n}\n
    array_hash_map.rs
    /* \u952e\u503c\u5bf9 */\n#[derive(Debug, Clone, PartialEq)]\npub struct Pair {\n    pub key: i32,\n    pub val: String,\n}\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\npub struct ArrayHashMap {\n    buckets: Vec<Option<Pair>>,\n}\n\nimpl ArrayHashMap {\n    pub fn new() -> ArrayHashMap {\n        // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n        Self {\n            buckets: vec![None; 100],\n        }\n    }\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fn hash_func(&self, key: i32) -> usize {\n        key as usize % 100\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    pub fn get(&self, key: i32) -> Option<&String> {\n        let index = self.hash_func(key);\n        self.buckets[index].as_ref().map(|pair| &pair.val)\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    pub fn put(&mut self, key: i32, val: &str) {\n        let index = self.hash_func(key);\n        self.buckets[index] = Some(Pair {\n            key,\n            val: val.to_string(),\n        });\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    pub fn remove(&mut self, key: i32) {\n        let index = self.hash_func(key);\n        // \u7f6e\u4e3a None \uff0c\u4ee3\u8868\u5220\u9664\n        self.buckets[index] = None;\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    pub fn entry_set(&self) -> Vec<&Pair> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref())\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    pub fn key_set(&self) -> Vec<&i32> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.key))\n            .collect()\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    pub fn value_set(&self) -> Vec<&String> {\n        self.buckets\n            .iter()\n            .filter_map(|pair| pair.as_ref().map(|pair| &pair.val))\n            .collect()\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    pub fn print(&self) {\n        for pair in self.entry_set() {\n            println!(\"{} -> {}\", pair.key, pair.val);\n        }\n    }\n}\n
    array_hash_map.c
    /* \u952e\u503c\u5bf9 int->string */\ntypedef struct {\n    int key;\n    char *val;\n} Pair;\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\ntypedef struct {\n    Pair *buckets[MAX_SIZE];\n} ArrayHashMap;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayHashMap *newArrayHashMap() {\n    ArrayHashMap *hmap = malloc(sizeof(ArrayHashMap));\n    for (int i=0; i < MAX_SIZE; i++) {\n        hmap->buckets[i] = NULL;\n    }\n    return hmap;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayHashMap(ArrayHashMap *hmap) {\n    for (int i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            free(hmap->buckets[i]->val);\n            free(hmap->buckets[i]);\n        }\n    }\n    free(hmap);\n}\n\n/* \u6dfb\u52a0\u64cd\u4f5c */\nvoid put(ArrayHashMap *hmap, const int key, const char *val) {\n    Pair *Pair = malloc(sizeof(Pair));\n    Pair->key = key;\n    Pair->val = malloc(strlen(val) + 1);\n    strcpy(Pair->val, val);\n\n    int index = hashFunc(key);\n    hmap->buckets[index] = Pair;\n}\n\n/* \u5220\u9664\u64cd\u4f5c */\nvoid removeItem(ArrayHashMap *hmap, const int key) {\n    int index = hashFunc(key);\n    free(hmap->buckets[index]->val);\n    free(hmap->buckets[index]);\n    hmap->buckets[index] = NULL;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\nvoid pairSet(ArrayHashMap *hmap, MapSet *set) {\n    Pair *entries;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    entries = malloc(sizeof(Pair) * total);\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            entries[index].key = hmap->buckets[i]->key;\n            entries[index].val = malloc(strlen(hmap->buckets[i]->val) + 1);\n            strcpy(entries[index].val, hmap->buckets[i]->val);\n            index++;\n        }\n    }\n    set->set = entries;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u952e */\nvoid keySet(ArrayHashMap *hmap, MapSet *set) {\n    int *keys;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    keys = malloc(total * sizeof(int));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            keys[index] = hmap->buckets[i]->key;\n            index++;\n        }\n    }\n    set->set = keys;\n    set->len = total;\n}\n\n/* \u83b7\u53d6\u6240\u6709\u503c */\nvoid valueSet(ArrayHashMap *hmap, MapSet *set) {\n    char **vals;\n    int i = 0, index = 0;\n    int total = 0;\n    /* \u7edf\u8ba1\u6709\u6548\u952e\u503c\u5bf9\u6570\u91cf */\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            total++;\n        }\n    }\n    vals = malloc(total * sizeof(char *));\n    for (i = 0; i < MAX_SIZE; i++) {\n        if (hmap->buckets[i] != NULL) {\n            vals[index] = hmap->buckets[i]->val;\n            index++;\n        }\n    }\n    set->set = vals;\n    set->len = total;\n}\n\n/* \u6253\u5370\u54c8\u5e0c\u8868 */\nvoid print(ArrayHashMap *hmap) {\n    int i;\n    MapSet set;\n    pairSet(hmap, &set);\n    Pair *entries = (Pair *)set.set;\n    for (i = 0; i < set.len; i++) {\n        printf(\"%d -> %s\\n\", entries[i].key, entries[i].val);\n    }\n    free(set.set);\n}\n
    array_hash_map.kt
    /* \u952e\u503c\u5bf9 */\nclass Pair(\n    var key: Int,\n    var _val: String\n)\n\n/* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 */\nclass ArrayHashMap {\n    // \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    private val buckets = arrayOfNulls<Pair>(100)\n\n    /* \u54c8\u5e0c\u51fd\u6570 */\n    fun hashFunc(key: Int): Int {\n        val index = key % 100\n        return index\n    }\n\n    /* \u67e5\u8be2\u64cd\u4f5c */\n    fun get(key: Int): String? {\n        val index = hashFunc(key)\n        val pair = buckets[index] ?: return null\n        return pair._val\n    }\n\n    /* \u6dfb\u52a0\u64cd\u4f5c */\n    fun put(key: Int, _val: String) {\n        val pair = Pair(key, _val)\n        val index = hashFunc(key)\n        buckets[index] = pair\n    }\n\n    /* \u5220\u9664\u64cd\u4f5c */\n    fun remove(key: Int) {\n        val index = hashFunc(key)\n        // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n        buckets[index] = null\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 */\n    fun pairSet(): MutableList<Pair> {\n        val pairSet = mutableListOf<Pair>()\n        for (pair in buckets) {\n            if (pair != null)\n                pairSet.add(pair)\n        }\n        return pairSet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u952e */\n    fun keySet(): MutableList<Int> {\n        val keySet = mutableListOf<Int>()\n        for (pair in buckets) {\n            if (pair != null)\n                keySet.add(pair.key)\n        }\n        return keySet\n    }\n\n    /* \u83b7\u53d6\u6240\u6709\u503c */\n    fun valueSet(): MutableList<String> {\n        val valueSet = mutableListOf<String>()\n        for (pair in buckets) {\n            if (pair != null)\n                valueSet.add(pair._val)\n        }\n        return valueSet\n    }\n\n    /* \u6253\u5370\u54c8\u5e0c\u8868 */\n    fun print() {\n        for (kv in pairSet()) {\n            val key = kv.key\n            val _val = kv._val\n            println(\"$key -> $_val\")\n        }\n    }\n}\n
    array_hash_map.rb
    ### \u952e\u503c\u5bf9 ###\nclass Pair\n  attr_accessor :key, :val\n\n  def initialize(key, val)\n    @key = key\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868 ###\nclass ArrayHashMap\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    # \u521d\u59cb\u5316\u6570\u7ec4\uff0c\u5305\u542b 100 \u4e2a\u6876\n    @buckets = Array.new(100)\n  end\n\n  ### \u54c8\u5e0c\u51fd\u6570 ###\n  def hash_func(key)\n    index = key % 100\n  end\n\n  ### \u67e5\u8be2\u64cd\u4f5c ###\n  def get(key)\n    index = hash_func(key)\n    pair = @buckets[index]\n\n    return if pair.nil?\n    pair.val\n  end\n\n  ### \u6dfb\u52a0\u64cd\u4f5c ###\n  def put(key, val)\n    pair = Pair.new(key, val)\n    index = hash_func(key)\n    @buckets[index] = pair\n  end\n\n  ### \u5220\u9664\u64cd\u4f5c ###\n  def remove(key)\n    index = hash_func(key)\n    # \u7f6e\u4e3a nil \uff0c\u4ee3\u8868\u5220\u9664\n    @buckets[index] = nil\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9 ###\n  def entry_set\n    result = []\n    @buckets.each { |pair| result << pair unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u952e ###\n  def key_set\n    result = []\n    @buckets.each { |pair| result << pair.key unless pair.nil? }\n    result\n  end\n\n  ### \u83b7\u53d6\u6240\u6709\u503c ###\n  def value_set\n    result = []\n    @buckets.each { |pair| result << pair.val unless pair.nil? }\n    result\n  end\n\n  ### \u6253\u5370\u54c8\u5e0c\u8868 ###\n  def print\n    @buckets.each { |pair| puts \"#{pair.key} -> #{pair.val}\" unless pair.nil? }\n  end\nend\n
    array_hash_map.zig
    // \u952e\u503c\u5bf9\nconst Pair = struct {\n    key: usize = undefined,\n    val: []const u8 = undefined,\n\n   pub fn init(key: usize, val: []const u8) Pair {\n        return Pair {\n            .key = key,\n            .val = val,\n        };\n    }\n};\n\n// \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u54c8\u5e0c\u8868\nfn ArrayHashMap(comptime T: type) type {\n    return struct {\n        bucket: ?std.ArrayList(?T) = null,\n        mem_allocator: std.mem.Allocator = undefined,\n\n        const Self = @This();\n\n        // \u6784\u9020\u51fd\u6570\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            self.mem_allocator = allocator;\n            // \u521d\u59cb\u5316\u4e00\u4e2a\u957f\u5ea6\u4e3a 100 \u7684\u6876\uff08\u6570\u7ec4\uff09\n            self.bucket = std.ArrayList(?T).init(self.mem_allocator);\n            var i: i32 = 0;\n            while (i < 100) : (i += 1) {\n                try self.bucket.?.append(null);\n            }\n        }\n\n        // \u6790\u6784\u51fd\u6570\n        pub fn deinit(self: *Self) void {\n            if (self.bucket != null) self.bucket.?.deinit();\n        }\n\n        // \u54c8\u5e0c\u51fd\u6570\n        fn hashFunc(key: usize) usize {\n            var index = key % 100;\n            return index;\n        }\n\n        // \u67e5\u8be2\u64cd\u4f5c\n        pub fn get(self: *Self, key: usize) []const u8 {\n            var index = hashFunc(key);\n            var pair = self.bucket.?.items[index];\n            return pair.?.val;\n        }\n\n        // \u6dfb\u52a0\u64cd\u4f5c\n        pub fn put(self: *Self, key: usize, val: []const u8) !void {\n            var pair = Pair.init(key, val);\n            var index = hashFunc(key);\n            self.bucket.?.items[index] = pair;\n        }\n\n        // \u5220\u9664\u64cd\u4f5c\n        pub fn remove(self: *Self, key: usize) !void {\n            var index = hashFunc(key);\n            // \u7f6e\u4e3a null \uff0c\u4ee3\u8868\u5220\u9664\n            self.bucket.?.items[index] = null;\n        }       \n\n        // \u83b7\u53d6\u6240\u6709\u952e\u503c\u5bf9\n        pub fn pairSet(self: *Self) !std.ArrayList(T) {\n            var entry_set = std.ArrayList(T).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try entry_set.append(item.?);\n            }\n            return entry_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u952e\n        pub fn keySet(self: *Self) !std.ArrayList(usize) {\n            var key_set = std.ArrayList(usize).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try key_set.append(item.?.key);\n            }\n            return key_set;\n        }  \n\n        // \u83b7\u53d6\u6240\u6709\u503c\n        pub fn valueSet(self: *Self) !std.ArrayList([]const u8) {\n            var value_set = std.ArrayList([]const u8).init(self.mem_allocator);\n            for (self.bucket.?.items) |item| {\n                if (item == null) continue;\n                try value_set.append(item.?.val);\n            }\n            return value_set;\n        }\n\n        // \u6253\u5370\u54c8\u5e0c\u8868\n        pub fn print(self: *Self) !void {\n            var entry_set = try self.pairSet();\n            defer entry_set.deinit();\n            for (entry_set.items) |item| {\n                std.debug.print(\"{} -> {s}\\n\", .{item.key, item.val});\n            }\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_hashing/hash_map/#613","title":"6.1.3 \u00a0 \u54c8\u5e0c\u51b2\u7a81\u4e0e\u6269\u5bb9","text":"

    \u4ece\u672c\u8d28\u4e0a\u770b\uff0c\u54c8\u5e0c\u51fd\u6570\u7684\u4f5c\u7528\u662f\u5c06\u6240\u6709 key \u6784\u6210\u7684\u8f93\u5165\u7a7a\u95f4\u6620\u5c04\u5230\u6570\u7ec4\u6240\u6709\u7d22\u5f15\u6784\u6210\u7684\u8f93\u51fa\u7a7a\u95f4\uff0c\u800c\u8f93\u5165\u7a7a\u95f4\u5f80\u5f80\u8fdc\u5927\u4e8e\u8f93\u51fa\u7a7a\u95f4\u3002\u56e0\u6b64\uff0c\u7406\u8bba\u4e0a\u4e00\u5b9a\u5b58\u5728\u201c\u591a\u4e2a\u8f93\u5165\u5bf9\u5e94\u76f8\u540c\u8f93\u51fa\u201d\u7684\u60c5\u51b5\u3002

    \u5bf9\u4e8e\u4e0a\u8ff0\u793a\u4f8b\u4e2d\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u5f53\u8f93\u5165\u7684 key \u540e\u4e24\u4f4d\u76f8\u540c\u65f6\uff0c\u54c8\u5e0c\u51fd\u6570\u7684\u8f93\u51fa\u7ed3\u679c\u4e5f\u76f8\u540c\u3002\u4f8b\u5982\uff0c\u67e5\u8be2\u5b66\u53f7\u4e3a 12836 \u548c 20336 \u7684\u4e24\u4e2a\u5b66\u751f\u65f6\uff0c\u6211\u4eec\u5f97\u5230\uff1a

    12836 % 100 = 36\n20336 % 100 = 36\n

    \u5982\u56fe 6-3 \u6240\u793a\uff0c\u4e24\u4e2a\u5b66\u53f7\u6307\u5411\u4e86\u540c\u4e00\u4e2a\u59d3\u540d\uff0c\u8fd9\u663e\u7136\u662f\u4e0d\u5bf9\u7684\u3002\u6211\u4eec\u5c06\u8fd9\u79cd\u591a\u4e2a\u8f93\u5165\u5bf9\u5e94\u540c\u4e00\u8f93\u51fa\u7684\u60c5\u51b5\u79f0\u4e3a\u54c8\u5e0c\u51b2\u7a81\uff08hash collision\uff09\u3002

    \u56fe 6-3 \u00a0 \u54c8\u5e0c\u51b2\u7a81\u793a\u4f8b

    \u5bb9\u6613\u60f3\u5230\uff0c\u54c8\u5e0c\u8868\u5bb9\u91cf \\(n\\) \u8d8a\u5927\uff0c\u591a\u4e2a key \u88ab\u5206\u914d\u5230\u540c\u4e00\u4e2a\u6876\u4e2d\u7684\u6982\u7387\u5c31\u8d8a\u4f4e\uff0c\u51b2\u7a81\u5c31\u8d8a\u5c11\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6269\u5bb9\u54c8\u5e0c\u8868\u6765\u51cf\u5c11\u54c8\u5e0c\u51b2\u7a81\u3002

    \u5982\u56fe 6-4 \u6240\u793a\uff0c\u6269\u5bb9\u524d\u952e\u503c\u5bf9 (136, A) \u548c (236, D) \u53d1\u751f\u51b2\u7a81\uff0c\u6269\u5bb9\u540e\u51b2\u7a81\u6d88\u5931\u3002

    \u56fe 6-4 \u00a0 \u54c8\u5e0c\u8868\u6269\u5bb9

    \u7c7b\u4f3c\u4e8e\u6570\u7ec4\u6269\u5bb9\uff0c\u54c8\u5e0c\u8868\u6269\u5bb9\u9700\u5c06\u6240\u6709\u952e\u503c\u5bf9\u4ece\u539f\u54c8\u5e0c\u8868\u8fc1\u79fb\u81f3\u65b0\u54c8\u5e0c\u8868\uff0c\u975e\u5e38\u8017\u65f6\uff1b\u5e76\u4e14\u7531\u4e8e\u54c8\u5e0c\u8868\u5bb9\u91cf capacity \u6539\u53d8\uff0c\u6211\u4eec\u9700\u8981\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u6765\u91cd\u65b0\u8ba1\u7b97\u6240\u6709\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u4f4d\u7f6e\uff0c\u8fd9\u8fdb\u4e00\u6b65\u589e\u52a0\u4e86\u6269\u5bb9\u8fc7\u7a0b\u7684\u8ba1\u7b97\u5f00\u9500\u3002\u4e3a\u6b64\uff0c\u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u4f1a\u9884\u7559\u8db3\u591f\u5927\u7684\u54c8\u5e0c\u8868\u5bb9\u91cf\uff0c\u9632\u6b62\u9891\u7e41\u6269\u5bb9\u3002

    \u8d1f\u8f7d\u56e0\u5b50\uff08load factor\uff09\u662f\u54c8\u5e0c\u8868\u7684\u4e00\u4e2a\u91cd\u8981\u6982\u5ff5\uff0c\u5176\u5b9a\u4e49\u4e3a\u54c8\u5e0c\u8868\u7684\u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u6570\u91cf\uff0c\u7528\u4e8e\u8861\u91cf\u54c8\u5e0c\u51b2\u7a81\u7684\u4e25\u91cd\u7a0b\u5ea6\uff0c\u4e5f\u5e38\u4f5c\u4e3a\u54c8\u5e0c\u8868\u6269\u5bb9\u7684\u89e6\u53d1\u6761\u4ef6\u3002\u4f8b\u5982\u5728 Java \u4e2d\uff0c\u5f53\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7 \\(0.75\\) \u65f6\uff0c\u7cfb\u7edf\u4f1a\u5c06\u54c8\u5e0c\u8868\u6269\u5bb9\u81f3\u539f\u5148\u7684 \\(2\\) \u500d\u3002

    "},{"location":"chapter_hashing/summary/","title":"6.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_hashing/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u8f93\u5165 key \uff0c\u54c8\u5e0c\u8868\u80fd\u591f\u5728 \\(O(1)\\) \u65f6\u95f4\u5185\u67e5\u8be2\u5230 value \uff0c\u6548\u7387\u975e\u5e38\u9ad8\u3002
    • \u5e38\u89c1\u7684\u54c8\u5e0c\u8868\u64cd\u4f5c\u5305\u62ec\u67e5\u8be2\u3001\u6dfb\u52a0\u952e\u503c\u5bf9\u3001\u5220\u9664\u952e\u503c\u5bf9\u548c\u904d\u5386\u54c8\u5e0c\u8868\u7b49\u3002
    • \u54c8\u5e0c\u51fd\u6570\u5c06 key \u6620\u5c04\u4e3a\u6570\u7ec4\u7d22\u5f15\uff0c\u4ece\u800c\u8bbf\u95ee\u5bf9\u5e94\u6876\u5e76\u83b7\u53d6 value \u3002
    • \u4e24\u4e2a\u4e0d\u540c\u7684 key \u53ef\u80fd\u5728\u7ecf\u8fc7\u54c8\u5e0c\u51fd\u6570\u540e\u5f97\u5230\u76f8\u540c\u7684\u6570\u7ec4\u7d22\u5f15\uff0c\u5bfc\u81f4\u67e5\u8be2\u7ed3\u679c\u51fa\u9519\uff0c\u8fd9\u79cd\u73b0\u8c61\u88ab\u79f0\u4e3a\u54c8\u5e0c\u51b2\u7a81\u3002
    • \u54c8\u5e0c\u8868\u5bb9\u91cf\u8d8a\u5927\uff0c\u54c8\u5e0c\u51b2\u7a81\u7684\u6982\u7387\u5c31\u8d8a\u4f4e\u3002\u56e0\u6b64\u53ef\u4ee5\u901a\u8fc7\u6269\u5bb9\u54c8\u5e0c\u8868\u6765\u7f13\u89e3\u54c8\u5e0c\u51b2\u7a81\u3002\u4e0e\u6570\u7ec4\u6269\u5bb9\u7c7b\u4f3c\uff0c\u54c8\u5e0c\u8868\u6269\u5bb9\u64cd\u4f5c\u7684\u5f00\u9500\u5f88\u5927\u3002
    • \u8d1f\u8f7d\u56e0\u5b50\u5b9a\u4e49\u4e3a\u54c8\u5e0c\u8868\u4e2d\u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u6570\u91cf\uff0c\u53cd\u6620\u4e86\u54c8\u5e0c\u51b2\u7a81\u7684\u4e25\u91cd\u7a0b\u5ea6\uff0c\u5e38\u7528\u4f5c\u89e6\u53d1\u54c8\u5e0c\u8868\u6269\u5bb9\u7684\u6761\u4ef6\u3002
    • \u94fe\u5f0f\u5730\u5740\u901a\u8fc7\u5c06\u5355\u4e2a\u5143\u7d20\u8f6c\u5316\u4e3a\u94fe\u8868\uff0c\u5c06\u6240\u6709\u51b2\u7a81\u5143\u7d20\u5b58\u50a8\u5728\u540c\u4e00\u4e2a\u94fe\u8868\u4e2d\u3002\u7136\u800c\uff0c\u94fe\u8868\u8fc7\u957f\u4f1a\u964d\u4f4e\u67e5\u8be2\u6548\u7387\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fdb\u4e00\u6b65\u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u6765\u63d0\u9ad8\u6548\u7387\u3002
    • \u5f00\u653e\u5bfb\u5740\u901a\u8fc7\u591a\u6b21\u63a2\u6d4b\u6765\u5904\u7406\u54c8\u5e0c\u51b2\u7a81\u3002\u7ebf\u6027\u63a2\u6d4b\u4f7f\u7528\u56fa\u5b9a\u6b65\u957f\uff0c\u7f3a\u70b9\u662f\u4e0d\u80fd\u5220\u9664\u5143\u7d20\uff0c\u4e14\u5bb9\u6613\u4ea7\u751f\u805a\u96c6\u3002\u591a\u6b21\u54c8\u5e0c\u4f7f\u7528\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570\u8fdb\u884c\u63a2\u6d4b\uff0c\u76f8\u8f83\u7ebf\u6027\u63a2\u6d4b\u66f4\u4e0d\u6613\u4ea7\u751f\u805a\u96c6\uff0c\u4f46\u591a\u4e2a\u54c8\u5e0c\u51fd\u6570\u589e\u52a0\u4e86\u8ba1\u7b97\u91cf\u3002
    • \u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u91c7\u53d6\u4e86\u4e0d\u540c\u7684\u54c8\u5e0c\u8868\u5b9e\u73b0\u3002\u4f8b\u5982\uff0cJava \u7684 HashMap \u4f7f\u7528\u94fe\u5f0f\u5730\u5740\uff0c\u800c Python \u7684 Dict \u91c7\u7528\u5f00\u653e\u5bfb\u5740\u3002
    • \u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u6211\u4eec\u5e0c\u671b\u54c8\u5e0c\u7b97\u6cd5\u5177\u6709\u786e\u5b9a\u6027\u3001\u9ad8\u6548\u7387\u548c\u5747\u5300\u5206\u5e03\u7684\u7279\u70b9\u3002\u5728\u5bc6\u7801\u5b66\u4e2d\uff0c\u54c8\u5e0c\u7b97\u6cd5\u8fd8\u5e94\u8be5\u5177\u5907\u6297\u78b0\u649e\u6027\u548c\u96ea\u5d29\u6548\u5e94\u3002
    • \u54c8\u5e0c\u7b97\u6cd5\u901a\u5e38\u91c7\u7528\u5927\u8d28\u6570\u4f5c\u4e3a\u6a21\u6570\uff0c\u4ee5\u6700\u5927\u5316\u5730\u4fdd\u8bc1\u54c8\u5e0c\u503c\u5747\u5300\u5206\u5e03\uff0c\u51cf\u5c11\u54c8\u5e0c\u51b2\u7a81\u3002
    • \u5e38\u89c1\u7684\u54c8\u5e0c\u7b97\u6cd5\u5305\u62ec MD5\u3001SHA-1\u3001SHA-2 \u548c SHA-3 \u7b49\u3002MD5 \u5e38\u7528\u4e8e\u6821\u9a8c\u6587\u4ef6\u5b8c\u6574\u6027\uff0cSHA-2 \u5e38\u7528\u4e8e\u5b89\u5168\u5e94\u7528\u4e0e\u534f\u8bae\u3002
    • \u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u4f1a\u4e3a\u6570\u636e\u7c7b\u578b\u63d0\u4f9b\u5185\u7f6e\u54c8\u5e0c\u7b97\u6cd5\uff0c\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u8868\u4e2d\u7684\u6876\u7d22\u5f15\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u53ea\u6709\u4e0d\u53ef\u53d8\u5bf9\u8c61\u662f\u53ef\u54c8\u5e0c\u7684\u3002
    "},{"location":"chapter_hashing/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u662f \\(O(n)\\) \uff1f

    \u5f53\u54c8\u5e0c\u51b2\u7a81\u6bd4\u8f83\u4e25\u91cd\u65f6\uff0c\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u9000\u5316\u81f3 \\(O(n)\\) \u3002\u5f53\u54c8\u5e0c\u51fd\u6570\u8bbe\u8ba1\u5f97\u6bd4\u8f83\u597d\u3001\u5bb9\u91cf\u8bbe\u7f6e\u6bd4\u8f83\u5408\u7406\u3001\u51b2\u7a81\u6bd4\u8f83\u5e73\u5747\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u3002\u6211\u4eec\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u5185\u7f6e\u7684\u54c8\u5e0c\u8868\u65f6\uff0c\u901a\u5e38\u8ba4\u4e3a\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(1)\\) \u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u4e0d\u4f7f\u7528\u54c8\u5e0c\u51fd\u6570 \\(f(x) = x\\) \u5462\uff1f\u8fd9\u6837\u5c31\u4e0d\u4f1a\u6709\u51b2\u7a81\u4e86\u3002

    \u5728 \\(f(x) = x\\) \u54c8\u5e0c\u51fd\u6570\u4e0b\uff0c\u6bcf\u4e2a\u5143\u7d20\u5bf9\u5e94\u552f\u4e00\u7684\u6876\u7d22\u5f15\uff0c\u8fd9\u4e0e\u6570\u7ec4\u7b49\u4ef7\u3002\u7136\u800c\uff0c\u8f93\u5165\u7a7a\u95f4\u901a\u5e38\u8fdc\u5927\u4e8e\u8f93\u51fa\u7a7a\u95f4\uff08\u6570\u7ec4\u957f\u5ea6\uff09\uff0c\u56e0\u6b64\u54c8\u5e0c\u51fd\u6570\u7684\u6700\u540e\u4e00\u6b65\u5f80\u5f80\u662f\u5bf9\u6570\u7ec4\u957f\u5ea6\u53d6\u6a21\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u54c8\u5e0c\u8868\u7684\u76ee\u6807\u662f\u5c06\u4e00\u4e2a\u8f83\u5927\u7684\u72b6\u6001\u7a7a\u95f4\u6620\u5c04\u5230\u4e00\u4e2a\u8f83\u5c0f\u7684\u7a7a\u95f4\uff0c\u5e76\u63d0\u4f9b \\(O(1)\\) \u7684\u67e5\u8be2\u6548\u7387\u3002

    Q\uff1a\u54c8\u5e0c\u8868\u5e95\u5c42\u5b9e\u73b0\u662f\u6570\u7ec4\u3001\u94fe\u8868\u3001\u4e8c\u53c9\u6811\uff0c\u4f46\u4e3a\u4ec0\u4e48\u6548\u7387\u53ef\u4ee5\u6bd4\u5b83\u4eec\u66f4\u9ad8\u5462\uff1f

    \u9996\u5148\uff0c\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u6548\u7387\u53d8\u9ad8\uff0c\u4f46\u7a7a\u95f4\u6548\u7387\u53d8\u4f4e\u4e86\u3002\u54c8\u5e0c\u8868\u6709\u76f8\u5f53\u4e00\u90e8\u5206\u5185\u5b58\u672a\u4f7f\u7528\u3002

    \u5176\u6b21\uff0c\u53ea\u662f\u5728\u7279\u5b9a\u4f7f\u7528\u573a\u666f\u4e0b\u65f6\u95f4\u6548\u7387\u53d8\u9ad8\u4e86\u3002\u5982\u679c\u4e00\u4e2a\u529f\u80fd\u80fd\u591f\u5728\u76f8\u540c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e0b\u4f7f\u7528\u6570\u7ec4\u6216\u94fe\u8868\u5b9e\u73b0\uff0c\u90a3\u4e48\u901a\u5e38\u6bd4\u54c8\u5e0c\u8868\u66f4\u5feb\u3002\u8fd9\u662f\u56e0\u4e3a\u54c8\u5e0c\u51fd\u6570\u8ba1\u7b97\u9700\u8981\u5f00\u9500\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u7684\u5e38\u6570\u9879\u66f4\u5927\u3002

    \u6700\u540e\uff0c\u54c8\u5e0c\u8868\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u80fd\u53d1\u751f\u52a3\u5316\u3002\u4f8b\u5982\u5728\u94fe\u5f0f\u5730\u5740\u4e2d\uff0c\u6211\u4eec\u91c7\u53d6\u5728\u94fe\u8868\u6216\u7ea2\u9ed1\u6811\u4e2d\u6267\u884c\u67e5\u627e\u64cd\u4f5c\uff0c\u4ecd\u7136\u6709\u9000\u5316\u81f3 \\(O(n)\\) \u65f6\u95f4\u7684\u98ce\u9669\u3002

    Q\uff1a\u591a\u6b21\u54c8\u5e0c\u6709\u4e0d\u80fd\u76f4\u63a5\u5220\u9664\u5143\u7d20\u7684\u7f3a\u9677\u5417\uff1f\u6807\u8bb0\u4e3a\u5df2\u5220\u9664\u7684\u7a7a\u95f4\u8fd8\u80fd\u518d\u6b21\u4f7f\u7528\u5417\uff1f

    \u591a\u6b21\u54c8\u5e0c\u662f\u5f00\u653e\u5bfb\u5740\u7684\u4e00\u79cd\uff0c\u5f00\u653e\u5bfb\u5740\u6cd5\u90fd\u6709\u4e0d\u80fd\u76f4\u63a5\u5220\u9664\u5143\u7d20\u7684\u7f3a\u9677\uff0c\u9700\u8981\u901a\u8fc7\u6807\u8bb0\u5220\u9664\u3002\u6807\u8bb0\u4e3a\u5df2\u5220\u9664\u7684\u7a7a\u95f4\u53ef\u4ee5\u518d\u6b21\u4f7f\u7528\u3002\u5f53\u5c06\u65b0\u5143\u7d20\u63d2\u5165\u54c8\u5e0c\u8868\uff0c\u5e76\u4e14\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u627e\u5230\u6807\u8bb0\u4e3a\u5df2\u5220\u9664\u7684\u4f4d\u7f6e\u65f6\uff0c\u8be5\u4f4d\u7f6e\u53ef\u4ee5\u88ab\u65b0\u5143\u7d20\u4f7f\u7528\u3002\u8fd9\u6837\u505a\u65e2\u80fd\u4fdd\u6301\u54c8\u5e0c\u8868\u7684\u63a2\u6d4b\u5e8f\u5217\u4e0d\u53d8\uff0c\u53c8\u80fd\u4fdd\u8bc1\u54c8\u5e0c\u8868\u7684\u7a7a\u95f4\u4f7f\u7528\u7387\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u5728\u7ebf\u6027\u63a2\u6d4b\u4e2d\uff0c\u67e5\u627e\u5143\u7d20\u7684\u65f6\u5019\u4f1a\u51fa\u73b0\u54c8\u5e0c\u51b2\u7a81\u5462\uff1f

    \u67e5\u627e\u7684\u65f6\u5019\u901a\u8fc7\u54c8\u5e0c\u51fd\u6570\u627e\u5230\u5bf9\u5e94\u7684\u6876\u548c\u952e\u503c\u5bf9\uff0c\u53d1\u73b0 key \u4e0d\u5339\u914d\uff0c\u8fd9\u5c31\u4ee3\u8868\u6709\u54c8\u5e0c\u51b2\u7a81\u3002\u56e0\u6b64\uff0c\u7ebf\u6027\u63a2\u6d4b\u6cd5\u4f1a\u6839\u636e\u9884\u5148\u8bbe\u5b9a\u7684\u6b65\u957f\u4f9d\u6b21\u5411\u4e0b\u67e5\u627e\uff0c\u76f4\u81f3\u627e\u5230\u6b63\u786e\u7684\u952e\u503c\u5bf9\u6216\u65e0\u6cd5\u627e\u5230\u8df3\u51fa\u4e3a\u6b62\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48\u54c8\u5e0c\u8868\u6269\u5bb9\u80fd\u591f\u7f13\u89e3\u54c8\u5e0c\u51b2\u7a81\uff1f

    \u54c8\u5e0c\u51fd\u6570\u7684\u6700\u540e\u4e00\u6b65\u5f80\u5f80\u662f\u5bf9\u6570\u7ec4\u957f\u5ea6 \\(n\\) \u53d6\u6a21\uff08\u53d6\u4f59\uff09\uff0c\u8ba9\u8f93\u51fa\u503c\u843d\u5728\u6570\u7ec4\u7d22\u5f15\u8303\u56f4\u5185\uff1b\u5728\u6269\u5bb9\u540e\uff0c\u6570\u7ec4\u957f\u5ea6 \\(n\\) \u53d1\u751f\u53d8\u5316\uff0c\u800c key \u5bf9\u5e94\u7684\u7d22\u5f15\u4e5f\u53ef\u80fd\u53d1\u751f\u53d8\u5316\u3002\u539f\u5148\u843d\u5728\u540c\u4e00\u4e2a\u6876\u7684\u591a\u4e2a key \uff0c\u5728\u6269\u5bb9\u540e\u53ef\u80fd\u4f1a\u88ab\u5206\u914d\u5230\u591a\u4e2a\u6876\u4e2d\uff0c\u4ece\u800c\u5b9e\u73b0\u54c8\u5e0c\u51b2\u7a81\u7684\u7f13\u89e3\u3002

    "},{"location":"chapter_heap/","title":"\u7b2c 8 \u7ae0 \u00a0 \u5806","text":"

    Abstract

    \u5806\u5c31\u50cf\u662f\u5c71\u5cb3\u5cf0\u5ce6\uff0c\u5c42\u53e0\u8d77\u4f0f\u3001\u5f62\u6001\u5404\u5f02\u3002

    \u5ea7\u5ea7\u5c71\u5cf0\u9ad8\u4f4e\u9519\u843d\uff0c\u800c\u6700\u9ad8\u7684\u5c71\u5cf0\u603b\u662f\u6700\u5148\u6620\u5165\u773c\u5e18\u3002

    "},{"location":"chapter_heap/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 8.1 \u00a0 \u5806
    • 8.2 \u00a0 \u5efa\u5806\u64cd\u4f5c
    • 8.3 \u00a0 Top-k \u95ee\u9898
    • 8.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_heap/build_heap/","title":"8.2 \u00a0 \u5efa\u5806\u64cd\u4f5c","text":"

    \u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5e0c\u671b\u4f7f\u7528\u4e00\u4e2a\u5217\u8868\u7684\u6240\u6709\u5143\u7d20\u6765\u6784\u5efa\u4e00\u4e2a\u5806\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u88ab\u79f0\u4e3a\u201c\u5efa\u5806\u64cd\u4f5c\u201d\u3002

    "},{"location":"chapter_heap/build_heap/#821","title":"8.2.1 \u00a0 \u501f\u52a9\u5165\u5806\u64cd\u4f5c\u5b9e\u73b0","text":"

    \u6211\u4eec\u9996\u5148\u521b\u5efa\u4e00\u4e2a\u7a7a\u5806\uff0c\u7136\u540e\u904d\u5386\u5217\u8868\uff0c\u4f9d\u6b21\u5bf9\u6bcf\u4e2a\u5143\u7d20\u6267\u884c\u201c\u5165\u5806\u64cd\u4f5c\u201d\uff0c\u5373\u5148\u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u5806\u7684\u5c3e\u90e8\uff0c\u518d\u5bf9\u8be5\u5143\u7d20\u6267\u884c\u201c\u4ece\u5e95\u81f3\u9876\u201d\u5806\u5316\u3002

    \u6bcf\u5f53\u4e00\u4e2a\u5143\u7d20\u5165\u5806\uff0c\u5806\u7684\u957f\u5ea6\u5c31\u52a0\u4e00\u3002\u7531\u4e8e\u8282\u70b9\u662f\u4ece\u9876\u5230\u5e95\u4f9d\u6b21\u88ab\u6dfb\u52a0\u8fdb\u4e8c\u53c9\u6811\u7684\uff0c\u56e0\u6b64\u5806\u662f\u201c\u81ea\u4e0a\u800c\u4e0b\u201d\u6784\u5efa\u7684\u3002

    \u8bbe\u5143\u7d20\u6570\u91cf\u4e3a \\(n\\) \uff0c\u6bcf\u4e2a\u5143\u7d20\u7684\u5165\u5806\u64cd\u4f5c\u4f7f\u7528 \\(O(\\log{n})\\) \u65f6\u95f4\uff0c\u56e0\u6b64\u8be5\u5efa\u5806\u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    "},{"location":"chapter_heap/build_heap/#822","title":"8.2.2 \u00a0 \u901a\u8fc7\u904d\u5386\u5806\u5316\u5b9e\u73b0","text":"

    \u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9e\u73b0\u4e00\u79cd\u66f4\u4e3a\u9ad8\u6548\u7684\u5efa\u5806\u65b9\u6cd5\uff0c\u5171\u5206\u4e3a\u4e24\u6b65\u3002

    1. \u5c06\u5217\u8868\u6240\u6709\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u5730\u6dfb\u52a0\u5230\u5806\u4e2d\uff0c\u6b64\u65f6\u5806\u7684\u6027\u8d28\u5c1a\u672a\u5f97\u5230\u6ee1\u8db3\u3002
    2. \u5012\u5e8f\u904d\u5386\u5806\uff08\u5c42\u5e8f\u904d\u5386\u7684\u5012\u5e8f\uff09\uff0c\u4f9d\u6b21\u5bf9\u6bcf\u4e2a\u975e\u53f6\u8282\u70b9\u6267\u884c\u201c\u4ece\u9876\u81f3\u5e95\u5806\u5316\u201d\u3002

    \u6bcf\u5f53\u5806\u5316\u4e00\u4e2a\u8282\u70b9\u540e\uff0c\u4ee5\u8be5\u8282\u70b9\u4e3a\u6839\u8282\u70b9\u7684\u5b50\u6811\u5c31\u5f62\u6210\u4e00\u4e2a\u5408\u6cd5\u7684\u5b50\u5806\u3002\u800c\u7531\u4e8e\u662f\u5012\u5e8f\u904d\u5386\uff0c\u56e0\u6b64\u5806\u662f\u201c\u81ea\u4e0b\u800c\u4e0a\u201d\u6784\u5efa\u7684\u3002

    \u4e4b\u6240\u4ee5\u9009\u62e9\u5012\u5e8f\u904d\u5386\uff0c\u662f\u56e0\u4e3a\u8fd9\u6837\u80fd\u591f\u4fdd\u8bc1\u5f53\u524d\u8282\u70b9\u4e4b\u4e0b\u7684\u5b50\u6811\u5df2\u7ecf\u662f\u5408\u6cd5\u7684\u5b50\u5806\uff0c\u8fd9\u6837\u5806\u5316\u5f53\u524d\u8282\u70b9\u624d\u662f\u6709\u6548\u7684\u3002

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u7531\u4e8e\u53f6\u8282\u70b9\u6ca1\u6709\u5b50\u8282\u70b9\uff0c\u56e0\u6b64\u5b83\u4eec\u5929\u7136\u5c31\u662f\u5408\u6cd5\u7684\u5b50\u5806\uff0c\u65e0\u987b\u5806\u5316\u3002\u5982\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\uff0c\u6700\u540e\u4e00\u4e2a\u975e\u53f6\u8282\u70b9\u662f\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u7684\u7236\u8282\u70b9\uff0c\u6211\u4eec\u4ece\u5b83\u5f00\u59cb\u5012\u5e8f\u904d\u5386\u5e76\u6267\u884c\u5806\u5316\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def __init__(self, nums: list[int]):\n    \"\"\"\u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\"\"\"\n    # \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    self.max_heap = nums\n    # \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(self.parent(self.size() - 1), -1, -1):\n        self.sift_down(i)\n
    my_heap.cpp
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(vector<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums;\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.java
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<Integer> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new ArrayList<>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = parent(size() - 1); i >= 0; i--) {\n        siftDown(i);\n    }\n}\n
    my_heap.cs
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(IEnumerable<int> nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = new List<int>(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var size = Parent(this.Size() - 1);\n    for (int i = size; i >= 0; i--) {\n        SiftDown(i);\n    }\n}\n
    my_heap.go
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nfunc newMaxHeap(nums []any) *maxHeap {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    h := &maxHeap{data: nums}\n    for i := h.parent(len(h.data) - 1); i >= 0; i-- {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        h.siftDown(i)\n    }\n    return h\n}\n
    my_heap.swift
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\ninit(nums: [Int]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    maxHeap = nums\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0 ... parent(i: size() - 1)).reversed() {\n        siftDown(i: i)\n    }\n}\n
    my_heap.js
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.#maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.#parent(this.size() - 1); i >= 0; i--) {\n        this.#siftDown(i);\n    }\n}\n
    my_heap.ts
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u5efa\u7acb\u7a7a\u5806\u6216\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nconstructor(nums?: number[]) {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    this.maxHeap = nums === undefined ? [] : [...nums];\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = this.parent(this.size() - 1); i >= 0; i--) {\n        this.siftDown(i);\n    }\n}\n
    my_heap.dart
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nMaxHeap(List<int> nums) {\n  // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n  _maxHeap = nums;\n  // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = _parent(size() - 1); i >= 0; i--) {\n    siftDown(i);\n  }\n}\n
    my_heap.rs
    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\nfn new(nums: Vec<i32>) -> Self {\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    let mut heap = MaxHeap { max_heap: nums };\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=Self::parent(heap.size() - 1)).rev() {\n        heap.sift_down(i);\n    }\n    heap\n}\n
    my_heap.c
    /* \u6784\u9020\u51fd\u6570\uff0c\u6839\u636e\u5207\u7247\u5efa\u5806 */\nMaxHeap *newMaxHeap(int nums[], int size) {\n    // \u6240\u6709\u5143\u7d20\u5165\u5806\n    MaxHeap *maxHeap = (MaxHeap *)malloc(sizeof(MaxHeap));\n    maxHeap->size = size;\n    memcpy(maxHeap->data, nums, size * sizeof(int));\n    for (int i = parent(maxHeap, size - 1); i >= 0; i--) {\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        siftDown(maxHeap, i);\n    }\n    return maxHeap;\n}\n
    my_heap.kt
    /* \u5927\u9876\u5806 */\nclass MaxHeap(nums: MutableList<Int>?) {\n    // \u4f7f\u7528\u5217\u8868\u800c\u975e\u6570\u7ec4\uff0c\u8fd9\u6837\u65e0\u987b\u8003\u8651\u6269\u5bb9\u95ee\u9898\n    private val maxHeap = mutableListOf<Int>()\n\n    /* \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806 */\n    init {\n        // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n        maxHeap.addAll(nums!!)\n        // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n        for (i in parent(size() - 1) downTo 0) {\n            siftDown(i)\n        }\n    }\n\n    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    private fun parent(i: Int): Int {\n        return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u4ea4\u6362\u5143\u7d20 */\n    private fun swap(i: Int, j: Int) {\n        val temp = maxHeap[i]\n        maxHeap[i] = maxHeap[j]\n        maxHeap[j] = temp\n    }\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    fun size(): Int {\n        return maxHeap.size\n    }\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n        return size() == 0\n    }\n\n    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        return maxHeap[0]\n    }\n\n    /* \u5143\u7d20\u5165\u5806 */\n    fun push(_val: Int) {\n        // \u6dfb\u52a0\u8282\u70b9\n        maxHeap.add(_val)\n        // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n        siftUp(size() - 1)\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n    private fun siftUp(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n            val p = parent(i)\n            // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n            if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, p)\n            // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n            i = p\n        }\n    }\n\n    /* \u5143\u7d20\u51fa\u5806 */\n    fun pop(): Int {\n        // \u5224\u7a7a\u5904\u7406\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(0, size() - 1)\n        // \u5220\u9664\u8282\u70b9\n        val _val = maxHeap.removeAt(size() - 1)\n        // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n        siftDown(0)\n        // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n        return _val\n    }\n\n    /* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n    private fun siftDown(it: Int) {\n        // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n        var i = it\n        while (true) {\n            // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n            val l = left(i)\n            val r = right(i)\n            var ma = i\n            if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n            if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n            // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n            if (ma == i) break\n            // \u4ea4\u6362\u4e24\u8282\u70b9\n            swap(i, ma)\n            // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n            i = ma\n        }\n    }\n\n    /* \u6253\u5370\u5806\uff08\u4e8c\u53c9\u6811\uff09 */\n    fun print() {\n        val queue = PriorityQueue { a: Int, b: Int -> b - a }\n        queue.addAll(maxHeap)\n        printHeap(queue)\n    }\n}\n
    my_heap.rb
    [class]{MaxHeap}-[func]{__init__}\n
    my_heap.zig
    // \u6784\u9020\u65b9\u6cd5\uff0c\u6839\u636e\u8f93\u5165\u5217\u8868\u5efa\u5806\nfn init(self: *Self, allocator: std.mem.Allocator, nums: []const T) !void {\n    if (self.max_heap != null) return;\n    self.max_heap = std.ArrayList(T).init(allocator);\n    // \u5c06\u5217\u8868\u5143\u7d20\u539f\u5c01\u4e0d\u52a8\u6dfb\u52a0\u8fdb\u5806\n    try self.max_heap.?.appendSlice(nums);\n    // \u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    var i: usize = parent(self.size() - 1) + 1;\n    while (i > 0) : (i -= 1) {\n        try self.siftDown(i - 1);\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/build_heap/#823","title":"8.2.3 \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"

    \u4e0b\u9762\uff0c\u6211\u4eec\u6765\u5c1d\u8bd5\u63a8\u7b97\u7b2c\u4e8c\u79cd\u5efa\u5806\u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002

    • \u5047\u8bbe\u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(n\\) \uff0c\u5219\u53f6\u8282\u70b9\u6570\u91cf\u4e3a \\((n + 1) / 2\\) \uff0c\u5176\u4e2d \\(/\\) \u4e3a\u5411\u4e0b\u6574\u9664\u3002\u56e0\u6b64\u9700\u8981\u5806\u5316\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\((n - 1) / 2\\) \u3002
    • \u5728\u4ece\u9876\u81f3\u5e95\u5806\u5316\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u4e2a\u8282\u70b9\u6700\u591a\u5806\u5316\u5230\u53f6\u8282\u70b9\uff0c\u56e0\u6b64\u6700\u5927\u8fed\u4ee3\u6b21\u6570\u4e3a\u4e8c\u53c9\u6811\u9ad8\u5ea6 \\(\\log n\\) \u3002

    \u5c06\u4e0a\u8ff0\u4e24\u8005\u76f8\u4e58\uff0c\u53ef\u5f97\u5230\u5efa\u5806\u8fc7\u7a0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002\u4f46\u8fd9\u4e2a\u4f30\u7b97\u7ed3\u679c\u5e76\u4e0d\u51c6\u786e\uff0c\u56e0\u4e3a\u6211\u4eec\u6ca1\u6709\u8003\u8651\u5230\u4e8c\u53c9\u6811\u5e95\u5c42\u8282\u70b9\u6570\u91cf\u8fdc\u591a\u4e8e\u9876\u5c42\u8282\u70b9\u7684\u6027\u8d28\u3002

    \u63a5\u4e0b\u6765\u6211\u4eec\u6765\u8fdb\u884c\u66f4\u4e3a\u51c6\u786e\u7684\u8ba1\u7b97\u3002\u4e3a\u4e86\u964d\u4f4e\u8ba1\u7b97\u96be\u5ea6\uff0c\u5047\u8bbe\u7ed9\u5b9a\u4e00\u4e2a\u8282\u70b9\u6570\u91cf\u4e3a \\(n\\) \u3001\u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u201c\u5b8c\u7f8e\u4e8c\u53c9\u6811\u201d\uff0c\u8be5\u5047\u8bbe\u4e0d\u4f1a\u5f71\u54cd\u8ba1\u7b97\u7ed3\u679c\u7684\u6b63\u786e\u6027\u3002

    \u56fe 8-5 \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811\u7684\u5404\u5c42\u8282\u70b9\u6570\u91cf

    \u5982\u56fe 8-5 \u6240\u793a\uff0c\u8282\u70b9\u201c\u4ece\u9876\u81f3\u5e95\u5806\u5316\u201d\u7684\u6700\u5927\u8fed\u4ee3\u6b21\u6570\u7b49\u4e8e\u8be5\u8282\u70b9\u5230\u53f6\u8282\u70b9\u7684\u8ddd\u79bb\uff0c\u800c\u8be5\u8ddd\u79bb\u6b63\u662f\u201c\u8282\u70b9\u9ad8\u5ea6\u201d\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5bf9\u5404\u5c42\u7684\u201c\u8282\u70b9\u6570\u91cf \\(\\times\\) \u8282\u70b9\u9ad8\u5ea6\u201d\u6c42\u548c\uff0c\u5f97\u5230\u6240\u6709\u8282\u70b9\u7684\u5806\u5316\u8fed\u4ee3\u6b21\u6570\u7684\u603b\u548c\u3002

    \\[ T(h) = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{(h-1)}\\times1 \\]

    \u5316\u7b80\u4e0a\u5f0f\u9700\u8981\u501f\u52a9\u4e2d\u5b66\u7684\u6570\u5217\u77e5\u8bc6\uff0c\u5148\u5c06 \\(T(h)\\) \u4e58\u4ee5 \\(2\\) \uff0c\u5f97\u5230\uff1a

    \\[ \\begin{aligned} T(h) & = 2^0h + 2^1(h-1) + 2^2(h-2) + \\dots + 2^{h-1}\\times1 \\newline 2 T(h) & = 2^1h + 2^2(h-1) + 2^3(h-2) + \\dots + 2^{h}\\times1 \\newline \\end{aligned} \\]

    \u4f7f\u7528\u9519\u4f4d\u76f8\u51cf\u6cd5\uff0c\u7528\u4e0b\u5f0f \\(2 T(h)\\) \u51cf\u53bb\u4e0a\u5f0f \\(T(h)\\) \uff0c\u53ef\u5f97\uff1a

    \\[ 2T(h) - T(h) = T(h) = -2^0h + 2^1 + 2^2 + \\dots + 2^{h-1} + 2^h \\]

    \u89c2\u5bdf\u4e0a\u5f0f\uff0c\u53d1\u73b0 \\(T(h)\\) \u662f\u4e00\u4e2a\u7b49\u6bd4\u6570\u5217\uff0c\u53ef\u76f4\u63a5\u4f7f\u7528\u6c42\u548c\u516c\u5f0f\uff0c\u5f97\u5230\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\uff1a

    \\[ \\begin{aligned} T(h) & = 2 \\frac{1 - 2^h}{1 - 2} - h \\newline & = 2^{h+1} - h - 2 \\newline & = O(2^h) \\end{aligned} \\]

    \u8fdb\u4e00\u6b65\uff0c\u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u5b8c\u7f8e\u4e8c\u53c9\u6811\u7684\u8282\u70b9\u6570\u91cf\u4e3a \\(n = 2^{h+1} - 1\\) \uff0c\u6613\u5f97\u590d\u6742\u5ea6\u4e3a \\(O(2^h) = O(n)\\) \u3002\u4ee5\u4e0a\u63a8\u7b97\u8868\u660e\uff0c\u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u975e\u5e38\u9ad8\u6548\u3002

    "},{"location":"chapter_heap/heap/","title":"8.1 \u00a0 \u5806","text":"

    \u5806\uff08heap\uff09\u662f\u4e00\u79cd\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u7684\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u4e3b\u8981\u53ef\u5206\u4e3a\u4e24\u79cd\u7c7b\u578b\uff0c\u5982\u56fe 8-1 \u6240\u793a\u3002

    • \u5c0f\u9876\u5806\uff08min heap\uff09\uff1a\u4efb\u610f\u8282\u70b9\u7684\u503c \\(\\leq\\) \u5176\u5b50\u8282\u70b9\u7684\u503c\u3002
    • \u5927\u9876\u5806\uff08max heap\uff09\uff1a\u4efb\u610f\u8282\u70b9\u7684\u503c \\(\\geq\\) \u5176\u5b50\u8282\u70b9\u7684\u503c\u3002

    \u56fe 8-1 \u00a0 \u5c0f\u9876\u5806\u4e0e\u5927\u9876\u5806

    \u5806\u4f5c\u4e3a\u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u4e00\u4e2a\u7279\u4f8b\uff0c\u5177\u6709\u4ee5\u4e0b\u7279\u6027\u3002

    • \u6700\u5e95\u5c42\u8282\u70b9\u9760\u5de6\u586b\u5145\uff0c\u5176\u4ed6\u5c42\u7684\u8282\u70b9\u90fd\u88ab\u586b\u6ee1\u3002
    • \u6211\u4eec\u5c06\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\u79f0\u4e3a\u201c\u5806\u9876\u201d\uff0c\u5c06\u5e95\u5c42\u6700\u9760\u53f3\u7684\u8282\u70b9\u79f0\u4e3a\u201c\u5806\u5e95\u201d\u3002
    • \u5bf9\u4e8e\u5927\u9876\u5806\uff08\u5c0f\u9876\u5806\uff09\uff0c\u5806\u9876\u5143\u7d20\uff08\u6839\u8282\u70b9\uff09\u7684\u503c\u662f\u6700\u5927\uff08\u6700\u5c0f\uff09\u7684\u3002
    "},{"location":"chapter_heap/heap/#811","title":"8.1.1 \u00a0 \u5806\u7684\u5e38\u7528\u64cd\u4f5c","text":"

    \u9700\u8981\u6307\u51fa\u7684\u662f\uff0c\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u7684\u662f\u4f18\u5148\u961f\u5217\uff08priority queue\uff09\uff0c\u8fd9\u662f\u4e00\u79cd\u62bd\u8c61\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5b9a\u4e49\u4e3a\u5177\u6709\u4f18\u5148\u7ea7\u6392\u5e8f\u7684\u961f\u5217\u3002

    \u5b9e\u9645\u4e0a\uff0c\u5806\u901a\u5e38\u7528\u4e8e\u5b9e\u73b0\u4f18\u5148\u961f\u5217\uff0c\u5927\u9876\u5806\u76f8\u5f53\u4e8e\u5143\u7d20\u6309\u4ece\u5927\u5230\u5c0f\u7684\u987a\u5e8f\u51fa\u961f\u7684\u4f18\u5148\u961f\u5217\u3002\u4ece\u4f7f\u7528\u89d2\u5ea6\u6765\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u201c\u4f18\u5148\u961f\u5217\u201d\u548c\u201c\u5806\u201d\u770b\u4f5c\u7b49\u4ef7\u7684\u6570\u636e\u7ed3\u6784\u3002\u56e0\u6b64\uff0c\u672c\u4e66\u5bf9\u4e24\u8005\u4e0d\u505a\u7279\u522b\u533a\u5206\uff0c\u7edf\u4e00\u79f0\u4f5c\u201c\u5806\u201d\u3002

    \u5806\u7684\u5e38\u7528\u64cd\u4f5c\u89c1\u8868 8-1 \uff0c\u65b9\u6cd5\u540d\u9700\u8981\u6839\u636e\u7f16\u7a0b\u8bed\u8a00\u6765\u786e\u5b9a\u3002

    \u8868 8-1 \u00a0 \u5806\u7684\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5\u540d \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push() \u5143\u7d20\u5165\u5806 \\(O(\\log n)\\) pop() \u5806\u9876\u5143\u7d20\u51fa\u5806 \\(O(\\log n)\\) peek() \u8bbf\u95ee\u5806\u9876\u5143\u7d20\uff08\u5bf9\u4e8e\u5927 / \u5c0f\u9876\u5806\u5206\u522b\u4e3a\u6700\u5927 / \u5c0f\u503c\uff09 \\(O(1)\\) size() \u83b7\u53d6\u5806\u7684\u5143\u7d20\u6570\u91cf \\(O(1)\\) isEmpty() \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a \\(O(1)\\)

    \u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u7684\u5806\u7c7b\uff08\u6216\u4f18\u5148\u961f\u5217\u7c7b\uff09\u3002

    \u7c7b\u4f3c\u4e8e\u6392\u5e8f\u7b97\u6cd5\u4e2d\u7684\u201c\u4ece\u5c0f\u5230\u5927\u6392\u5217\u201d\u548c\u201c\u4ece\u5927\u5230\u5c0f\u6392\u5217\u201d\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e\u4e00\u4e2a flag \u6216\u4fee\u6539 Comparator \u5b9e\u73b0\u201c\u5c0f\u9876\u5806\u201d\u4e0e\u201c\u5927\u9876\u5806\u201d\u4e4b\u95f4\u7684\u8f6c\u6362\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap.py
    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\nmin_heap, flag = [], 1\n# \u521d\u59cb\u5316\u5927\u9876\u5806\nmax_heap, flag = [], -1\n\n# Python \u7684 heapq \u6a21\u5757\u9ed8\u8ba4\u5b9e\u73b0\u5c0f\u9876\u5806\n# \u8003\u8651\u5c06\u201c\u5143\u7d20\u53d6\u8d1f\u201d\u540e\u518d\u5165\u5806\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5c06\u5927\u5c0f\u5173\u7cfb\u98a0\u5012\uff0c\u4ece\u800c\u5b9e\u73b0\u5927\u9876\u5806\n# \u5728\u672c\u793a\u4f8b\u4e2d\uff0cflag = 1 \u65f6\u5bf9\u5e94\u5c0f\u9876\u5806\uff0cflag = -1 \u65f6\u5bf9\u5e94\u5927\u9876\u5806\n\n# \u5143\u7d20\u5165\u5806\nheapq.heappush(max_heap, flag * 1)\nheapq.heappush(max_heap, flag * 3)\nheapq.heappush(max_heap, flag * 2)\nheapq.heappush(max_heap, flag * 5)\nheapq.heappush(max_heap, flag * 4)\n\n# \u83b7\u53d6\u5806\u9876\u5143\u7d20\npeek: int = flag * max_heap[0] # 5\n\n# \u5806\u9876\u5143\u7d20\u51fa\u5806\n# \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nval = flag * heapq.heappop(max_heap) # 5\nval = flag * heapq.heappop(max_heap) # 4\nval = flag * heapq.heappop(max_heap) # 3\nval = flag * heapq.heappop(max_heap) # 2\nval = flag * heapq.heappop(max_heap) # 1\n\n# \u83b7\u53d6\u5806\u5927\u5c0f\nsize: int = len(max_heap)\n\n# \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = not max_heap\n\n# \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806\nmin_heap: list[int] = [1, 3, 2, 5, 4]\nheapq.heapify(min_heap)\n
    heap.cpp
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\npriority_queue<int, vector<int>, greater<int>> minHeap;\n// \u521d\u59cb\u5316\u5927\u9876\u5806\npriority_queue<int, vector<int>, less<int>> maxHeap;\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.push(1);\nmaxHeap.push(3);\nmaxHeap.push(2);\nmaxHeap.push(5);\nmaxHeap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.top(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nmaxHeap.pop(); // 5\nmaxHeap.pop(); // 4\nmaxHeap.pop(); // 3\nmaxHeap.pop(); // 2\nmaxHeap.pop(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nvector<int> input{1, 3, 2, 5, 4};\npriority_queue<int, vector<int>, greater<int>> minHeap(input.begin(), input.end());\n
    heap.java
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nQueue<Integer> minHeap = new PriorityQueue<>();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1);\nmaxHeap.offer(3);\nmaxHeap.offer(2);\nmaxHeap.offer(5);\nmaxHeap.offer(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.peek(); // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll(); // 5\npeek = maxHeap.poll(); // 4\npeek = maxHeap.poll(); // 3\npeek = maxHeap.poll(); // 2\npeek = maxHeap.poll(); // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.size();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = maxHeap.isEmpty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<>(Arrays.asList(1, 3, 2, 5, 4));\n
    heap.cs
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nPriorityQueue<int, int> minHeap = new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nPriorityQueue<int, int> maxHeap = new(Comparer<int>.Create((x, y) => y - x));\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.Enqueue(1, 1);\nmaxHeap.Enqueue(3, 3);\nmaxHeap.Enqueue(2, 2);\nmaxHeap.Enqueue(5, 5);\nmaxHeap.Enqueue(4, 4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nint peek = maxHeap.Peek();//5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.Dequeue();  // 5\npeek = maxHeap.Dequeue();  // 4\npeek = maxHeap.Dequeue();  // 3\npeek = maxHeap.Dequeue();  // 2\npeek = maxHeap.Dequeue();  // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nint size = maxHeap.Count;\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = maxHeap.Count == 0;\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = new PriorityQueue<int, int>([(1, 1), (3, 3), (2, 2), (5, 5), (4, 4)]);\n
    heap.go
    // Go \u8bed\u8a00\u4e2d\u53ef\u4ee5\u901a\u8fc7\u5b9e\u73b0 heap.Interface \u6765\u6784\u5efa\u6574\u6570\u5927\u9876\u5806\n// \u5b9e\u73b0 heap.Interface \u9700\u8981\u540c\u65f6\u5b9e\u73b0 sort.Interface\ntype intHeap []any\n\n// Push heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u63a8\u5165\u5143\u7d20\u5230\u5806\nfunc (h *intHeap) Push(x any) {\n    // Push \u548c Pop \u4f7f\u7528 pointer receiver \u4f5c\u4e3a\u53c2\u6570\n    // \u56e0\u4e3a\u5b83\u4eec\u4e0d\u4ec5\u4f1a\u5bf9\u5207\u7247\u7684\u5185\u5bb9\u8fdb\u884c\u8c03\u6574\uff0c\u8fd8\u4f1a\u4fee\u6539\u5207\u7247\u7684\u957f\u5ea6\u3002\n    *h = append(*h, x.(int))\n}\n\n// Pop heap.Interface \u7684\u65b9\u6cd5\uff0c\u5b9e\u73b0\u5f39\u51fa\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Pop() any {\n    // \u5f85\u51fa\u5806\u5143\u7d20\u5b58\u653e\u5728\u6700\u540e\n    last := (*h)[len(*h)-1]\n    *h = (*h)[:len(*h)-1]\n    return last\n}\n\n// Len sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Len() int {\n    return len(*h)\n}\n\n// Less sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Less(i, j int) bool {\n    // \u5982\u679c\u5b9e\u73b0\u5c0f\u9876\u5806\uff0c\u5219\u9700\u8981\u8c03\u6574\u4e3a\u5c0f\u4e8e\u53f7\n    return (*h)[i].(int) > (*h)[j].(int)\n}\n\n// Swap sort.Interface \u7684\u65b9\u6cd5\nfunc (h *intHeap) Swap(i, j int) {\n    (*h)[i], (*h)[j] = (*h)[j], (*h)[i]\n}\n\n// Top \u83b7\u53d6\u5806\u9876\u5143\u7d20\nfunc (h *intHeap) Top() any {\n    return (*h)[0]\n}\n\n/* Driver Code */\nfunc TestHeap(t *testing.T) {\n    /* \u521d\u59cb\u5316\u5806 */\n    // \u521d\u59cb\u5316\u5927\u9876\u5806\n    maxHeap := &intHeap{}\n    heap.Init(maxHeap)\n    /* \u5143\u7d20\u5165\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u6dfb\u52a0\u5143\u7d20\n    heap.Push(maxHeap, 1)\n    heap.Push(maxHeap, 3)\n    heap.Push(maxHeap, 2)\n    heap.Push(maxHeap, 4)\n    heap.Push(maxHeap, 5)\n\n    /* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\n    top := maxHeap.Top()\n    fmt.Printf(\"\u5806\u9876\u5143\u7d20\u4e3a %d\\n\", top)\n\n    /* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n    // \u8c03\u7528 heap.Interface \u7684\u65b9\u6cd5\uff0c\u6765\u79fb\u9664\u5143\u7d20\n    heap.Pop(maxHeap) // 5\n    heap.Pop(maxHeap) // 4\n    heap.Pop(maxHeap) // 3\n    heap.Pop(maxHeap) // 2\n    heap.Pop(maxHeap) // 1\n\n    /* \u83b7\u53d6\u5806\u5927\u5c0f */\n    size := len(*maxHeap)\n    fmt.Printf(\"\u5806\u5143\u7d20\u6570\u91cf\u4e3a %d\\n\", size)\n\n    /* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\n    isEmpty := len(*maxHeap) == 0\n    fmt.Printf(\"\u5806\u662f\u5426\u4e3a\u7a7a %t\\n\", isEmpty)\n}\n
    heap.swift
    /* \u521d\u59cb\u5316\u5806 */\n// Swift \u7684 Heap \u7c7b\u578b\u540c\u65f6\u652f\u6301\u6700\u5927\u5806\u548c\u6700\u5c0f\u5806\uff0c\u4e14\u9700\u8981\u5f15\u5165 swift-collections\nvar heap = Heap<Int>()\n\n/* \u5143\u7d20\u5165\u5806 */\nheap.insert(1)\nheap.insert(3)\nheap.insert(2)\nheap.insert(5)\nheap.insert(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = heap.max()!\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\npeek = heap.removeMax() // 5\npeek = heap.removeMax() // 4\npeek = heap.removeMax() // 3\npeek = heap.removeMax() // 2\npeek = heap.removeMax() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = heap.count\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = heap.isEmpty\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet heap2 = Heap([1, 3, 2, 5, 4])\n
    heap.js
    // JavaScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.ts
    // TypeScript \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.dart
    // Dart \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.rs
    use std::collections::BinaryHeap;\nuse std::cmp::Reverse;\n\n/* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nlet mut min_heap = BinaryHeap::<Reverse<i32>>::new();\n// \u521d\u59cb\u5316\u5927\u9876\u5806\nlet mut max_heap = BinaryHeap::new();\n\n/* \u5143\u7d20\u5165\u5806 */\nmax_heap.push(1);\nmax_heap.push(3);\nmax_heap.push(2);\nmax_heap.push(5);\nmax_heap.push(4);\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nlet peek = max_heap.peek().unwrap();  // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\nlet peek = max_heap.pop().unwrap();   // 5\nlet peek = max_heap.pop().unwrap();   // 4\nlet peek = max_heap.pop().unwrap();   // 3\nlet peek = max_heap.pop().unwrap();   // 2\nlet peek = max_heap.pop().unwrap();   // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nlet size = max_heap.len();\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = max_heap.is_empty();\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nlet min_heap = BinaryHeap::from(vec![Reverse(1), Reverse(3), Reverse(2), Reverse(5), Reverse(4)]);\n
    heap.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e Heap \u7c7b\n
    heap.kt
    /* \u521d\u59cb\u5316\u5806 */\n// \u521d\u59cb\u5316\u5c0f\u9876\u5806\nvar minHeap = PriorityQueue<Int>()\n// \u521d\u59cb\u5316\u5927\u9876\u5806\uff08\u4f7f\u7528 lambda \u8868\u8fbe\u5f0f\u4fee\u6539 Comparator \u5373\u53ef\uff09\nval maxHeap = PriorityQueue { a: Int, b: Int -> b - a }\n\n/* \u5143\u7d20\u5165\u5806 */\nmaxHeap.offer(1)\nmaxHeap.offer(3)\nmaxHeap.offer(2)\nmaxHeap.offer(5)\nmaxHeap.offer(4)\n\n/* \u83b7\u53d6\u5806\u9876\u5143\u7d20 */\nvar peek = maxHeap.peek() // 5\n\n/* \u5806\u9876\u5143\u7d20\u51fa\u5806 */\n// \u51fa\u5806\u5143\u7d20\u4f1a\u5f62\u6210\u4e00\u4e2a\u4ece\u5927\u5230\u5c0f\u7684\u5e8f\u5217\npeek = maxHeap.poll() // 5\npeek = maxHeap.poll() // 4\npeek = maxHeap.poll() // 3\npeek = maxHeap.poll() // 2\npeek = maxHeap.poll() // 1\n\n/* \u83b7\u53d6\u5806\u5927\u5c0f */\nval size = maxHeap.size\n\n/* \u5224\u65ad\u5806\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = maxHeap.isEmpty()\n\n/* \u8f93\u5165\u5217\u8868\u5e76\u5efa\u5806 */\nminHeap = PriorityQueue(mutableListOf(1, 3, 2, 5, 4))\n
    heap.rb
    \n
    heap.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#812","title":"8.1.2 \u00a0 \u5806\u7684\u5b9e\u73b0","text":"

    \u4e0b\u6587\u5b9e\u73b0\u7684\u662f\u5927\u9876\u5806\u3002\u82e5\u8981\u5c06\u5176\u8f6c\u6362\u4e3a\u5c0f\u9876\u5806\uff0c\u53ea\u9700\u5c06\u6240\u6709\u5927\u5c0f\u903b\u8f91\u5224\u65ad\u8fdb\u884c\u9006\u8f6c\uff08\u4f8b\u5982\uff0c\u5c06 \\(\\geq\\) \u66ff\u6362\u4e3a \\(\\leq\\) \uff09\u3002\u611f\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u3002

    "},{"location":"chapter_heap/heap/#1","title":"1. \u00a0 \u5806\u7684\u5b58\u50a8\u4e0e\u8868\u793a","text":"

    \u201c\u4e8c\u53c9\u6811\u201d\u7ae0\u8282\u8bb2\u8fc7\uff0c\u5b8c\u5168\u4e8c\u53c9\u6811\u975e\u5e38\u9002\u5408\u7528\u6570\u7ec4\u6765\u8868\u793a\u3002\u7531\u4e8e\u5806\u6b63\u662f\u4e00\u79cd\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u56e0\u6b64\u6211\u4eec\u5c06\u91c7\u7528\u6570\u7ec4\u6765\u5b58\u50a8\u5806\u3002

    \u5f53\u4f7f\u7528\u6570\u7ec4\u8868\u793a\u4e8c\u53c9\u6811\u65f6\uff0c\u5143\u7d20\u4ee3\u8868\u8282\u70b9\u503c\uff0c\u7d22\u5f15\u4ee3\u8868\u8282\u70b9\u5728\u4e8c\u53c9\u6811\u4e2d\u7684\u4f4d\u7f6e\u3002\u8282\u70b9\u6307\u9488\u901a\u8fc7\u7d22\u5f15\u6620\u5c04\u516c\u5f0f\u6765\u5b9e\u73b0\u3002

    \u5982\u56fe 8-2 \u6240\u793a\uff0c\u7ed9\u5b9a\u7d22\u5f15 \\(i\\) \uff0c\u5176\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\(2i + 1\\) \uff0c\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\(2i + 2\\) \uff0c\u7236\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\((i - 1) / 2\\)\uff08\u5411\u4e0b\u6574\u9664\uff09\u3002\u5f53\u7d22\u5f15\u8d8a\u754c\u65f6\uff0c\u8868\u793a\u7a7a\u8282\u70b9\u6216\u8282\u70b9\u4e0d\u5b58\u5728\u3002

    \u56fe 8-2 \u00a0 \u5806\u7684\u8868\u793a\u4e0e\u5b58\u50a8

    \u6211\u4eec\u53ef\u4ee5\u5c06\u7d22\u5f15\u6620\u5c04\u516c\u5f0f\u5c01\u88c5\u6210\u51fd\u6570\uff0c\u65b9\u4fbf\u540e\u7eed\u4f7f\u7528\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def left(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 1\n\ndef right(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return 2 * i + 2\n\ndef parent(self, i: int) -> int:\n    \"\"\"\u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n    return (i - 1) // 2  # \u5411\u4e0b\u6574\u9664\n
    my_heap.cpp
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.java
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.cs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Left(int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint Right(int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint Parent(int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.go
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (h *maxHeap) parent(i int) int {\n    // \u5411\u4e0b\u6574\u9664\n    return (i - 1) / 2\n}\n
    my_heap.swift
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc left(i: Int) -> Int {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc right(i: Int) -> Int {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc parent(i: Int) -> Int {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.js
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#left(i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n#right(i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n#parent(i) {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.ts
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nleft(i: number): number {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nright(i: number): number {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nparent(i: number): number {\n    return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.dart
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _left(int i) {\n  return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint _right(int i) {\n  return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint _parent(int i) {\n  return (i - 1) ~/ 2; // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rs
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn left(i: usize) -> usize {\n    2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfn right(i: usize) -> usize {\n    2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfn parent(i: usize) -> usize {\n    (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.c
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint left(MaxHeap *maxHeap, int i) {\n    return 2 * i + 1;\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nint right(MaxHeap *maxHeap, int i) {\n    return 2 * i + 2;\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nint parent(MaxHeap *maxHeap, int i) {\n    return (i - 1) / 2; // \u5411\u4e0b\u53d6\u6574\n}\n
    my_heap.kt
    /* \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun left(i: Int): Int {\n    return 2 * i + 1\n}\n\n/* \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfun right(i: Int): Int {\n    return 2 * i + 2\n}\n\n/* \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfun parent(i: Int): Int {\n    return (i - 1) / 2 // \u5411\u4e0b\u6574\u9664\n}\n
    my_heap.rb
    ### \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef left(i)\n  2 * i + 1\nend\n\n### \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef right(i)\n  2 * i + 2\nend\n\n### \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\ndef parent(i)\n  (i - 1) / 2     # \u5411\u4e0b\u6574\u9664\nend\n
    my_heap.zig
    // \u83b7\u53d6\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn left(i: usize) usize {\n    return 2 * i + 1;\n}\n\n// \u83b7\u53d6\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\nfn right(i: usize) usize {\n    return 2 * i + 2;\n}\n\n// \u83b7\u53d6\u7236\u8282\u70b9\u7684\u7d22\u5f15\nfn parent(i: usize) usize {\n    // return (i - 1) / 2; // \u5411\u4e0b\u6574\u9664\n    return @divFloor(i - 1, 2);\n}\n
    "},{"location":"chapter_heap/heap/#2","title":"2. \u00a0 \u8bbf\u95ee\u5806\u9876\u5143\u7d20","text":"

    \u5806\u9876\u5143\u7d20\u5373\u4e3a\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\uff0c\u4e5f\u5c31\u662f\u5217\u8868\u7684\u9996\u4e2a\u5143\u7d20\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def peek(self) -> int:\n    \"\"\"\u8bbf\u95ee\u5806\u9876\u5143\u7d20\"\"\"\n    return self.max_heap[0]\n
    my_heap.cpp
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap[0];\n}\n
    my_heap.java
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n    return maxHeap.get(0);\n}\n
    my_heap.cs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint Peek() {\n    return maxHeap[0];\n}\n
    my_heap.go
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc (h *maxHeap) peek() any {\n    return h.data[0]\n}\n
    my_heap.swift
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunc peek() -> Int {\n    maxHeap[0]\n}\n
    my_heap.js
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek() {\n    return this.#maxHeap[0];\n}\n
    my_heap.ts
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\npeek(): number {\n    return this.maxHeap[0];\n}\n
    my_heap.dart
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek() {\n  return _maxHeap[0];\n}\n
    my_heap.rs
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfn peek(&self) -> Option<i32> {\n    self.max_heap.first().copied()\n}\n
    my_heap.c
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peek(MaxHeap *maxHeap) {\n    return maxHeap->data[0];\n}\n
    my_heap.kt
    /* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfun peek(): Int {\n    return maxHeap[0]\n}\n
    my_heap.rb
    ### \u8bbf\u95ee\u5806\u9876\u5143\u7d20 ###\ndef peek\n  @max_heap[0]\nend\n
    my_heap.zig
    // \u8bbf\u95ee\u5806\u9876\u5143\u7d20\nfn peek(self: *Self) T {\n    return self.max_heap.?.items[0];\n}  \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#3","title":"3. \u00a0 \u5143\u7d20\u5165\u5806","text":"

    \u7ed9\u5b9a\u5143\u7d20 val \uff0c\u6211\u4eec\u9996\u5148\u5c06\u5176\u6dfb\u52a0\u5230\u5806\u5e95\u3002\u6dfb\u52a0\u4e4b\u540e\uff0c\u7531\u4e8e val \u53ef\u80fd\u5927\u4e8e\u5806\u4e2d\u5176\u4ed6\u5143\u7d20\uff0c\u5806\u7684\u6210\u7acb\u6761\u4ef6\u53ef\u80fd\u5df2\u88ab\u7834\u574f\uff0c\u56e0\u6b64\u9700\u8981\u4fee\u590d\u4ece\u63d2\u5165\u8282\u70b9\u5230\u6839\u8282\u70b9\u7684\u8def\u5f84\u4e0a\u7684\u5404\u4e2a\u8282\u70b9\uff0c\u8fd9\u4e2a\u64cd\u4f5c\u88ab\u79f0\u4e3a\u5806\u5316\uff08heapify\uff09\u3002

    \u8003\u8651\u4ece\u5165\u5806\u8282\u70b9\u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u6267\u884c\u5806\u5316\u3002\u5982\u56fe 8-3 \u6240\u793a\uff0c\u6211\u4eec\u6bd4\u8f83\u63d2\u5165\u8282\u70b9\u4e0e\u5176\u7236\u8282\u70b9\u7684\u503c\uff0c\u5982\u679c\u63d2\u5165\u8282\u70b9\u66f4\u5927\uff0c\u5219\u5c06\u5b83\u4eec\u4ea4\u6362\u3002\u7136\u540e\u7ee7\u7eed\u6267\u884c\u6b64\u64cd\u4f5c\uff0c\u4ece\u5e95\u81f3\u9876\u4fee\u590d\u5806\u4e2d\u7684\u5404\u4e2a\u8282\u70b9\uff0c\u76f4\u81f3\u8d8a\u8fc7\u6839\u8282\u70b9\u6216\u9047\u5230\u65e0\u987b\u4ea4\u6362\u7684\u8282\u70b9\u65f6\u7ed3\u675f\u3002

    <1><2><3><4><5><6><7><8><9>

    \u56fe 8-3 \u00a0 \u5143\u7d20\u5165\u5806\u6b65\u9aa4

    \u8bbe\u8282\u70b9\u603b\u6570\u4e3a \\(n\\) \uff0c\u5219\u6811\u7684\u9ad8\u5ea6\u4e3a \\(O(\\log n)\\) \u3002\u7531\u6b64\u53ef\u77e5\uff0c\u5806\u5316\u64cd\u4f5c\u7684\u5faa\u73af\u8f6e\u6570\u6700\u591a\u4e3a \\(O(\\log n)\\) \uff0c\u5143\u7d20\u5165\u5806\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def push(self, val: int):\n    \"\"\"\u5143\u7d20\u5165\u5806\"\"\"\n    # \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.append(val)\n    # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1)\n\ndef sift_up(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\"\"\"\n    while True:\n        # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p = self.parent(i)\n        # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 or self.max_heap[i] <= self.max_heap[p]:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p)\n        # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n
    my_heap.cpp
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.push_back(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap[i], maxHeap[p]);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap.get(i) <= maxHeap.get(p))\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u5165\u5806 */\nvoid Push(int val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.Add(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    SiftUp(Size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid SiftUp(int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = Parent(i);\n        // \u82e5\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p])\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u5165\u5806 */\nfunc (h *maxHeap) push(val any) {\n    // \u6dfb\u52a0\u8282\u70b9\n    h.data = append(h.data, val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    h.siftUp(len(h.data) - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc (h *maxHeap) siftUp(i int) {\n    for true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        p := h.parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || h.data[i].(int) <= h.data[p].(int) {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u5165\u5806 */\nfunc push(val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.append(val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(i: size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfunc siftUp(i: Int) {\n    var i = i\n    while true {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = parent(i: i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if p < 0 || maxHeap[i] <= maxHeap[p] {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u5165\u5806 */\npush(val) {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.#maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.#siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\n#siftUp(i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.#parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.#maxHeap[i] <= this.#maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u5165\u5806 */\npush(val: number): void {\n    // \u6dfb\u52a0\u8282\u70b9\n    this.maxHeap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    this.siftUp(this.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nsiftUp(i: number): void {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        const p = this.parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(int val) {\n  // \u6dfb\u52a0\u8282\u70b9\n  _maxHeap.add(val);\n  // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  siftUp(size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(int i) {\n  while (true) {\n    // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    int p = _parent(i);\n    // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    if (p < 0 || _maxHeap[i] <= _maxHeap[p]) {\n      break;\n    }\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, p);\n    // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u5165\u5806 */\nfn push(&mut self, val: i32) {\n    // \u6dfb\u52a0\u8282\u70b9\n    self.max_heap.push(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    self.sift_up(self.size() - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfn sift_up(&mut self, mut i: usize) {\n    loop {\n        // \u8282\u70b9 i \u5df2\u7ecf\u662f\u5806\u9876\u8282\u70b9\u4e86\uff0c\u7ed3\u675f\u5806\u5316\n        if i == 0 {\n            break;\n        }\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        let p = Self::parent(i);\n        // \u5f53\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if self.max_heap[i] <= self.max_heap[p] {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid push(MaxHeap *maxHeap, int val) {\n    // \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u4e0d\u5e94\u8be5\u6dfb\u52a0\u8fd9\u4e48\u591a\u8282\u70b9\n    if (maxHeap->size == MAX_SIZE) {\n        printf(\"heap is full!\");\n        return;\n    }\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap->data[maxHeap->size] = val;\n    maxHeap->size++;\n\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(maxHeap, maxHeap->size - 1);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nvoid siftUp(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        int p = parent(maxHeap, i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap->data[i] <= maxHeap->data[p]) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u5165\u5806 */\nfun push(_val: Int) {\n    // \u6dfb\u52a0\u8282\u70b9\n    maxHeap.add(_val)\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    siftUp(size() - 1)\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 */\nfun siftUp(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        val p = parent(i)\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 || maxHeap[i] <= maxHeap[p]) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, p)\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u5165\u5806 ###\ndef push(val)\n  # \u6dfb\u52a0\u8282\u70b9\n  @max_heap << val\n  # \u4ece\u5e95\u81f3\u9876\u5806\u5316\n  sift_up(size - 1)\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316 ###\ndef sift_up(i)\n  loop do\n    # \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n    p = parent(i)\n    # \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n    break if p < 0 || @max_heap[i] <= @max_heap[p]\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, p)\n    # \u5faa\u73af\u5411\u4e0a\u5806\u5316\n    i = p\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u5165\u5806\nfn push(self: *Self, val: T) !void {\n    // \u6dfb\u52a0\u8282\u70b9\n    try self.max_heap.?.append(val);\n    // \u4ece\u5e95\u81f3\u9876\u5806\u5316\n    try self.siftUp(self.size() - 1);\n}  \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u5e95\u81f3\u9876\u5806\u5316\nfn siftUp(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u83b7\u53d6\u8282\u70b9 i \u7684\u7236\u8282\u70b9\n        var p = parent(i);\n        // \u5f53\u201c\u8d8a\u8fc7\u6839\u8282\u70b9\u201d\u6216\u201c\u8282\u70b9\u65e0\u987b\u4fee\u590d\u201d\u65f6\uff0c\u7ed3\u675f\u5806\u5316\n        if (p < 0 or self.max_heap.?.items[i] <= self.max_heap.?.items[p]) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, p);\n        // \u5faa\u73af\u5411\u4e0a\u5806\u5316\n        i = p;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#4","title":"4. \u00a0 \u5806\u9876\u5143\u7d20\u51fa\u5806","text":"

    \u5806\u9876\u5143\u7d20\u662f\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9\uff0c\u5373\u5217\u8868\u9996\u5143\u7d20\u3002\u5982\u679c\u6211\u4eec\u76f4\u63a5\u4ece\u5217\u8868\u4e2d\u5220\u9664\u9996\u5143\u7d20\uff0c\u90a3\u4e48\u4e8c\u53c9\u6811\u4e2d\u6240\u6709\u8282\u70b9\u7684\u7d22\u5f15\u90fd\u4f1a\u53d1\u751f\u53d8\u5316\uff0c\u8fd9\u5c06\u4f7f\u5f97\u540e\u7eed\u4f7f\u7528\u5806\u5316\u8fdb\u884c\u4fee\u590d\u53d8\u5f97\u56f0\u96be\u3002\u4e3a\u4e86\u5c3d\u91cf\u51cf\u5c11\u5143\u7d20\u7d22\u5f15\u7684\u53d8\u52a8\uff0c\u6211\u4eec\u91c7\u7528\u4ee5\u4e0b\u64cd\u4f5c\u6b65\u9aa4\u3002

    1. \u4ea4\u6362\u5806\u9876\u5143\u7d20\u4e0e\u5806\u5e95\u5143\u7d20\uff08\u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff09\u3002
    2. \u4ea4\u6362\u5b8c\u6210\u540e\uff0c\u5c06\u5806\u5e95\u4ece\u5217\u8868\u4e2d\u5220\u9664\uff08\u6ce8\u610f\uff0c\u7531\u4e8e\u5df2\u7ecf\u4ea4\u6362\uff0c\u56e0\u6b64\u5b9e\u9645\u4e0a\u5220\u9664\u7684\u662f\u539f\u6765\u7684\u5806\u9876\u5143\u7d20\uff09\u3002
    3. \u4ece\u6839\u8282\u70b9\u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u6267\u884c\u5806\u5316\u3002

    \u5982\u56fe 8-4 \u6240\u793a\uff0c\u201c\u4ece\u9876\u81f3\u5e95\u5806\u5316\u201d\u7684\u64cd\u4f5c\u65b9\u5411\u4e0e\u201c\u4ece\u5e95\u81f3\u9876\u5806\u5316\u201d\u76f8\u53cd\uff0c\u6211\u4eec\u5c06\u6839\u8282\u70b9\u7684\u503c\u4e0e\u5176\u4e24\u4e2a\u5b50\u8282\u70b9\u7684\u503c\u8fdb\u884c\u6bd4\u8f83\uff0c\u5c06\u6700\u5927\u7684\u5b50\u8282\u70b9\u4e0e\u6839\u8282\u70b9\u4ea4\u6362\u3002\u7136\u540e\u5faa\u73af\u6267\u884c\u6b64\u64cd\u4f5c\uff0c\u76f4\u5230\u8d8a\u8fc7\u53f6\u8282\u70b9\u6216\u9047\u5230\u65e0\u987b\u4ea4\u6362\u7684\u8282\u70b9\u65f6\u7ed3\u675f\u3002

    <1><2><3><4><5><6><7><8><9><10>

    \u56fe 8-4 \u00a0 \u5806\u9876\u5143\u7d20\u51fa\u5806\u6b65\u9aa4

    \u4e0e\u5143\u7d20\u5165\u5806\u64cd\u4f5c\u76f8\u4f3c\uff0c\u5806\u9876\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u4e3a \\(O(\\log n)\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig my_heap.py
    def pop(self) -> int:\n    \"\"\"\u5143\u7d20\u51fa\u5806\"\"\"\n    # \u5224\u7a7a\u5904\u7406\n    if self.is_empty():\n        raise IndexError(\"\u5806\u4e3a\u7a7a\")\n    # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1)\n    # \u5220\u9664\u8282\u70b9\n    val = self.max_heap.pop()\n    # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0)\n    # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n\ndef sift_down(self, i: int):\n    \"\"\"\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l, r, ma = self.left(i), self.right(i), i\n        if l < self.size() and self.max_heap[l] > self.max_heap[ma]:\n            ma = l\n        if r < self.size() and self.max_heap[r] > self.max_heap[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma)\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n
    my_heap.cpp
    /* \u5143\u7d20\u51fa\u5806 */\nvoid pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) {\n        throw out_of_range(\"\u5806\u4e3a\u7a7a\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap[0], maxHeap[size() - 1]);\n    // \u5220\u9664\u8282\u70b9\n    maxHeap.pop_back();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        swap(maxHeap[i], maxHeap[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.java
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty())\n        throw new IndexOutOfBoundsException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.remove(size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = left(i), r = right(i), ma = i;\n        if (l < size() && maxHeap.get(l) > maxHeap.get(ma))\n            ma = l;\n        if (r < size() && maxHeap.get(r) > maxHeap.get(ma))\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.cs
    /* \u5143\u7d20\u51fa\u5806 */\nint Pop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (IsEmpty())\n        throw new IndexOutOfRangeException();\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    Swap(0, Size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap.Last();\n    maxHeap.RemoveAt(Size() - 1);\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    SiftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = Left(i), r = Right(i), ma = i;\n        if (l < Size() && maxHeap[l] > maxHeap[ma])\n            ma = l;\n        if (r < Size() && maxHeap[r] > maxHeap[ma])\n            ma = r;\n        // \u82e5\u201c\u8282\u70b9 i \u6700\u5927\u201d\u6216\u201c\u8d8a\u8fc7\u53f6\u8282\u70b9\u201d\uff0c\u5219\u7ed3\u675f\u5806\u5316\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        Swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.go
    /* \u5143\u7d20\u51fa\u5806 */\nfunc (h *maxHeap) pop() any {\n    // \u5224\u7a7a\u5904\u7406\n    if h.isEmpty() {\n        fmt.Println(\"error\")\n        return nil\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    h.swap(0, h.size()-1)\n    // \u5220\u9664\u8282\u70b9\n    val := h.data[len(h.data)-1]\n    h.data = h.data[:len(h.data)-1]\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    h.siftDown(0)\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc (h *maxHeap) siftDown(i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        l, r, max := h.left(i), h.right(i), i\n        if l < h.size() && h.data[l].(int) > h.data[max].(int) {\n            max = l\n        }\n        if r < h.size() && h.data[r].(int) > h.data[max].(int) {\n            max = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if max == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        h.swap(i, max)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max\n    }\n}\n
    my_heap.swift
    /* \u5143\u7d20\u51fa\u5806 */\nfunc pop() -> Int {\n    // \u5224\u7a7a\u5904\u7406\n    if isEmpty() {\n        fatalError(\"\u5806\u4e3a\u7a7a\")\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(i: 0, j: size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    let val = maxHeap.remove(at: size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(i: 0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = left(i: i)\n        let r = right(i: i)\n        var ma = i\n        if l < size(), maxHeap[l] > maxHeap[ma] {\n            ma = l\n        }\n        if r < size(), maxHeap[r] > maxHeap[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i: i, j: ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.js
    /* \u5143\u7d20\u51fa\u5806 */\npop() {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new Error('\u5806\u4e3a\u7a7a');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.#swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.#maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.#siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\n#siftDown(i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.#left(i),\n            r = this.#right(i);\n        let ma = i;\n        if (l < this.size() && this.#maxHeap[l] > this.#maxHeap[ma]) ma = l;\n        if (r < this.size() && this.#maxHeap[r] > this.#maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.#swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.ts
    /* \u5143\u7d20\u51fa\u5806 */\npop(): number {\n    // \u5224\u7a7a\u5904\u7406\n    if (this.isEmpty()) throw new RangeError('Heap is empty.');\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    this.swap(0, this.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    const val = this.maxHeap.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    this.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nsiftDown(i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        const l = this.left(i),\n            r = this.right(i);\n        let ma = i;\n        if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;\n        if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        this.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.dart
    /* \u5143\u7d20\u51fa\u5806 */\nint pop() {\n  // \u5224\u7a7a\u5904\u7406\n  if (isEmpty()) throw Exception('\u5806\u4e3a\u7a7a');\n  // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  _swap(0, size() - 1);\n  // \u5220\u9664\u8282\u70b9\n  int val = _maxHeap.removeLast();\n  // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  siftDown(0);\n  // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = _left(i);\n    int r = _right(i);\n    int ma = i;\n    if (l < size() && _maxHeap[l] > _maxHeap[ma]) ma = l;\n    if (r < size() && _maxHeap[r] > _maxHeap[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    _swap(i, ma);\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n
    my_heap.rs
    /* \u5143\u7d20\u51fa\u5806 */\nfn pop(&mut self) -> i32 {\n    // \u5224\u7a7a\u5904\u7406\n    if self.is_empty() {\n        panic!(\"index out of bounds\");\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    let val = self.max_heap.pop().unwrap();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    self.sift_down(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(&mut self, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let (l, r, mut ma) = (Self::left(i), Self::right(i), i);\n        if l < self.size() && self.max_heap[l] > self.max_heap[ma] {\n            ma = l;\n        }\n        if r < self.size() && self.max_heap[r] > self.max_heap[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    my_heap.c
    /* \u5143\u7d20\u51fa\u5806 */\nint pop(MaxHeap *maxHeap) {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty(maxHeap)) {\n        printf(\"heap is empty!\");\n        return INT_MAX;\n    }\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(maxHeap, 0, size(maxHeap) - 1);\n    // \u5220\u9664\u8282\u70b9\n    int val = maxHeap->data[maxHeap->size - 1];\n    maxHeap->size--;\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(maxHeap, 0);\n\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(MaxHeap *maxHeap, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a max\n        int l = left(maxHeap, i);\n        int r = right(maxHeap, i);\n        int max = i;\n        if (l < size(maxHeap) && maxHeap->data[l] > maxHeap->data[max]) {\n            max = l;\n        }\n        if (r < size(maxHeap) && maxHeap->data[r] > maxHeap->data[max]) {\n            max = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (max == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(maxHeap, i, max);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = max;\n    }\n}\n
    my_heap.kt
    /* \u5143\u7d20\u51fa\u5806 */\nfun pop(): Int {\n    // \u5224\u7a7a\u5904\u7406\n    if (isEmpty()) throw IndexOutOfBoundsException()\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    swap(0, size() - 1)\n    // \u5220\u9664\u8282\u70b9\n    val _val = maxHeap.removeAt(size() - 1)\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    siftDown(0)\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return _val\n}\n\n/* \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(it: Int) {\n    // Kotlin\u7684\u51fd\u6570\u53c2\u6570\u4e0d\u53ef\u53d8\uff0c\u56e0\u6b64\u521b\u5efa\u4e34\u65f6\u53d8\u91cf\n    var i = it\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = left(i)\n        val r = right(i)\n        var ma = i\n        if (l < size() && maxHeap[l] > maxHeap[ma]) ma = l\n        if (r < size() && maxHeap[r] > maxHeap[ma]) ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n
    my_heap.rb
    ### \u5143\u7d20\u51fa\u5806 ###\ndef pop\n  # \u5224\u7a7a\u5904\u7406\n  raise IndexError, \"\u5806\u4e3a\u7a7a\" if is_empty?\n  # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n  swap(0, size - 1)\n  # \u5220\u9664\u8282\u70b9\n  val = @max_heap.pop\n  # \u4ece\u9876\u81f3\u5e95\u5806\u5316\n  sift_down(0)\n  # \u8fd4\u56de\u5806\u9876\u5143\u7d20\n  val\nend\n\n### \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 ###\ndef sift_down(i)\n  loop do\n    # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    l, r, ma = left(i), right(i), i\n    ma = l if l < size && @max_heap[l] > @max_heap[ma]\n    ma = r if r < size && @max_heap[r] > @max_heap[ma]\n\n    # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    break if ma == i\n\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    swap(i, ma)\n    # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma\n  end\nend\n
    my_heap.zig
    // \u5143\u7d20\u51fa\u5806\nfn pop(self: *Self) !T {\n    // \u5224\u65ad\u5904\u7406\n    if (self.isEmpty()) unreachable;\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    try self.swap(0, self.size() - 1);\n    // \u5220\u9664\u8282\u70b9\n    var val = self.max_heap.?.pop();\n    // \u4ece\u9876\u81f3\u5e95\u5806\u5316\n    try self.siftDown(0);\n    // \u8fd4\u56de\u5806\u9876\u5143\u7d20\n    return val;\n} \n\n// \u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\nfn siftDown(self: *Self, i_: usize) !void {\n    var i = i_;\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        var l = left(i);\n        var r = right(i);\n        var ma = i;\n        if (l < self.size() and self.max_heap.?.items[l] > self.max_heap.?.items[ma]) ma = l;\n        if (r < self.size() and self.max_heap.?.items[r] > self.max_heap.?.items[ma]) ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        try self.swap(i, ma);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_heap/heap/#813","title":"8.1.3 \u00a0 \u5806\u7684\u5e38\u89c1\u5e94\u7528","text":"
    • \u4f18\u5148\u961f\u5217\uff1a\u5806\u901a\u5e38\u4f5c\u4e3a\u5b9e\u73b0\u4f18\u5148\u961f\u5217\u7684\u9996\u9009\u6570\u636e\u7ed3\u6784\uff0c\u5176\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(\\log n)\\) \uff0c\u800c\u5efa\u961f\u64cd\u4f5c\u4e3a \\(O(n)\\) \uff0c\u8fd9\u4e9b\u64cd\u4f5c\u90fd\u975e\u5e38\u9ad8\u6548\u3002
    • \u5806\u6392\u5e8f\uff1a\u7ed9\u5b9a\u4e00\u7ec4\u6570\u636e\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u5b83\u4eec\u5efa\u7acb\u4e00\u4e2a\u5806\uff0c\u7136\u540e\u4e0d\u65ad\u5730\u6267\u884c\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\uff0c\u4ece\u800c\u5f97\u5230\u6709\u5e8f\u6570\u636e\u3002\u7136\u800c\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u4f7f\u7528\u4e00\u79cd\u66f4\u4f18\u96c5\u7684\u65b9\u5f0f\u5b9e\u73b0\u5806\u6392\u5e8f\uff0c\u8be6\u89c1\u201c\u5806\u6392\u5e8f\u201d\u7ae0\u8282\u3002
    • \u83b7\u53d6\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\uff1a\u8fd9\u662f\u4e00\u4e2a\u7ecf\u5178\u7684\u7b97\u6cd5\u95ee\u9898\uff0c\u540c\u65f6\u4e5f\u662f\u4e00\u79cd\u5178\u578b\u5e94\u7528\uff0c\u4f8b\u5982\u9009\u62e9\u70ed\u5ea6\u524d 10 \u7684\u65b0\u95fb\u4f5c\u4e3a\u5fae\u535a\u70ed\u641c\uff0c\u9009\u53d6\u9500\u91cf\u524d 10 \u7684\u5546\u54c1\u7b49\u3002
    "},{"location":"chapter_heap/summary/","title":"8.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_heap/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u5806\u662f\u4e00\u68f5\u5b8c\u5168\u4e8c\u53c9\u6811\uff0c\u6839\u636e\u6210\u7acb\u6761\u4ef6\u53ef\u5206\u4e3a\u5927\u9876\u5806\u548c\u5c0f\u9876\u5806\u3002\u5927\uff08\u5c0f\uff09\u9876\u5806\u7684\u5806\u9876\u5143\u7d20\u662f\u6700\u5927\uff08\u5c0f\uff09\u7684\u3002
    • \u4f18\u5148\u961f\u5217\u7684\u5b9a\u4e49\u662f\u5177\u6709\u51fa\u961f\u4f18\u5148\u7ea7\u7684\u961f\u5217\uff0c\u901a\u5e38\u4f7f\u7528\u5806\u6765\u5b9e\u73b0\u3002
    • \u5806\u7684\u5e38\u7528\u64cd\u4f5c\u53ca\u5176\u5bf9\u5e94\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5305\u62ec\uff1a\u5143\u7d20\u5165\u5806 \\(O(\\log n)\\)\u3001\u5806\u9876\u5143\u7d20\u51fa\u5806 \\(O(\\log n)\\) \u548c\u8bbf\u95ee\u5806\u9876\u5143\u7d20 \\(O(1)\\) \u7b49\u3002
    • \u5b8c\u5168\u4e8c\u53c9\u6811\u975e\u5e38\u9002\u5408\u7528\u6570\u7ec4\u8868\u793a\uff0c\u56e0\u6b64\u6211\u4eec\u901a\u5e38\u4f7f\u7528\u6570\u7ec4\u6765\u5b58\u50a8\u5806\u3002
    • \u5806\u5316\u64cd\u4f5c\u7528\u4e8e\u7ef4\u62a4\u5806\u7684\u6027\u8d28\uff0c\u5728\u5165\u5806\u548c\u51fa\u5806\u64cd\u4f5c\u4e2d\u90fd\u4f1a\u7528\u5230\u3002
    • \u8f93\u5165 \\(n\\) \u4e2a\u5143\u7d20\u5e76\u5efa\u5806\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f18\u5316\u81f3 \\(O(n)\\) \uff0c\u975e\u5e38\u9ad8\u6548\u3002
    • Top-k \u662f\u4e00\u4e2a\u7ecf\u5178\u7b97\u6cd5\u95ee\u9898\uff0c\u53ef\u4ee5\u4f7f\u7528\u5806\u6570\u636e\u7ed3\u6784\u9ad8\u6548\u89e3\u51b3\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log k)\\) \u3002
    "},{"location":"chapter_heap/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6570\u636e\u7ed3\u6784\u7684\u201c\u5806\u201d\u4e0e\u5185\u5b58\u7ba1\u7406\u7684\u201c\u5806\u201d\u662f\u540c\u4e00\u4e2a\u6982\u5ff5\u5417\uff1f

    \u4e24\u8005\u4e0d\u662f\u540c\u4e00\u4e2a\u6982\u5ff5\uff0c\u53ea\u662f\u78b0\u5de7\u90fd\u53eb\u201c\u5806\u201d\u3002\u8ba1\u7b97\u673a\u7cfb\u7edf\u5185\u5b58\u4e2d\u7684\u5806\u662f\u52a8\u6001\u5185\u5b58\u5206\u914d\u7684\u4e00\u90e8\u5206\uff0c\u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u53ef\u4ee5\u4f7f\u7528\u5b83\u6765\u5b58\u50a8\u6570\u636e\u3002\u7a0b\u5e8f\u53ef\u4ee5\u8bf7\u6c42\u4e00\u5b9a\u91cf\u7684\u5806\u5185\u5b58\uff0c\u7528\u4e8e\u5b58\u50a8\u5982\u5bf9\u8c61\u548c\u6570\u7ec4\u7b49\u590d\u6742\u7ed3\u6784\u3002\u5f53\u8fd9\u4e9b\u6570\u636e\u4e0d\u518d\u9700\u8981\u65f6\uff0c\u7a0b\u5e8f\u9700\u8981\u91ca\u653e\u8fd9\u4e9b\u5185\u5b58\uff0c\u4ee5\u9632\u6b62\u5185\u5b58\u6cc4\u6f0f\u3002\u76f8\u8f83\u4e8e\u6808\u5185\u5b58\uff0c\u5806\u5185\u5b58\u7684\u7ba1\u7406\u548c\u4f7f\u7528\u9700\u8981\u66f4\u8c28\u614e\uff0c\u4f7f\u7528\u4e0d\u5f53\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u548c\u91ce\u6307\u9488\u7b49\u95ee\u9898\u3002

    "},{"location":"chapter_heap/top_k/","title":"8.3 \u00a0 Top-k \u95ee\u9898","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u65e0\u5e8f\u6570\u7ec4 nums \uff0c\u8bf7\u8fd4\u56de\u6570\u7ec4\u4e2d\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u3002

    \u5bf9\u4e8e\u8be5\u95ee\u9898\uff0c\u6211\u4eec\u5148\u4ecb\u7ecd\u4e24\u79cd\u601d\u8def\u6bd4\u8f83\u76f4\u63a5\u7684\u89e3\u6cd5\uff0c\u518d\u4ecb\u7ecd\u6548\u7387\u66f4\u9ad8\u7684\u5806\u89e3\u6cd5\u3002

    "},{"location":"chapter_heap/top_k/#831","title":"8.3.1 \u00a0 \u65b9\u6cd5\u4e00\uff1a\u904d\u5386\u9009\u62e9","text":"

    \u6211\u4eec\u53ef\u4ee5\u8fdb\u884c\u56fe 8-6 \u6240\u793a\u7684 \\(k\\) \u8f6e\u904d\u5386\uff0c\u5206\u522b\u5728\u6bcf\u8f6e\u4e2d\u63d0\u53d6\u7b2c \\(1\\)\u3001\\(2\\)\u3001\\(\\dots\\)\u3001\\(k\\) \u5927\u7684\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nk)\\) \u3002

    \u6b64\u65b9\u6cd5\u53ea\u9002\u7528\u4e8e \\(k \\ll n\\) \u7684\u60c5\u51b5\uff0c\u56e0\u4e3a\u5f53 \\(k\\) \u4e0e \\(n\\) \u6bd4\u8f83\u63a5\u8fd1\u65f6\uff0c\u5176\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u5411\u4e8e \\(O(n^2)\\) \uff0c\u975e\u5e38\u8017\u65f6\u3002

    \u56fe 8-6 \u00a0 \u904d\u5386\u5bfb\u627e\u6700\u5927\u7684 k \u4e2a\u5143\u7d20

    Tip

    \u5f53 \\(k = n\\) \u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u5230\u5b8c\u6574\u7684\u6709\u5e8f\u5e8f\u5217\uff0c\u6b64\u65f6\u7b49\u4ef7\u4e8e\u201c\u9009\u62e9\u6392\u5e8f\u201d\u7b97\u6cd5\u3002

    "},{"location":"chapter_heap/top_k/#832","title":"8.3.2 \u00a0 \u65b9\u6cd5\u4e8c\uff1a\u6392\u5e8f","text":"

    \u5982\u56fe 8-7 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u5bf9\u6570\u7ec4 nums \u8fdb\u884c\u6392\u5e8f\uff0c\u518d\u8fd4\u56de\u6700\u53f3\u8fb9\u7684 \\(k\\) \u4e2a\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002

    \u663e\u7136\uff0c\u8be5\u65b9\u6cd5\u201c\u8d85\u989d\u201d\u5b8c\u6210\u4efb\u52a1\u4e86\uff0c\u56e0\u4e3a\u6211\u4eec\u53ea\u9700\u627e\u51fa\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u5373\u53ef\uff0c\u800c\u4e0d\u9700\u8981\u6392\u5e8f\u5176\u4ed6\u5143\u7d20\u3002

    \u56fe 8-7 \u00a0 \u6392\u5e8f\u5bfb\u627e\u6700\u5927\u7684 k \u4e2a\u5143\u7d20

    "},{"location":"chapter_heap/top_k/#833","title":"8.3.3 \u00a0 \u65b9\u6cd5\u4e09\uff1a\u5806","text":"

    \u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u5806\u66f4\u52a0\u9ad8\u6548\u5730\u89e3\u51b3 Top-k \u95ee\u9898\uff0c\u6d41\u7a0b\u5982\u56fe 8-8 \u6240\u793a\u3002

    1. \u521d\u59cb\u5316\u4e00\u4e2a\u5c0f\u9876\u5806\uff0c\u5176\u5806\u9876\u5143\u7d20\u6700\u5c0f\u3002
    2. \u5148\u5c06\u6570\u7ec4\u7684\u524d \\(k\\) \u4e2a\u5143\u7d20\u4f9d\u6b21\u5165\u5806\u3002
    3. \u4ece\u7b2c \\(k + 1\\) \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\uff0c\u5e76\u5c06\u5f53\u524d\u5143\u7d20\u5165\u5806\u3002
    4. \u904d\u5386\u5b8c\u6210\u540e\uff0c\u5806\u4e2d\u4fdd\u5b58\u7684\u5c31\u662f\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u3002
    <1><2><3><4><5><6><7><8><9>

    \u56fe 8-8 \u00a0 \u57fa\u4e8e\u5806\u5bfb\u627e\u6700\u5927\u7684 k \u4e2a\u5143\u7d20

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig top_k.py
    def top_k_heap(nums: list[int], k: int) -> list[int]:\n    \"\"\"\u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\"\"\"\n    # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    heap = []\n    # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i in range(k):\n        heapq.heappush(heap, nums[i])\n    # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in range(k, len(nums)):\n        # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap[0]:\n            heapq.heappop(heap)\n            heapq.heappush(heap, nums[i])\n    return heap\n
    top_k.cpp
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\npriority_queue<int, vector<int>, greater<int>> topKHeap(vector<int> &nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    priority_queue<int, vector<int>, greater<int>> heap;\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.push(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.size(); i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.top()) {\n            heap.pop();\n            heap.push(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.java
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nQueue<Integer> topKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    Queue<Integer> heap = new PriorityQueue<Integer>();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.offer(nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll();\n            heap.offer(nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.cs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nPriorityQueue<int, int> TopKHeap(int[] nums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    PriorityQueue<int, int> heap = new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        heap.Enqueue(nums[i], nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < nums.Length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.Peek()) {\n            heap.Dequeue();\n            heap.Enqueue(nums[i], nums[i]);\n        }\n    }\n    return heap;\n}\n
    top_k.go
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums []int, k int) *minHeap {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    h := &minHeap{}\n    heap.Init(h)\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for i := 0; i < k; i++ {\n        heap.Push(h, nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i := k; i < len(nums); i++ {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > h.Top().(int) {\n            heap.Pop(h)\n            heap.Push(h, nums[i])\n        }\n    }\n    return h\n}\n
    top_k.swift
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunc topKHeap(nums: [Int], k: Int) -> [Int] {\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5c0f\u9876\u5806\uff0c\u5e76\u5c06\u524d k \u4e2a\u5143\u7d20\u5efa\u5806\n    var heap = Heap(nums.prefix(k))\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for i in nums.indices.dropFirst(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if nums[i] > heap.min()! {\n            _ = heap.removeMin()\n            heap.insert(nums[i])\n        }\n    }\n    return heap.unordered\n}\n
    top_k.js
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap, val) {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums, k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.ts
    /* \u5143\u7d20\u5165\u5806 */\nfunction pushMinHeap(maxHeap: MaxHeap, val: number): void {\n    // \u5143\u7d20\u53d6\u53cd\n    maxHeap.push(-val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nfunction popMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.pop();\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nfunction peekMinHeap(maxHeap: MaxHeap): number {\n    // \u5143\u7d20\u53d6\u53cd\n    return -maxHeap.peek();\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nfunction getMinHeap(maxHeap: MaxHeap): number[] {\n    // \u5143\u7d20\u53d6\u53cd\n    return maxHeap.getMaxHeap().map((num: number) => -num);\n}\n\n/* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfunction topKHeap(nums: number[], k: number): number[] {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    const maxHeap = new MaxHeap([]);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (let i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (let i = k; i < nums.length; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    // \u8fd4\u56de\u5806\u4e2d\u5143\u7d20\n    return getMinHeap(maxHeap);\n}\n
    top_k.dart
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nMinHeap topKHeap(List<int> nums, int k) {\n  // \u521d\u59cb\u5316\u5c0f\u9876\u5806\uff0c\u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  MinHeap heap = MinHeap(nums.sublist(0, k));\n  // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for (int i = k; i < nums.length; i++) {\n    // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if (nums[i] > heap.peek()) {\n      heap.pop();\n      heap.push(nums[i]);\n    }\n  }\n  return heap;\n}\n
    top_k.rs
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfn top_k_heap(nums: Vec<i32>, k: usize) -> BinaryHeap<Reverse<i32>> {\n    // BinaryHeap \u662f\u5927\u9876\u5806\uff0c\u4f7f\u7528 Reverse \u5c06\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u5b9e\u73b0\u5c0f\u9876\u5806\n    let mut heap = BinaryHeap::<Reverse<i32>>::new();\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for &num in nums.iter().take(k) {\n        heap.push(Reverse(num));\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for &num in nums.iter().skip(k) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if num > heap.peek().unwrap().0 {\n            heap.pop();\n            heap.push(Reverse(num));\n        }\n    }\n    heap\n}\n
    top_k.c
    /* \u5143\u7d20\u5165\u5806 */\nvoid pushMinHeap(MaxHeap *maxHeap, int val) {\n    // \u5143\u7d20\u53d6\u53cd\n    push(maxHeap, -val);\n}\n\n/* \u5143\u7d20\u51fa\u5806 */\nint popMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -pop(maxHeap);\n}\n\n/* \u8bbf\u95ee\u5806\u9876\u5143\u7d20 */\nint peekMinHeap(MaxHeap *maxHeap) {\n    // \u5143\u7d20\u53d6\u53cd\n    return -peek(maxHeap);\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n/* \u53d6\u51fa\u5806\u4e2d\u5143\u7d20 */\nint *getMinHeap(MaxHeap *maxHeap) {\n    // \u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\u5e76\u5b58\u5165 res \u6570\u7ec4\n    int *res = (int *)malloc(maxHeap->size * sizeof(int));\n    for (int i = 0; i < maxHeap->size; i++) {\n        res[i] = -maxHeap->data[i];\n    }\n    return res;\n}\n\n// \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20\u7684\u51fd\u6570\nint *topKHeap(int *nums, int sizeNums, int k) {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    // \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n    int *empty = (int *)malloc(0);\n    MaxHeap *maxHeap = newMaxHeap(empty, 0);\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (int i = 0; i < k; i++) {\n        pushMinHeap(maxHeap, nums[i]);\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (int i = k; i < sizeNums; i++) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > peekMinHeap(maxHeap)) {\n            popMinHeap(maxHeap);\n            pushMinHeap(maxHeap, nums[i]);\n        }\n    }\n    int *res = getMinHeap(maxHeap);\n    // \u91ca\u653e\u5185\u5b58\n    delMaxHeap(maxHeap);\n    return res;\n}\n
    top_k.kt
    /* \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 */\nfun topKHeap(nums: IntArray, k: Int): Queue<Int> {\n    // \u521d\u59cb\u5316\u5c0f\u9876\u5806\n    val heap = PriorityQueue<Int>()\n    // \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n    for (i in 0..<k) {\n        heap.offer(nums[i])\n    }\n    // \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n    for (i in k..<nums.size) {\n        // \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n        if (nums[i] > heap.peek()) {\n            heap.poll()\n            heap.offer(nums[i])\n        }\n    }\n    return heap\n}\n
    top_k.rb
    ### \u57fa\u4e8e\u5806\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5927\u7684 k \u4e2a\u5143\u7d20 ###\ndef top_k_heap(nums, k)\n  # \u521d\u59cb\u5316\u5c0f\u9876\u5806\n  # \u8bf7\u6ce8\u610f\uff1a\u6211\u4eec\u5c06\u5806\u4e2d\u6240\u6709\u5143\u7d20\u53d6\u53cd\uff0c\u4ece\u800c\u7528\u5927\u9876\u5806\u6765\u6a21\u62df\u5c0f\u9876\u5806\n  max_heap = MaxHeap.new([])\n\n  # \u5c06\u6570\u7ec4\u7684\u524d k \u4e2a\u5143\u7d20\u5165\u5806\n  for i in 0...k\n    push_min_heap(max_heap, nums[i])\n  end\n\n  # \u4ece\u7b2c k+1 \u4e2a\u5143\u7d20\u5f00\u59cb\uff0c\u4fdd\u6301\u5806\u7684\u957f\u5ea6\u4e3a k\n  for i in k...nums.length\n    # \u82e5\u5f53\u524d\u5143\u7d20\u5927\u4e8e\u5806\u9876\u5143\u7d20\uff0c\u5219\u5c06\u5806\u9876\u5143\u7d20\u51fa\u5806\u3001\u5f53\u524d\u5143\u7d20\u5165\u5806\n    if nums[i] > peek_min_heap(max_heap)\n      pop_min_heap(max_heap)\n      push_min_heap(max_heap, nums[i])\n    end\n  end\n\n  get_min_heap(max_heap)\nend\n
    top_k.zig
    [class]{}-[func]{topKHeap}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u603b\u5171\u6267\u884c\u4e86 \\(n\\) \u8f6e\u5165\u5806\u548c\u51fa\u5806\uff0c\u5806\u7684\u6700\u5927\u957f\u5ea6\u4e3a \\(k\\) \uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log k)\\) \u3002\u8be5\u65b9\u6cd5\u7684\u6548\u7387\u5f88\u9ad8\uff0c\u5f53 \\(k\\) \u8f83\u5c0f\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u5411 \\(O(n)\\) \uff1b\u5f53 \\(k\\) \u8f83\u5927\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e0d\u4f1a\u8d85\u8fc7 \\(O(n \\log n)\\) \u3002

    \u53e6\u5916\uff0c\u8be5\u65b9\u6cd5\u9002\u7528\u4e8e\u52a8\u6001\u6570\u636e\u6d41\u7684\u4f7f\u7528\u573a\u666f\u3002\u5728\u4e0d\u65ad\u52a0\u5165\u6570\u636e\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u6301\u7eed\u7ef4\u62a4\u5806\u5185\u7684\u5143\u7d20\uff0c\u4ece\u800c\u5b9e\u73b0\u6700\u5927\u7684 \\(k\\) \u4e2a\u5143\u7d20\u7684\u52a8\u6001\u66f4\u65b0\u3002

    "},{"location":"chapter_hello_algo/","title":"\u5e8f","text":"

    \u51e0\u5e74\u524d\uff0c\u6211\u5728\u529b\u6263\u4e0a\u5206\u4eab\u4e86\u201c\u5251\u6307 Offer\u201d\u7cfb\u5217\u9898\u89e3\uff0c\u53d7\u5230\u4e86\u8bb8\u591a\u8bfb\u8005\u7684\u9f13\u52b1\u548c\u652f\u6301\u3002\u5728\u4e0e\u8bfb\u8005\u4ea4\u6d41\u671f\u95f4\uff0c\u6211\u6700\u5e38\u88ab\u95ee\u7684\u4e00\u4e2a\u95ee\u9898\u662f\u201c\u5982\u4f55\u5165\u95e8\u7b97\u6cd5\u201d\u3002\u9010\u6e10\u5730\uff0c\u6211\u5bf9\u8fd9\u4e2a\u95ee\u9898\u4ea7\u751f\u4e86\u6d53\u539a\u7684\u5174\u8da3\u3002

    \u4e24\u773c\u4e00\u62b9\u9ed1\u5730\u5237\u9898\u4f3c\u4e4e\u662f\u6700\u53d7\u6b22\u8fce\u7684\u65b9\u6cd5\uff0c\u7b80\u5355\u3001\u76f4\u63a5\u4e14\u6709\u6548\u3002\u7136\u800c\u5237\u9898\u5c31\u5982\u540c\u73a9\u201c\u626b\u96f7\u201d\u6e38\u620f\uff0c\u81ea\u5b66\u80fd\u529b\u5f3a\u7684\u4eba\u80fd\u591f\u987a\u5229\u5c06\u5730\u96f7\u9010\u4e2a\u6392\u6389\uff0c\u800c\u57fa\u7840\u4e0d\u8db3\u7684\u4eba\u5f88\u53ef\u80fd\u88ab\u70b8\u5f97\u6ee1\u5934\u662f\u5305\uff0c\u5e76\u5728\u632b\u6298\u4e2d\u6b65\u6b65\u9000\u7f29\u3002\u901a\u8bfb\u6559\u6750\u4e5f\u662f\u4e00\u79cd\u5e38\u89c1\u505a\u6cd5\uff0c\u4f46\u5bf9\u4e8e\u9762\u5411\u6c42\u804c\u7684\u4eba\u6765\u8bf4\uff0c\u6bd5\u4e1a\u8bba\u6587\u3001\u6295\u9012\u7b80\u5386\u3001\u51c6\u5907\u7b14\u8bd5\u548c\u9762\u8bd5\u5df2\u7ecf\u6d88\u8017\u4e86\u5927\u90e8\u5206\u7cbe\u529b\uff0c\u5543\u539a\u91cd\u7684\u4e66\u5f80\u5f80\u53d8\u6210\u4e86\u4e00\u9879\u8270\u5de8\u7684\u6311\u6218\u3002

    \u5982\u679c\u4f60\u4e5f\u9762\u4e34\u7c7b\u4f3c\u7684\u56f0\u6270\uff0c\u90a3\u4e48\u5f88\u5e78\u8fd0\u8fd9\u672c\u4e66\u201c\u627e\u201d\u5230\u4e86\u4f60\u3002\u672c\u4e66\u662f\u6211\u5bf9\u8fd9\u4e2a\u95ee\u9898\u7ed9\u51fa\u7684\u7b54\u6848\uff0c\u5373\u4f7f\u4e0d\u662f\u6700\u4f18\u89e3\uff0c\u4e5f\u81f3\u5c11\u662f\u4e00\u6b21\u79ef\u6781\u7684\u5c1d\u8bd5\u3002\u672c\u4e66\u867d\u7136\u4e0d\u8db3\u4ee5\u8ba9\u4f60\u76f4\u63a5\u62ff\u5230 Offer\uff0c\u4f46\u4f1a\u5f15\u5bfc\u4f60\u63a2\u7d22\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u201c\u77e5\u8bc6\u5730\u56fe\u201d\uff0c\u5e26\u4f60\u4e86\u89e3\u4e0d\u540c\u201c\u5730\u96f7\u201d\u7684\u5f62\u72b6\u3001\u5927\u5c0f\u548c\u5206\u5e03\u4f4d\u7f6e\uff0c\u8ba9\u4f60\u638c\u63e1\u5404\u79cd\u201c\u6392\u96f7\u65b9\u6cd5\u201d\u3002\u6709\u4e86\u8fd9\u4e9b\u672c\u9886\uff0c\u76f8\u4fe1\u4f60\u53ef\u4ee5\u66f4\u52a0\u81ea\u5982\u5730\u5237\u9898\u548c\u9605\u8bfb\u6587\u732e\uff0c\u9010\u6b65\u6784\u5efa\u8d77\u5b8c\u6574\u7684\u77e5\u8bc6\u4f53\u7cfb\u3002

    \u6211\u6df1\u6df1\u8d5e\u540c\u8d39\u66fc\u6559\u6388\u6240\u8a00\uff1a\u201cKnowledge isn't free. You have to pay attention.\u201d\u4ece\u8fd9\u4e2a\u610f\u4e49\u4e0a\u770b\uff0c\u8fd9\u672c\u4e66\u5e76\u975e\u5b8c\u5168\u201c\u514d\u8d39\u201d\u3002\u4e3a\u4e86\u4e0d\u8f9c\u8d1f\u4f60\u4e3a\u672c\u4e66\u6240\u4ed8\u51fa\u7684\u5b9d\u8d35\u201c\u6ce8\u610f\u529b\u201d\uff0c\u6211\u4f1a\u7aed\u5c3d\u6240\u80fd\uff0c\u6295\u5165\u6700\u5927\u7684\u201c\u6ce8\u610f\u529b\u201d\u6765\u5b8c\u6210\u672c\u4e66\u7684\u521b\u4f5c\u3002

    \u672c\u4eba\u81ea\u77e5\u5b66\u758f\u624d\u6d45\uff0c\u4e66\u4e2d\u5185\u5bb9\u867d\u7136\u5df2\u7ecf\u8fc7\u4e00\u6bb5\u65f6\u95f4\u7684\u6253\u78e8\uff0c\u4f46\u4e00\u5b9a\u4ecd\u6709\u8bb8\u591a\u9519\u8bef\uff0c\u6073\u8bf7\u5404\u4f4d\u8001\u5e08\u548c\u540c\u5b66\u6279\u8bc4\u6307\u6b63\u3002

    Hello\uff0c\u7b97\u6cd5\uff01

    \u8ba1\u7b97\u673a\u7684\u51fa\u73b0\u7ed9\u4e16\u754c\u5e26\u6765\u4e86\u5de8\u5927\u53d8\u9769\uff0c\u5b83\u51ed\u501f\u9ad8\u901f\u7684\u8ba1\u7b97\u80fd\u529b\u548c\u51fa\u8272\u7684\u53ef\u7f16\u7a0b\u6027\uff0c\u6210\u4e3a\u4e86\u6267\u884c\u7b97\u6cd5\u4e0e\u5904\u7406\u6570\u636e\u7684\u7406\u60f3\u5a92\u4ecb\u3002\u65e0\u8bba\u662f\u7535\u5b50\u6e38\u620f\u7684\u903c\u771f\u753b\u9762\u3001\u81ea\u52a8\u9a7e\u9a76\u7684\u667a\u80fd\u51b3\u7b56\uff0c\u8fd8\u662f AlphaGo \u7684\u7cbe\u5f69\u68cb\u5c40\u3001ChatGPT \u7684\u81ea\u7136\u4ea4\u4e92\uff0c\u8fd9\u4e9b\u5e94\u7528\u90fd\u662f\u7b97\u6cd5\u5728\u8ba1\u7b97\u673a\u4e0a\u7684\u7cbe\u5999\u6f14\u7ece\u3002

    \u4e8b\u5b9e\u4e0a\uff0c\u5728\u8ba1\u7b97\u673a\u95ee\u4e16\u4e4b\u524d\uff0c\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u5c31\u5df2\u7ecf\u5b58\u5728\u4e8e\u4e16\u754c\u7684\u5404\u4e2a\u89d2\u843d\u3002\u65e9\u671f\u7684\u7b97\u6cd5\u76f8\u5bf9\u7b80\u5355\uff0c\u4f8b\u5982\u53e4\u4ee3\u7684\u8ba1\u6570\u65b9\u6cd5\u548c\u5de5\u5177\u5236\u4f5c\u6b65\u9aa4\u7b49\u3002\u968f\u7740\u6587\u660e\u7684\u8fdb\u6b65\uff0c\u7b97\u6cd5\u9010\u6e10\u53d8\u5f97\u66f4\u52a0\u7cbe\u7ec6\u548c\u590d\u6742\u3002\u4ece\u5de7\u593a\u5929\u5de5\u7684\u5320\u4eba\u6280\u827a\u3001\u5230\u89e3\u653e\u751f\u4ea7\u529b\u7684\u5de5\u4e1a\u4ea7\u54c1\u3001\u518d\u5230\u5b87\u5b99\u8fd0\u884c\u7684\u79d1\u5b66\u89c4\u5f8b\uff0c\u51e0\u4e4e\u6bcf\u4e00\u4ef6\u5e73\u51e1\u6216\u4ee4\u4eba\u60ca\u53f9\u7684\u4e8b\u7269\u80cc\u540e\uff0c\u90fd\u9690\u85cf\u7740\u7cbe\u5999\u7684\u7b97\u6cd5\u601d\u60f3\u3002

    \u540c\u6837\uff0c\u6570\u636e\u7ed3\u6784\u65e0\u5904\u4e0d\u5728\uff1a\u5927\u5230\u793e\u4f1a\u7f51\u7edc\uff0c\u5c0f\u5230\u5730\u94c1\u7ebf\u8def\uff0c\u8bb8\u591a\u7cfb\u7edf\u90fd\u53ef\u4ee5\u5efa\u6a21\u4e3a\u201c\u56fe\u201d\uff1b\u5927\u5230\u4e00\u4e2a\u56fd\u5bb6\uff0c\u5c0f\u5230\u4e00\u4e2a\u5bb6\u5ead\uff0c\u793e\u4f1a\u7684\u4e3b\u8981\u7ec4\u7ec7\u5f62\u5f0f\u5448\u73b0\u51fa\u201c\u6811\u201d\u7684\u7279\u5f81\uff1b\u51ac\u5929\u7684\u8863\u670d\u5c31\u50cf\u201c\u6808\u201d\uff0c\u6700\u5148\u7a7f\u4e0a\u7684\u6700\u540e\u624d\u80fd\u8131\u4e0b\uff1b\u7fbd\u6bdb\u7403\u7b52\u5219\u5982\u540c\u201c\u961f\u5217\u201d\uff0c\u4e00\u7aef\u653e\u5165\u3001\u53e6\u4e00\u7aef\u53d6\u51fa\uff1b\u5b57\u5178\u5c31\u50cf\u4e00\u4e2a\u201c\u54c8\u5e0c\u8868\u201d\uff0c\u80fd\u591f\u5feb\u901f\u67e5\u627e\u76ee\u6807\u8bcd\u6761\u3002

    \u672c\u4e66\u65e8\u5728\u901a\u8fc7\u6e05\u6670\u6613\u61c2\u7684\u52a8\u753b\u56fe\u89e3\u548c\u53ef\u8fd0\u884c\u7684\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u7406\u89e3\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u80fd\u591f\u901a\u8fc7\u7f16\u7a0b\u6765\u5b9e\u73b0\u5b83\u4eec\u3002\u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u672c\u4e66\u81f4\u529b\u4e8e\u63ed\u793a\u7b97\u6cd5\u5728\u590d\u6742\u4e16\u754c\u4e2d\u7684\u751f\u52a8\u4f53\u73b0\uff0c\u5c55\u73b0\u7b97\u6cd5\u4e4b\u7f8e\u3002\u5e0c\u671b\u672c\u4e66\u80fd\u591f\u5e2e\u52a9\u5230\u4f60\uff01

    "},{"location":"chapter_introduction/","title":"\u7b2c 1 \u7ae0 \u00a0 \u521d\u8bc6\u7b97\u6cd5","text":"

    Abstract

    \u4e00\u4f4d\u5c11\u5973\u7fe9\u7fe9\u8d77\u821e\uff0c\u4e0e\u6570\u636e\u4ea4\u7ec7\u5728\u4e00\u8d77\uff0c\u88d9\u6446\u4e0a\u98d8\u626c\u7740\u7b97\u6cd5\u7684\u65cb\u5f8b\u3002

    \u5979\u9080\u8bf7\u4f60\u5171\u821e\uff0c\u8bf7\u7d27\u8ddf\u5979\u7684\u6b65\u4f10\uff0c\u8e0f\u5165\u5145\u6ee1\u903b\u8f91\u4e0e\u7f8e\u611f\u7684\u7b97\u6cd5\u4e16\u754c\u3002

    "},{"location":"chapter_introduction/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 1.1 \u00a0 \u7b97\u6cd5\u65e0\u5904\u4e0d\u5728
    • 1.2 \u00a0 \u7b97\u6cd5\u662f\u4ec0\u4e48
    • 1.3 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_introduction/algorithms_are_everywhere/","title":"1.1 \u00a0 \u7b97\u6cd5\u65e0\u5904\u4e0d\u5728","text":"

    \u5f53\u6211\u4eec\u542c\u5230\u201c\u7b97\u6cd5\u201d\u8fd9\u4e2a\u8bcd\u65f6\uff0c\u5f88\u81ea\u7136\u5730\u4f1a\u60f3\u5230\u6570\u5b66\u3002\u7136\u800c\u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u7b97\u6cd5\u5e76\u4e0d\u6d89\u53ca\u590d\u6742\u6570\u5b66\uff0c\u800c\u662f\u66f4\u591a\u5730\u4f9d\u8d56\u57fa\u672c\u903b\u8f91\uff0c\u8fd9\u4e9b\u903b\u8f91\u5728\u6211\u4eec\u7684\u65e5\u5e38\u751f\u6d3b\u4e2d\u5904\u5904\u53ef\u89c1\u3002

    \u5728\u6b63\u5f0f\u63a2\u8ba8\u7b97\u6cd5\u4e4b\u524d\uff0c\u6709\u4e00\u4e2a\u6709\u8da3\u7684\u4e8b\u5b9e\u503c\u5f97\u5206\u4eab\uff1a\u4f60\u5df2\u7ecf\u5728\u4e0d\u77e5\u4e0d\u89c9\u4e2d\u5b66\u4f1a\u4e86\u8bb8\u591a\u7b97\u6cd5\uff0c\u5e76\u4e60\u60ef\u5c06\u5b83\u4eec\u5e94\u7528\u5230\u65e5\u5e38\u751f\u6d3b\u4e2d\u4e86\u3002\u4e0b\u9762\u6211\u5c06\u4e3e\u51e0\u4e2a\u5177\u4f53\u7684\u4f8b\u5b50\u6765\u8bc1\u5b9e\u8fd9\u4e00\u70b9\u3002

    \u4f8b\u4e00\uff1a\u67e5\u5b57\u5178\u3002\u5728\u5b57\u5178\u91cc\uff0c\u6bcf\u4e2a\u6c49\u5b57\u90fd\u5bf9\u5e94\u4e00\u4e2a\u62fc\u97f3\uff0c\u800c\u5b57\u5178\u662f\u6309\u7167\u62fc\u97f3\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\u7684\u3002\u5047\u8bbe\u6211\u4eec\u9700\u8981\u67e5\u627e\u4e00\u4e2a\u62fc\u97f3\u9996\u5b57\u6bcd\u4e3a \\(r\\) \u7684\u5b57\uff0c\u901a\u5e38\u4f1a\u6309\u7167\u56fe 1-1 \u6240\u793a\u7684\u65b9\u5f0f\u5b9e\u73b0\u3002

    1. \u7ffb\u5f00\u5b57\u5178\u7ea6\u4e00\u534a\u7684\u9875\u6570\uff0c\u67e5\u770b\u8be5\u9875\u7684\u9996\u5b57\u6bcd\u662f\u4ec0\u4e48\uff0c\u5047\u8bbe\u9996\u5b57\u6bcd\u4e3a \\(m\\) \u3002
    2. \u7531\u4e8e\u5728\u62fc\u97f3\u5b57\u6bcd\u8868\u4e2d \\(r\\) \u4f4d\u4e8e \\(m\\) \u4e4b\u540e\uff0c\u6240\u4ee5\u6392\u9664\u5b57\u5178\u524d\u534a\u90e8\u5206\uff0c\u67e5\u627e\u8303\u56f4\u7f29\u5c0f\u5230\u540e\u534a\u90e8\u5206\u3002
    3. \u4e0d\u65ad\u91cd\u590d\u6b65\u9aa4 1. \u548c \u6b65\u9aa4 2. \uff0c\u76f4\u81f3\u627e\u5230\u62fc\u97f3\u9996\u5b57\u6bcd\u4e3a \\(r\\) \u7684\u9875\u7801\u4e3a\u6b62\u3002
    <1><2><3><4><5>

    \u56fe 1-1 \u00a0 \u67e5\u5b57\u5178\u6b65\u9aa4

    \u67e5\u5b57\u5178\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5fc5\u5907\u6280\u80fd\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u8457\u540d\u7684\u201c\u4e8c\u5206\u67e5\u627e\u201d\u7b97\u6cd5\u3002\u4ece\u6570\u636e\u7ed3\u6784\u7684\u89d2\u5ea6\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u5b57\u5178\u89c6\u4e3a\u4e00\u4e2a\u5df2\u6392\u5e8f\u7684\u201c\u6570\u7ec4\u201d\uff1b\u4ece\u7b97\u6cd5\u7684\u89d2\u5ea6\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u4e0a\u8ff0\u67e5\u5b57\u5178\u7684\u4e00\u7cfb\u5217\u64cd\u4f5c\u770b\u4f5c\u201c\u4e8c\u5206\u67e5\u627e\u201d\u3002

    \u4f8b\u4e8c\uff1a\u6574\u7406\u6251\u514b\u3002\u6211\u4eec\u5728\u6253\u724c\u65f6\uff0c\u6bcf\u5c40\u90fd\u9700\u8981\u6574\u7406\u624b\u4e2d\u7684\u6251\u514b\u724c\uff0c\u4f7f\u5176\u4ece\u5c0f\u5230\u5927\u6392\u5217\uff0c\u5b9e\u73b0\u6d41\u7a0b\u5982\u56fe 1-2 \u6240\u793a\u3002

    1. \u5c06\u6251\u514b\u724c\u5212\u5206\u4e3a\u201c\u6709\u5e8f\u201d\u548c\u201c\u65e0\u5e8f\u201d\u4e24\u90e8\u5206\uff0c\u5e76\u5047\u8bbe\u521d\u59cb\u72b6\u6001\u4e0b\u6700\u5de6 1 \u5f20\u6251\u514b\u724c\u5df2\u7ecf\u6709\u5e8f\u3002
    2. \u5728\u65e0\u5e8f\u90e8\u5206\u62bd\u51fa\u4e00\u5f20\u6251\u514b\u724c\uff0c\u63d2\u5165\u81f3\u6709\u5e8f\u90e8\u5206\u7684\u6b63\u786e\u4f4d\u7f6e\uff1b\u5b8c\u6210\u540e\u6700\u5de6 2 \u5f20\u6251\u514b\u5df2\u7ecf\u6709\u5e8f\u3002
    3. \u4e0d\u65ad\u5faa\u73af\u6b65\u9aa4 2. \uff0c\u6bcf\u4e00\u8f6e\u5c06\u4e00\u5f20\u6251\u514b\u724c\u4ece\u65e0\u5e8f\u90e8\u5206\u63d2\u5165\u81f3\u6709\u5e8f\u90e8\u5206\uff0c\u76f4\u81f3\u6240\u6709\u6251\u514b\u724c\u90fd\u6709\u5e8f\u3002

    \u56fe 1-2 \u00a0 \u6251\u514b\u6392\u5e8f\u6b65\u9aa4

    \u4e0a\u8ff0\u6574\u7406\u6251\u514b\u724c\u7684\u65b9\u6cd5\u672c\u8d28\u4e0a\u662f\u201c\u63d2\u5165\u6392\u5e8f\u201d\u7b97\u6cd5\uff0c\u5b83\u5728\u5904\u7406\u5c0f\u578b\u6570\u636e\u96c6\u65f6\u975e\u5e38\u9ad8\u6548\u3002\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\u7684\u6392\u5e8f\u5e93\u51fd\u6570\u4e2d\u90fd\u6709\u63d2\u5165\u6392\u5e8f\u7684\u8eab\u5f71\u3002

    \u4f8b\u4e09\uff1a\u8d27\u5e01\u627e\u96f6\u3002\u5047\u8bbe\u6211\u4eec\u5728\u8d85\u5e02\u8d2d\u4e70\u4e86 \\(69\\) \u5143\u7684\u5546\u54c1\uff0c\u7ed9\u4e86\u6536\u94f6\u5458 \\(100\\) \u5143\uff0c\u5219\u6536\u94f6\u5458\u9700\u8981\u627e\u6211\u4eec \\(31\\) \u5143\u3002\u4ed6\u4f1a\u5f88\u81ea\u7136\u5730\u5b8c\u6210\u5982\u56fe 1-3 \u6240\u793a\u7684\u601d\u8003\u3002

    1. \u53ef\u9009\u9879\u662f\u6bd4 \\(31\\) \u5143\u9762\u503c\u66f4\u5c0f\u7684\u8d27\u5e01\uff0c\u5305\u62ec \\(1\\) \u5143\u3001\\(5\\) \u5143\u3001\\(10\\) \u5143\u3001\\(20\\) \u5143\u3002
    2. \u4ece\u53ef\u9009\u9879\u4e2d\u62ff\u51fa\u6700\u5927\u7684 \\(20\\) \u5143\uff0c\u5269\u4f59 \\(31 - 20 = 11\\) \u5143\u3002
    3. \u4ece\u5269\u4f59\u53ef\u9009\u9879\u4e2d\u62ff\u51fa\u6700\u5927\u7684 \\(10\\) \u5143\uff0c\u5269\u4f59 \\(11 - 10 = 1\\) \u5143\u3002
    4. \u4ece\u5269\u4f59\u53ef\u9009\u9879\u4e2d\u62ff\u51fa\u6700\u5927\u7684 \\(1\\) \u5143\uff0c\u5269\u4f59 \\(1 - 1 = 0\\) \u5143\u3002
    5. \u5b8c\u6210\u627e\u96f6\uff0c\u65b9\u6848\u4e3a \\(20 + 10 + 1 = 31\\) \u5143\u3002

    \u56fe 1-3 \u00a0 \u8d27\u5e01\u627e\u96f6\u8fc7\u7a0b

    \u5728\u4ee5\u4e0a\u6b65\u9aa4\u4e2d\uff0c\u6211\u4eec\u6bcf\u4e00\u6b65\u90fd\u91c7\u53d6\u5f53\u524d\u770b\u6765\u6700\u597d\u7684\u9009\u62e9\uff08\u5c3d\u53ef\u80fd\u7528\u5927\u9762\u989d\u7684\u8d27\u5e01\uff09\uff0c\u6700\u7ec8\u5f97\u5230\u4e86\u53ef\u884c\u7684\u627e\u96f6\u65b9\u6848\u3002\u4ece\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u89d2\u5ea6\u770b\uff0c\u8fd9\u79cd\u65b9\u6cd5\u672c\u8d28\u4e0a\u662f\u201c\u8d2a\u5fc3\u201d\u7b97\u6cd5\u3002

    \u5c0f\u5230\u70f9\u996a\u4e00\u9053\u83dc\uff0c\u5927\u5230\u661f\u9645\u822a\u884c\uff0c\u51e0\u4e4e\u6240\u6709\u95ee\u9898\u7684\u89e3\u51b3\u90fd\u79bb\u4e0d\u5f00\u7b97\u6cd5\u3002\u8ba1\u7b97\u673a\u7684\u51fa\u73b0\u4f7f\u5f97\u6211\u4eec\u80fd\u591f\u901a\u8fc7\u7f16\u7a0b\u5c06\u6570\u636e\u7ed3\u6784\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\uff0c\u540c\u65f6\u7f16\u5199\u4ee3\u7801\u8c03\u7528 CPU \u548c GPU \u6267\u884c\u7b97\u6cd5\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u6211\u4eec\u5c31\u80fd\u628a\u751f\u6d3b\u4e2d\u7684\u95ee\u9898\u8f6c\u79fb\u5230\u8ba1\u7b97\u673a\u4e0a\uff0c\u4ee5\u66f4\u9ad8\u6548\u7684\u65b9\u5f0f\u89e3\u51b3\u5404\u79cd\u590d\u6742\u95ee\u9898\u3002

    Tip

    \u5982\u679c\u4f60\u5bf9\u6570\u636e\u7ed3\u6784\u3001\u7b97\u6cd5\u3001\u6570\u7ec4\u548c\u4e8c\u5206\u67e5\u627e\u7b49\u6982\u5ff5\u4ecd\u611f\u5230\u4e00\u77e5\u534a\u89e3\uff0c\u8bf7\u7ee7\u7eed\u5f80\u4e0b\u9605\u8bfb\uff0c\u672c\u4e66\u5c06\u5f15\u5bfc\u4f60\u8fc8\u5165\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u77e5\u8bc6\u6bbf\u5802\u3002

    "},{"location":"chapter_introduction/summary/","title":"1.3 \u00a0 \u5c0f\u7ed3","text":"
    • \u7b97\u6cd5\u5728\u65e5\u5e38\u751f\u6d3b\u4e2d\u65e0\u5904\u4e0d\u5728\uff0c\u5e76\u4e0d\u662f\u9065\u4e0d\u53ef\u53ca\u7684\u9ad8\u6df1\u77e5\u8bc6\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u5df2\u7ecf\u5728\u4e0d\u77e5\u4e0d\u89c9\u4e2d\u5b66\u4f1a\u4e86\u8bb8\u591a\u7b97\u6cd5\uff0c\u7528\u4ee5\u89e3\u51b3\u751f\u6d3b\u4e2d\u7684\u5927\u5c0f\u95ee\u9898\u3002
    • \u67e5\u5b57\u5178\u7684\u539f\u7406\u4e0e\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u76f8\u4e00\u81f4\u3002\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u4f53\u73b0\u4e86\u5206\u800c\u6cbb\u4e4b\u7684\u91cd\u8981\u7b97\u6cd5\u601d\u60f3\u3002
    • \u6574\u7406\u6251\u514b\u7684\u8fc7\u7a0b\u4e0e\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\u975e\u5e38\u7c7b\u4f3c\u3002\u63d2\u5165\u6392\u5e8f\u7b97\u6cd5\u9002\u5408\u6392\u5e8f\u5c0f\u578b\u6570\u636e\u96c6\u3002
    • \u8d27\u5e01\u627e\u96f6\u7684\u6b65\u9aa4\u672c\u8d28\u4e0a\u662f\u8d2a\u5fc3\u7b97\u6cd5\uff0c\u6bcf\u4e00\u6b65\u90fd\u91c7\u53d6\u5f53\u524d\u770b\u6765\u6700\u597d\u7684\u9009\u62e9\u3002
    • \u7b97\u6cd5\u662f\u5728\u6709\u9650\u65f6\u95f4\u5185\u89e3\u51b3\u7279\u5b9a\u95ee\u9898\u7684\u4e00\u7ec4\u6307\u4ee4\u6216\u64cd\u4f5c\u6b65\u9aa4\uff0c\u800c\u6570\u636e\u7ed3\u6784\u662f\u8ba1\u7b97\u673a\u4e2d\u7ec4\u7ec7\u548c\u5b58\u50a8\u6570\u636e\u7684\u65b9\u5f0f\u3002
    • \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7d27\u5bc6\u76f8\u8fde\u3002\u6570\u636e\u7ed3\u6784\u662f\u7b97\u6cd5\u7684\u57fa\u77f3\uff0c\u800c\u7b97\u6cd5\u662f\u6570\u636e\u7ed3\u6784\u53d1\u6325\u4f5c\u7528\u7684\u821e\u53f0\u3002
    • \u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7c7b\u6bd4\u4e3a\u62fc\u88c5\u79ef\u6728\uff0c\u79ef\u6728\u4ee3\u8868\u6570\u636e\uff0c\u79ef\u6728\u7684\u5f62\u72b6\u548c\u8fde\u63a5\u65b9\u5f0f\u7b49\u4ee3\u8868\u6570\u636e\u7ed3\u6784\uff0c\u62fc\u88c5\u79ef\u6728\u7684\u6b65\u9aa4\u5219\u5bf9\u5e94\u7b97\u6cd5\u3002
    "},{"location":"chapter_introduction/summary/#1-q-a","title":"1. \u00a0 Q & A","text":"

    Q\uff1a\u4f5c\u4e3a\u4e00\u540d\u7a0b\u5e8f\u5458\uff0c\u6211\u5728\u65e5\u5e38\u5de5\u4f5c\u4e2d\u4ece\u672a\u7528\u7b97\u6cd5\u89e3\u51b3\u8fc7\u95ee\u9898\uff0c\u5e38\u7528\u7b97\u6cd5\u90fd\u88ab\u7f16\u7a0b\u8bed\u8a00\u5c01\u88c5\u597d\u4e86\uff0c\u76f4\u63a5\u7528\u5c31\u53ef\u4ee5\u4e86\uff1b\u8fd9\u662f\u5426\u610f\u5473\u7740\u6211\u4eec\u5de5\u4f5c\u4e2d\u7684\u95ee\u9898\u8fd8\u6ca1\u6709\u5230\u8fbe\u9700\u8981\u7b97\u6cd5\u7684\u7a0b\u5ea6\uff1f

    \u5982\u679c\u628a\u5177\u4f53\u7684\u5de5\u4f5c\u6280\u80fd\u6bd4\u4f5c\u662f\u6b66\u529f\u7684\u201c\u62db\u5f0f\u201d\u7684\u8bdd\uff0c\u90a3\u4e48\u57fa\u7840\u79d1\u76ee\u5e94\u8be5\u66f4\u50cf\u662f\u201c\u5185\u529f\u201d\u3002

    \u6211\u8ba4\u4e3a\u5b66\u7b97\u6cd5\uff08\u4ee5\u53ca\u5176\u4ed6\u57fa\u7840\u79d1\u76ee\uff09\u7684\u610f\u4e49\u4e0d\u662f\u5728\u4e8e\u5728\u5de5\u4f5c\u4e2d\u4ece\u96f6\u5b9e\u73b0\u5b83\uff0c\u800c\u662f\u57fa\u4e8e\u5b66\u5230\u7684\u77e5\u8bc6\uff0c\u5728\u89e3\u51b3\u95ee\u9898\u65f6\u80fd\u591f\u4f5c\u51fa\u4e13\u4e1a\u7684\u53cd\u5e94\u548c\u5224\u65ad\uff0c\u4ece\u800c\u63d0\u5347\u5de5\u4f5c\u7684\u6574\u4f53\u8d28\u91cf\u3002\u4e3e\u4e00\u4e2a\u7b80\u5355\u4f8b\u5b50\uff0c\u6bcf\u79cd\u7f16\u7a0b\u8bed\u8a00\u90fd\u5185\u7f6e\u4e86\u6392\u5e8f\u51fd\u6570\uff1a

    • \u5982\u679c\u6211\u4eec\u6ca1\u6709\u5b66\u8fc7\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\uff0c\u90a3\u4e48\u7ed9\u5b9a\u4efb\u4f55\u6570\u636e\uff0c\u6211\u4eec\u53ef\u80fd\u90fd\u585e\u7ed9\u8fd9\u4e2a\u6392\u5e8f\u51fd\u6570\u53bb\u505a\u4e86\u3002\u8fd0\u884c\u987a\u7545\u3001\u6027\u80fd\u4e0d\u9519\uff0c\u770b\u4e0a\u53bb\u5e76\u6ca1\u6709\u4ec0\u4e48\u95ee\u9898\u3002
    • \u4f46\u5982\u679c\u5b66\u8fc7\u7b97\u6cd5\uff0c\u6211\u4eec\u5c31\u4f1a\u77e5\u9053\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(n \\log n)\\) \uff1b\u800c\u5982\u679c\u7ed9\u5b9a\u7684\u6570\u636e\u662f\u56fa\u5b9a\u4f4d\u6570\u7684\u6574\u6570\uff08\u4f8b\u5982\u5b66\u53f7\uff09\uff0c\u90a3\u4e48\u6211\u4eec\u5c31\u53ef\u4ee5\u7528\u6548\u7387\u66f4\u9ad8\u7684\u201c\u57fa\u6570\u6392\u5e8f\u201d\u6765\u505a\uff0c\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u964d\u4e3a \\(O(nk)\\) \uff0c\u5176\u4e2d \\(k\\) \u4e3a\u4f4d\u6570\u3002\u5f53\u6570\u636e\u4f53\u91cf\u5f88\u5927\u65f6\uff0c\u8282\u7701\u51fa\u6765\u7684\u8fd0\u884c\u65f6\u95f4\u5c31\u80fd\u521b\u9020\u8f83\u5927\u4ef7\u503c\uff08\u6210\u672c\u964d\u4f4e\u3001\u4f53\u9a8c\u53d8\u597d\u7b49\uff09\u3002

    \u5728\u5de5\u7a0b\u9886\u57df\u4e2d\uff0c\u5927\u91cf\u95ee\u9898\u662f\u96be\u4ee5\u8fbe\u5230\u6700\u4f18\u89e3\u7684\uff0c\u8bb8\u591a\u95ee\u9898\u53ea\u662f\u88ab\u201c\u5dee\u4e0d\u591a\u201d\u5730\u89e3\u51b3\u4e86\u3002\u95ee\u9898\u7684\u96be\u6613\u7a0b\u5ea6\u4e00\u65b9\u9762\u53d6\u51b3\u4e8e\u95ee\u9898\u672c\u8eab\u7684\u6027\u8d28\uff0c\u53e6\u4e00\u65b9\u9762\u4e5f\u53d6\u51b3\u4e8e\u89c2\u6d4b\u95ee\u9898\u7684\u4eba\u7684\u77e5\u8bc6\u50a8\u5907\u3002\u4eba\u7684\u77e5\u8bc6\u8d8a\u5b8c\u5907\u3001\u7ecf\u9a8c\u8d8a\u591a\uff0c\u5206\u6790\u95ee\u9898\u5c31\u4f1a\u8d8a\u6df1\u5165\uff0c\u95ee\u9898\u5c31\u80fd\u88ab\u89e3\u51b3\u5f97\u66f4\u4f18\u96c5\u3002

    "},{"location":"chapter_introduction/what_is_dsa/","title":"1.2 \u00a0 \u7b97\u6cd5\u662f\u4ec0\u4e48","text":""},{"location":"chapter_introduction/what_is_dsa/#121","title":"1.2.1 \u00a0 \u7b97\u6cd5\u5b9a\u4e49","text":"

    \u7b97\u6cd5\uff08algorithm\uff09\u662f\u5728\u6709\u9650\u65f6\u95f4\u5185\u89e3\u51b3\u7279\u5b9a\u95ee\u9898\u7684\u4e00\u7ec4\u6307\u4ee4\u6216\u64cd\u4f5c\u6b65\u9aa4\uff0c\u5b83\u5177\u6709\u4ee5\u4e0b\u7279\u6027\u3002

    • \u95ee\u9898\u662f\u660e\u786e\u7684\uff0c\u5305\u542b\u6e05\u6670\u7684\u8f93\u5165\u548c\u8f93\u51fa\u5b9a\u4e49\u3002
    • \u5177\u6709\u53ef\u884c\u6027\uff0c\u80fd\u591f\u5728\u6709\u9650\u6b65\u9aa4\u3001\u65f6\u95f4\u548c\u5185\u5b58\u7a7a\u95f4\u4e0b\u5b8c\u6210\u3002
    • \u5404\u6b65\u9aa4\u90fd\u6709\u786e\u5b9a\u7684\u542b\u4e49\uff0c\u5728\u76f8\u540c\u7684\u8f93\u5165\u548c\u8fd0\u884c\u6761\u4ef6\u4e0b\uff0c\u8f93\u51fa\u59cb\u7ec8\u76f8\u540c\u3002
    "},{"location":"chapter_introduction/what_is_dsa/#122","title":"1.2.2 \u00a0 \u6570\u636e\u7ed3\u6784\u5b9a\u4e49","text":"

    \u6570\u636e\u7ed3\u6784\uff08data structure\uff09\u662f\u8ba1\u7b97\u673a\u4e2d\u7ec4\u7ec7\u548c\u5b58\u50a8\u6570\u636e\u7684\u65b9\u5f0f\uff0c\u5177\u6709\u4ee5\u4e0b\u8bbe\u8ba1\u76ee\u6807\u3002

    • \u7a7a\u95f4\u5360\u7528\u5c3d\u91cf\u5c11\uff0c\u4ee5\u8282\u7701\u8ba1\u7b97\u673a\u5185\u5b58\u3002
    • \u6570\u636e\u64cd\u4f5c\u5c3d\u53ef\u80fd\u5feb\u901f\uff0c\u6db5\u76d6\u6570\u636e\u8bbf\u95ee\u3001\u6dfb\u52a0\u3001\u5220\u9664\u3001\u66f4\u65b0\u7b49\u3002
    • \u63d0\u4f9b\u7b80\u6d01\u7684\u6570\u636e\u8868\u793a\u548c\u903b\u8f91\u4fe1\u606f\uff0c\u4ee5\u4fbf\u7b97\u6cd5\u9ad8\u6548\u8fd0\u884c\u3002

    \u6570\u636e\u7ed3\u6784\u8bbe\u8ba1\u662f\u4e00\u4e2a\u5145\u6ee1\u6743\u8861\u7684\u8fc7\u7a0b\u3002\u5982\u679c\u60f3\u5728\u67d0\u65b9\u9762\u53d6\u5f97\u63d0\u5347\uff0c\u5f80\u5f80\u9700\u8981\u5728\u53e6\u4e00\u65b9\u9762\u4f5c\u51fa\u59a5\u534f\u3002\u4e0b\u9762\u4e3e\u4e24\u4e2a\u4f8b\u5b50\u3002

    • \u94fe\u8868\u76f8\u8f83\u4e8e\u6570\u7ec4\uff0c\u5728\u6570\u636e\u6dfb\u52a0\u548c\u5220\u9664\u64cd\u4f5c\u4e0a\u66f4\u52a0\u4fbf\u6377\uff0c\u4f46\u727a\u7272\u4e86\u6570\u636e\u8bbf\u95ee\u901f\u5ea6\u3002
    • \u56fe\u76f8\u8f83\u4e8e\u94fe\u8868\uff0c\u63d0\u4f9b\u4e86\u66f4\u4e30\u5bcc\u7684\u903b\u8f91\u4fe1\u606f\uff0c\u4f46\u9700\u8981\u5360\u7528\u66f4\u5927\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    "},{"location":"chapter_introduction/what_is_dsa/#123","title":"1.2.3 \u00a0 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u5173\u7cfb","text":"

    \u5982\u56fe 1-4 \u6240\u793a\uff0c\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u9ad8\u5ea6\u76f8\u5173\u3001\u7d27\u5bc6\u7ed3\u5408\uff0c\u5177\u4f53\u8868\u73b0\u5728\u4ee5\u4e0b\u4e09\u4e2a\u65b9\u9762\u3002

    • \u6570\u636e\u7ed3\u6784\u662f\u7b97\u6cd5\u7684\u57fa\u77f3\u3002\u6570\u636e\u7ed3\u6784\u4e3a\u7b97\u6cd5\u63d0\u4f9b\u4e86\u7ed3\u6784\u5316\u5b58\u50a8\u7684\u6570\u636e\uff0c\u4ee5\u53ca\u64cd\u4f5c\u6570\u636e\u7684\u65b9\u6cd5\u3002
    • \u7b97\u6cd5\u662f\u6570\u636e\u7ed3\u6784\u53d1\u6325\u4f5c\u7528\u7684\u821e\u53f0\u3002\u6570\u636e\u7ed3\u6784\u672c\u8eab\u4ec5\u5b58\u50a8\u6570\u636e\u4fe1\u606f\uff0c\u7ed3\u5408\u7b97\u6cd5\u624d\u80fd\u89e3\u51b3\u7279\u5b9a\u95ee\u9898\u3002
    • \u7b97\u6cd5\u901a\u5e38\u53ef\u4ee5\u57fa\u4e8e\u4e0d\u540c\u7684\u6570\u636e\u7ed3\u6784\u5b9e\u73b0\uff0c\u4f46\u6267\u884c\u6548\u7387\u53ef\u80fd\u76f8\u5dee\u5f88\u5927\uff0c\u9009\u62e9\u5408\u9002\u7684\u6570\u636e\u7ed3\u6784\u662f\u5173\u952e\u3002

    \u56fe 1-4 \u00a0 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u5173\u7cfb

    \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u72b9\u5982\u56fe 1-5 \u6240\u793a\u7684\u62fc\u88c5\u79ef\u6728\u3002\u4e00\u5957\u79ef\u6728\uff0c\u9664\u4e86\u5305\u542b\u8bb8\u591a\u96f6\u4ef6\u4e4b\u5916\uff0c\u8fd8\u9644\u6709\u8be6\u7ec6\u7684\u7ec4\u88c5\u8bf4\u660e\u4e66\u3002\u6211\u4eec\u6309\u7167\u8bf4\u660e\u4e66\u4e00\u6b65\u6b65\u64cd\u4f5c\uff0c\u5c31\u80fd\u7ec4\u88c5\u51fa\u7cbe\u7f8e\u7684\u79ef\u6728\u6a21\u578b\u3002

    \u56fe 1-5 \u00a0 \u62fc\u88c5\u79ef\u6728

    \u4e24\u8005\u7684\u8be6\u7ec6\u5bf9\u5e94\u5173\u7cfb\u5982\u8868 1-1 \u6240\u793a\u3002

    \u8868 1-1 \u00a0 \u5c06\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7c7b\u6bd4\u4e3a\u62fc\u88c5\u79ef\u6728

    \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 \u62fc\u88c5\u79ef\u6728 \u8f93\u5165\u6570\u636e \u672a\u62fc\u88c5\u7684\u79ef\u6728 \u6570\u636e\u7ed3\u6784 \u79ef\u6728\u7ec4\u7ec7\u5f62\u5f0f\uff0c\u5305\u62ec\u5f62\u72b6\u3001\u5927\u5c0f\u3001\u8fde\u63a5\u65b9\u5f0f\u7b49 \u7b97\u6cd5 \u628a\u79ef\u6728\u62fc\u6210\u76ee\u6807\u5f62\u6001\u7684\u4e00\u7cfb\u5217\u64cd\u4f5c\u6b65\u9aa4 \u8f93\u51fa\u6570\u636e \u79ef\u6728\u6a21\u578b

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u662f\u72ec\u7acb\u4e8e\u7f16\u7a0b\u8bed\u8a00\u7684\u3002\u6b63\u56e0\u5982\u6b64\uff0c\u672c\u4e66\u5f97\u4ee5\u63d0\u4f9b\u57fa\u4e8e\u591a\u79cd\u7f16\u7a0b\u8bed\u8a00\u7684\u5b9e\u73b0\u3002

    \u7ea6\u5b9a\u4fd7\u6210\u7684\u7b80\u79f0

    \u5728\u5b9e\u9645\u8ba8\u8bba\u65f6\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5c06\u201c\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u201d\u7b80\u79f0\u4e3a\u201c\u7b97\u6cd5\u201d\u3002\u6bd4\u5982\u4f17\u6240\u5468\u77e5\u7684 LeetCode \u7b97\u6cd5\u9898\u76ee\uff0c\u5b9e\u9645\u4e0a\u540c\u65f6\u8003\u67e5\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u4e24\u65b9\u9762\u7684\u77e5\u8bc6\u3002

    "},{"location":"chapter_paperbook/","title":"\u7eb8\u8d28\u4e66","text":"

    \u7ecf\u8fc7\u957f\u65f6\u95f4\u7684\u6253\u78e8\uff0c\u300aHello \u7b97\u6cd5\u300b\u7eb8\u8d28\u4e66\u7ec8\u4e8e\u53d1\u5e03\u4e86\uff01\u6b64\u65f6\u7684\u5fc3\u60c5\u53ef\u4ee5\u7528\u4e00\u53e5\u8bd7\u6765\u5f62\u5bb9\uff1a

    \u8ffd\u98ce\u8d76\u6708\u83ab\u505c\u7559\uff0c\u5e73\u829c\u5c3d\u5904\u662f\u6625\u5c71\u3002

    \u4ee5\u4e0b\u89c6\u9891\u5c55\u793a\u4e86\u7eb8\u8d28\u4e66\uff0c\u5e76\u4e14\u5305\u542b\u6211\u7684\u4e00\u4e9b\u601d\u8003\uff1a

    • \u5b66\u4e60\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u91cd\u8981\u6027\u3002
    • \u4e3a\u4ec0\u4e48\u5728\u7eb8\u8d28\u4e66\u4e2d\u9009\u62e9 Python\u3002
    • \u5bf9\u77e5\u8bc6\u5206\u4eab\u7684\u7406\u89e3\u3002

    \u65b0\u4eba UP \u4e3b\uff0c\u8bf7\u591a\u591a\u5173\u7167\u3001\u4e00\u952e\u4e09\u8fde\uff5e\u8c22\u8c22\uff01

    \u9644\u7eb8\u8d28\u4e66\u5feb\u7167\uff1a

    "},{"location":"chapter_paperbook/#_2","title":"\u4f18\u52bf\u4e0e\u4e0d\u8db3","text":"

    \u603b\u7ed3\u4e00\u4e0b\u7eb8\u8d28\u4e66\u53ef\u80fd\u4f1a\u7ed9\u5927\u5bb6\u5e26\u6765\u60ca\u559c\u7684\u5730\u65b9\uff1a

    • \u91c7\u7528\u5168\u5f69\u5370\u5237\uff0c\u80fd\u591f\u539f\u6c41\u539f\u5473\u5730\u53d1\u6325\u51fa\u672c\u4e66\u201c\u52a8\u753b\u56fe\u89e3\u201d\u7684\u4f18\u52bf\u3002
    • \u8003\u7a76\u7eb8\u5f20\u6750\u8d28\uff0c\u65e2\u4fdd\u8bc1\u8272\u5f69\u9ad8\u5ea6\u8fd8\u539f\uff0c\u4e5f\u4fdd\u7559\u7eb8\u8d28\u4e66\u7279\u6709\u7684\u8d28\u611f\u3002
    • \u7eb8\u8d28\u7248\u6bd4\u7f51\u9875\u7248\u7684\u683c\u5f0f\u66f4\u52a0\u89c4\u8303\uff0c\u4f8b\u5982\u56fe\u4e2d\u7684\u516c\u5f0f\u4f7f\u7528\u659c\u4f53\u3002
    • \u5728\u4e0d\u63d0\u5347\u5b9a\u4ef7\u7684\u524d\u63d0\u4e0b\uff0c\u9644\u8d60\u601d\u7ef4\u5bfc\u56fe\u6298\u9875\u3001\u4e66\u7b7e\u3002
    • \u7eb8\u8d28\u4e66\u3001\u7f51\u9875\u7248\u3001PDF \u7248\u5185\u5bb9\u540c\u6b65\uff0c\u968f\u610f\u5207\u6362\u9605\u8bfb\u3002

    Tip

    \u7531\u4e8e\u7eb8\u8d28\u4e66\u548c\u7f51\u9875\u7248\u7684\u540c\u6b65\u96be\u5ea6\u8f83\u5927\uff0c\u56e0\u6b64\u53ef\u80fd\u4f1a\u6709\u4e00\u4e9b\u7ec6\u8282\u4e0a\u7684\u4e0d\u540c\uff0c\u8bf7\u60a8\u89c1\u8c05\uff01

    \u5f53\u7136\uff0c\u7eb8\u8d28\u4e66\u4e5f\u6709\u4e00\u4e9b\u503c\u5f97\u5927\u5bb6\u5165\u624b\u524d\u8003\u8651\u7684\u5730\u65b9\uff1a

    • \u4f7f\u7528 Python \u8bed\u8a00\uff0c\u53ef\u80fd\u4e0d\u5339\u914d\u4f60\u7684\u4e3b\u8bed\u8a00\uff08\u53ef\u4ee5\u628a Python \u770b\u4f5c\u4f2a\u4ee3\u7801\uff0c\u91cd\u5728\u7406\u89e3\u601d\u8def\uff09\u3002
    • \u5168\u5f69\u5370\u5237\u867d\u7136\u5927\u5e45\u63d0\u5347\u4e86\u56fe\u89e3\u548c\u4ee3\u7801\u7684\u9605\u8bfb\u4f53\u9a8c\uff0c\u4f46\u4ef7\u683c\u4f1a\u6bd4\u9ed1\u767d\u5370\u5237\u9ad8\u4e00\u4e9b\u3002

    Tip

    \u201c\u5370\u5237\u8d28\u91cf\u201d\u548c\u201c\u4ef7\u683c\u201d\u5c31\u50cf\u7b97\u6cd5\u4e2d\u7684\u201c\u65f6\u95f4\u6548\u7387\u201d\u548c\u201c\u7a7a\u95f4\u6548\u7387\u201d\uff0c\u96be\u4ee5\u4e24\u5168\u3002\u800c\u6211\u8ba4\u4e3a\uff0c\u201c\u5370\u5237\u8d28\u91cf\u201d\u5bf9\u5e94\u7684\u662f\u201c\u65f6\u95f4\u6548\u7387\u201d\uff0c\u66f4\u5e94\u8be5\u88ab\u6ce8\u91cd\u3002

    "},{"location":"chapter_paperbook/#_3","title":"\u8d2d\u4e70\u94fe\u63a5","text":"

    \u5982\u679c\u4f60\u5bf9\u7eb8\u8d28\u4e66\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u8003\u8651\u5165\u624b\u4e00\u672c\u3002\u6211\u4eec\u4e3a\u5927\u5bb6\u4e89\u53d6\u5230\u4e86\u65b0\u4e66 5 \u6298\u4f18\u60e0\uff0c\u8bf7\u89c1\u6b64\u94fe\u63a5\u6216\u626b\u63cf\u4ee5\u4e0b\u4e8c\u7ef4\u7801\uff1a

    "},{"location":"chapter_paperbook/#_4","title":"\u5c3e\u8bb0","text":"

    \u8d77\u521d\uff0c\u6211\u4f4e\u4f30\u4e86\u7eb8\u8d28\u4e66\u51fa\u7248\u7684\u5de5\u4f5c\u91cf\uff0c\u4ee5\u4e3a\u53ea\u8981\u7ef4\u62a4\u597d\u4e86\u5f00\u6e90\u9879\u76ee\uff0c\u7eb8\u8d28\u7248\u5c31\u53ef\u4ee5\u901a\u8fc7\u67d0\u4e9b\u81ea\u52a8\u5316\u624b\u6bb5\u751f\u6210\u51fa\u6765\u3002\u5b9e\u8df5\u8bc1\u660e\uff0c\u7eb8\u8d28\u4e66\u7684\u751f\u4ea7\u6d41\u7a0b\u4e0e\u5f00\u6e90\u9879\u76ee\u7684\u66f4\u65b0\u673a\u5236\u5b58\u5728\u5f88\u5927\u7684\u4e0d\u540c\uff0c\u4e24\u8005\u4e4b\u95f4\u7684\u8f6c\u5316\u9700\u8981\u505a\u8bb8\u591a\u989d\u5916\u5de5\u4f5c\u3002

    \u4e00\u672c\u4e66\u7684\u521d\u7a3f\u4e0e\u8fbe\u5230\u51fa\u7248\u6807\u51c6\u7684\u5b9a\u7a3f\u4e4b\u95f4\u4ecd\u6709\u8f83\u957f\u8ddd\u79bb\uff0c\u9700\u8981\u51fa\u7248\u793e\uff08\u7b56\u5212\u3001\u7f16\u8f91\u3001\u8bbe\u8ba1\u3001\u5e02\u573a\u7b49\uff09\u4e0e\u4f5c\u8005\u7684\u901a\u529b\u5408\u4f5c\u3001\u957f\u671f\u96d5\u7422\u3002\u5728\u6b64\u611f\u8c22\u56fe\u7075\u7b56\u5212\u7f16\u8f91\u738b\u519b\u82b1\u3001\u4ee5\u53ca\u4eba\u6c11\u90ae\u7535\u51fa\u7248\u793e\u548c\u56fe\u7075\u793e\u533a\u6bcf\u4f4d\u53c2\u4e0e\u672c\u4e66\u51fa\u7248\u6d41\u7a0b\u7684\u5de5\u4f5c\u4eba\u5458\uff01

    \u5e0c\u671b\u8fd9\u672c\u4e66\u80fd\u591f\u5e2e\u52a9\u5230\u4f60\uff01

    "},{"location":"chapter_preface/","title":"\u7b2c 0 \u7ae0 \u00a0 \u524d\u8a00","text":"

    Abstract

    \u7b97\u6cd5\u72b9\u5982\u7f8e\u5999\u7684\u4ea4\u54cd\u4e50\uff0c\u6bcf\u4e00\u884c\u4ee3\u7801\u90fd\u50cf\u97f5\u5f8b\u822c\u6d41\u6dcc\u3002

    \u613f\u8fd9\u672c\u4e66\u5728\u4f60\u7684\u8111\u6d77\u4e2d\u8f7b\u8f7b\u54cd\u8d77\uff0c\u7559\u4e0b\u72ec\u7279\u800c\u6df1\u523b\u7684\u65cb\u5f8b\u3002

    "},{"location":"chapter_preface/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 0.1 \u00a0 \u5173\u4e8e\u672c\u4e66
    • 0.2 \u00a0 \u5982\u4f55\u4f7f\u7528\u672c\u4e66
    • 0.3 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_preface/about_the_book/","title":"0.1 \u00a0 \u5173\u4e8e\u672c\u4e66","text":"

    \u672c\u9879\u76ee\u65e8\u5728\u521b\u5efa\u4e00\u672c\u5f00\u6e90\u3001\u514d\u8d39\u3001\u5bf9\u65b0\u624b\u53cb\u597d\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5165\u95e8\u6559\u7a0b\u3002

    • \u5168\u4e66\u91c7\u7528\u52a8\u753b\u56fe\u89e3\uff0c\u7ed3\u6784\u5316\u5730\u8bb2\u89e3\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u77e5\u8bc6\uff0c\u5185\u5bb9\u6e05\u6670\u6613\u61c2\uff0c\u5b66\u4e60\u66f2\u7ebf\u5e73\u6ed1\u3002
    • \u7b97\u6cd5\u6e90\u4ee3\u7801\u7686\u53ef\u4e00\u952e\u8fd0\u884c\uff0c\u652f\u6301 Python\u3001C++\u3001Java\u3001C#\u3001Go\u3001Swift\u3001JavaScript\u3001TypeScript\u3001Dart\u3001Rust\u3001C \u548c Zig \u7b49\u8bed\u8a00\u3002
    • \u9f13\u52b1\u8bfb\u8005\u5728\u7ebf\u4e0a\u7ae0\u8282\u8bc4\u8bba\u533a\u4e92\u5e2e\u4e92\u52a9\u3001\u5171\u540c\u8fdb\u6b65\uff0c\u63d0\u95ee\u4e0e\u8bc4\u8bba\u901a\u5e38\u53ef\u5728\u4e24\u65e5\u5185\u5f97\u5230\u56de\u590d\u3002
    "},{"location":"chapter_preface/about_the_book/#011","title":"0.1.1 \u00a0 \u8bfb\u8005\u5bf9\u8c61","text":"

    \u82e5\u4f60\u662f\u7b97\u6cd5\u521d\u5b66\u8005\uff0c\u4ece\u672a\u63a5\u89e6\u8fc7\u7b97\u6cd5\uff0c\u6216\u8005\u5df2\u7ecf\u6709\u4e00\u4e9b\u5237\u9898\u7ecf\u9a8c\uff0c\u5bf9\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u6709\u6a21\u7cca\u7684\u8ba4\u8bc6\uff0c\u5728\u4f1a\u4e0e\u4e0d\u4f1a\u4e4b\u95f4\u53cd\u590d\u6a2a\u8df3\uff0c\u90a3\u4e48\u672c\u4e66\u6b63\u662f\u4e3a\u4f60\u91cf\u8eab\u5b9a\u5236\u7684\uff01

    \u5982\u679c\u4f60\u5df2\u7ecf\u79ef\u7d2f\u4e00\u5b9a\u7684\u5237\u9898\u91cf\uff0c\u719f\u6089\u5927\u90e8\u5206\u9898\u578b\uff0c\u90a3\u4e48\u672c\u4e66\u53ef\u52a9\u4f60\u56de\u987e\u4e0e\u68b3\u7406\u7b97\u6cd5\u77e5\u8bc6\u4f53\u7cfb\uff0c\u4ed3\u5e93\u6e90\u4ee3\u7801\u53ef\u4ee5\u5f53\u4f5c\u201c\u5237\u9898\u5de5\u5177\u5e93\u201d\u6216\u201c\u7b97\u6cd5\u5b57\u5178\u201d\u6765\u4f7f\u7528\u3002

    \u82e5\u4f60\u662f\u7b97\u6cd5\u201c\u5927\u795e\u201d\uff0c\u6211\u4eec\u671f\u5f85\u6536\u5230\u4f60\u7684\u5b9d\u8d35\u5efa\u8bae\uff0c\u6216\u8005\u4e00\u8d77\u53c2\u4e0e\u521b\u4f5c\u3002

    \u524d\u7f6e\u6761\u4ef6

    \u4f60\u9700\u8981\u81f3\u5c11\u5177\u5907\u4efb\u4e00\u8bed\u8a00\u7684\u7f16\u7a0b\u57fa\u7840\uff0c\u80fd\u591f\u9605\u8bfb\u548c\u7f16\u5199\u7b80\u5355\u4ee3\u7801\u3002

    "},{"location":"chapter_preface/about_the_book/#012","title":"0.1.2 \u00a0 \u5185\u5bb9\u7ed3\u6784","text":"

    \u672c\u4e66\u7684\u4e3b\u8981\u5185\u5bb9\u5982\u56fe 0-1 \u6240\u793a\u3002

    • \u590d\u6742\u5ea6\u5206\u6790\uff1a\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u7684\u8bc4\u4ef7\u7ef4\u5ea6\u4e0e\u65b9\u6cd5\u3002\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u7a7a\u95f4\u590d\u6742\u5ea6\u7684\u63a8\u7b97\u65b9\u6cd5\u3001\u5e38\u89c1\u7c7b\u578b\u3001\u793a\u4f8b\u7b49\u3002
    • \u6570\u636e\u7ed3\u6784\uff1a\u57fa\u672c\u6570\u636e\u7c7b\u578b\u548c\u6570\u636e\u7ed3\u6784\u7684\u5206\u7c7b\u65b9\u6cd5\u3002\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6808\u3001\u961f\u5217\u3001\u54c8\u5e0c\u8868\u3001\u6811\u3001\u5806\u3001\u56fe\u7b49\u6570\u636e\u7ed3\u6784\u7684\u5b9a\u4e49\u3001\u4f18\u7f3a\u70b9\u3001\u5e38\u7528\u64cd\u4f5c\u3001\u5e38\u89c1\u7c7b\u578b\u3001\u5178\u578b\u5e94\u7528\u3001\u5b9e\u73b0\u65b9\u6cd5\u7b49\u3002
    • \u7b97\u6cd5\uff1a\u641c\u7d22\u3001\u6392\u5e8f\u3001\u5206\u6cbb\u3001\u56de\u6eaf\u3001\u52a8\u6001\u89c4\u5212\u3001\u8d2a\u5fc3\u7b49\u7b97\u6cd5\u7684\u5b9a\u4e49\u3001\u4f18\u7f3a\u70b9\u3001\u6548\u7387\u3001\u5e94\u7528\u573a\u666f\u3001\u89e3\u9898\u6b65\u9aa4\u548c\u793a\u4f8b\u95ee\u9898\u7b49\u3002

    \u56fe 0-1 \u00a0 \u672c\u4e66\u4e3b\u8981\u5185\u5bb9

    "},{"location":"chapter_preface/about_the_book/#013","title":"0.1.3 \u00a0 \u81f4\u8c22","text":"

    \u672c\u4e66\u5728\u5f00\u6e90\u793e\u533a\u4f17\u591a\u8d21\u732e\u8005\u7684\u5171\u540c\u52aa\u529b\u4e0b\u4e0d\u65ad\u5b8c\u5584\u3002\u611f\u8c22\u6bcf\u4e00\u4f4d\u6295\u5165\u65f6\u95f4\u4e0e\u7cbe\u529b\u7684\u64b0\u7a3f\u4eba\uff0c\u4ed6\u4eec\u662f\uff08\u6309\u7167 GitHub \u81ea\u52a8\u751f\u6210\u7684\u987a\u5e8f\uff09\uff1akrahets\u3001Gonglja\u3001nuomi1\u3001codingonion\u3001Reanon\u3001justin-tse\u3001hpstory\u3001danielsss\u3001curtishd\u3001night-cruise\u3001S-N-O-R-L-A-X\u3001msk397\u3001gvenusleo\u3001RiverTwilight\u3001gyt95\u3001zhuoqinyue\u3001Zuoxun\u3001mingXta\u3001hello-ikun\u3001khoaxuantu\u3001FangYuan33\u3001GN-Yu\u3001longsizhuo\u3001mgisr\u3001Cathay-Chen\u3001guowei-gong\u3001xBLACKICEx\u3001K3v123\u3001IsChristina\u3001JoseHung\u3001qualifier1024\u3001pengchzn\u3001Guanngxu\u3001QiLOL\u3001L-Super\u3001WSL0809\u3001Slone123c\u3001lhxsm\u3001yuan0221\u3001what-is-me\u3001rongyi\u3001JeffersonHuang\u3001longranger2\u3001theNefelibatas\u3001yuelinxin\u3001xiongsp\u3001nanlei\u3001a16su\u3001cy-by-side\u3001gaofer\u3001malone6\u3001Wonderdch\u3001hongyun-robot\u3001XiaChuerwu\u3001yd-j\u3001bluebean-cloud\u3001iron-irax\u3001he-weilai\u3001Nigh\u3001MolDuM\u3001Phoenix0415\u3001XC-Zero\u3001SamJin98\u3001reeswell\u3001NI-SW\u3001Horbin-Magician\u3001xjr7670\u3001YangXuanyi\u3001DullSword\u3001iStig\u3001qq909244296\u3001jiaxianhua\u3001wenjianmin\u3001keshida\u3001kilikilikid\u3001lclc6\u3001lwbaptx\u3001luluxia\u3001boloboloda\u3001hts0000\u3001gledfish\u3001fbigm\u3001echo1937\u3001szu17dmy\u3001dshlstarr\u3001coderlef\u3001czruby\u3001beintentional\u3001KeiichiKasai\u3001xb534\u3001ElaBosak233\u3001baagod\u3001zhouLion\u3001yishangzhang\u3001yi427\u3001yabo083\u3001weibk\u3001wangwang105\u3001th1nk3r-ing\u3001tao363\u30014yDX3906\u3001syd168\u3001siqyka\u3001selear\u3001sdshaoda\u3001noobcodemaker\u3001chadyi\u3001lyl625760\u3001lucaswangdev\u3001liuxjerry\u30010130w\u3001shanghai-Jerry\u3001JackYang-hellobobo\u3001Javesun99\u3001lipusheng\u3001ShiMaRing\u3001FreddieLi\u3001FloranceYeh\u3001Transmigration-zhou\u3001fanchenggang\u3001gltianwen\u3001Dr-XYZ\u3001curly210102\u3001CuB3y0nd\u3001youshaoXG\u3001bubble9um\u3001fanenr\u300152coder\u3001foursevenlove\u3001KorsChen\u3001ZongYangL\u3001hezhizhen\u3001linzeyan\u3001ZJKung\u3001GaochaoZhu\u3001yang-le\u3001Evilrabbit520\u3001Turing-1024-Lee\u3001Suremotoo\u3001Allen-Scai\u3001Richard-Zhang1019\u3001qingpeng9802\u3001primexiao\u3001nidhoggfgg\u30011ch0\u3001MwumLi\u3001ZnYang2018\u3001hugtyftg\u3001logan-qiu\u3001psychelzh \u548c Keynman \u3002

    \u672c\u4e66\u7684\u4ee3\u7801\u5ba1\u9605\u5de5\u4f5c\u7531 codingonion\u3001curtishd\u3001Gonglja\u3001gvenusleo\u3001hpstory\u3001justin-tse\u3001krahets\u3001night-cruise\u3001nuomi1 \u548c Reanon \u5b8c\u6210\uff08\u6309\u7167\u9996\u5b57\u6bcd\u987a\u5e8f\u6392\u5217\uff09\u3002\u611f\u8c22\u4ed6\u4eec\u4ed8\u51fa\u7684\u65f6\u95f4\u4e0e\u7cbe\u529b\uff0c\u6b63\u662f\u4ed6\u4eec\u786e\u4fdd\u4e86\u5404\u8bed\u8a00\u4ee3\u7801\u7684\u89c4\u8303\u4e0e\u7edf\u4e00\u3002

    \u5728\u672c\u4e66\u7684\u521b\u4f5c\u8fc7\u7a0b\u4e2d\uff0c\u6211\u5f97\u5230\u4e86\u8bb8\u591a\u4eba\u7684\u5e2e\u52a9\u3002

    • \u611f\u8c22\u6211\u5728\u516c\u53f8\u7684\u5bfc\u5e08\u674e\u6c50\u535a\u58eb\uff0c\u5728\u4e00\u6b21\u7545\u8c08\u4e2d\u4f60\u9f13\u52b1\u6211\u201c\u5feb\u884c\u52a8\u8d77\u6765\u201d\uff0c\u575a\u5b9a\u4e86\u6211\u5199\u8fd9\u672c\u4e66\u7684\u51b3\u5fc3\uff1b
    • \u611f\u8c22\u6211\u7684\u5973\u670b\u53cb\u6ce1\u6ce1\u4f5c\u4e3a\u672c\u4e66\u7684\u9996\u4f4d\u8bfb\u8005\uff0c\u4ece\u7b97\u6cd5\u5c0f\u767d\u7684\u89d2\u5ea6\u63d0\u51fa\u8bb8\u591a\u5b9d\u8d35\u5efa\u8bae\uff0c\u4f7f\u5f97\u672c\u4e66\u66f4\u9002\u5408\u65b0\u624b\u9605\u8bfb\uff1b
    • \u611f\u8c22\u817e\u5b9d\u3001\u7426\u5b9d\u3001\u98de\u5b9d\u4e3a\u672c\u4e66\u8d77\u4e86\u4e00\u4e2a\u5bcc\u6709\u521b\u610f\u7684\u540d\u5b57\uff0c\u5524\u8d77\u5927\u5bb6\u5199\u4e0b\u7b2c\u4e00\u884c\u4ee3\u7801\u201cHello World!\u201d\u7684\u7f8e\u597d\u56de\u5fc6\uff1b
    • \u611f\u8c22\u6821\u94e8\u5728\u77e5\u8bc6\u4ea7\u6743\u65b9\u9762\u63d0\u4f9b\u7684\u4e13\u4e1a\u5e2e\u52a9\uff0c\u8fd9\u5bf9\u672c\u5f00\u6e90\u4e66\u7684\u5b8c\u5584\u8d77\u5230\u4e86\u91cd\u8981\u4f5c\u7528\uff1b
    • \u611f\u8c22\u82cf\u6f7c\u4e3a\u672c\u4e66\u8bbe\u8ba1\u4e86\u7cbe\u7f8e\u7684\u5c01\u9762\u548c logo \uff0c\u5e76\u5728\u6211\u7684\u5f3a\u8feb\u75c7\u7684\u9a71\u4f7f\u4e0b\u591a\u6b21\u8010\u5fc3\u4fee\u6539\uff1b
    • \u611f\u8c22 @squidfunk \u63d0\u4f9b\u7684\u6392\u7248\u5efa\u8bae\uff0c\u4ee5\u53ca\u4ed6\u5f00\u53d1\u7684\u5f00\u6e90\u6587\u6863\u4e3b\u9898 Material-for-MkDocs \u3002

    \u5728\u5199\u4f5c\u8fc7\u7a0b\u4e2d\uff0c\u6211\u9605\u8bfb\u4e86\u8bb8\u591a\u5173\u4e8e\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u6559\u6750\u548c\u6587\u7ae0\u3002\u8fd9\u4e9b\u4f5c\u54c1\u4e3a\u672c\u4e66\u63d0\u4f9b\u4e86\u4f18\u79c0\u7684\u8303\u672c\uff0c\u786e\u4fdd\u4e86\u672c\u4e66\u5185\u5bb9\u7684\u51c6\u786e\u6027\u4e0e\u54c1\u8d28\u3002\u5728\u6b64\u611f\u8c22\u6240\u6709\u8001\u5e08\u548c\u524d\u8f88\u7684\u6770\u51fa\u8d21\u732e\uff01

    \u672c\u4e66\u5021\u5bfc\u624b\u8111\u5e76\u7528\u7684\u5b66\u4e60\u65b9\u5f0f\uff0c\u5728\u8fd9\u4e00\u70b9\u4e0a\u6211\u6df1\u53d7\u300a\u52a8\u624b\u5b66\u6df1\u5ea6\u5b66\u4e60\u300b\u7684\u542f\u53d1\u3002\u5728\u6b64\u5411\u5404\u4f4d\u8bfb\u8005\u5f3a\u70c8\u63a8\u8350\u8fd9\u672c\u4f18\u79c0\u7684\u8457\u4f5c\u3002

    \u8877\u5fc3\u611f\u8c22\u6211\u7684\u7236\u6bcd\uff0c\u6b63\u662f\u4f60\u4eec\u4e00\u76f4\u4ee5\u6765\u7684\u652f\u6301\u4e0e\u9f13\u52b1\uff0c\u8ba9\u6211\u6709\u673a\u4f1a\u505a\u8fd9\u4ef6\u5bcc\u6709\u8da3\u5473\u7684\u4e8b\u3002

    "},{"location":"chapter_preface/suggestions/","title":"0.2 \u00a0 \u5982\u4f55\u4f7f\u7528\u672c\u4e66","text":"

    Tip

    \u4e3a\u4e86\u83b7\u5f97\u6700\u4f73\u7684\u9605\u8bfb\u4f53\u9a8c\uff0c\u5efa\u8bae\u4f60\u901a\u8bfb\u672c\u8282\u5185\u5bb9\u3002

    "},{"location":"chapter_preface/suggestions/#021","title":"0.2.1 \u00a0 \u884c\u6587\u98ce\u683c\u7ea6\u5b9a","text":"
    • \u6807\u9898\u540e\u6807\u6ce8 * \u7684\u662f\u9009\u8bfb\u7ae0\u8282\uff0c\u5185\u5bb9\u76f8\u5bf9\u56f0\u96be\u3002\u5982\u679c\u4f60\u7684\u65f6\u95f4\u6709\u9650\uff0c\u53ef\u4ee5\u5148\u8df3\u8fc7\u3002
    • \u4e13\u4e1a\u672f\u8bed\u4f1a\u4f7f\u7528\u9ed1\u4f53\uff08\u7eb8\u8d28\u7248\u548c PDF \u7248\uff09\u6216\u6dfb\u52a0\u4e0b\u5212\u7ebf\uff08\u7f51\u9875\u7248\uff09\uff0c\u4f8b\u5982\u6570\u7ec4\uff08array\uff09\u3002\u5efa\u8bae\u8bb0\u4f4f\u5b83\u4eec\uff0c\u4ee5\u4fbf\u9605\u8bfb\u6587\u732e\u3002
    • \u91cd\u70b9\u5185\u5bb9\u548c\u603b\u7ed3\u6027\u8bed\u53e5\u4f1a \u52a0\u7c97\uff0c\u8fd9\u7c7b\u6587\u5b57\u503c\u5f97\u7279\u522b\u5173\u6ce8\u3002
    • \u6709\u7279\u6307\u542b\u4e49\u7684\u8bcd\u53e5\u4f1a\u4f7f\u7528\u201c\u5f15\u53f7\u201d\u6807\u6ce8\uff0c\u4ee5\u907f\u514d\u6b67\u4e49\u3002
    • \u5f53\u6d89\u53ca\u7f16\u7a0b\u8bed\u8a00\u4e4b\u95f4\u4e0d\u4e00\u81f4\u7684\u540d\u8bcd\u65f6\uff0c\u672c\u4e66\u5747\u4ee5 Python \u4e3a\u51c6\uff0c\u4f8b\u5982\u4f7f\u7528 None \u6765\u8868\u793a\u201c\u7a7a\u201d\u3002
    • \u672c\u4e66\u90e8\u5206\u653e\u5f03\u4e86\u7f16\u7a0b\u8bed\u8a00\u7684\u6ce8\u91ca\u89c4\u8303\uff0c\u4ee5\u6362\u53d6\u66f4\u52a0\u7d27\u51d1\u7684\u5185\u5bb9\u6392\u7248\u3002\u6ce8\u91ca\u4e3b\u8981\u5206\u4e3a\u4e09\u79cd\u7c7b\u578b\uff1a\u6807\u9898\u6ce8\u91ca\u3001\u5185\u5bb9\u6ce8\u91ca\u3001\u591a\u884c\u6ce8\u91ca\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    \"\"\"\u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49\"\"\"\n\n# \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n\"\"\"\n\u591a\u884c\n\u6ce8\u91ca\n\"\"\"\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    /* \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 */\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n/**\n * \u591a\u884c\n * \u6ce8\u91ca\n */\n
    ### \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49 ###\n\n# \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n# \u591a\u884c\n# \u6ce8\u91ca\n
    // \u6807\u9898\u6ce8\u91ca\uff0c\u7528\u4e8e\u6807\u6ce8\u51fd\u6570\u3001\u7c7b\u3001\u6d4b\u8bd5\u6837\u4f8b\u7b49\n\n// \u5185\u5bb9\u6ce8\u91ca\uff0c\u7528\u4e8e\u8be6\u89e3\u4ee3\u7801\n\n// \u591a\u884c\n// \u6ce8\u91ca\n
    "},{"location":"chapter_preface/suggestions/#022","title":"0.2.2 \u00a0 \u5728\u52a8\u753b\u56fe\u89e3\u4e2d\u9ad8\u6548\u5b66\u4e60","text":"

    \u76f8\u8f83\u4e8e\u6587\u5b57\uff0c\u89c6\u9891\u548c\u56fe\u7247\u5177\u6709\u66f4\u9ad8\u7684\u4fe1\u606f\u5bc6\u5ea6\u548c\u7ed3\u6784\u5316\u7a0b\u5ea6\uff0c\u66f4\u6613\u4e8e\u7406\u89e3\u3002\u5728\u672c\u4e66\u4e2d\uff0c\u91cd\u70b9\u548c\u96be\u70b9\u77e5\u8bc6\u5c06\u4e3b\u8981\u901a\u8fc7\u52a8\u753b\u4ee5\u56fe\u89e3\u5f62\u5f0f\u5c55\u793a\uff0c\u800c\u6587\u5b57\u5219\u4f5c\u4e3a\u89e3\u91ca\u4e0e\u8865\u5145\u3002

    \u5982\u679c\u4f60\u5728\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u53d1\u73b0\u67d0\u6bb5\u5185\u5bb9\u63d0\u4f9b\u4e86\u5982\u56fe 0-2 \u6240\u793a\u7684\u52a8\u753b\u56fe\u89e3\uff0c\u8bf7\u4ee5\u56fe\u4e3a\u4e3b\u3001\u4ee5\u6587\u5b57\u4e3a\u8f85\uff0c\u7efc\u5408\u4e24\u8005\u6765\u7406\u89e3\u5185\u5bb9\u3002

    \u56fe 0-2 \u00a0 \u52a8\u753b\u56fe\u89e3\u793a\u4f8b

    "},{"location":"chapter_preface/suggestions/#023","title":"0.2.3 \u00a0 \u5728\u4ee3\u7801\u5b9e\u8df5\u4e2d\u52a0\u6df1\u7406\u89e3","text":"

    \u672c\u4e66\u7684\u914d\u5957\u4ee3\u7801\u6258\u7ba1\u5728 GitHub \u4ed3\u5e93\u3002\u5982\u56fe 0-3 \u6240\u793a\uff0c\u6e90\u4ee3\u7801\u9644\u6709\u6d4b\u8bd5\u6837\u4f8b\uff0c\u53ef\u4e00\u952e\u8fd0\u884c\u3002

    \u5982\u679c\u65f6\u95f4\u5141\u8bb8\uff0c\u5efa\u8bae\u4f60\u53c2\u7167\u4ee3\u7801\u81ea\u884c\u6572\u4e00\u904d\u3002\u5982\u679c\u5b66\u4e60\u65f6\u95f4\u6709\u9650\uff0c\u8bf7\u81f3\u5c11\u901a\u8bfb\u5e76\u8fd0\u884c\u6240\u6709\u4ee3\u7801\u3002

    \u4e0e\u9605\u8bfb\u4ee3\u7801\u76f8\u6bd4\uff0c\u7f16\u5199\u4ee3\u7801\u7684\u8fc7\u7a0b\u5f80\u5f80\u80fd\u5e26\u6765\u66f4\u591a\u6536\u83b7\u3002\u52a8\u624b\u5b66\uff0c\u624d\u662f\u771f\u7684\u5b66\u3002

    \u56fe 0-3 \u00a0 \u8fd0\u884c\u4ee3\u7801\u793a\u4f8b

    \u8fd0\u884c\u4ee3\u7801\u7684\u524d\u7f6e\u5de5\u4f5c\u4e3b\u8981\u5206\u4e3a\u4e09\u6b65\u3002

    \u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5\u672c\u5730\u7f16\u7a0b\u73af\u5883\u3002\u8bf7\u53c2\u7167\u9644\u5f55\u6240\u793a\u7684\u6559\u7a0b\u8fdb\u884c\u5b89\u88c5\uff0c\u5982\u679c\u5df2\u5b89\u88c5\uff0c\u5219\u53ef\u8df3\u8fc7\u6b64\u6b65\u9aa4\u3002

    \u7b2c\u4e8c\u6b65\uff1a\u514b\u9686\u6216\u4e0b\u8f7d\u4ee3\u7801\u4ed3\u5e93\u3002\u524d\u5f80 GitHub \u4ed3\u5e93\u3002\u5982\u679c\u5df2\u7ecf\u5b89\u88c5 Git \uff0c\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u547d\u4ee4\u514b\u9686\u672c\u4ed3\u5e93\uff1a

    git clone https://github.com/krahets/hello-algo.git\n

    \u5f53\u7136\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5728\u56fe 0-4 \u6240\u793a\u7684\u4f4d\u7f6e\uff0c\u70b9\u51fb\u201cDownload ZIP\u201d\u6309\u94ae\u76f4\u63a5\u4e0b\u8f7d\u4ee3\u7801\u538b\u7f29\u5305\uff0c\u7136\u540e\u5728\u672c\u5730\u89e3\u538b\u5373\u53ef\u3002

    \u56fe 0-4 \u00a0 \u514b\u9686\u4ed3\u5e93\u4e0e\u4e0b\u8f7d\u4ee3\u7801

    \u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6e90\u4ee3\u7801\u3002\u5982\u56fe 0-5 \u6240\u793a\uff0c\u5bf9\u4e8e\u9876\u90e8\u6807\u6709\u6587\u4ef6\u540d\u79f0\u7684\u4ee3\u7801\u5757\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u4ed3\u5e93\u7684 codes \u6587\u4ef6\u5939\u5185\u627e\u5230\u5bf9\u5e94\u7684\u6e90\u4ee3\u7801\u6587\u4ef6\u3002\u6e90\u4ee3\u7801\u6587\u4ef6\u53ef\u4e00\u952e\u8fd0\u884c\uff0c\u5c06\u5e2e\u52a9\u4f60\u8282\u7701\u4e0d\u5fc5\u8981\u7684\u8c03\u8bd5\u65f6\u95f4\uff0c\u8ba9\u4f60\u80fd\u591f\u4e13\u6ce8\u4e8e\u5b66\u4e60\u5185\u5bb9\u3002

    \u56fe 0-5 \u00a0 \u4ee3\u7801\u5757\u4e0e\u5bf9\u5e94\u7684\u6e90\u4ee3\u7801\u6587\u4ef6

    \u9664\u4e86\u672c\u5730\u8fd0\u884c\u4ee3\u7801\uff0c\u7f51\u9875\u7248\u8fd8\u652f\u6301 Python \u4ee3\u7801\u7684\u53ef\u89c6\u5316\u8fd0\u884c\uff08\u57fa\u4e8e pythontutor \u5b9e\u73b0\uff09\u3002\u5982\u56fe 0-6 \u6240\u793a\uff0c\u4f60\u53ef\u4ee5\u70b9\u51fb\u4ee3\u7801\u5757\u4e0b\u65b9\u7684\u201c\u53ef\u89c6\u5316\u8fd0\u884c\u201d\u6765\u5c55\u5f00\u89c6\u56fe\uff0c\u89c2\u5bdf\u7b97\u6cd5\u4ee3\u7801\u7684\u6267\u884c\u8fc7\u7a0b\uff1b\u4e5f\u53ef\u4ee5\u70b9\u51fb\u201c\u5168\u5c4f\u89c2\u770b\u201d\uff0c\u4ee5\u83b7\u5f97\u66f4\u597d\u7684\u9605\u89c8\u4f53\u9a8c\u3002

    \u56fe 0-6 \u00a0 Python \u4ee3\u7801\u7684\u53ef\u89c6\u5316\u8fd0\u884c

    "},{"location":"chapter_preface/suggestions/#024","title":"0.2.4 \u00a0 \u5728\u63d0\u95ee\u8ba8\u8bba\u4e2d\u5171\u540c\u6210\u957f","text":"

    \u5728\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u8bf7\u4e0d\u8981\u8f7b\u6613\u8df3\u8fc7\u90a3\u4e9b\u6ca1\u5b66\u660e\u767d\u7684\u77e5\u8bc6\u70b9\u3002\u6b22\u8fce\u5728\u8bc4\u8bba\u533a\u63d0\u51fa\u4f60\u7684\u95ee\u9898\uff0c\u6211\u548c\u5c0f\u4f19\u4f34\u4eec\u5c06\u7aed\u8bda\u4e3a\u4f60\u89e3\u7b54\uff0c\u4e00\u822c\u60c5\u51b5\u4e0b\u53ef\u5728\u4e24\u5929\u5185\u56de\u590d\u3002

    \u5982\u56fe 0-7 \u6240\u793a\uff0c\u7f51\u9875\u7248\u6bcf\u4e2a\u7ae0\u8282\u7684\u5e95\u90e8\u90fd\u914d\u6709\u8bc4\u8bba\u533a\u3002\u5e0c\u671b\u4f60\u80fd\u591a\u5173\u6ce8\u8bc4\u8bba\u533a\u7684\u5185\u5bb9\u3002\u4e00\u65b9\u9762\uff0c\u4f60\u53ef\u4ee5\u4e86\u89e3\u5927\u5bb6\u9047\u5230\u7684\u95ee\u9898\uff0c\u4ece\u800c\u67e5\u6f0f\u8865\u7f3a\uff0c\u6fc0\u53d1\u66f4\u6df1\u5165\u7684\u601d\u8003\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u671f\u5f85\u4f60\u80fd\u6177\u6168\u5730\u56de\u7b54\u5176\u4ed6\u5c0f\u4f19\u4f34\u7684\u95ee\u9898\uff0c\u5206\u4eab\u4f60\u7684\u89c1\u89e3\uff0c\u5e2e\u52a9\u4ed6\u4eba\u8fdb\u6b65\u3002

    \u56fe 0-7 \u00a0 \u8bc4\u8bba\u533a\u793a\u4f8b

    "},{"location":"chapter_preface/suggestions/#025","title":"0.2.5 \u00a0 \u7b97\u6cd5\u5b66\u4e60\u8def\u7ebf","text":"

    \u4ece\u603b\u4f53\u4e0a\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u7684\u8fc7\u7a0b\u5212\u5206\u4e3a\u4e09\u4e2a\u9636\u6bb5\u3002

    1. \u9636\u6bb5\u4e00\uff1a\u7b97\u6cd5\u5165\u95e8\u3002\u6211\u4eec\u9700\u8981\u719f\u6089\u5404\u79cd\u6570\u636e\u7ed3\u6784\u7684\u7279\u70b9\u548c\u7528\u6cd5\uff0c\u5b66\u4e60\u4e0d\u540c\u7b97\u6cd5\u7684\u539f\u7406\u3001\u6d41\u7a0b\u3001\u7528\u9014\u548c\u6548\u7387\u7b49\u65b9\u9762\u7684\u5185\u5bb9\u3002
    2. \u9636\u6bb5\u4e8c\uff1a\u5237\u7b97\u6cd5\u9898\u3002\u5efa\u8bae\u4ece\u70ed\u95e8\u9898\u76ee\u5f00\u5237\uff0c\u5148\u79ef\u7d2f\u81f3\u5c11 100 \u9053\u9898\u76ee\uff0c\u719f\u6089\u4e3b\u6d41\u7684\u7b97\u6cd5\u95ee\u9898\u3002\u521d\u6b21\u5237\u9898\u65f6\uff0c\u201c\u77e5\u8bc6\u9057\u5fd8\u201d\u53ef\u80fd\u662f\u4e00\u4e2a\u6311\u6218\uff0c\u4f46\u8bf7\u653e\u5fc3\uff0c\u8fd9\u662f\u5f88\u6b63\u5e38\u7684\u3002\u6211\u4eec\u53ef\u4ee5\u6309\u7167\u201c\u827e\u5bbe\u6d69\u65af\u9057\u5fd8\u66f2\u7ebf\u201d\u6765\u590d\u4e60\u9898\u76ee\uff0c\u901a\u5e38\u5728\u8fdb\u884c 3\uff5e5 \u8f6e\u7684\u91cd\u590d\u540e\uff0c\u5c31\u80fd\u5c06\u5176\u7262\u8bb0\u5728\u5fc3\u3002\u63a8\u8350\u7684\u9898\u5355\u548c\u5237\u9898\u8ba1\u5212\u8bf7\u89c1\u6b64 GitHub \u4ed3\u5e93\u3002
    3. \u9636\u6bb5\u4e09\uff1a\u642d\u5efa\u77e5\u8bc6\u4f53\u7cfb\u3002\u5728\u5b66\u4e60\u65b9\u9762\uff0c\u6211\u4eec\u53ef\u4ee5\u9605\u8bfb\u7b97\u6cd5\u4e13\u680f\u6587\u7ae0\u3001\u89e3\u9898\u6846\u67b6\u548c\u7b97\u6cd5\u6559\u6750\uff0c\u4ee5\u4e0d\u65ad\u4e30\u5bcc\u77e5\u8bc6\u4f53\u7cfb\u3002\u5728\u5237\u9898\u65b9\u9762\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u91c7\u7528\u8fdb\u9636\u5237\u9898\u7b56\u7565\uff0c\u5982\u6309\u4e13\u9898\u5206\u7c7b\u3001\u4e00\u9898\u591a\u89e3\u3001\u4e00\u89e3\u591a\u9898\u7b49\uff0c\u76f8\u5173\u7684\u5237\u9898\u5fc3\u5f97\u53ef\u4ee5\u5728\u5404\u4e2a\u793e\u533a\u627e\u5230\u3002

    \u5982\u56fe 0-8 \u6240\u793a\uff0c\u672c\u4e66\u5185\u5bb9\u4e3b\u8981\u6db5\u76d6\u201c\u9636\u6bb5\u4e00\u201d\uff0c\u65e8\u5728\u5e2e\u52a9\u4f60\u66f4\u9ad8\u6548\u5730\u5c55\u5f00\u9636\u6bb5\u4e8c\u548c\u9636\u6bb5\u4e09\u7684\u5b66\u4e60\u3002

    \u56fe 0-8 \u00a0 \u7b97\u6cd5\u5b66\u4e60\u8def\u7ebf

    "},{"location":"chapter_preface/summary/","title":"0.3 \u00a0 \u5c0f\u7ed3","text":"
    • \u672c\u4e66\u7684\u4e3b\u8981\u53d7\u4f17\u662f\u7b97\u6cd5\u521d\u5b66\u8005\u3002\u5982\u679c\u4f60\u5df2\u6709\u4e00\u5b9a\u57fa\u7840\uff0c\u672c\u4e66\u80fd\u5e2e\u52a9\u4f60\u7cfb\u7edf\u56de\u987e\u7b97\u6cd5\u77e5\u8bc6\uff0c\u4e66\u4e2d\u6e90\u4ee3\u7801\u4e5f\u53ef\u4f5c\u4e3a\u201c\u5237\u9898\u5de5\u5177\u5e93\u201d\u4f7f\u7528\u3002
    • \u4e66\u4e2d\u5185\u5bb9\u4e3b\u8981\u5305\u62ec\u590d\u6742\u5ea6\u5206\u6790\u3001\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u4e09\u90e8\u5206\uff0c\u6db5\u76d6\u4e86\u8be5\u9886\u57df\u7684\u5927\u90e8\u5206\u4e3b\u9898\u3002
    • \u5bf9\u4e8e\u7b97\u6cd5\u65b0\u624b\uff0c\u5728\u521d\u5b66\u9636\u6bb5\u9605\u8bfb\u4e00\u672c\u5165\u95e8\u4e66\u81f3\u5173\u91cd\u8981\uff0c\u53ef\u4ee5\u5c11\u8d70\u8bb8\u591a\u5f2f\u8def\u3002
    • \u4e66\u4e2d\u7684\u52a8\u753b\u56fe\u89e3\u901a\u5e38\u7528\u4e8e\u4ecb\u7ecd\u91cd\u70b9\u548c\u96be\u70b9\u77e5\u8bc6\u3002\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u5e94\u7ed9\u4e88\u8fd9\u4e9b\u5185\u5bb9\u66f4\u591a\u5173\u6ce8\u3002
    • \u5b9e\u8df5\u4e43\u5b66\u4e60\u7f16\u7a0b\u4e4b\u6700\u4f73\u9014\u5f84\u3002\u5f3a\u70c8\u5efa\u8bae\u8fd0\u884c\u6e90\u4ee3\u7801\u5e76\u4eb2\u81ea\u6572\u4ee3\u7801\u3002
    • \u672c\u4e66\u7f51\u9875\u7248\u7684\u6bcf\u4e2a\u7ae0\u8282\u90fd\u8bbe\u6709\u8bc4\u8bba\u533a\uff0c\u6b22\u8fce\u968f\u65f6\u5206\u4eab\u4f60\u7684\u7591\u60d1\u4e0e\u89c1\u89e3\u3002
    "},{"location":"chapter_reference/","title":"\u53c2\u8003\u6587\u732e","text":"

    [1] Thomas H. Cormen, et al. Introduction to Algorithms (3rd Edition).

    [2] Aditya Bhargava. Grokking Algorithms: An Illustrated Guide for Programmers and Other Curious People (1st Edition).

    [3] Robert Sedgewick, et al. Algorithms (4th Edition).

    [4] \u4e25\u851a\u654f. \u6570\u636e\u7ed3\u6784\uff08C \u8bed\u8a00\u7248\uff09.

    [5] \u9093\u4fca\u8f89. \u6570\u636e\u7ed3\u6784\uff08C++ \u8bed\u8a00\u7248\uff0c\u7b2c\u4e09\u7248\uff09.

    [6] \u9a6c\u514b \u827e\u4f26 \u7ef4\u65af\u8457\uff0c\u9648\u8d8a\u8bd1. \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5206\u6790\uff1aJava\u8bed\u8a00\u63cf\u8ff0\uff08\u7b2c\u4e09\u7248\uff09.

    [7] \u7a0b\u6770. \u5927\u8bdd\u6570\u636e\u7ed3\u6784.

    [8] \u738b\u4e89. \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u4e4b\u7f8e.

    [9] Gayle Laakmann McDowell. Cracking the Coding Interview: 189 Programming Questions and Solutions (6th Edition).

    [10] Aston Zhang, et al. Dive into Deep Learning.

    "},{"location":"chapter_searching/","title":"\u7b2c 10 \u7ae0 \u00a0 \u641c\u7d22","text":"

    Abstract

    \u641c\u7d22\u662f\u4e00\u573a\u672a\u77e5\u7684\u5192\u9669\uff0c\u6211\u4eec\u6216\u8bb8\u9700\u8981\u8d70\u904d\u795e\u79d8\u7a7a\u95f4\u7684\u6bcf\u4e2a\u89d2\u843d\uff0c\u53c8\u6216\u8bb8\u53ef\u4ee5\u5feb\u901f\u9501\u5b9a\u76ee\u6807\u3002

    \u5728\u8fd9\u573a\u5bfb\u89c5\u4e4b\u65c5\u4e2d\uff0c\u6bcf\u4e00\u6b21\u63a2\u7d22\u90fd\u53ef\u80fd\u5f97\u5230\u4e00\u4e2a\u672a\u66fe\u6599\u60f3\u7684\u7b54\u6848\u3002

    "},{"location":"chapter_searching/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 10.1 \u00a0 \u4e8c\u5206\u67e5\u627e
    • 10.2 \u00a0 \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9
    • 10.3 \u00a0 \u4e8c\u5206\u67e5\u627e\u8fb9\u754c
    • 10.4 \u00a0 \u54c8\u5e0c\u4f18\u5316\u7b56\u7565
    • 10.5 \u00a0 \u91cd\u8bc6\u641c\u7d22\u7b97\u6cd5
    • 10.6 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_searching/binary_search/","title":"10.1 \u00a0 \u4e8c\u5206\u67e5\u627e","text":"

    \u4e8c\u5206\u67e5\u627e\uff08binary search\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u9ad8\u6548\u641c\u7d22\u7b97\u6cd5\u3002\u5b83\u5229\u7528\u6570\u636e\u7684\u6709\u5e8f\u6027\uff0c\u6bcf\u8f6e\u7f29\u5c0f\u4e00\u534a\u641c\u7d22\u8303\u56f4\uff0c\u76f4\u81f3\u627e\u5230\u76ee\u6807\u5143\u7d20\u6216\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u4e3a\u6b62\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4 nums \uff0c\u5143\u7d20\u6309\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u4e14\u4e0d\u91cd\u590d\u3002\u8bf7\u67e5\u627e\u5e76\u8fd4\u56de\u5143\u7d20 target \u5728\u8be5\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15\u3002\u82e5\u6570\u7ec4\u4e0d\u5305\u542b\u8be5\u5143\u7d20\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002\u793a\u4f8b\u5982\u56fe 10-1 \u6240\u793a\u3002

    \u56fe 10-1 \u00a0 \u4e8c\u5206\u67e5\u627e\u793a\u4f8b\u6570\u636e

    \u5982\u56fe 10-2 \u6240\u793a\uff0c\u6211\u4eec\u5148\u521d\u59cb\u5316\u6307\u9488 \\(i = 0\\) \u548c \\(j = n - 1\\) \uff0c\u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u548c\u5c3e\u5143\u7d20\uff0c\u4ee3\u8868\u641c\u7d22\u533a\u95f4 \\([0, n - 1]\\) \u3002\u8bf7\u6ce8\u610f\uff0c\u4e2d\u62ec\u53f7\u8868\u793a\u95ed\u533a\u95f4\uff0c\u5176\u5305\u542b\u8fb9\u754c\u503c\u672c\u8eab\u3002

    \u63a5\u4e0b\u6765\uff0c\u5faa\u73af\u6267\u884c\u4ee5\u4e0b\u4e24\u6b65\u3002

    1. \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 \\(m = \\lfloor {(i + j) / 2} \\rfloor\\) \uff0c\u5176\u4e2d \\(\\lfloor \\: \\rfloor\\) \u8868\u793a\u5411\u4e0b\u53d6\u6574\u64cd\u4f5c\u3002
    2. \u5224\u65ad nums[m] \u548c target \u7684\u5927\u5c0f\u5173\u7cfb\uff0c\u5206\u4e3a\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\u3002
      1. \u5f53 nums[m] < target \u65f6\uff0c\u8bf4\u660e target \u5728\u533a\u95f4 \\([m + 1, j]\\) \u4e2d\uff0c\u56e0\u6b64\u6267\u884c \\(i = m + 1\\) \u3002
      2. \u5f53 nums[m] > target \u65f6\uff0c\u8bf4\u660e target \u5728\u533a\u95f4 \\([i, m - 1]\\) \u4e2d\uff0c\u56e0\u6b64\u6267\u884c \\(j = m - 1\\) \u3002
      3. \u5f53 nums[m] = target \u65f6\uff0c\u8bf4\u660e\u627e\u5230 target \uff0c\u56e0\u6b64\u8fd4\u56de\u7d22\u5f15 \\(m\\) \u3002

    \u82e5\u6570\u7ec4\u4e0d\u5305\u542b\u76ee\u6807\u5143\u7d20\uff0c\u641c\u7d22\u533a\u95f4\u6700\u7ec8\u4f1a\u7f29\u5c0f\u4e3a\u7a7a\u3002\u6b64\u65f6\u8fd4\u56de \\(-1\\) \u3002

    <1><2><3><4><5><6><7>

    \u56fe 10-2 \u00a0 \u4e8c\u5206\u67e5\u627e\u6d41\u7a0b

    \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u7531\u4e8e \\(i\\) \u548c \\(j\\) \u90fd\u662f int \u7c7b\u578b\uff0c\u56e0\u6b64 \\(i + j\\) \u53ef\u80fd\u4f1a\u8d85\u51fa int \u7c7b\u578b\u7684\u53d6\u503c\u8303\u56f4\u3002\u4e3a\u4e86\u907f\u514d\u5927\u6570\u8d8a\u754c\uff0c\u6211\u4eec\u901a\u5e38\u91c7\u7528\u516c\u5f0f \\(m = \\lfloor {i + (j - i) / 2} \\rfloor\\) \u6765\u8ba1\u7b97\u4e2d\u70b9\u3002

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search.py
    def binary_search(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09\"\"\"\n    # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    i, j = 0, len(nums) - 1\n    # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j:\n        # \u7406\u8bba\u4e0a Python \u7684\u6570\u5b57\u53ef\u4ee5\u65e0\u9650\u5927\uff08\u53d6\u51b3\u4e8e\u5185\u5b58\u5927\u5c0f\uff09\uff0c\u65e0\u987b\u8003\u8651\u5927\u6570\u8d8a\u754c\u95ee\u9898\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n
    binary_search.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(vector<int> &nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.size() - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.java
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.cs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint BinarySearch(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = nums.Length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2;   // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else                       // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.go
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunc binarySearch(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    i, j := 0, len(nums)-1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    for i <= j {\n        m := i + (j-i)/2      // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.swift
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunc binarySearch(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.js
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunction binarySearch(nums, target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let i = 0,\n        j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m \uff0c\u4f7f\u7528 parseInt() \u5411\u4e0b\u53d6\u6574\n        const m = parseInt(i + (j - i) / 2);\n        if (nums[m] < target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else return m; // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.ts
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfunction binarySearch(nums: number[], target: number): number {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let i = 0,\n        j = nums.length - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        const m = Math.floor(i + (j - i) / 2);\n        if (nums[m] < target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if (nums[m] > target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    return -1; // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n}\n
    binary_search.dart
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(List<int> nums, int target) {\n  // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n  int i = 0, j = nums.length - 1;\n  // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n      i = m + 1;\n    } else if (nums[m] > target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n      j = m - 1;\n    } else {\n      // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n      return m;\n    }\n  }\n  // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n  return -1;\n}\n
    binary_search.rs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfn binary_search(nums: &[i32], target: i32) -> i32 {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    let mut i = 0;\n    let mut j = nums.len() as i32 - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if nums[m as usize] > target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.c
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nint binarySearch(int *nums, int len, int target) {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    int i = 0, j = len - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.kt
    /* \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 */\nfun binarySearch(nums: IntArray, target: Int): Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i = 0\n    var j = nums.size - 1\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        else  // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.rb
    ### \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09 ###\ndef binary_search(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n  i, j = 0, nums.length - 1\n\n  # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n  while i <= j\n    # \u7406\u8bba\u4e0a Ruby \u7684\u6570\u5b57\u53ef\u4ee5\u65e0\u9650\u5927\uff08\u53d6\u51b3\u4e8e\u5185\u5b58\u5927\u5c0f\uff09\uff0c\u65e0\u987b\u8003\u8651\u5927\u6570\u8d8a\u754c\u95ee\u9898\n    m = (i + j) / 2   # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n\n    if nums[m] < target\n      i = m + 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    end\n  end\n\n  -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\nend\n
    binary_search.zig
    // \u4e8c\u5206\u67e5\u627e\uff08\u53cc\u95ed\u533a\u95f4\uff09\nfn binarySearch(comptime T: type, nums: std.ArrayList(T), target: T) T {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1] \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20\n    var i: usize = 0;\n    var j: usize = nums.items.len - 1;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i > j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        var m = i + (j - i) / 2;                // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums.items[m] < target) {           // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1;\n        } else if (nums.items[m] > target) {    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1;\n        } else {                                // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return @intCast(m);\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \uff1a\u5728\u4e8c\u5206\u5faa\u73af\u4e2d\uff0c\u533a\u95f4\u6bcf\u8f6e\u7f29\u5c0f\u4e00\u534a\uff0c\u56e0\u6b64\u5faa\u73af\u6b21\u6570\u4e3a \\(\\log_2 n\\) \u3002

    \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7a7a\u95f4\u3002

    "},{"location":"chapter_searching/binary_search/#1011","title":"10.1.1 \u00a0 \u533a\u95f4\u8868\u793a\u65b9\u6cd5","text":"

    \u9664\u4e86\u4e0a\u8ff0\u53cc\u95ed\u533a\u95f4\u5916\uff0c\u5e38\u89c1\u7684\u533a\u95f4\u8868\u793a\u8fd8\u6709\u201c\u5de6\u95ed\u53f3\u5f00\u201d\u533a\u95f4\uff0c\u5b9a\u4e49\u4e3a \\([0, n)\\) \uff0c\u5373\u5de6\u8fb9\u754c\u5305\u542b\u81ea\u8eab\uff0c\u53f3\u8fb9\u754c\u4e0d\u5305\u542b\u81ea\u8eab\u3002\u5728\u8be5\u8868\u793a\u4e0b\uff0c\u533a\u95f4 \\([i, j)\\) \u5728 \\(i = j\\) \u65f6\u4e3a\u7a7a\u3002

    \u6211\u4eec\u53ef\u4ee5\u57fa\u4e8e\u8be5\u8868\u793a\u5b9e\u73b0\u5177\u6709\u76f8\u540c\u529f\u80fd\u7684\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search.py
    def binary_search_lcro(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09\"\"\"\n    # \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    i, j = 0, len(nums)\n    # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n        elif nums[m] > target:\n            j = m  # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n        else:\n            return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    return -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n
    binary_search.cpp
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(vector<int> &nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.size();\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.java
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.cs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint BinarySearchLCRO(int[] nums, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = nums.Length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2;   // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else                       // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.go
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunc binarySearchLCRO(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    i, j := 0, len(nums)\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    for i < j {\n        m := i + (j-i)/2      // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.swift
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunc binarySearchLCRO(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i = nums.startIndex\n    var j = nums.endIndex\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        } else if nums[m] > target { // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        } else { // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.js
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunction binarySearchLCRO(nums, target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let i = 0,\n        j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m \uff0c\u4f7f\u7528 parseInt() \u5411\u4e0b\u53d6\u6574\n        const m = parseInt(i + (j - i) / 2);\n        if (nums[m] < target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target)\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n        else return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.ts
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfunction binarySearchLCRO(nums: number[], target: number): number {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let i = 0,\n        j = nums.length;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        const m = Math.floor(i + (j - i) / 2);\n        if (nums[m] < target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if (nums[m] > target) {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    return -1; // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n}\n
    binary_search.dart
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(List<int> nums, int target) {\n  // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n  int i = 0, j = nums.length;\n  // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n  while (i < j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n      i = m + 1;\n    } else if (nums[m] > target) {\n      // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n      j = m;\n    } else {\n      // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n      return m;\n    }\n  }\n  // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n  return -1;\n}\n
    binary_search.rs
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfn binary_search_lcro(nums: &[i32], target: i32) -> i32 {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    let mut i = 0;\n    let mut j = nums.len() as i32;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while i < j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if nums[m as usize] > target {\n            // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.c
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nint binarySearchLCRO(int *nums, int len, int target) {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    int i = 0, j = len;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target)    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        else // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m;\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    binary_search.kt
    /* \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 */\nfun binarySearchLCRO(nums: IntArray, target: Int): Int {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i = 0\n    var j = nums.size\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i < j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1\n        else if (nums[m] > target) // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m\n        else  // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return m\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1\n}\n
    binary_search.rb
    ### \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09 ###\ndef binary_search_lcro(nums, target)\n  # \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n  i, j = 0, nums.length\n\n  # \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n  while i < j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n    else\n      return m  # \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n    end\n  end\n\n  -1  # \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\nend\n
    binary_search.zig
    // \u4e8c\u5206\u67e5\u627e\uff08\u5de6\u95ed\u53f3\u5f00\u533a\u95f4\uff09\nfn binarySearchLCRO(comptime T: type, nums: std.ArrayList(T), target: T) T {\n    // \u521d\u59cb\u5316\u5de6\u95ed\u53f3\u5f00\u533a\u95f4 [0, n) \uff0c\u5373 i, j \u5206\u522b\u6307\u5411\u6570\u7ec4\u9996\u5143\u7d20\u3001\u5c3e\u5143\u7d20+1\n    var i: usize = 0;\n    var j: usize = nums.items.len;\n    // \u5faa\u73af\uff0c\u5f53\u641c\u7d22\u533a\u95f4\u4e3a\u7a7a\u65f6\u8df3\u51fa\uff08\u5f53 i = j \u65f6\u4e3a\u7a7a\uff09\n    while (i <= j) {\n        var m = i + (j - i) / 2;                // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums.items[m] < target) {           // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [m+1, j) \u4e2d\n            i = m + 1;\n        } else if (nums.items[m] > target) {    // \u6b64\u60c5\u51b5\u8bf4\u660e target \u5728\u533a\u95f4 [i, m) \u4e2d\n            j = m;\n        } else {                                // \u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de\u5176\u7d22\u5f15\n            return @intCast(m);\n        }\n    }\n    // \u672a\u627e\u5230\u76ee\u6807\u5143\u7d20\uff0c\u8fd4\u56de -1\n    return -1;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u5982\u56fe 10-3 \u6240\u793a\uff0c\u5728\u4e24\u79cd\u533a\u95f4\u8868\u793a\u4e0b\uff0c\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u7684\u521d\u59cb\u5316\u3001\u5faa\u73af\u6761\u4ef6\u548c\u7f29\u5c0f\u533a\u95f4\u64cd\u4f5c\u7686\u6709\u6240\u4e0d\u540c\u3002

    \u7531\u4e8e\u201c\u53cc\u95ed\u533a\u95f4\u201d\u8868\u793a\u4e2d\u7684\u5de6\u53f3\u8fb9\u754c\u90fd\u88ab\u5b9a\u4e49\u4e3a\u95ed\u533a\u95f4\uff0c\u56e0\u6b64\u901a\u8fc7\u6307\u9488 \\(i\\) \u548c\u6307\u9488 \\(j\\) \u7f29\u5c0f\u533a\u95f4\u7684\u64cd\u4f5c\u4e5f\u662f\u5bf9\u79f0\u7684\u3002\u8fd9\u6837\u66f4\u4e0d\u5bb9\u6613\u51fa\u9519\uff0c\u56e0\u6b64\u4e00\u822c\u5efa\u8bae\u91c7\u7528\u201c\u53cc\u95ed\u533a\u95f4\u201d\u7684\u5199\u6cd5\u3002

    \u56fe 10-3 \u00a0 \u4e24\u79cd\u533a\u95f4\u5b9a\u4e49

    "},{"location":"chapter_searching/binary_search/#1012","title":"10.1.2 \u00a0 \u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u4e8c\u5206\u67e5\u627e\u5728\u65f6\u95f4\u548c\u7a7a\u95f4\u65b9\u9762\u90fd\u6709\u8f83\u597d\u7684\u6027\u80fd\u3002

    • \u4e8c\u5206\u67e5\u627e\u7684\u65f6\u95f4\u6548\u7387\u9ad8\u3002\u5728\u5927\u6570\u636e\u91cf\u4e0b\uff0c\u5bf9\u6570\u9636\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5177\u6709\u663e\u8457\u4f18\u52bf\u3002\u4f8b\u5982\uff0c\u5f53\u6570\u636e\u5927\u5c0f \\(n = 2^{20}\\) \u65f6\uff0c\u7ebf\u6027\u67e5\u627e\u9700\u8981 \\(2^{20} = 1048576\\) \u8f6e\u5faa\u73af\uff0c\u800c\u4e8c\u5206\u67e5\u627e\u4ec5\u9700 \\(\\log_2 2^{20} = 20\\) \u8f6e\u5faa\u73af\u3002
    • \u4e8c\u5206\u67e5\u627e\u65e0\u987b\u989d\u5916\u7a7a\u95f4\u3002\u76f8\u8f83\u4e8e\u9700\u8981\u501f\u52a9\u989d\u5916\u7a7a\u95f4\u7684\u641c\u7d22\u7b97\u6cd5\uff08\u4f8b\u5982\u54c8\u5e0c\u67e5\u627e\uff09\uff0c\u4e8c\u5206\u67e5\u627e\u66f4\u52a0\u8282\u7701\u7a7a\u95f4\u3002

    \u7136\u800c\uff0c\u4e8c\u5206\u67e5\u627e\u5e76\u975e\u9002\u7528\u4e8e\u6240\u6709\u60c5\u51b5\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u4e8c\u5206\u67e5\u627e\u4ec5\u9002\u7528\u4e8e\u6709\u5e8f\u6570\u636e\u3002\u82e5\u8f93\u5165\u6570\u636e\u65e0\u5e8f\uff0c\u4e3a\u4e86\u4f7f\u7528\u4e8c\u5206\u67e5\u627e\u800c\u4e13\u95e8\u8fdb\u884c\u6392\u5e8f\uff0c\u5f97\u4e0d\u507f\u5931\u3002\u56e0\u4e3a\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u901a\u5e38\u4e3a \\(O(n \\log n)\\) \uff0c\u6bd4\u7ebf\u6027\u67e5\u627e\u548c\u4e8c\u5206\u67e5\u627e\u90fd\u66f4\u9ad8\u3002\u5bf9\u4e8e\u9891\u7e41\u63d2\u5165\u5143\u7d20\u7684\u573a\u666f\uff0c\u4e3a\u4fdd\u6301\u6570\u7ec4\u6709\u5e8f\u6027\uff0c\u9700\u8981\u5c06\u5143\u7d20\u63d2\u5165\u5230\u7279\u5b9a\u4f4d\u7f6e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u4e5f\u662f\u975e\u5e38\u6602\u8d35\u7684\u3002
    • \u4e8c\u5206\u67e5\u627e\u4ec5\u9002\u7528\u4e8e\u6570\u7ec4\u3002\u4e8c\u5206\u67e5\u627e\u9700\u8981\u8df3\u8dc3\u5f0f\uff08\u975e\u8fde\u7eed\u5730\uff09\u8bbf\u95ee\u5143\u7d20\uff0c\u800c\u5728\u94fe\u8868\u4e2d\u6267\u884c\u8df3\u8dc3\u5f0f\u8bbf\u95ee\u7684\u6548\u7387\u8f83\u4f4e\uff0c\u56e0\u6b64\u4e0d\u9002\u5408\u5e94\u7528\u5728\u94fe\u8868\u6216\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002
    • \u5c0f\u6570\u636e\u91cf\u4e0b\uff0c\u7ebf\u6027\u67e5\u627e\u6027\u80fd\u66f4\u4f73\u3002\u5728\u7ebf\u6027\u67e5\u627e\u4e2d\uff0c\u6bcf\u8f6e\u53ea\u9700 1 \u6b21\u5224\u65ad\u64cd\u4f5c\uff1b\u800c\u5728\u4e8c\u5206\u67e5\u627e\u4e2d\uff0c\u9700\u8981 1 \u6b21\u52a0\u6cd5\u30011 \u6b21\u9664\u6cd5\u30011 ~ 3 \u6b21\u5224\u65ad\u64cd\u4f5c\u30011 \u6b21\u52a0\u6cd5\uff08\u51cf\u6cd5\uff09\uff0c\u5171 4 ~ 6 \u4e2a\u5355\u5143\u64cd\u4f5c\uff1b\u56e0\u6b64\uff0c\u5f53\u6570\u636e\u91cf \\(n\\) \u8f83\u5c0f\u65f6\uff0c\u7ebf\u6027\u67e5\u627e\u53cd\u800c\u6bd4\u4e8c\u5206\u67e5\u627e\u66f4\u5feb\u3002
    "},{"location":"chapter_searching/binary_search_edge/","title":"10.3 \u00a0 \u4e8c\u5206\u67e5\u627e\u8fb9\u754c","text":""},{"location":"chapter_searching/binary_search_edge/#1031","title":"10.3.1 \u00a0 \u67e5\u627e\u5de6\u8fb9\u754c","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6709\u5e8f\u6570\u7ec4 nums \uff0c\u5176\u4e2d\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\u3002\u8bf7\u8fd4\u56de\u6570\u7ec4\u4e2d\u6700\u5de6\u4e00\u4e2a\u5143\u7d20 target \u7684\u7d22\u5f15\u3002\u82e5\u6570\u7ec4\u4e2d\u4e0d\u5305\u542b\u8be5\u5143\u7d20\uff0c\u5219\u8fd4\u56de \\(-1\\) \u3002

    \u56de\u5fc6\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\u7684\u65b9\u6cd5\uff0c\u641c\u7d22\u5b8c\u6210\u540e \\(i\\) \u6307\u5411\u6700\u5de6\u4e00\u4e2a target \uff0c\u56e0\u6b64\u67e5\u627e\u63d2\u5165\u70b9\u672c\u8d28\u4e0a\u662f\u5728\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target \u7684\u7d22\u5f15\u3002

    \u8003\u8651\u901a\u8fc7\u67e5\u627e\u63d2\u5165\u70b9\u7684\u51fd\u6570\u5b9e\u73b0\u67e5\u627e\u5de6\u8fb9\u754c\u3002\u8bf7\u6ce8\u610f\uff0c\u6570\u7ec4\u4e2d\u53ef\u80fd\u4e0d\u5305\u542b target \uff0c\u8fd9\u79cd\u60c5\u51b5\u53ef\u80fd\u5bfc\u81f4\u4ee5\u4e0b\u4e24\u79cd\u7ed3\u679c\u3002

    • \u63d2\u5165\u70b9\u7684\u7d22\u5f15 \\(i\\) \u8d8a\u754c\u3002
    • \u5143\u7d20 nums[i] \u4e0e target \u4e0d\u76f8\u7b49\u3002

    \u5f53\u9047\u5230\u4ee5\u4e0a\u4e24\u79cd\u60c5\u51b5\u65f6\uff0c\u76f4\u63a5\u8fd4\u56de \\(-1\\) \u5373\u53ef\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_edge.py
    def binary_search_left_edge(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target\"\"\"\n    # \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    i = binary_search_insertion(nums, target)\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == len(nums) or nums[i] != target:\n        return -1\n    # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n
    binary_search_edge.cpp
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(vector<int> &nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.size() || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.java
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(int[] nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binary_search_insertion.binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.length || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.cs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint BinarySearchLeftEdge(int[] nums, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binary_search_insertion.BinarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.Length || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.go
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunc binarySearchLeftEdge(nums []int, target int) int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    i := binarySearchInsertion(nums, target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == len(nums) || nums[i] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.swift
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunc binarySearchLeftEdge(nums: [Int], target: Int) -> Int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    let i = binarySearchInsertion(nums: nums, target: target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == nums.endIndex || nums[i] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.js
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunction binarySearchLeftEdge(nums, target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    const i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i === nums.length || nums[i] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.ts
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfunction binarySearchLeftEdge(nums: Array<number>, target: number): number {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    const i = binarySearchInsertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i === nums.length || nums[i] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.dart
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(List<int> nums, int target) {\n  // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n  int i = binarySearchInsertion(nums, target);\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  if (i == nums.length || nums[i] != target) {\n    return -1;\n  }\n  // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n  return i;\n}\n
    binary_search_edge.rs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfn binary_search_left_edge(nums: &[i32], target: i32) -> i32 {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    let i = binary_search_insertion(nums, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if i == nums.len() as i32 || nums[i as usize] != target {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    i\n}\n
    binary_search_edge.c
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nint binarySearchLeftEdge(int *nums, int numSize, int target) {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    int i = binarySearchInsertion(nums, numSize, target);\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == numSize || nums[i] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i;\n}\n
    binary_search_edge.kt
    /* \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target */\nfun binarySearchLeftEdge(nums: IntArray, target: Int): Int {\n    // \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n    val i = binarySearchInsertion(nums, target)\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (i == nums.size || nums[i] != target) {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\n    return i\n}\n
    binary_search_edge.rb
    ### \u4e8c\u5206\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target ###\ndef binary_search_left_edge(nums, target)\n  # \u7b49\u4ef7\u4e8e\u67e5\u627e target \u7684\u63d2\u5165\u70b9\n  i = binary_search_insertion(nums, target)\n\n  # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  return -1 if i == nums.length || nums[i] != target\n\n  i # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 i\nend\n
    binary_search_edge.zig
    [class]{}-[func]{binarySearchLeftEdge}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_searching/binary_search_edge/#1032","title":"10.3.2 \u00a0 \u67e5\u627e\u53f3\u8fb9\u754c","text":"

    \u90a3\u4e48\u5982\u4f55\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target \u5462\uff1f\u6700\u76f4\u63a5\u7684\u65b9\u5f0f\u662f\u4fee\u6539\u4ee3\u7801\uff0c\u66ff\u6362\u5728 nums[m] == target \u60c5\u51b5\u4e0b\u7684\u6307\u9488\u6536\u7f29\u64cd\u4f5c\u3002\u4ee3\u7801\u5728\u6b64\u7701\u7565\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u3002

    \u4e0b\u9762\u6211\u4eec\u4ecb\u7ecd\u4e24\u79cd\u66f4\u52a0\u53d6\u5de7\u7684\u65b9\u6cd5\u3002

    "},{"location":"chapter_searching/binary_search_edge/#1","title":"1. \u00a0 \u590d\u7528\u67e5\u627e\u5de6\u8fb9\u754c","text":"

    \u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u67e5\u627e\u6700\u5de6\u5143\u7d20\u7684\u51fd\u6570\u6765\u67e5\u627e\u6700\u53f3\u5143\u7d20\uff0c\u5177\u4f53\u65b9\u6cd5\u4e3a\uff1a\u5c06\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\u3002

    \u5982\u56fe 10-7 \u6240\u793a\uff0c\u67e5\u627e\u5b8c\u6210\u540e\uff0c\u6307\u9488 \\(i\\) \u6307\u5411\u6700\u5de6\u4e00\u4e2a target + 1\uff08\u5982\u679c\u5b58\u5728\uff09\uff0c\u800c \\(j\\) \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0c\u56e0\u6b64\u8fd4\u56de \\(j\\) \u5373\u53ef\u3002

    \u56fe 10-7 \u00a0 \u5c06\u67e5\u627e\u53f3\u8fb9\u754c\u8f6c\u5316\u4e3a\u67e5\u627e\u5de6\u8fb9\u754c

    \u8bf7\u6ce8\u610f\uff0c\u8fd4\u56de\u7684\u63d2\u5165\u70b9\u662f \\(i\\) \uff0c\u56e0\u6b64\u9700\u8981\u5c06\u5176\u51cf \\(1\\) \uff0c\u4ece\u800c\u83b7\u5f97 \\(j\\) \uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_edge.py
    def binary_search_right_edge(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target\"\"\"\n    # \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    i = binary_search_insertion(nums, target + 1)\n    # j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    j = i - 1\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 or nums[j] != target:\n        return -1\n    # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n
    binary_search_edge.cpp
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(vector<int> &nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.java
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(int[] nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binary_search_insertion.binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.cs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint BinarySearchRightEdge(int[] nums, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binary_search_insertion.BinarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.go
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunc binarySearchRightEdge(nums []int, target int) int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    i := binarySearchInsertion(nums, target+1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    j := i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.swift
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunc binarySearchRightEdge(nums: [Int], target: Int) -> Int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    let i = binarySearchInsertion(nums: nums, target: target + 1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    let j = i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j] != target {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.js
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunction binarySearchRightEdge(nums, target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    const i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    const j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j === -1 || nums[j] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.ts
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfunction binarySearchRightEdge(nums: Array<number>, target: number): number {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    const i = binarySearchInsertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    const j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j === -1 || nums[j] !== target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.dart
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(List<int> nums, int target) {\n  // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n  int i = binarySearchInsertion(nums, target + 1);\n  // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n  int j = i - 1;\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  if (j == -1 || nums[j] != target) {\n    return -1;\n  }\n  // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n  return j;\n}\n
    binary_search_edge.rs
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfn binary_search_right_edge(nums: &[i32], target: i32) -> i32 {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    let i = binary_search_insertion(nums, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    let j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if j == -1 || nums[j as usize] != target {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    j\n}\n
    binary_search_edge.c
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nint binarySearchRightEdge(int *nums, int numSize, int target) {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    int i = binarySearchInsertion(nums, numSize, target + 1);\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    int j = i - 1;\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1;\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j;\n}\n
    binary_search_edge.kt
    /* \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target */\nfun binarySearchRightEdge(nums: IntArray, target: Int): Int {\n    // \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n    val i = binarySearchInsertion(nums, target + 1)\n    // j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n    val j = i - 1\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n    if (j == -1 || nums[j] != target) {\n        return -1\n    }\n    // \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\n    return j\n}\n
    binary_search_edge.rb
    ### \u4e8c\u5206\u67e5\u627e\u6700\u53f3\u4e00\u4e2a target ###\ndef binary_search_right_edge(nums, target)\n  # \u8f6c\u5316\u4e3a\u67e5\u627e\u6700\u5de6\u4e00\u4e2a target + 1\n  i = binary_search_insertion(nums, target + 1)\n\n  # j \u6307\u5411\u6700\u53f3\u4e00\u4e2a target \uff0ci \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\n  j = i - 1\n\n  # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de -1\n  return -1 if j == -1 || nums[j] != target\n\n  j # \u627e\u5230 target \uff0c\u8fd4\u56de\u7d22\u5f15 j\nend\n
    binary_search_edge.zig
    [class]{}-[func]{binarySearchRightEdge}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_searching/binary_search_edge/#2","title":"2. \u00a0 \u8f6c\u5316\u4e3a\u67e5\u627e\u5143\u7d20","text":"

    \u6211\u4eec\u77e5\u9053\uff0c\u5f53\u6570\u7ec4\u4e0d\u5305\u542b target \u65f6\uff0c\u6700\u7ec8 \\(i\\) \u548c \\(j\\) \u4f1a\u5206\u522b\u6307\u5411\u9996\u4e2a\u5927\u4e8e\u3001\u5c0f\u4e8e target \u7684\u5143\u7d20\u3002

    \u56e0\u6b64\uff0c\u5982\u56fe 10-8 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u9020\u4e00\u4e2a\u6570\u7ec4\u4e2d\u4e0d\u5b58\u5728\u7684\u5143\u7d20\uff0c\u7528\u4e8e\u67e5\u627e\u5de6\u53f3\u8fb9\u754c\u3002

    • \u67e5\u627e\u6700\u5de6\u4e00\u4e2a target \uff1a\u53ef\u4ee5\u8f6c\u5316\u4e3a\u67e5\u627e target - 0.5 \uff0c\u5e76\u8fd4\u56de\u6307\u9488 \\(i\\) \u3002
    • \u67e5\u627e\u6700\u53f3\u4e00\u4e2a target \uff1a\u53ef\u4ee5\u8f6c\u5316\u4e3a\u67e5\u627e target + 0.5 \uff0c\u5e76\u8fd4\u56de\u6307\u9488 \\(j\\) \u3002

    \u56fe 10-8 \u00a0 \u5c06\u67e5\u627e\u8fb9\u754c\u8f6c\u5316\u4e3a\u67e5\u627e\u5143\u7d20

    \u4ee3\u7801\u5728\u6b64\u7701\u7565\uff0c\u4ee5\u4e0b\u4e24\u70b9\u503c\u5f97\u6ce8\u610f\u3002

    • \u7ed9\u5b9a\u6570\u7ec4\u4e0d\u5305\u542b\u5c0f\u6570\uff0c\u8fd9\u610f\u5473\u7740\u6211\u4eec\u65e0\u987b\u5173\u5fc3\u5982\u4f55\u5904\u7406\u76f8\u7b49\u7684\u60c5\u51b5\u3002
    • \u56e0\u4e3a\u8be5\u65b9\u6cd5\u5f15\u5165\u4e86\u5c0f\u6570\uff0c\u6240\u4ee5\u9700\u8981\u5c06\u51fd\u6570\u4e2d\u7684\u53d8\u91cf target \u6539\u4e3a\u6d6e\u70b9\u6570\u7c7b\u578b\uff08Python \u65e0\u987b\u6539\u52a8\uff09\u3002
    "},{"location":"chapter_searching/binary_search_insertion/","title":"10.2 \u00a0 \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9","text":"

    \u4e8c\u5206\u67e5\u627e\u4e0d\u4ec5\u53ef\u7528\u4e8e\u641c\u7d22\u76ee\u6807\u5143\u7d20\uff0c\u8fd8\u53ef\u7528\u4e8e\u89e3\u51b3\u8bb8\u591a\u53d8\u79cd\u95ee\u9898\uff0c\u6bd4\u5982\u641c\u7d22\u76ee\u6807\u5143\u7d20\u7684\u63d2\u5165\u4f4d\u7f6e\u3002

    "},{"location":"chapter_searching/binary_search_insertion/#1021","title":"10.2.1 \u00a0 \u65e0\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6709\u5e8f\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u5143\u7d20 target \uff0c\u6570\u7ec4\u4e0d\u5b58\u5728\u91cd\u590d\u5143\u7d20\u3002\u73b0\u5c06 target \u63d2\u5165\u6570\u7ec4 nums \u4e2d\uff0c\u5e76\u4fdd\u6301\u5176\u6709\u5e8f\u6027\u3002\u82e5\u6570\u7ec4\u4e2d\u5df2\u5b58\u5728\u5143\u7d20 target \uff0c\u5219\u63d2\u5165\u5230\u5176\u5de6\u65b9\u3002\u8bf7\u8fd4\u56de\u63d2\u5165\u540e target \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15\u3002\u793a\u4f8b\u5982\u56fe 10-4 \u6240\u793a\u3002

    \u56fe 10-4 \u00a0 \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\u793a\u4f8b\u6570\u636e

    \u5982\u679c\u60f3\u590d\u7528\u4e0a\u4e00\u8282\u7684\u4e8c\u5206\u67e5\u627e\u4ee3\u7801\uff0c\u5219\u9700\u8981\u56de\u7b54\u4ee5\u4e0b\u4e24\u4e2a\u95ee\u9898\u3002

    \u95ee\u9898\u4e00\uff1a\u5f53\u6570\u7ec4\u4e2d\u5305\u542b target \u65f6\uff0c\u63d2\u5165\u70b9\u7684\u7d22\u5f15\u662f\u5426\u662f\u8be5\u5143\u7d20\u7684\u7d22\u5f15\uff1f

    \u9898\u76ee\u8981\u6c42\u5c06 target \u63d2\u5165\u5230\u76f8\u7b49\u5143\u7d20\u7684\u5de6\u8fb9\uff0c\u8fd9\u610f\u5473\u7740\u65b0\u63d2\u5165\u7684 target \u66ff\u6362\u4e86\u539f\u6765 target \u7684\u4f4d\u7f6e\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u5f53\u6570\u7ec4\u5305\u542b target \u65f6\uff0c\u63d2\u5165\u70b9\u7684\u7d22\u5f15\u5c31\u662f\u8be5 target \u7684\u7d22\u5f15\u3002

    \u95ee\u9898\u4e8c\uff1a\u5f53\u6570\u7ec4\u4e2d\u4e0d\u5b58\u5728 target \u65f6\uff0c\u63d2\u5165\u70b9\u662f\u54ea\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\uff1f

    \u8fdb\u4e00\u6b65\u601d\u8003\u4e8c\u5206\u67e5\u627e\u8fc7\u7a0b\uff1a\u5f53 nums[m] < target \u65f6 \\(i\\) \u79fb\u52a8\uff0c\u8fd9\u610f\u5473\u7740\u6307\u9488 \\(i\\) \u5728\u5411\u5927\u4e8e\u7b49\u4e8e target \u7684\u5143\u7d20\u9760\u8fd1\u3002\u540c\u7406\uff0c\u6307\u9488 \\(j\\) \u59cb\u7ec8\u5728\u5411\u5c0f\u4e8e\u7b49\u4e8e target \u7684\u5143\u7d20\u9760\u8fd1\u3002

    \u56e0\u6b64\u4e8c\u5206\u7ed3\u675f\u65f6\u4e00\u5b9a\u6709\uff1a\\(i\\) \u6307\u5411\u9996\u4e2a\u5927\u4e8e target \u7684\u5143\u7d20\uff0c\\(j\\) \u6307\u5411\u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u3002\u6613\u5f97\u5f53\u6570\u7ec4\u4e0d\u5305\u542b target \u65f6\uff0c\u63d2\u5165\u7d22\u5f15\u4e3a \\(i\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_insertion.py
    def binary_search_insertion_simple(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09\"\"\"\n    i, j = 0, len(nums) - 1  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            return m  # \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n
    binary_search_insertion.cpp
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(vector<int> &nums, int target) {\n    int i = 0, j = nums.size() - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.java
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(int[] nums, int target) {\n    int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.cs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint BinarySearchInsertionSimple(int[] nums, int target) {\n    int i = 0, j = nums.Length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.go
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertionSimple(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    i, j := 0, len(nums)-1\n    for i <= j {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        m := i + (j-i)/2\n        if nums[m] < target {\n            // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target {\n            // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else {\n            // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n            return m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.swift
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertionSimple(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m] > target {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.js
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertionSimple(nums, target) {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.ts
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertionSimple(\n    nums: Array<number>,\n    target: number\n): number {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.dart
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(List<int> nums, int target) {\n  int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    } else if (nums[m] > target) {\n      j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    } else {\n      return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    }\n  }\n  // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n  return i;\n}\n
    binary_search_insertion.rs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfn binary_search_insertion_simple(nums: &[i32], target: i32) -> i32 {\n    let (mut i, mut j) = (0, nums.len() as i32 - 1); // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m as usize] > target {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m;\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    i\n}\n
    binary_search_insertion.c
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertionSimple(int *nums, int numSize, int target) {\n    int i = 0, j = numSize - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m; // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.kt
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 */\nfun binarySearchInsertionSimple(nums: IntArray, target: Int): Int {\n    var i = 0\n    var j = nums.size - 1 // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            return m // \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n        }\n    }\n    // \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.rb
    ### \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u65e0\u91cd\u590d\u5143\u7d20\uff09 ###\ndef binary_search_insertion_simple(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  i, j = 0, nums.length - 1\n\n  while i <= j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      return m  # \u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 m\n    end\n  end\n\n  i # \u672a\u627e\u5230 target \uff0c\u8fd4\u56de\u63d2\u5165\u70b9 i\nend\n
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertionSimple}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_searching/binary_search_insertion/#1022","title":"10.2.2 \u00a0 \u5b58\u5728\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5","text":"

    Question

    \u5728\u4e0a\u4e00\u9898\u7684\u57fa\u7840\u4e0a\uff0c\u89c4\u5b9a\u6570\u7ec4\u53ef\u80fd\u5305\u542b\u91cd\u590d\u5143\u7d20\uff0c\u5176\u4f59\u4e0d\u53d8\u3002

    \u5047\u8bbe\u6570\u7ec4\u4e2d\u5b58\u5728\u591a\u4e2a target \uff0c\u5219\u666e\u901a\u4e8c\u5206\u67e5\u627e\u53ea\u80fd\u8fd4\u56de\u5176\u4e2d\u4e00\u4e2a target \u7684\u7d22\u5f15\uff0c\u800c\u65e0\u6cd5\u786e\u5b9a\u8be5\u5143\u7d20\u7684\u5de6\u8fb9\u548c\u53f3\u8fb9\u8fd8\u6709\u591a\u5c11 target\u3002

    \u9898\u76ee\u8981\u6c42\u5c06\u76ee\u6807\u5143\u7d20\u63d2\u5165\u5230\u6700\u5de6\u8fb9\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981\u67e5\u627e\u6570\u7ec4\u4e2d\u6700\u5de6\u4e00\u4e2a target \u7684\u7d22\u5f15\u3002\u521d\u6b65\u8003\u8651\u901a\u8fc7\u56fe 10-5 \u6240\u793a\u7684\u6b65\u9aa4\u5b9e\u73b0\u3002

    1. \u6267\u884c\u4e8c\u5206\u67e5\u627e\uff0c\u5f97\u5230\u4efb\u610f\u4e00\u4e2a target \u7684\u7d22\u5f15\uff0c\u8bb0\u4e3a \\(k\\) \u3002
    2. \u4ece\u7d22\u5f15 \\(k\\) \u5f00\u59cb\uff0c\u5411\u5de6\u8fdb\u884c\u7ebf\u6027\u904d\u5386\uff0c\u5f53\u627e\u5230\u6700\u5de6\u8fb9\u7684 target \u65f6\u8fd4\u56de\u3002

    \u56fe 10-5 \u00a0 \u7ebf\u6027\u67e5\u627e\u91cd\u590d\u5143\u7d20\u7684\u63d2\u5165\u70b9

    \u6b64\u65b9\u6cd5\u867d\u7136\u53ef\u7528\uff0c\u4f46\u5176\u5305\u542b\u7ebf\u6027\u67e5\u627e\uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002\u5f53\u6570\u7ec4\u4e2d\u5b58\u5728\u5f88\u591a\u91cd\u590d\u7684 target \u65f6\uff0c\u8be5\u65b9\u6cd5\u6548\u7387\u5f88\u4f4e\u3002

    \u73b0\u8003\u8651\u62d3\u5c55\u4e8c\u5206\u67e5\u627e\u4ee3\u7801\u3002\u5982\u56fe 10-6 \u6240\u793a\uff0c\u6574\u4f53\u6d41\u7a0b\u4fdd\u6301\u4e0d\u53d8\uff0c\u6bcf\u8f6e\u5148\u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 \\(m\\) \uff0c\u518d\u5224\u65ad target \u548c nums[m] \u7684\u5927\u5c0f\u5173\u7cfb\uff0c\u5206\u4e3a\u4ee5\u4e0b\u51e0\u79cd\u60c5\u51b5\u3002

    • \u5f53 nums[m] < target \u6216 nums[m] > target \u65f6\uff0c\u8bf4\u660e\u8fd8\u6ca1\u6709\u627e\u5230 target \uff0c\u56e0\u6b64\u91c7\u7528\u666e\u901a\u4e8c\u5206\u67e5\u627e\u7684\u7f29\u5c0f\u533a\u95f4\u64cd\u4f5c\uff0c\u4ece\u800c\u4f7f\u6307\u9488 \\(i\\) \u548c \\(j\\) \u5411 target \u9760\u8fd1\u3002
    • \u5f53 nums[m] == target \u65f6\uff0c\u8bf4\u660e\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 \\([i, m - 1]\\) \u4e2d\uff0c\u56e0\u6b64\u91c7\u7528 \\(j = m - 1\\) \u6765\u7f29\u5c0f\u533a\u95f4\uff0c\u4ece\u800c\u4f7f\u6307\u9488 \\(j\\) \u5411\u5c0f\u4e8e target \u7684\u5143\u7d20\u9760\u8fd1\u3002

    \u5faa\u73af\u5b8c\u6210\u540e\uff0c\\(i\\) \u6307\u5411\u6700\u5de6\u8fb9\u7684 target \uff0c\\(j\\) \u6307\u5411\u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\uff0c\u56e0\u6b64\u7d22\u5f15 \\(i\\) \u5c31\u662f\u63d2\u5165\u70b9\u3002

    <1><2><3><4><5><6><7><8>

    \u56fe 10-6 \u00a0 \u4e8c\u5206\u67e5\u627e\u91cd\u590d\u5143\u7d20\u7684\u63d2\u5165\u70b9\u7684\u6b65\u9aa4

    \u89c2\u5bdf\u4ee5\u4e0b\u4ee3\u7801\uff0c\u5224\u65ad\u5206\u652f nums[m] > target \u548c nums[m] == target \u7684\u64cd\u4f5c\u76f8\u540c\uff0c\u56e0\u6b64\u4e24\u8005\u53ef\u4ee5\u5408\u5e76\u3002

    \u5373\u4fbf\u5982\u6b64\uff0c\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u5c06\u5224\u65ad\u6761\u4ef6\u4fdd\u6301\u5c55\u5f00\uff0c\u56e0\u4e3a\u5176\u903b\u8f91\u66f4\u52a0\u6e05\u6670\u3001\u53ef\u8bfb\u6027\u66f4\u597d\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_insertion.py
    def binary_search_insertion(nums: list[int], target: int) -> int:\n    \"\"\"\u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09\"\"\"\n    i, j = 0, len(nums) - 1  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j:\n        m = (i + j) // 2  # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target:\n            i = m + 1  # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        elif nums[m] > target:\n            j = m - 1  # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        else:\n            j = m - 1  # \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    # \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n
    binary_search_insertion.cpp
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(vector<int> &nums, int target) {\n    int i = 0, j = nums.size() - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.java
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(int[] nums, int target) {\n    int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.cs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint BinarySearchInsertion(int[] nums, int target) {\n    int i = 0, j = nums.Length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.go
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertion(nums []int, target int) int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    i, j := 0, len(nums)-1\n    for i <= j {\n        // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        m := i + (j-i)/2\n        if nums[m] < target {\n            // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n            i = m + 1\n        } else if nums[m] > target {\n            // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        } else {\n            // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n            j = m - 1\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.swift
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunc binarySearchInsertion(nums: [Int], target: Int) -> Int {\n    // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    var i = nums.startIndex\n    var j = nums.endIndex - 1\n    while i <= j {\n        let m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m] < target {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m] > target {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1 // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.js
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertion(nums, target) {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.ts
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfunction binarySearchInsertion(nums: Array<number>, target: number): number {\n    let i = 0,\n        j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        const m = Math.floor(i + (j - i) / 2); // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m, \u4f7f\u7528 Math.floor() \u5411\u4e0b\u53d6\u6574\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.dart
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(List<int> nums, int target) {\n  int i = 0, j = nums.length - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  while (i <= j) {\n    int m = i + (j - i) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    if (nums[m] < target) {\n      i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    } else if (nums[m] > target) {\n      j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    } else {\n      j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    }\n  }\n  // \u8fd4\u56de\u63d2\u5165\u70b9 i\n  return i;\n}\n
    binary_search_insertion.rs
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\npub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 {\n    let (mut i, mut j) = (0, nums.len() as i32 - 1); // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while i <= j {\n        let m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if nums[m as usize] < target {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if nums[m as usize] > target {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    i\n}\n
    binary_search_insertion.c
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nint binarySearchInsertion(int *nums, int numSize, int target) {\n    int i = 0, j = numSize - 1; // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        int m = i + (j - i) / 2; // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1; // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1; // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1; // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i;\n}\n
    binary_search_insertion.kt
    /* \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 */\nfun binarySearchInsertion(nums: IntArray, target: Int): Int {\n    var i = 0\n    var j = nums.size - 1 // \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n    while (i <= j) {\n        val m = i + (j - i) / 2 // \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n        if (nums[m] < target) {\n            i = m + 1 // target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n        } else if (nums[m] > target) {\n            j = m - 1 // target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n        } else {\n            j = m - 1 // \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n        }\n    }\n    // \u8fd4\u56de\u63d2\u5165\u70b9 i\n    return i\n}\n
    binary_search_insertion.rb
    ### \u4e8c\u5206\u67e5\u627e\u63d2\u5165\u70b9\uff08\u5b58\u5728\u91cd\u590d\u5143\u7d20\uff09 ###\ndef binary_search_insertion(nums, target)\n  # \u521d\u59cb\u5316\u53cc\u95ed\u533a\u95f4 [0, n-1]\n  i, j = 0, nums.length - 1\n\n  while i <= j\n    # \u8ba1\u7b97\u4e2d\u70b9\u7d22\u5f15 m\n    m = (i + j) / 2\n\n    if nums[m] < target\n      i = m + 1 # target \u5728\u533a\u95f4 [m+1, j] \u4e2d\n    elsif nums[m] > target\n      j = m - 1 # target \u5728\u533a\u95f4 [i, m-1] \u4e2d\n    else\n      j = m - 1 # \u9996\u4e2a\u5c0f\u4e8e target \u7684\u5143\u7d20\u5728\u533a\u95f4 [i, m-1] \u4e2d\n    end\n  end\n\n  i # \u8fd4\u56de\u63d2\u5165\u70b9 i\nend\n
    binary_search_insertion.zig
    [class]{}-[func]{binarySearchInsertion}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    Tip

    \u672c\u8282\u7684\u4ee3\u7801\u90fd\u662f\u201c\u53cc\u95ed\u533a\u95f4\u201d\u5199\u6cd5\u3002\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u201c\u5de6\u95ed\u53f3\u5f00\u201d\u5199\u6cd5\u3002

    \u603b\u7684\u6765\u770b\uff0c\u4e8c\u5206\u67e5\u627e\u65e0\u975e\u5c31\u662f\u7ed9\u6307\u9488 \\(i\\) \u548c \\(j\\) \u5206\u522b\u8bbe\u5b9a\u641c\u7d22\u76ee\u6807\uff0c\u76ee\u6807\u53ef\u80fd\u662f\u4e00\u4e2a\u5177\u4f53\u7684\u5143\u7d20\uff08\u4f8b\u5982 target \uff09\uff0c\u4e5f\u53ef\u80fd\u662f\u4e00\u4e2a\u5143\u7d20\u8303\u56f4\uff08\u4f8b\u5982\u5c0f\u4e8e target \u7684\u5143\u7d20\uff09\u3002

    \u5728\u4e0d\u65ad\u7684\u5faa\u73af\u4e8c\u5206\u4e2d\uff0c\u6307\u9488 \\(i\\) \u548c \\(j\\) \u90fd\u9010\u6e10\u903c\u8fd1\u9884\u5148\u8bbe\u5b9a\u7684\u76ee\u6807\u3002\u6700\u7ec8\uff0c\u5b83\u4eec\u6216\u662f\u6210\u529f\u627e\u5230\u7b54\u6848\uff0c\u6216\u662f\u8d8a\u8fc7\u8fb9\u754c\u540e\u505c\u6b62\u3002

    "},{"location":"chapter_searching/replace_linear_by_hashing/","title":"10.4 \u00a0 \u54c8\u5e0c\u4f18\u5316\u7b56\u7565","text":"

    \u5728\u7b97\u6cd5\u9898\u4e2d\uff0c\u6211\u4eec\u5e38\u901a\u8fc7\u5c06\u7ebf\u6027\u67e5\u627e\u66ff\u6362\u4e3a\u54c8\u5e0c\u67e5\u627e\u6765\u964d\u4f4e\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6211\u4eec\u501f\u52a9\u4e00\u4e2a\u7b97\u6cd5\u9898\u6765\u52a0\u6df1\u7406\u89e3\u3002

    Question

    \u7ed9\u5b9a\u4e00\u4e2a\u6574\u6570\u6570\u7ec4 nums \u548c\u4e00\u4e2a\u76ee\u6807\u5143\u7d20 target \uff0c\u8bf7\u5728\u6570\u7ec4\u4e2d\u641c\u7d22\u201c\u548c\u201d\u4e3a target \u7684\u4e24\u4e2a\u5143\u7d20\uff0c\u5e76\u8fd4\u56de\u5b83\u4eec\u7684\u6570\u7ec4\u7d22\u5f15\u3002\u8fd4\u56de\u4efb\u610f\u4e00\u4e2a\u89e3\u5373\u53ef\u3002

    "},{"location":"chapter_searching/replace_linear_by_hashing/#1041","title":"10.4.1 \u00a0 \u7ebf\u6027\u67e5\u627e\uff1a\u4ee5\u65f6\u95f4\u6362\u7a7a\u95f4","text":"

    \u8003\u8651\u76f4\u63a5\u904d\u5386\u6240\u6709\u53ef\u80fd\u7684\u7ec4\u5408\u3002\u5982\u56fe 10-9 \u6240\u793a\uff0c\u6211\u4eec\u5f00\u542f\u4e00\u4e2a\u4e24\u5c42\u5faa\u73af\uff0c\u5728\u6bcf\u8f6e\u4e2d\u5224\u65ad\u4e24\u4e2a\u6574\u6570\u7684\u548c\u662f\u5426\u4e3a target \uff0c\u82e5\u662f\uff0c\u5219\u8fd4\u56de\u5b83\u4eec\u7684\u7d22\u5f15\u3002

    \u56fe 10-9 \u00a0 \u7ebf\u6027\u67e5\u627e\u6c42\u89e3\u4e24\u6570\u4e4b\u548c

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig two_sum.py
    def two_sum_brute_force(nums: list[int], target: int) -> list[int]:\n    \"\"\"\u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e\"\"\"\n    # \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in range(len(nums) - 1):\n        for j in range(i + 1, len(nums)):\n            if nums[i] + nums[j] == target:\n                return [i, j]\n    return []\n
    two_sum.cpp
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nvector<int> twoSumBruteForce(vector<int> &nums, int target) {\n    int size = nums.size();\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return {i, j};\n        }\n    }\n    return {};\n}\n
    two_sum.java
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint[] twoSumBruteForce(int[] nums, int target) {\n    int size = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return new int[] { i, j };\n        }\n    }\n    return new int[0];\n}\n
    two_sum.cs
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint[] TwoSumBruteForce(int[] nums, int target) {\n    int size = nums.Length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = i + 1; j < size; j++) {\n            if (nums[i] + nums[j] == target)\n                return [i, j];\n        }\n    }\n    return [];\n}\n
    two_sum.go
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunc twoSumBruteForce(nums []int, target int) []int {\n    size := len(nums)\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i := 0; i < size-1; i++ {\n        for j := i + 1; j < size; j++ {\n            if nums[i]+nums[j] == target {\n                return []int{i, j}\n            }\n        }\n    }\n    return nil\n}\n
    two_sum.swift
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunc twoSumBruteForce(nums: [Int], target: Int) -> [Int] {\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in nums.indices.dropLast() {\n        for j in nums.indices.dropFirst(i + 1) {\n            if nums[i] + nums[j] == target {\n                return [i, j]\n            }\n        }\n    }\n    return [0]\n}\n
    two_sum.js
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunction twoSumBruteForce(nums, target) {\n    const n = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (let i = 0; i < n; i++) {\n        for (let j = i + 1; j < n; j++) {\n            if (nums[i] + nums[j] === target) {\n                return [i, j];\n            }\n        }\n    }\n    return [];\n}\n
    two_sum.ts
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfunction twoSumBruteForce(nums: number[], target: number): number[] {\n    const n = nums.length;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (let i = 0; i < n; i++) {\n        for (let j = i + 1; j < n; j++) {\n            if (nums[i] + nums[j] === target) {\n                return [i, j];\n            }\n        }\n    }\n    return [];\n}\n
    two_sum.dart
    /* \u65b9\u6cd5\u4e00\uff1a \u66b4\u529b\u679a\u4e3e */\nList<int> twoSumBruteForce(List<int> nums, int target) {\n  int size = nums.length;\n  // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n  for (var i = 0; i < size - 1; i++) {\n    for (var j = i + 1; j < size; j++) {\n      if (nums[i] + nums[j] == target) return [i, j];\n    }\n  }\n  return [0];\n}\n
    two_sum.rs
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\npub fn two_sum_brute_force(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {\n    let size = nums.len();\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for i in 0..size - 1 {\n        for j in i + 1..size {\n            if nums[i] + nums[j] == target {\n                return Some(vec![i as i32, j as i32]);\n            }\n        }\n    }\n    None\n}\n
    two_sum.c
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nint *twoSumBruteForce(int *nums, int numsSize, int target, int *returnSize) {\n    for (int i = 0; i < numsSize; ++i) {\n        for (int j = i + 1; j < numsSize; ++j) {\n            if (nums[i] + nums[j] == target) {\n                int *res = malloc(sizeof(int) * 2);\n                res[0] = i, res[1] = j;\n                *returnSize = 2;\n                return res;\n            }\n        }\n    }\n    *returnSize = 0;\n    return NULL;\n}\n
    two_sum.kt
    /* \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e */\nfun twoSumBruteForce(nums: IntArray, target: Int): IntArray {\n    val size = nums.size\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    for (i in 0..<size - 1) {\n        for (j in i + 1..<size) {\n            if (nums[i] + nums[j] == target) return intArrayOf(i, j)\n        }\n    }\n    return IntArray(0)\n}\n
    two_sum.rb
    ### \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e ###\ndef two_sum_brute_force(nums, target)\n  # \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n  for i in 0...(nums.length - 1)\n    for j in (i + 1)...nums.length\n      return [i, j] if nums[i] + nums[j] == target\n    end\n  end\n\n  []\nend\n
    two_sum.zig
    // \u65b9\u6cd5\u4e00\uff1a\u66b4\u529b\u679a\u4e3e\nfn twoSumBruteForce(nums: []i32, target: i32) ?[2]i32 {\n    var size: usize = nums.len;\n    var i: usize = 0;\n    // \u4e24\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n^2)\n    while (i < size - 1) : (i += 1) {\n        var j = i + 1;\n        while (j < size) : (j += 1) {\n            if (nums[i] + nums[j] == target) {\n                return [_]i32{@intCast(i), @intCast(j)};\n            }\n        }\n    }\n    return null;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6b64\u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \uff0c\u5728\u5927\u6570\u636e\u91cf\u4e0b\u975e\u5e38\u8017\u65f6\u3002

    "},{"location":"chapter_searching/replace_linear_by_hashing/#1042","title":"10.4.2 \u00a0 \u54c8\u5e0c\u67e5\u627e\uff1a\u4ee5\u7a7a\u95f4\u6362\u65f6\u95f4","text":"

    \u8003\u8651\u501f\u52a9\u4e00\u4e2a\u54c8\u5e0c\u8868\uff0c\u952e\u503c\u5bf9\u5206\u522b\u4e3a\u6570\u7ec4\u5143\u7d20\u548c\u5143\u7d20\u7d22\u5f15\u3002\u5faa\u73af\u904d\u5386\u6570\u7ec4\uff0c\u6bcf\u8f6e\u6267\u884c\u56fe 10-10 \u6240\u793a\u7684\u6b65\u9aa4\u3002

    1. \u5224\u65ad\u6570\u5b57 target - nums[i] \u662f\u5426\u5728\u54c8\u5e0c\u8868\u4e2d\uff0c\u82e5\u662f\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\u8fd9\u4e24\u4e2a\u5143\u7d20\u7684\u7d22\u5f15\u3002
    2. \u5c06\u952e\u503c\u5bf9 nums[i] \u548c\u7d22\u5f15 i \u6dfb\u52a0\u8fdb\u54c8\u5e0c\u8868\u3002
    <1><2><3>

    \u56fe 10-10 \u00a0 \u8f85\u52a9\u54c8\u5e0c\u8868\u6c42\u89e3\u4e24\u6570\u4e4b\u548c

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff0c\u4ec5\u9700\u5355\u5c42\u5faa\u73af\u5373\u53ef\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig two_sum.py
    def two_sum_hash_table(nums: list[int], target: int) -> list[int]:\n    \"\"\"\u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868\"\"\"\n    # \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    dic = {}\n    # \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for i in range(len(nums)):\n        if target - nums[i] in dic:\n            return [dic[target - nums[i]], i]\n        dic[nums[i]] = i\n    return []\n
    two_sum.cpp
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nvector<int> twoSumHashTable(vector<int> &nums, int target) {\n    int size = nums.size();\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    unordered_map<int, int> dic;\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.find(target - nums[i]) != dic.end()) {\n            return {dic[target - nums[i]], i};\n        }\n        dic.emplace(nums[i], i);\n    }\n    return {};\n}\n
    two_sum.java
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint[] twoSumHashTable(int[] nums, int target) {\n    int size = nums.length;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    Map<Integer, Integer> dic = new HashMap<>();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.containsKey(target - nums[i])) {\n            return new int[] { dic.get(target - nums[i]), i };\n        }\n        dic.put(nums[i], i);\n    }\n    return new int[0];\n}\n
    two_sum.cs
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint[] TwoSumHashTable(int[] nums, int target) {\n    int size = nums.Length;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    Dictionary<int, int> dic = [];\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (int i = 0; i < size; i++) {\n        if (dic.ContainsKey(target - nums[i])) {\n            return [dic[target - nums[i]], i];\n        }\n        dic.Add(nums[i], i);\n    }\n    return [];\n}\n
    two_sum.go
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunc twoSumHashTable(nums []int, target int) []int {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    hashTable := map[int]int{}\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for idx, val := range nums {\n        if preIdx, ok := hashTable[target-val]; ok {\n            return []int{preIdx, idx}\n        }\n        hashTable[val] = idx\n    }\n    return nil\n}\n
    two_sum.swift
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunc twoSumHashTable(nums: [Int], target: Int) -> [Int] {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    var dic: [Int: Int] = [:]\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for i in nums.indices {\n        if let j = dic[target - nums[i]] {\n            return [j, i]\n        }\n        dic[nums[i]] = i\n    }\n    return [0]\n}\n
    two_sum.js
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunction twoSumHashTable(nums, target) {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let m = {};\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (let i = 0; i < nums.length; i++) {\n        if (m[target - nums[i]] !== undefined) {\n            return [m[target - nums[i]], i];\n        } else {\n            m[nums[i]] = i;\n        }\n    }\n    return [];\n}\n
    two_sum.ts
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfunction twoSumHashTable(nums: number[], target: number): number[] {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let m: Map<number, number> = new Map();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (let i = 0; i < nums.length; i++) {\n        let index = m.get(target - nums[i]);\n        if (index !== undefined) {\n            return [index, i];\n        } else {\n            m.set(nums[i], i);\n        }\n    }\n    return [];\n}\n
    two_sum.dart
    /* \u65b9\u6cd5\u4e8c\uff1a \u8f85\u52a9\u54c8\u5e0c\u8868 */\nList<int> twoSumHashTable(List<int> nums, int target) {\n  int size = nums.length;\n  // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  Map<int, int> dic = HashMap();\n  // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  for (var i = 0; i < size; i++) {\n    if (dic.containsKey(target - nums[i])) {\n      return [dic[target - nums[i]]!, i];\n    }\n    dic.putIfAbsent(nums[i], () => i);\n  }\n  return [0];\n}\n
    two_sum.rs
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\npub fn two_sum_hash_table(nums: &Vec<i32>, target: i32) -> Option<Vec<i32>> {\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    let mut dic = HashMap::new();\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (i, num) in nums.iter().enumerate() {\n        match dic.get(&(target - num)) {\n            Some(v) => return Some(vec![*v as i32, i as i32]),\n            None => dic.insert(num, i as i32),\n        };\n    }\n    None\n}\n
    two_sum.c
    /* \u54c8\u5e0c\u8868 */\ntypedef struct {\n    int key;\n    int val;\n    UT_hash_handle hh; // \u57fa\u4e8e uthash.h \u5b9e\u73b0\n} HashTable;\n\n/* \u54c8\u5e0c\u8868\u67e5\u8be2 */\nHashTable *find(HashTable *h, int key) {\n    HashTable *tmp;\n    HASH_FIND_INT(h, &key, tmp);\n    return tmp;\n}\n\n/* \u54c8\u5e0c\u8868\u5143\u7d20\u63d2\u5165 */\nvoid insert(HashTable *h, int key, int val) {\n    HashTable *t = find(h, key);\n    if (t == NULL) {\n        HashTable *tmp = malloc(sizeof(HashTable));\n        tmp->key = key, tmp->val = val;\n        HASH_ADD_INT(h, key, tmp);\n    } else {\n        t->val = val;\n    }\n}\n\n/* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nint *twoSumHashTable(int *nums, int numsSize, int target, int *returnSize) {\n    HashTable *hashtable = NULL;\n    for (int i = 0; i < numsSize; i++) {\n        HashTable *t = find(hashtable, target - nums[i]);\n        if (t != NULL) {\n            int *res = malloc(sizeof(int) * 2);\n            res[0] = t->val, res[1] = i;\n            *returnSize = 2;\n            return res;\n        }\n        insert(hashtable, nums[i], i);\n    }\n    *returnSize = 0;\n    return NULL;\n}\n
    two_sum.kt
    /* \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 */\nfun twoSumHashTable(nums: IntArray, target: Int): IntArray {\n    val size = nums.size\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    val dic = HashMap<Int, Int>()\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    for (i in 0..<size) {\n        if (dic.containsKey(target - nums[i])) {\n            return intArrayOf(dic[target - nums[i]]!!, i)\n        }\n        dic[nums[i]] = i\n    }\n    return IntArray(0)\n}\n
    two_sum.rb
    ### \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868 ###\ndef two_sum_hash_table(nums, target)\n  # \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  dic = {}\n  # \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n  for i in 0...nums.length\n    return [dic[target - nums[i]], i] if dic.has_key?(target - nums[i])\n\n    dic[nums[i]] = i\n  end\n\n  []\nend\n
    two_sum.zig
    // \u65b9\u6cd5\u4e8c\uff1a\u8f85\u52a9\u54c8\u5e0c\u8868\nfn twoSumHashTable(nums: []i32, target: i32) !?[2]i32 {\n    var size: usize = nums.len;\n    // \u8f85\u52a9\u54c8\u5e0c\u8868\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    var dic = std.AutoHashMap(i32, i32).init(std.heap.page_allocator);\n    defer dic.deinit();\n    var i: usize = 0;\n    // \u5355\u5c42\u5faa\u73af\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\n    while (i < size) : (i += 1) {\n        if (dic.contains(target - nums[i])) {\n            return [_]i32{dic.get(target - nums[i]).?, @intCast(i)};\n        }\n        try dic.put(nums[i], @intCast(i));\n    }\n    return null;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u6b64\u65b9\u6cd5\u901a\u8fc7\u54c8\u5e0c\u67e5\u627e\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n^2)\\) \u964d\u81f3 \\(O(n)\\) \uff0c\u5927\u5e45\u63d0\u5347\u8fd0\u884c\u6548\u7387\u3002

    \u7531\u4e8e\u9700\u8981\u7ef4\u62a4\u4e00\u4e2a\u989d\u5916\u7684\u54c8\u5e0c\u8868\uff0c\u56e0\u6b64\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u3002\u5c3d\u7ba1\u5982\u6b64\uff0c\u8be5\u65b9\u6cd5\u7684\u6574\u4f53\u65f6\u7a7a\u6548\u7387\u66f4\u4e3a\u5747\u8861\uff0c\u56e0\u6b64\u5b83\u662f\u672c\u9898\u7684\u6700\u4f18\u89e3\u6cd5\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/","title":"10.5 \u00a0 \u91cd\u8bc6\u641c\u7d22\u7b97\u6cd5","text":"

    \u641c\u7d22\u7b97\u6cd5\uff08searching algorithm\uff09\u7528\u4e8e\u5728\u6570\u636e\u7ed3\u6784\uff08\u4f8b\u5982\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6811\u6216\u56fe\uff09\u4e2d\u641c\u7d22\u4e00\u4e2a\u6216\u4e00\u7ec4\u6ee1\u8db3\u7279\u5b9a\u6761\u4ef6\u7684\u5143\u7d20\u3002

    \u641c\u7d22\u7b97\u6cd5\u53ef\u6839\u636e\u5b9e\u73b0\u601d\u8def\u5206\u4e3a\u4ee5\u4e0b\u4e24\u7c7b\u3002

    • \u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u6765\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\uff0c\u4f8b\u5982\u6570\u7ec4\u3001\u94fe\u8868\u3001\u6811\u548c\u56fe\u7684\u904d\u5386\u7b49\u3002
    • \u5229\u7528\u6570\u636e\u7ec4\u7ec7\u7ed3\u6784\u6216\u6570\u636e\u5305\u542b\u7684\u5148\u9a8c\u4fe1\u606f\uff0c\u5b9e\u73b0\u9ad8\u6548\u5143\u7d20\u67e5\u627e\uff0c\u4f8b\u5982\u4e8c\u5206\u67e5\u627e\u3001\u54c8\u5e0c\u67e5\u627e\u548c\u4e8c\u53c9\u641c\u7d22\u6811\u67e5\u627e\u7b49\u3002

    \u4e0d\u96be\u53d1\u73b0\uff0c\u8fd9\u4e9b\u77e5\u8bc6\u70b9\u90fd\u5df2\u5728\u524d\u9762\u7684\u7ae0\u8282\u4e2d\u4ecb\u7ecd\u8fc7\uff0c\u56e0\u6b64\u641c\u7d22\u7b97\u6cd5\u5bf9\u4e8e\u6211\u4eec\u6765\u8bf4\u5e76\u4e0d\u964c\u751f\u3002\u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5c06\u4ece\u66f4\u52a0\u7cfb\u7edf\u7684\u89c6\u89d2\u5207\u5165\uff0c\u91cd\u65b0\u5ba1\u89c6\u641c\u7d22\u7b97\u6cd5\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1051","title":"10.5.1 \u00a0 \u66b4\u529b\u641c\u7d22","text":"

    \u66b4\u529b\u641c\u7d22\u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u7684\u6bcf\u4e2a\u5143\u7d20\u6765\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002

    • \u201c\u7ebf\u6027\u641c\u7d22\u201d\u9002\u7528\u4e8e\u6570\u7ec4\u548c\u94fe\u8868\u7b49\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002\u5b83\u4ece\u6570\u636e\u7ed3\u6784\u7684\u4e00\u7aef\u5f00\u59cb\uff0c\u9010\u4e2a\u8bbf\u95ee\u5143\u7d20\uff0c\u76f4\u5230\u627e\u5230\u76ee\u6807\u5143\u7d20\u6216\u5230\u8fbe\u53e6\u4e00\u7aef\u4ecd\u6ca1\u6709\u627e\u5230\u76ee\u6807\u5143\u7d20\u4e3a\u6b62\u3002
    • \u201c\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u201d\u548c\u201c\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u201d\u662f\u56fe\u548c\u6811\u7684\u4e24\u79cd\u904d\u5386\u7b56\u7565\u3002\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u4ece\u521d\u59cb\u8282\u70b9\u5f00\u59cb\u9010\u5c42\u641c\u7d22\uff0c\u7531\u8fd1\u53ca\u8fdc\u5730\u8bbf\u95ee\u5404\u4e2a\u8282\u70b9\u3002\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u4ece\u521d\u59cb\u8282\u70b9\u5f00\u59cb\uff0c\u6cbf\u7740\u4e00\u6761\u8def\u5f84\u8d70\u5230\u5934\uff0c\u518d\u56de\u6eaf\u5e76\u5c1d\u8bd5\u5176\u4ed6\u8def\u5f84\uff0c\u76f4\u5230\u904d\u5386\u5b8c\u6574\u4e2a\u6570\u636e\u7ed3\u6784\u3002

    \u66b4\u529b\u641c\u7d22\u7684\u4f18\u70b9\u662f\u7b80\u5355\u4e14\u901a\u7528\u6027\u597d\uff0c\u65e0\u987b\u5bf9\u6570\u636e\u505a\u9884\u5904\u7406\u548c\u501f\u52a9\u989d\u5916\u7684\u6570\u636e\u7ed3\u6784\u3002

    \u7136\u800c\uff0c\u6b64\u7c7b\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u5176\u4e2d \\(n\\) \u4e3a\u5143\u7d20\u6570\u91cf\uff0c\u56e0\u6b64\u5728\u6570\u636e\u91cf\u8f83\u5927\u7684\u60c5\u51b5\u4e0b\u6027\u80fd\u8f83\u5dee\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1052","title":"10.5.2 \u00a0 \u81ea\u9002\u5e94\u641c\u7d22","text":"

    \u81ea\u9002\u5e94\u641c\u7d22\u5229\u7528\u6570\u636e\u7684\u7279\u6709\u5c5e\u6027\uff08\u4f8b\u5982\u6709\u5e8f\u6027\uff09\u6765\u4f18\u5316\u641c\u7d22\u8fc7\u7a0b\uff0c\u4ece\u800c\u66f4\u9ad8\u6548\u5730\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002

    • \u201c\u4e8c\u5206\u67e5\u627e\u201d\u5229\u7528\u6570\u636e\u7684\u6709\u5e8f\u6027\u5b9e\u73b0\u9ad8\u6548\u67e5\u627e\uff0c\u4ec5\u9002\u7528\u4e8e\u6570\u7ec4\u3002
    • \u201c\u54c8\u5e0c\u67e5\u627e\u201d\u5229\u7528\u54c8\u5e0c\u8868\u5c06\u641c\u7d22\u6570\u636e\u548c\u76ee\u6807\u6570\u636e\u5efa\u7acb\u4e3a\u952e\u503c\u5bf9\u6620\u5c04\uff0c\u4ece\u800c\u5b9e\u73b0\u67e5\u8be2\u64cd\u4f5c\u3002
    • \u201c\u6811\u67e5\u627e\u201d\u5728\u7279\u5b9a\u7684\u6811\u7ed3\u6784\uff08\u4f8b\u5982\u4e8c\u53c9\u641c\u7d22\u6811\uff09\u4e2d\uff0c\u57fa\u4e8e\u6bd4\u8f83\u8282\u70b9\u503c\u6765\u5feb\u901f\u6392\u9664\u8282\u70b9\uff0c\u4ece\u800c\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002

    \u6b64\u7c7b\u7b97\u6cd5\u7684\u4f18\u70b9\u662f\u6548\u7387\u9ad8\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe\u5230 \\(O(\\log n)\\) \u751a\u81f3 \\(O(1)\\) \u3002

    \u7136\u800c\uff0c\u4f7f\u7528\u8fd9\u4e9b\u7b97\u6cd5\u5f80\u5f80\u9700\u8981\u5bf9\u6570\u636e\u8fdb\u884c\u9884\u5904\u7406\u3002\u4f8b\u5982\uff0c\u4e8c\u5206\u67e5\u627e\u9700\u8981\u9884\u5148\u5bf9\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\uff0c\u54c8\u5e0c\u67e5\u627e\u548c\u6811\u67e5\u627e\u90fd\u9700\u8981\u501f\u52a9\u989d\u5916\u7684\u6570\u636e\u7ed3\u6784\uff0c\u7ef4\u62a4\u8fd9\u4e9b\u6570\u636e\u7ed3\u6784\u4e5f\u9700\u8981\u989d\u5916\u7684\u65f6\u95f4\u548c\u7a7a\u95f4\u5f00\u9500\u3002

    Tip

    \u81ea\u9002\u5e94\u641c\u7d22\u7b97\u6cd5\u5e38\u88ab\u79f0\u4e3a\u67e5\u627e\u7b97\u6cd5\uff0c\u4e3b\u8981\u7528\u4e8e\u5728\u7279\u5b9a\u6570\u636e\u7ed3\u6784\u4e2d\u5feb\u901f\u68c0\u7d22\u76ee\u6807\u5143\u7d20\u3002

    "},{"location":"chapter_searching/searching_algorithm_revisited/#1053","title":"10.5.3 \u00a0 \u641c\u7d22\u65b9\u6cd5\u9009\u53d6","text":"

    \u7ed9\u5b9a\u5927\u5c0f\u4e3a \\(n\\) \u7684\u4e00\u7ec4\u6570\u636e\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7ebf\u6027\u641c\u7d22\u3001\u4e8c\u5206\u67e5\u627e\u3001\u6811\u67e5\u627e\u3001\u54c8\u5e0c\u67e5\u627e\u7b49\u591a\u79cd\u65b9\u6cd5\u4ece\u4e2d\u641c\u7d22\u76ee\u6807\u5143\u7d20\u3002\u5404\u4e2a\u65b9\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u5982\u56fe 10-11 \u6240\u793a\u3002

    \u56fe 10-11 \u00a0 \u591a\u79cd\u641c\u7d22\u7b56\u7565

    \u4e0a\u8ff0\u51e0\u79cd\u65b9\u6cd5\u7684\u64cd\u4f5c\u6548\u7387\u4e0e\u7279\u6027\u5982\u8868 10-1 \u6240\u793a\u3002

    \u8868 10-1 \u00a0 \u67e5\u627e\u7b97\u6cd5\u6548\u7387\u5bf9\u6bd4

    \u7ebf\u6027\u641c\u7d22 \u4e8c\u5206\u67e5\u627e \u6811\u67e5\u627e \u54c8\u5e0c\u67e5\u627e \u67e5\u627e\u5143\u7d20 \\(O(n)\\) \\(O(\\log n)\\) \\(O(\\log n)\\) \\(O(1)\\) \u63d2\u5165\u5143\u7d20 \\(O(1)\\) \\(O(n)\\) \\(O(\\log n)\\) \\(O(1)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(n)\\) \\(O(\\log n)\\) \\(O(1)\\) \u989d\u5916\u7a7a\u95f4 \\(O(1)\\) \\(O(1)\\) \\(O(n)\\) \\(O(n)\\) \u6570\u636e\u9884\u5904\u7406 / \u6392\u5e8f \\(O(n \\log n)\\) \u5efa\u6811 \\(O(n \\log n)\\) \u5efa\u54c8\u5e0c\u8868 \\(O(n)\\) \u6570\u636e\u662f\u5426\u6709\u5e8f \u65e0\u5e8f \u6709\u5e8f \u6709\u5e8f \u65e0\u5e8f

    \u641c\u7d22\u7b97\u6cd5\u7684\u9009\u62e9\u8fd8\u53d6\u51b3\u4e8e\u6570\u636e\u4f53\u91cf\u3001\u641c\u7d22\u6027\u80fd\u8981\u6c42\u3001\u6570\u636e\u67e5\u8be2\u4e0e\u66f4\u65b0\u9891\u7387\u7b49\u3002

    \u7ebf\u6027\u641c\u7d22

    • \u901a\u7528\u6027\u8f83\u597d\uff0c\u65e0\u987b\u4efb\u4f55\u6570\u636e\u9884\u5904\u7406\u64cd\u4f5c\u3002\u5047\u5982\u6211\u4eec\u4ec5\u9700\u67e5\u8be2\u4e00\u6b21\u6570\u636e\uff0c\u90a3\u4e48\u5176\u4ed6\u4e09\u79cd\u65b9\u6cd5\u7684\u6570\u636e\u9884\u5904\u7406\u7684\u65f6\u95f4\u6bd4\u7ebf\u6027\u641c\u7d22\u7684\u65f6\u95f4\u8fd8\u8981\u66f4\u957f\u3002
    • \u9002\u7528\u4e8e\u4f53\u91cf\u8f83\u5c0f\u7684\u6570\u636e\uff0c\u6b64\u60c5\u51b5\u4e0b\u65f6\u95f4\u590d\u6742\u5ea6\u5bf9\u6548\u7387\u5f71\u54cd\u8f83\u5c0f\u3002
    • \u9002\u7528\u4e8e\u6570\u636e\u66f4\u65b0\u9891\u7387\u8f83\u9ad8\u7684\u573a\u666f\uff0c\u56e0\u4e3a\u8be5\u65b9\u6cd5\u4e0d\u9700\u8981\u5bf9\u6570\u636e\u8fdb\u884c\u4efb\u4f55\u989d\u5916\u7ef4\u62a4\u3002

    \u4e8c\u5206\u67e5\u627e

    • \u9002\u7528\u4e8e\u5927\u6570\u636e\u91cf\u7684\u60c5\u51b5\uff0c\u6548\u7387\u8868\u73b0\u7a33\u5b9a\uff0c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \u3002
    • \u6570\u636e\u91cf\u4e0d\u80fd\u8fc7\u5927\uff0c\u56e0\u4e3a\u5b58\u50a8\u6570\u7ec4\u9700\u8981\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u3002
    • \u4e0d\u9002\u7528\u4e8e\u9ad8\u9891\u589e\u5220\u6570\u636e\u7684\u573a\u666f\uff0c\u56e0\u4e3a\u7ef4\u62a4\u6709\u5e8f\u6570\u7ec4\u7684\u5f00\u9500\u8f83\u5927\u3002

    \u54c8\u5e0c\u67e5\u627e

    • \u9002\u5408\u5bf9\u67e5\u8be2\u6027\u80fd\u8981\u6c42\u5f88\u9ad8\u7684\u573a\u666f\uff0c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\) \u3002
    • \u4e0d\u9002\u5408\u9700\u8981\u6709\u5e8f\u6570\u636e\u6216\u8303\u56f4\u67e5\u627e\u7684\u573a\u666f\uff0c\u56e0\u4e3a\u54c8\u5e0c\u8868\u65e0\u6cd5\u7ef4\u62a4\u6570\u636e\u7684\u6709\u5e8f\u6027\u3002
    • \u5bf9\u54c8\u5e0c\u51fd\u6570\u548c\u54c8\u5e0c\u51b2\u7a81\u5904\u7406\u7b56\u7565\u7684\u4f9d\u8d56\u6027\u8f83\u9ad8\uff0c\u5177\u6709\u8f83\u5927\u7684\u6027\u80fd\u52a3\u5316\u98ce\u9669\u3002
    • \u4e0d\u9002\u5408\u6570\u636e\u91cf\u8fc7\u5927\u7684\u60c5\u51b5\uff0c\u56e0\u4e3a\u54c8\u5e0c\u8868\u9700\u8981\u989d\u5916\u7a7a\u95f4\u6765\u6700\u5927\u7a0b\u5ea6\u5730\u51cf\u5c11\u51b2\u7a81\uff0c\u4ece\u800c\u63d0\u4f9b\u826f\u597d\u7684\u67e5\u8be2\u6027\u80fd\u3002

    \u6811\u67e5\u627e

    • \u9002\u7528\u4e8e\u6d77\u91cf\u6570\u636e\uff0c\u56e0\u4e3a\u6811\u8282\u70b9\u5728\u5185\u5b58\u4e2d\u662f\u5206\u6563\u5b58\u50a8\u7684\u3002
    • \u9002\u5408\u9700\u8981\u7ef4\u62a4\u6709\u5e8f\u6570\u636e\u6216\u8303\u56f4\u67e5\u627e\u7684\u573a\u666f\u3002
    • \u5728\u6301\u7eed\u589e\u5220\u8282\u70b9\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u53ef\u80fd\u4ea7\u751f\u503e\u659c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u52a3\u5316\u81f3 \\(O(n)\\) \u3002
    • \u82e5\u4f7f\u7528 AVL \u6811\u6216\u7ea2\u9ed1\u6811\uff0c\u5219\u5404\u9879\u64cd\u4f5c\u53ef\u5728 \\(O(\\log n)\\) \u6548\u7387\u4e0b\u7a33\u5b9a\u8fd0\u884c\uff0c\u4f46\u7ef4\u62a4\u6811\u5e73\u8861\u7684\u64cd\u4f5c\u4f1a\u589e\u52a0\u989d\u5916\u7684\u5f00\u9500\u3002
    "},{"location":"chapter_searching/summary/","title":"10.6 \u00a0 \u5c0f\u7ed3","text":"
    • \u4e8c\u5206\u67e5\u627e\u4f9d\u8d56\u6570\u636e\u7684\u6709\u5e8f\u6027\uff0c\u901a\u8fc7\u5faa\u73af\u9010\u6b65\u7f29\u51cf\u4e00\u534a\u641c\u7d22\u533a\u95f4\u6765\u8fdb\u884c\u67e5\u627e\u3002\u5b83\u8981\u6c42\u8f93\u5165\u6570\u636e\u6709\u5e8f\uff0c\u4e14\u4ec5\u9002\u7528\u4e8e\u6570\u7ec4\u6216\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u3002
    • \u66b4\u529b\u641c\u7d22\u901a\u8fc7\u904d\u5386\u6570\u636e\u7ed3\u6784\u6765\u5b9a\u4f4d\u6570\u636e\u3002\u7ebf\u6027\u641c\u7d22\u9002\u7528\u4e8e\u6570\u7ec4\u548c\u94fe\u8868\uff0c\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u548c\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u9002\u7528\u4e8e\u56fe\u548c\u6811\u3002\u6b64\u7c7b\u7b97\u6cd5\u901a\u7528\u6027\u597d\uff0c\u65e0\u987b\u5bf9\u6570\u636e\u8fdb\u884c\u9884\u5904\u7406\uff0c\u4f46\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u8f83\u9ad8\u3002
    • \u54c8\u5e0c\u67e5\u627e\u3001\u6811\u67e5\u627e\u548c\u4e8c\u5206\u67e5\u627e\u5c5e\u4e8e\u9ad8\u6548\u641c\u7d22\u65b9\u6cd5\uff0c\u53ef\u5728\u7279\u5b9a\u6570\u636e\u7ed3\u6784\u4e2d\u5feb\u901f\u5b9a\u4f4d\u76ee\u6807\u5143\u7d20\u3002\u6b64\u7c7b\u7b97\u6cd5\u6548\u7387\u9ad8\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe \\(O(\\log n)\\) \u751a\u81f3 \\(O(1)\\) \uff0c\u4f46\u901a\u5e38\u9700\u8981\u501f\u52a9\u989d\u5916\u6570\u636e\u7ed3\u6784\u3002
    • \u5b9e\u9645\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u5bf9\u6570\u636e\u4f53\u91cf\u3001\u641c\u7d22\u6027\u80fd\u8981\u6c42\u3001\u6570\u636e\u67e5\u8be2\u548c\u66f4\u65b0\u9891\u7387\u7b49\u56e0\u7d20\u8fdb\u884c\u5177\u4f53\u5206\u6790\uff0c\u4ece\u800c\u9009\u62e9\u5408\u9002\u7684\u641c\u7d22\u65b9\u6cd5\u3002
    • \u7ebf\u6027\u641c\u7d22\u9002\u7528\u4e8e\u5c0f\u578b\u6216\u9891\u7e41\u66f4\u65b0\u7684\u6570\u636e\uff1b\u4e8c\u5206\u67e5\u627e\u9002\u7528\u4e8e\u5927\u578b\u3001\u6392\u5e8f\u7684\u6570\u636e\uff1b\u54c8\u5e0c\u67e5\u627e\u9002\u7528\u4e8e\u5bf9\u67e5\u8be2\u6548\u7387\u8981\u6c42\u8f83\u9ad8\u4e14\u65e0\u987b\u8303\u56f4\u67e5\u8be2\u7684\u6570\u636e\uff1b\u6811\u67e5\u627e\u9002\u7528\u4e8e\u9700\u8981\u7ef4\u62a4\u987a\u5e8f\u548c\u652f\u6301\u8303\u56f4\u67e5\u8be2\u7684\u5927\u578b\u52a8\u6001\u6570\u636e\u3002
    • \u7528\u54c8\u5e0c\u67e5\u627e\u66ff\u6362\u7ebf\u6027\u67e5\u627e\u662f\u4e00\u79cd\u5e38\u7528\u7684\u4f18\u5316\u8fd0\u884c\u65f6\u95f4\u7684\u7b56\u7565\uff0c\u53ef\u5c06\u65f6\u95f4\u590d\u6742\u5ea6\u4ece \\(O(n)\\) \u964d\u81f3 \\(O(1)\\) \u3002
    "},{"location":"chapter_sorting/","title":"\u7b2c 11 \u7ae0 \u00a0 \u6392\u5e8f","text":"

    Abstract

    \u6392\u5e8f\u72b9\u5982\u4e00\u628a\u5c06\u6df7\u4e71\u53d8\u4e3a\u79e9\u5e8f\u7684\u9b54\u6cd5\u94a5\u5319\uff0c\u4f7f\u6211\u4eec\u80fd\u4ee5\u66f4\u9ad8\u6548\u7684\u65b9\u5f0f\u7406\u89e3\u4e0e\u5904\u7406\u6570\u636e\u3002

    \u65e0\u8bba\u662f\u7b80\u5355\u7684\u5347\u5e8f\uff0c\u8fd8\u662f\u590d\u6742\u7684\u5206\u7c7b\u6392\u5217\uff0c\u6392\u5e8f\u90fd\u5411\u6211\u4eec\u5c55\u793a\u4e86\u6570\u636e\u7684\u548c\u8c10\u7f8e\u611f\u3002

    "},{"location":"chapter_sorting/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 11.1 \u00a0 \u6392\u5e8f\u7b97\u6cd5
    • 11.2 \u00a0 \u9009\u62e9\u6392\u5e8f
    • 11.3 \u00a0 \u5192\u6ce1\u6392\u5e8f
    • 11.4 \u00a0 \u63d2\u5165\u6392\u5e8f
    • 11.5 \u00a0 \u5feb\u901f\u6392\u5e8f
    • 11.6 \u00a0 \u5f52\u5e76\u6392\u5e8f
    • 11.7 \u00a0 \u5806\u6392\u5e8f
    • 11.8 \u00a0 \u6876\u6392\u5e8f
    • 11.9 \u00a0 \u8ba1\u6570\u6392\u5e8f
    • 11.10 \u00a0 \u57fa\u6570\u6392\u5e8f
    • 11.11 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_sorting/bubble_sort/","title":"11.3 \u00a0 \u5192\u6ce1\u6392\u5e8f","text":"

    \u5192\u6ce1\u6392\u5e8f\uff08bubble sort\uff09\u901a\u8fc7\u8fde\u7eed\u5730\u6bd4\u8f83\u4e0e\u4ea4\u6362\u76f8\u90bb\u5143\u7d20\u5b9e\u73b0\u6392\u5e8f\u3002\u8fd9\u4e2a\u8fc7\u7a0b\u5c31\u50cf\u6c14\u6ce1\u4ece\u5e95\u90e8\u5347\u5230\u9876\u90e8\u4e00\u6837\uff0c\u56e0\u6b64\u5f97\u540d\u5192\u6ce1\u6392\u5e8f\u3002

    \u5982\u56fe 11-4 \u6240\u793a\uff0c\u5192\u6ce1\u8fc7\u7a0b\u53ef\u4ee5\u5229\u7528\u5143\u7d20\u4ea4\u6362\u64cd\u4f5c\u6765\u6a21\u62df\uff1a\u4ece\u6570\u7ec4\u6700\u5de6\u7aef\u5f00\u59cb\u5411\u53f3\u904d\u5386\uff0c\u4f9d\u6b21\u6bd4\u8f83\u76f8\u90bb\u5143\u7d20\u5927\u5c0f\uff0c\u5982\u679c\u201c\u5de6\u5143\u7d20 > \u53f3\u5143\u7d20\u201d\u5c31\u4ea4\u6362\u4e8c\u8005\u3002\u904d\u5386\u5b8c\u6210\u540e\uff0c\u6700\u5927\u7684\u5143\u7d20\u4f1a\u88ab\u79fb\u52a8\u5230\u6570\u7ec4\u7684\u6700\u53f3\u7aef\u3002

    <1><2><3><4><5><6><7>

    \u56fe 11-4 \u00a0 \u5229\u7528\u5143\u7d20\u4ea4\u6362\u64cd\u4f5c\u6a21\u62df\u5192\u6ce1

    "},{"location":"chapter_sorting/bubble_sort/#1131","title":"11.3.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u8bbe\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6b65\u9aa4\u5982\u56fe 11-5 \u6240\u793a\u3002

    1. \u9996\u5148\uff0c\u5bf9 \\(n\\) \u4e2a\u5143\u7d20\u6267\u884c\u201c\u5192\u6ce1\u201d\uff0c\u5c06\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u6b63\u786e\u4f4d\u7f6e\u3002
    2. \u63a5\u4e0b\u6765\uff0c\u5bf9\u5269\u4f59 \\(n - 1\\) \u4e2a\u5143\u7d20\u6267\u884c\u201c\u5192\u6ce1\u201d\uff0c\u5c06\u7b2c\u4e8c\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u6b63\u786e\u4f4d\u7f6e\u3002
    3. \u4ee5\u6b64\u7c7b\u63a8\uff0c\u7ecf\u8fc7 \\(n - 1\\) \u8f6e\u201c\u5192\u6ce1\u201d\u540e\uff0c\u524d \\(n - 1\\) \u5927\u7684\u5143\u7d20\u90fd\u88ab\u4ea4\u6362\u81f3\u6b63\u786e\u4f4d\u7f6e\u3002
    4. \u4ec5\u5269\u7684\u4e00\u4e2a\u5143\u7d20\u5fc5\u5b9a\u662f\u6700\u5c0f\u5143\u7d20\uff0c\u65e0\u987b\u6392\u5e8f\uff0c\u56e0\u6b64\u6570\u7ec4\u6392\u5e8f\u5b8c\u6210\u3002

    \u56fe 11-5 \u00a0 \u5192\u6ce1\u6392\u5e8f\u6d41\u7a0b

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bubble_sort.py
    def bubble_sort(nums: list[int]):\n    \"\"\"\u5192\u6ce1\u6392\u5e8f\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(n - 1, 0, -1):\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j + 1] = nums[j + 1], nums[j]\n
    bubble_sort.cpp
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                // \u8fd9\u91cc\u4f7f\u7528\u4e86 std::swap() \u51fd\u6570\n                swap(nums[j], nums[j + 1]);\n            }\n        }\n    }\n}\n
    bubble_sort.java
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.cs
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid BubbleSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n            }\n        }\n    }\n}\n
    bubble_sort.go
    /* \u5192\u6ce1\u6392\u5e8f */\nfunc bubbleSort(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j+1] = nums[j+1], nums[j]\n            }\n        }\n    }\n}\n
    bubble_sort.swift
    /* \u5192\u6ce1\u6392\u5e8f */\nfunc bubbleSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums.swapAt(j, j + 1)\n            }\n        }\n    }\n}\n
    bubble_sort.js
    /* \u5192\u6ce1\u6392\u5e8f */\nfunction bubbleSort(nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.ts
    /* \u5192\u6ce1\u6392\u5e8f */\nfunction bubbleSort(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.dart
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (int i = nums.length - 1; i > 0; i--) {\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (int j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n      }\n    }\n  }\n}\n
    bubble_sort.rs
    /* \u5192\u6ce1\u6392\u5e8f */\nfn bubble_sort(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    bubble_sort.c
    /* \u5192\u6ce1\u6392\u5e8f */\nvoid bubbleSort(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = size - 1; i > 0; i--) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                int temp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = temp;\n            }\n        }\n    }\n}\n
    bubble_sort.kt
    /* \u5192\u6ce1\u6392\u5e8f */\nfun bubbleSort(nums: IntArray) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n            }\n        }\n    }\n}\n
    bubble_sort.rb
    [class]{}-[func]{bubble_sort}\n
    bubble_sort.zig
    // \u5192\u6ce1\u6392\u5e8f\nfn bubbleSort(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: usize = nums.len - 1;\n    while (i > 0) : (i -= 1) {\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n            }\n        }\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/bubble_sort/#1132","title":"11.3.2 \u00a0 \u6548\u7387\u4f18\u5316","text":"

    \u6211\u4eec\u53d1\u73b0\uff0c\u5982\u679c\u67d0\u8f6e\u201c\u5192\u6ce1\u201d\u4e2d\u6ca1\u6709\u6267\u884c\u4efb\u4f55\u4ea4\u6362\u64cd\u4f5c\uff0c\u8bf4\u660e\u6570\u7ec4\u5df2\u7ecf\u5b8c\u6210\u6392\u5e8f\uff0c\u53ef\u76f4\u63a5\u8fd4\u56de\u7ed3\u679c\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u589e\u52a0\u4e00\u4e2a\u6807\u5fd7\u4f4d flag \u6765\u76d1\u6d4b\u8fd9\u79cd\u60c5\u51b5\uff0c\u4e00\u65e6\u51fa\u73b0\u5c31\u7acb\u5373\u8fd4\u56de\u3002

    \u7ecf\u8fc7\u4f18\u5316\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u548c\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4ecd\u4e3a \\(O(n^2)\\) \uff1b\u4f46\u5f53\u8f93\u5165\u6570\u7ec4\u5b8c\u5168\u6709\u5e8f\u65f6\uff0c\u53ef\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bubble_sort.py
    def bubble_sort_with_flag(nums: list[int]):\n    \"\"\"\u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in range(n - 1, 0, -1):\n        flag = False  # \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        # \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in range(i):\n            if nums[j] > nums[j + 1]:\n                # \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j + 1] = nums[j + 1], nums[j]\n                flag = True  # \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n        if not flag:\n            break  # \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n
    bubble_sort.cpp
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.size() - 1; i > 0; i--) {\n        bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                // \u8fd9\u91cc\u4f7f\u7528\u4e86 std::swap() \u51fd\u6570\n                swap(nums[j], nums[j + 1]);\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag)\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.java
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nvoid bubbleSortWithFlag(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.length - 1; i > 0; i--) {\n        boolean flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                int tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag)\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.cs
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid BubbleSortWithFlag(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = nums.Length - 1; i > 0; i--) {\n        bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]);\n                flag = true;  // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break;     // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.go
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunc bubbleSortWithFlag(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i := len(nums) - 1; i > 0; i-- {\n        flag := false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j := 0; j < i; j++ {\n            if nums[j] > nums[j+1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums[j], nums[j+1] = nums[j+1], nums[j]\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if flag == false { // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n            break\n        }\n    }\n}\n
    bubble_sort.swift
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunc bubbleSortWithFlag(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in nums.indices.dropFirst().reversed() {\n        var flag = false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        for j in 0 ..< i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                nums.swapAt(j, j + 1)\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if !flag { // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n            break\n        }\n    }\n}\n
    bubble_sort.js
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunction bubbleSortWithFlag(nums) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        let flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.ts
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nfunction bubbleSortWithFlag(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (let i = nums.length - 1; i > 0; i--) {\n        let flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (let j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.dart
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n  for (int i = nums.length - 1; i > 0; i--) {\n    bool flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n    // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n    for (int j = 0; j < i; j++) {\n      if (nums[j] > nums[j + 1]) {\n        // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n        int tmp = nums[j];\n        nums[j] = nums[j + 1];\n        nums[j + 1] = tmp;\n        flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n      }\n    }\n    if (!flag) break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n  }\n}\n
    bubble_sort.rs
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nfn bubble_sort_with_flag(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for i in (1..nums.len()).rev() {\n        let mut flag = false; // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for j in 0..i {\n            if nums[j] > nums[j + 1] {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                let tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true; // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if !flag {\n            break; // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n        };\n    }\n}\n
    bubble_sort.c
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09*/\nvoid bubbleSortWithFlag(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (int i = size - 1; i > 0; i--) {\n        bool flag = false;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (int j = 0; j < i; j++) {\n            if (nums[j] > nums[j + 1]) {\n                int temp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = temp;\n                flag = true;\n            }\n        }\n        if (!flag)\n            break;\n    }\n}\n
    bubble_sort.kt
    /* \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09 */\nfun bubbleSortWithFlag(nums: IntArray) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    for (i in nums.size - 1 downTo 1) {\n        var flag = false // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        for (j in 0..<i) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                val temp = nums[j]\n                nums[j] = nums[j + 1]\n                nums[j + 1] = temp\n                flag = true // \u8bb0\u5f55\u4ea4\u6362\u5143\u7d20\n            }\n        }\n        if (!flag) break // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    bubble_sort.rb
    [class]{}-[func]{bubble_sort_with_flag}\n
    bubble_sort.zig
    // \u5192\u6ce1\u6392\u5e8f\uff08\u6807\u5fd7\u4f18\u5316\uff09\nfn bubbleSortWithFlag(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [0, i]\n    var i: usize = nums.len - 1;\n    while (i > 0) : (i -= 1) {\n        var flag = false;   // \u521d\u59cb\u5316\u6807\u5fd7\u4f4d\n        var j: usize = 0;\n        // \u5185\u5faa\u73af\uff1a\u5c06\u672a\u6392\u5e8f\u533a\u95f4 [0, i] \u4e2d\u7684\u6700\u5927\u5143\u7d20\u4ea4\u6362\u81f3\u8be5\u533a\u95f4\u7684\u6700\u53f3\u7aef\n        while (j < i) : (j += 1) {\n            if (nums[j] > nums[j + 1]) {\n                // \u4ea4\u6362 nums[j] \u4e0e nums[j + 1]\n                var tmp = nums[j];\n                nums[j] = nums[j + 1];\n                nums[j + 1] = tmp;\n                flag = true;\n            }\n        }\n        if (!flag) break;   // \u6b64\u8f6e\u201c\u5192\u6ce1\u201d\u672a\u4ea4\u6362\u4efb\u4f55\u5143\u7d20\uff0c\u76f4\u63a5\u8df3\u51fa\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/bubble_sort/#1133","title":"11.3.3 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\u3001\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5404\u8f6e\u201c\u5192\u6ce1\u201d\u904d\u5386\u7684\u6570\u7ec4\u957f\u5ea6\u4f9d\u6b21\u4e3a \\(n - 1\\)\u3001\\(n - 2\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \uff0c\u603b\u548c\u4e3a \\((n - 1) n / 2\\) \u3002\u5728\u5f15\u5165 flag \u4f18\u5316\u540e\uff0c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe\u5230 \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u7531\u4e8e\u5728\u201c\u5192\u6ce1\u201d\u4e2d\u9047\u5230\u76f8\u7b49\u5143\u7d20\u4e0d\u4ea4\u6362\u3002
    "},{"location":"chapter_sorting/bucket_sort/","title":"11.8 \u00a0 \u6876\u6392\u5e8f","text":"

    \u524d\u8ff0\u51e0\u79cd\u6392\u5e8f\u7b97\u6cd5\u90fd\u5c5e\u4e8e\u201c\u57fa\u4e8e\u6bd4\u8f83\u7684\u6392\u5e8f\u7b97\u6cd5\u201d\uff0c\u5b83\u4eec\u901a\u8fc7\u6bd4\u8f83\u5143\u7d20\u95f4\u7684\u5927\u5c0f\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u6b64\u7c7b\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u65e0\u6cd5\u8d85\u8d8a \\(O(n \\log n)\\) \u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u63a2\u8ba8\u51e0\u79cd\u201c\u975e\u6bd4\u8f83\u6392\u5e8f\u7b97\u6cd5\u201d\uff0c\u5b83\u4eec\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u7ebf\u6027\u9636\u3002

    \u6876\u6392\u5e8f\uff08bucket sort\uff09\u662f\u5206\u6cbb\u7b56\u7565\u7684\u4e00\u4e2a\u5178\u578b\u5e94\u7528\u3002\u5b83\u901a\u8fc7\u8bbe\u7f6e\u4e00\u4e9b\u5177\u6709\u5927\u5c0f\u987a\u5e8f\u7684\u6876\uff0c\u6bcf\u4e2a\u6876\u5bf9\u5e94\u4e00\u4e2a\u6570\u636e\u8303\u56f4\uff0c\u5c06\u6570\u636e\u5e73\u5747\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\uff1b\u7136\u540e\uff0c\u5728\u6bcf\u4e2a\u6876\u5185\u90e8\u5206\u522b\u6267\u884c\u6392\u5e8f\uff1b\u6700\u7ec8\u6309\u7167\u6876\u7684\u987a\u5e8f\u5c06\u6240\u6709\u6570\u636e\u5408\u5e76\u3002

    "},{"location":"chapter_sorting/bucket_sort/#1181","title":"11.8.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u8003\u8651\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\uff0c\u5176\u5143\u7d20\u662f\u8303\u56f4 \\([0, 1)\\) \u5185\u7684\u6d6e\u70b9\u6570\u3002\u6876\u6392\u5e8f\u7684\u6d41\u7a0b\u5982\u56fe 11-13 \u6240\u793a\u3002

    1. \u521d\u59cb\u5316 \\(k\\) \u4e2a\u6876\uff0c\u5c06 \\(n\\) \u4e2a\u5143\u7d20\u5206\u914d\u5230 \\(k\\) \u4e2a\u6876\u4e2d\u3002
    2. \u5bf9\u6bcf\u4e2a\u6876\u5206\u522b\u6267\u884c\u6392\u5e8f\uff08\u8fd9\u91cc\u91c7\u7528\u7f16\u7a0b\u8bed\u8a00\u7684\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff09\u3002
    3. \u6309\u7167\u6876\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u5408\u5e76\u7ed3\u679c\u3002

    \u56fe 11-13 \u00a0 \u6876\u6392\u5e8f\u7b97\u6cd5\u6d41\u7a0b

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig bucket_sort.py
    def bucket_sort(nums: list[float]):\n    \"\"\"\u6876\u6392\u5e8f\"\"\"\n    # \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    k = len(nums) // 2\n    buckets = [[] for _ in range(k)]\n    # 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for num in nums:\n        # \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        i = int(num * k)\n        # \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].append(num)\n    # 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for bucket in buckets:\n        # \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort()\n    # 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    i = 0\n    for bucket in buckets:\n        for num in bucket:\n            nums[i] = num\n            i += 1\n
    bucket_sort.cpp
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(vector<float> &nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.size() / 2;\n    vector<vector<float>> buckets(k);\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (float num : nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = num * k;\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 bucket_idx\n        buckets[i].push_back(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (vector<float> &bucket : buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        sort(bucket.begin(), bucket.end());\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int i = 0;\n    for (vector<float> &bucket : buckets) {\n        for (float num : bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.java
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(float[] nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.length / 2;\n    List<List<Float>> buckets = new ArrayList<>();\n    for (int i = 0; i < k; i++) {\n        buckets.add(new ArrayList<>());\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (float num : nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = (int) (num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets.get(i).add(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (List<Float> bucket : buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        Collections.sort(bucket);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int i = 0;\n    for (List<Float> bucket : buckets) {\n        for (float num : bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.cs
    /* \u6876\u6392\u5e8f */\nvoid BucketSort(float[] nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    int k = nums.Length / 2;\n    List<List<float>> buckets = [];\n    for (int i = 0; i < k; i++) {\n        buckets.Add([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    foreach (float num in nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        int i = (int)(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].Add(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    foreach (List<float> bucket in buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.Sort();\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    int j = 0;\n    foreach (List<float> bucket in buckets) {\n        foreach (float num in bucket) {\n            nums[j++] = num;\n        }\n    }\n}\n
    bucket_sort.go
    /* \u6876\u6392\u5e8f */\nfunc bucketSort(nums []float64) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    k := len(nums) / 2\n    buckets := make([][]float64, k)\n    for i := 0; i < k; i++ {\n        buckets[i] = make([]float64, 0)\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for _, num := range nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        i := int(num * float64(k))\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i] = append(buckets[i], num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for i := 0; i < k; i++ {\n        // \u4f7f\u7528\u5185\u7f6e\u5207\u7247\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        sort.Float64s(buckets[i])\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    i := 0\n    for _, bucket := range buckets {\n        for _, num := range bucket {\n            nums[i] = num\n            i++\n        }\n    }\n}\n
    bucket_sort.swift
    /* \u6876\u6392\u5e8f */\nfunc bucketSort(nums: inout [Double]) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    let k = nums.count / 2\n    var buckets = (0 ..< k).map { _ in [Double]() }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for num in nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        let i = Int(num * Double(k))\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].append(num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for i in buckets.indices {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        buckets[i].sort()\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    var i = nums.startIndex\n    for bucket in buckets {\n        for num in bucket {\n            nums[i] = num\n            i += 1\n        }\n    }\n}\n
    bucket_sort.js
    /* \u6876\u6392\u5e8f */\nfunction bucketSort(nums) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    const k = nums.length / 2;\n    const buckets = [];\n    for (let i = 0; i < k; i++) {\n        buckets.push([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (const num of nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        const i = Math.floor(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (const bucket of buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort((a, b) => a - b);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let i = 0;\n    for (const bucket of buckets) {\n        for (const num of bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.ts
    /* \u6876\u6392\u5e8f */\nfunction bucketSort(nums: number[]): void {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    const k = nums.length / 2;\n    const buckets: number[][] = [];\n    for (let i = 0; i < k; i++) {\n        buckets.push([]);\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (const num of nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        const i = Math.floor(num * k);\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (const bucket of buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort((a, b) => a - b);\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let i = 0;\n    for (const bucket of buckets) {\n        for (const num of bucket) {\n            nums[i++] = num;\n        }\n    }\n}\n
    bucket_sort.dart
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(List<double> nums) {\n  // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n  int k = nums.length ~/ 2;\n  List<List<double>> buckets = List.generate(k, (index) => []);\n\n  // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n  for (double _num in nums) {\n    // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 _num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n    int i = (_num * k).toInt();\n    // \u5c06 _num \u6dfb\u52a0\u8fdb\u6876 bucket_idx\n    buckets[i].add(_num);\n  }\n  // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n  for (List<double> bucket in buckets) {\n    bucket.sort();\n  }\n  // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n  int i = 0;\n  for (List<double> bucket in buckets) {\n    for (double _num in bucket) {\n      nums[i++] = _num;\n    }\n  }\n}\n
    bucket_sort.rs
    /* \u6876\u6392\u5e8f */\nfn bucket_sort(nums: &mut [f64]) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    let k = nums.len() / 2;\n    let mut buckets = vec![vec![]; k];\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for &mut num in &mut *nums {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        let i = (num * k as f64) as usize;\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].push(num);\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for bucket in &mut buckets {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort_by(|a, b| a.partial_cmp(b).unwrap());\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    let mut i = 0;\n    for bucket in &mut buckets {\n        for &mut num in bucket {\n            nums[i] = num;\n            i += 1;\n        }\n    }\n}\n
    bucket_sort.c
    /* \u6876\u6392\u5e8f */\nvoid bucketSort(float nums[], int n) {\n    int k = n / 2;                                 // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\n    int *sizes = malloc(k * sizeof(int));          // \u8bb0\u5f55\u6bcf\u4e2a\u6876\u7684\u5927\u5c0f\n    float **buckets = malloc(k * sizeof(float *)); // \u52a8\u6001\u6570\u7ec4\u7684\u6570\u7ec4\uff08\u6876\uff09\n    // \u4e3a\u6bcf\u4e2a\u6876\u9884\u5206\u914d\u8db3\u591f\u7684\u7a7a\u95f4\n    for (int i = 0; i < k; ++i) {\n        buckets[i] = (float *)malloc(n * sizeof(float));\n        sizes[i] = 0;\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (int i = 0; i < n; ++i) {\n        int idx = (int)(nums[i] * k);\n        buckets[idx][sizes[idx]++] = nums[i];\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (int i = 0; i < k; ++i) {\n        qsort(buckets[i], sizes[i], sizeof(float), compare);\n    }\n    // 3. \u5408\u5e76\u6392\u5e8f\u540e\u7684\u6876\n    int idx = 0;\n    for (int i = 0; i < k; ++i) {\n        for (int j = 0; j < sizes[i]; ++j) {\n            nums[idx++] = buckets[i][j];\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(buckets[i]);\n    }\n}\n
    bucket_sort.kt
    /* \u6876\u6392\u5e8f */\nfun bucketSort(nums: FloatArray) {\n    // \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n    val k = nums.size / 2\n    val buckets = mutableListOf<MutableList<Float>>()\n    for (i in 0..<k) {\n        buckets.add(mutableListOf())\n    }\n    // 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n    for (num in nums) {\n        // \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n        val i = (num * k).toInt()\n        // \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n        buckets[i].add(num)\n    }\n    // 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n    for (bucket in buckets) {\n        // \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n        bucket.sort()\n    }\n    // 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n    var i = 0\n    for (bucket in buckets) {\n        for (num in bucket) {\n            nums[i++] = num\n        }\n    }\n}\n
    bucket_sort.rb
    ### \u6876\u6392\u5e8f ###\ndef bucket_sort(nums)\n  # \u521d\u59cb\u5316 k = n/2 \u4e2a\u6876\uff0c\u9884\u671f\u5411\u6bcf\u4e2a\u6876\u5206\u914d 2 \u4e2a\u5143\u7d20\n  k = nums.length / 2\n  buckets = Array.new(k) { [] }\n\n  # 1. \u5c06\u6570\u7ec4\u5143\u7d20\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\n  nums.each do |num|\n    # \u8f93\u5165\u6570\u636e\u8303\u56f4\u4e3a [0, 1)\uff0c\u4f7f\u7528 num * k \u6620\u5c04\u5230\u7d22\u5f15\u8303\u56f4 [0, k-1]\n    i = (num * k).to_i\n    # \u5c06 num \u6dfb\u52a0\u8fdb\u6876 i\n    buckets[i] << num\n  end\n\n  # 2. \u5bf9\u5404\u4e2a\u6876\u6267\u884c\u6392\u5e8f\n  buckets.each do |bucket|\n    # \u4f7f\u7528\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u66ff\u6362\u6210\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\n    bucket.sort!\n  end\n\n  # 3. \u904d\u5386\u6876\u5408\u5e76\u7ed3\u679c\n  i = 0\n  buckets.each do |bucket|\n    bucket.each do |num|\n      nums[i] = num\n      i += 1\n    end\n  end\nend\n
    bucket_sort.zig
    [class]{}-[func]{bucketSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/bucket_sort/#1182","title":"11.8.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"

    \u6876\u6392\u5e8f\u9002\u7528\u4e8e\u5904\u7406\u4f53\u91cf\u5f88\u5927\u7684\u6570\u636e\u3002\u4f8b\u5982\uff0c\u8f93\u5165\u6570\u636e\u5305\u542b 100 \u4e07\u4e2a\u5143\u7d20\uff0c\u7531\u4e8e\u7a7a\u95f4\u9650\u5236\uff0c\u7cfb\u7edf\u5185\u5b58\u65e0\u6cd5\u4e00\u6b21\u6027\u52a0\u8f7d\u6240\u6709\u6570\u636e\u3002\u6b64\u65f6\uff0c\u53ef\u4ee5\u5c06\u6570\u636e\u5206\u6210 1000 \u4e2a\u6876\uff0c\u7136\u540e\u5206\u522b\u5bf9\u6bcf\u4e2a\u6876\u8fdb\u884c\u6392\u5e8f\uff0c\u6700\u540e\u5c06\u7ed3\u679c\u5408\u5e76\u3002

    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + k)\\) \uff1a\u5047\u8bbe\u5143\u7d20\u5728\u5404\u4e2a\u6876\u5185\u5e73\u5747\u5206\u5e03\uff0c\u90a3\u4e48\u6bcf\u4e2a\u6876\u5185\u7684\u5143\u7d20\u6570\u91cf\u4e3a \\(\\frac{n}{k}\\) \u3002\u5047\u8bbe\u6392\u5e8f\u5355\u4e2a\u6876\u4f7f\u7528 \\(O(\\frac{n}{k} \\log\\frac{n}{k})\\) \u65f6\u95f4\uff0c\u5219\u6392\u5e8f\u6240\u6709\u6876\u4f7f\u7528 \\(O(n \\log\\frac{n}{k})\\) \u65f6\u95f4\u3002\u5f53\u6876\u6570\u91cf \\(k\\) \u6bd4\u8f83\u5927\u65f6\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5219\u8d8b\u5411\u4e8e \\(O(n)\\) \u3002\u5408\u5e76\u7ed3\u679c\u65f6\u9700\u8981\u904d\u5386\u6240\u6709\u6876\u548c\u5143\u7d20\uff0c\u82b1\u8d39 \\(O(n + k)\\) \u65f6\u95f4\u3002
    • \u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u6570\u636e\u88ab\u5206\u914d\u5230\u4e00\u4e2a\u6876\u4e2d\uff0c\u4e14\u6392\u5e8f\u8be5\u6876\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + k)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u9700\u8981\u501f\u52a9 \\(k\\) \u4e2a\u6876\u548c\u603b\u5171 \\(n\\) \u4e2a\u5143\u7d20\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u6876\u6392\u5e8f\u662f\u5426\u7a33\u5b9a\u53d6\u51b3\u4e8e\u6392\u5e8f\u6876\u5185\u5143\u7d20\u7684\u7b97\u6cd5\u662f\u5426\u7a33\u5b9a\u3002
    "},{"location":"chapter_sorting/bucket_sort/#1183","title":"11.8.3 \u00a0 \u5982\u4f55\u5b9e\u73b0\u5e73\u5747\u5206\u914d","text":"

    \u6876\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u7406\u8bba\u4e0a\u53ef\u4ee5\u8fbe\u5230 \\(O(n)\\) \uff0c\u5173\u952e\u5728\u4e8e\u5c06\u5143\u7d20\u5747\u5300\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\uff0c\u56e0\u4e3a\u5b9e\u9645\u6570\u636e\u5f80\u5f80\u4e0d\u662f\u5747\u5300\u5206\u5e03\u7684\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u60f3\u8981\u5c06\u6dd8\u5b9d\u4e0a\u7684\u6240\u6709\u5546\u54c1\u6309\u4ef7\u683c\u8303\u56f4\u5e73\u5747\u5206\u914d\u5230 10 \u4e2a\u6876\u4e2d\uff0c\u4f46\u5546\u54c1\u4ef7\u683c\u5206\u5e03\u4e0d\u5747\uff0c\u4f4e\u4e8e 100 \u5143\u7684\u975e\u5e38\u591a\uff0c\u9ad8\u4e8e 1000 \u5143\u7684\u975e\u5e38\u5c11\u3002\u82e5\u5c06\u4ef7\u683c\u533a\u95f4\u5e73\u5747\u5212\u5206\u4e3a 10 \u4e2a\uff0c\u5404\u4e2a\u6876\u4e2d\u7684\u5546\u54c1\u6570\u91cf\u5dee\u8ddd\u4f1a\u975e\u5e38\u5927\u3002

    \u4e3a\u5b9e\u73b0\u5e73\u5747\u5206\u914d\uff0c\u6211\u4eec\u53ef\u4ee5\u5148\u8bbe\u5b9a\u4e00\u6761\u5927\u81f4\u7684\u5206\u754c\u7ebf\uff0c\u5c06\u6570\u636e\u7c97\u7565\u5730\u5206\u5230 3 \u4e2a\u6876\u4e2d\u3002\u5206\u914d\u5b8c\u6bd5\u540e\uff0c\u518d\u5c06\u5546\u54c1\u8f83\u591a\u7684\u6876\u7ee7\u7eed\u5212\u5206\u4e3a 3 \u4e2a\u6876\uff0c\u76f4\u81f3\u6240\u6709\u6876\u4e2d\u7684\u5143\u7d20\u6570\u91cf\u5927\u81f4\u76f8\u7b49\u3002

    \u5982\u56fe 11-14 \u6240\u793a\uff0c\u8fd9\u79cd\u65b9\u6cd5\u672c\u8d28\u4e0a\u662f\u521b\u5efa\u4e00\u68f5\u9012\u5f52\u6811\uff0c\u76ee\u6807\u662f\u8ba9\u53f6\u8282\u70b9\u7684\u503c\u5c3d\u53ef\u80fd\u5e73\u5747\u3002\u5f53\u7136\uff0c\u4e0d\u4e00\u5b9a\u8981\u6bcf\u8f6e\u5c06\u6570\u636e\u5212\u5206\u4e3a 3 \u4e2a\u6876\uff0c\u5177\u4f53\u5212\u5206\u65b9\u5f0f\u53ef\u6839\u636e\u6570\u636e\u7279\u70b9\u7075\u6d3b\u9009\u62e9\u3002

    \u56fe 11-14 \u00a0 \u9012\u5f52\u5212\u5206\u6876

    \u5982\u679c\u6211\u4eec\u63d0\u524d\u77e5\u9053\u5546\u54c1\u4ef7\u683c\u7684\u6982\u7387\u5206\u5e03\uff0c\u5219\u53ef\u4ee5\u6839\u636e\u6570\u636e\u6982\u7387\u5206\u5e03\u8bbe\u7f6e\u6bcf\u4e2a\u6876\u7684\u4ef7\u683c\u5206\u754c\u7ebf\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6570\u636e\u5206\u5e03\u5e76\u4e0d\u4e00\u5b9a\u9700\u8981\u7279\u610f\u7edf\u8ba1\uff0c\u4e5f\u53ef\u4ee5\u6839\u636e\u6570\u636e\u7279\u70b9\u91c7\u7528\u67d0\u79cd\u6982\u7387\u6a21\u578b\u8fdb\u884c\u8fd1\u4f3c\u3002

    \u5982\u56fe 11-15 \u6240\u793a\uff0c\u6211\u4eec\u5047\u8bbe\u5546\u54c1\u4ef7\u683c\u670d\u4ece\u6b63\u6001\u5206\u5e03\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5408\u7406\u5730\u8bbe\u5b9a\u4ef7\u683c\u533a\u95f4\uff0c\u4ece\u800c\u5c06\u5546\u54c1\u5e73\u5747\u5206\u914d\u5230\u5404\u4e2a\u6876\u4e2d\u3002

    \u56fe 11-15 \u00a0 \u6839\u636e\u6982\u7387\u5206\u5e03\u5212\u5206\u6876

    "},{"location":"chapter_sorting/counting_sort/","title":"11.9 \u00a0 \u8ba1\u6570\u6392\u5e8f","text":"

    \u8ba1\u6570\u6392\u5e8f\uff08counting sort\uff09\u901a\u8fc7\u7edf\u8ba1\u5143\u7d20\u6570\u91cf\u6765\u5b9e\u73b0\u6392\u5e8f\uff0c\u901a\u5e38\u5e94\u7528\u4e8e\u6574\u6570\u6570\u7ec4\u3002

    "},{"location":"chapter_sorting/counting_sort/#1191","title":"11.9.1 \u00a0 \u7b80\u5355\u5b9e\u73b0","text":"

    \u5148\u6765\u770b\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\u3002\u7ed9\u5b9a\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4 nums \uff0c\u5176\u4e2d\u7684\u5143\u7d20\u90fd\u662f\u201c\u975e\u8d1f\u6574\u6570\u201d\uff0c\u8ba1\u6570\u6392\u5e8f\u7684\u6574\u4f53\u6d41\u7a0b\u5982\u56fe 11-16 \u6240\u793a\u3002

    1. \u904d\u5386\u6570\u7ec4\uff0c\u627e\u51fa\u5176\u4e2d\u7684\u6700\u5927\u6570\u5b57\uff0c\u8bb0\u4e3a \\(m\\) \uff0c\u7136\u540e\u521b\u5efa\u4e00\u4e2a\u957f\u5ea6\u4e3a \\(m + 1\\) \u7684\u8f85\u52a9\u6570\u7ec4 counter \u3002
    2. \u501f\u52a9 counter \u7edf\u8ba1 nums \u4e2d\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\uff0c\u5176\u4e2d counter[num] \u5bf9\u5e94\u6570\u5b57 num \u7684\u51fa\u73b0\u6b21\u6570\u3002\u7edf\u8ba1\u65b9\u6cd5\u5f88\u7b80\u5355\uff0c\u53ea\u9700\u904d\u5386 nums\uff08\u8bbe\u5f53\u524d\u6570\u5b57\u4e3a num\uff09\uff0c\u6bcf\u8f6e\u5c06 counter[num] \u589e\u52a0 \\(1\\) \u5373\u53ef\u3002
    3. \u7531\u4e8e counter \u7684\u5404\u4e2a\u7d22\u5f15\u5929\u7136\u6709\u5e8f\uff0c\u56e0\u6b64\u76f8\u5f53\u4e8e\u6240\u6709\u6570\u5b57\u5df2\u7ecf\u6392\u5e8f\u597d\u4e86\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u904d\u5386 counter \uff0c\u6839\u636e\u5404\u6570\u5b57\u51fa\u73b0\u6b21\u6570\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u586b\u5165 nums \u5373\u53ef\u3002

    \u56fe 11-16 \u00a0 \u8ba1\u6570\u6392\u5e8f\u6d41\u7a0b

    \u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig counting_sort.py
    def counting_sort_naive(nums: list[int]):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\"\"\"\n    # \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\n    # 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m = 0\n    for num in nums:\n        m = max(m, num)\n    # 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    # counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter = [0] * (m + 1)\n    for num in nums:\n        counter[num] += 1\n    # 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    i = 0\n    for num in range(m + 1):\n        for _ in range(counter[num]):\n            nums[i] = num\n            i += 1\n
    counting_sort.cpp
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(vector<int> &nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    vector<int> counter(m + 1, 0);\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.java
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.cs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid CountingSortNaive(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    foreach (int num in nums) {\n        m = Math.Max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    foreach (int num in nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.go
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunc countingSortNaive(nums []int) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m := 0\n    for _, num := range nums {\n        if num > m {\n            m = num\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter := make([]int, m+1)\n    for _, num := range nums {\n        counter[num]++\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    for i, num := 0, 0; num < m+1; num++ {\n        for j := 0; j < counter[num]; j++ {\n            nums[i] = num\n            i++\n        }\n    }\n}\n
    counting_sort.swift
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunc countingSortNaive(nums: inout [Int]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = nums.max()!\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    var counter = Array(repeating: 0, count: m + 1)\n    for num in nums {\n        counter[num] += 1\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    var i = 0\n    for num in 0 ..< m + 1 {\n        for _ in 0 ..< counter[num] {\n            nums[i] = num\n            i += 1\n        }\n    }\n}\n
    counting_sort.js
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunction countingSortNaive(nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter = new Array(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let i = 0;\n    for (let num = 0; num < m + 1; num++) {\n        for (let j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.ts
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfunction countingSortNaive(nums: number[]): void {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter: number[] = new Array<number>(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let i = 0;\n    for (let num = 0; num < m + 1; num++) {\n        for (let j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n}\n
    counting_sort.dart
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(List<int> nums) {\n  // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n  int m = 0;\n  for (int _num in nums) {\n    m = max(m, _num);\n  }\n  // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  // counter[_num] \u4ee3\u8868 _num \u7684\u51fa\u73b0\u6b21\u6570\n  List<int> counter = List.filled(m + 1, 0);\n  for (int _num in nums) {\n    counter[_num]++;\n  }\n  // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n  int i = 0;\n  for (int _num = 0; _num < m + 1; _num++) {\n    for (int j = 0; j < counter[_num]; j++, i++) {\n      nums[i] = _num;\n    }\n  }\n}\n
    counting_sort.rs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfn counting_sort_naive(nums: &mut [i32]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = *nums.into_iter().max().unwrap();\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    let mut counter = vec![0; m as usize + 1];\n    for &num in &*nums {\n        counter[num as usize] += 1;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    let mut i = 0;\n    for num in 0..m + 1 {\n        for _ in 0..counter[num as usize] {\n            nums[i] = num;\n            i += 1;\n        }\n    }\n}\n
    counting_sort.c
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nvoid countingSortNaive(int nums[], int size) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int i = 0; i < size; i++) {\n        if (nums[i] > m) {\n            m = nums[i];\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int *counter = calloc(m + 1, sizeof(int));\n    for (int i = 0; i < size; i++) {\n        counter[nums[i]]++;\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    int i = 0;\n    for (int num = 0; num < m + 1; num++) {\n        for (int j = 0; j < counter[num]; j++, i++) {\n            nums[i] = num;\n        }\n    }\n    // 4. \u91ca\u653e\u5185\u5b58\n    free(counter);\n}\n
    counting_sort.kt
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u7b80\u5355\u5b9e\u73b0\uff0c\u65e0\u6cd5\u7528\u4e8e\u6392\u5e8f\u5bf9\u8c61\nfun countingSortNaive(nums: IntArray) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    var m = 0\n    for (num in nums) {\n        m = max(m, num)\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    val counter = IntArray(m + 1)\n    for (num in nums) {\n        counter[num]++\n    }\n    // 3. \u904d\u5386 counter \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u539f\u6570\u7ec4 nums\n    var i = 0\n    for (num in 0..<m + 1) {\n        var j = 0\n        while (j < counter[num]) {\n            nums[i] = num\n            j++\n            i++\n        }\n    }\n}\n
    counting_sort.rb
    [class]{}-[func]{counting_sort_naive}\n
    counting_sort.zig
    [class]{}-[func]{countingSortNaive}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u8ba1\u6570\u6392\u5e8f\u4e0e\u6876\u6392\u5e8f\u7684\u8054\u7cfb

    \u4ece\u6876\u6392\u5e8f\u7684\u89d2\u5ea6\u770b\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u8ba1\u6570\u6392\u5e8f\u4e2d\u7684\u8ba1\u6570\u6570\u7ec4 counter \u7684\u6bcf\u4e2a\u7d22\u5f15\u89c6\u4e3a\u4e00\u4e2a\u6876\uff0c\u5c06\u7edf\u8ba1\u6570\u91cf\u7684\u8fc7\u7a0b\u770b\u4f5c\u5c06\u5404\u4e2a\u5143\u7d20\u5206\u914d\u5230\u5bf9\u5e94\u7684\u6876\u4e2d\u3002\u672c\u8d28\u4e0a\uff0c\u8ba1\u6570\u6392\u5e8f\u662f\u6876\u6392\u5e8f\u5728\u6574\u578b\u6570\u636e\u4e0b\u7684\u4e00\u4e2a\u7279\u4f8b\u3002

    "},{"location":"chapter_sorting/counting_sort/#1192","title":"11.9.2 \u00a0 \u5b8c\u6574\u5b9e\u73b0","text":"

    \u7ec6\u5fc3\u7684\u8bfb\u8005\u53ef\u80fd\u53d1\u73b0\u4e86\uff0c\u5982\u679c\u8f93\u5165\u6570\u636e\u662f\u5bf9\u8c61\uff0c\u4e0a\u8ff0\u6b65\u9aa4 3. \u5c31\u5931\u6548\u4e86\u3002\u5047\u8bbe\u8f93\u5165\u6570\u636e\u662f\u5546\u54c1\u5bf9\u8c61\uff0c\u6211\u4eec\u60f3\u6309\u7167\u5546\u54c1\u4ef7\u683c\uff08\u7c7b\u7684\u6210\u5458\u53d8\u91cf\uff09\u5bf9\u5546\u54c1\u8fdb\u884c\u6392\u5e8f\uff0c\u800c\u4e0a\u8ff0\u7b97\u6cd5\u53ea\u80fd\u7ed9\u51fa\u4ef7\u683c\u7684\u6392\u5e8f\u7ed3\u679c\u3002

    \u90a3\u4e48\u5982\u4f55\u624d\u80fd\u5f97\u5230\u539f\u6570\u636e\u7684\u6392\u5e8f\u7ed3\u679c\u5462\uff1f\u6211\u4eec\u9996\u5148\u8ba1\u7b97 counter \u7684\u201c\u524d\u7f00\u548c\u201d\u3002\u987e\u540d\u601d\u4e49\uff0c\u7d22\u5f15 i \u5904\u7684\u524d\u7f00\u548c prefix[i] \u7b49\u4e8e\u6570\u7ec4\u524d i \u4e2a\u5143\u7d20\u4e4b\u548c\uff1a

    \\[ \\text{prefix}[i] = \\sum_{j=0}^i \\text{counter[j]} \\]

    \u524d\u7f00\u548c\u5177\u6709\u660e\u786e\u7684\u610f\u4e49\uff0cprefix[num] - 1 \u4ee3\u8868\u5143\u7d20 num \u5728\u7ed3\u679c\u6570\u7ec4 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\u3002\u8fd9\u4e2a\u4fe1\u606f\u975e\u5e38\u5173\u952e\uff0c\u56e0\u4e3a\u5b83\u544a\u8bc9\u6211\u4eec\u5404\u4e2a\u5143\u7d20\u5e94\u8be5\u51fa\u73b0\u5728\u7ed3\u679c\u6570\u7ec4\u7684\u54ea\u4e2a\u4f4d\u7f6e\u3002\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5012\u5e8f\u904d\u5386\u539f\u6570\u7ec4 nums \u7684\u6bcf\u4e2a\u5143\u7d20 num \uff0c\u5728\u6bcf\u8f6e\u8fed\u4ee3\u4e2d\u6267\u884c\u4ee5\u4e0b\u4e24\u6b65\u3002

    1. \u5c06 num \u586b\u5165\u6570\u7ec4 res \u7684\u7d22\u5f15 prefix[num] - 1 \u5904\u3002
    2. \u4ee4\u524d\u7f00\u548c prefix[num] \u51cf\u5c0f \\(1\\) \uff0c\u4ece\u800c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\u3002

    \u904d\u5386\u5b8c\u6210\u540e\uff0c\u6570\u7ec4 res \u4e2d\u5c31\u662f\u6392\u5e8f\u597d\u7684\u7ed3\u679c\uff0c\u6700\u540e\u4f7f\u7528 res \u8986\u76d6\u539f\u6570\u7ec4 nums \u5373\u53ef\u3002\u56fe 11-17 \u5c55\u793a\u4e86\u5b8c\u6574\u7684\u8ba1\u6570\u6392\u5e8f\u6d41\u7a0b\u3002

    <1><2><3><4><5><6><7><8>

    \u56fe 11-17 \u00a0 \u8ba1\u6570\u6392\u5e8f\u6b65\u9aa4

    \u8ba1\u6570\u6392\u5e8f\u7684\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig counting_sort.py
    def counting_sort(nums: list[int]):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\"\"\"\n    # \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\n    # 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m = max(nums)\n    # 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    # counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter = [0] * (m + 1)\n    for num in nums:\n        counter[num] += 1\n    # 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    # \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in range(m):\n        counter[i + 1] += counter[i]\n    # 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    # \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    n = len(nums)\n    res = [0] * n\n    for i in range(n - 1, -1, -1):\n        num = nums[i]\n        res[counter[num] - 1] = num  # \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num] -= 1  # \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    # \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in range(n):\n        nums[i] = res[i]\n
    counting_sort.cpp
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(vector<int> &nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    vector<int> counter(m + 1, 0);\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.size();\n    vector<int> res(n);\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--;              // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    nums = res;\n}\n
    counting_sort.java
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int num : nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    for (int num : nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.length;\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.cs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid CountingSort(int[] nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    foreach (int num in nums) {\n        m = Math.Max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int[] counter = new int[m + 1];\n    foreach (int num in nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int n = nums.Length;\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.go
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunc countingSort(nums []int) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    m := 0\n    for _, num := range nums {\n        if num > m {\n            m = num\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    counter := make([]int, m+1)\n    for _, num := range nums {\n        counter[num]++\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i := 0; i < m; i++ {\n        counter[i+1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    n := len(nums)\n    res := make([]int, n)\n    for i := n - 1; i >= 0; i-- {\n        num := nums[i]\n        // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        res[counter[num]-1] = num\n        // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n        counter[num]--\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    copy(nums, res)\n}\n
    counting_sort.swift
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunc countingSort(nums: inout [Int]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = nums.max()!\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    var counter = Array(repeating: 0, count: m + 1)\n    for num in nums {\n        counter[num] += 1\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in 0 ..< m {\n        counter[i + 1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    var res = Array(repeating: 0, count: nums.count)\n    for i in nums.indices.reversed() {\n        let num = nums[i]\n        res[counter[num] - 1] = num // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num] -= 1 // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in nums.indices {\n        nums[i] = res[i]\n    }\n}\n
    counting_sort.js
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunction countingSort(nums) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter = new Array(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (let i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    const n = nums.length;\n    const res = new Array(n);\n    for (let i = n - 1; i >= 0; i--) {\n        const num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.ts
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfunction countingSort(nums: number[]): void {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = 0;\n    for (const num of nums) {\n        m = Math.max(m, num);\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    const counter: number[] = new Array<number>(m + 1).fill(0);\n    for (const num of nums) {\n        counter[num]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (let i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    const n = nums.length;\n    const res: number[] = new Array<number>(n);\n    for (let i = n - 1; i >= 0; i--) {\n        const num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.dart
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(List<int> nums) {\n  // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n  int m = 0;\n  for (int _num in nums) {\n    m = max(m, _num);\n  }\n  // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  // counter[_num] \u4ee3\u8868 _num \u7684\u51fa\u73b0\u6b21\u6570\n  List<int> counter = List.filled(m + 1, 0);\n  for (int _num in nums) {\n    counter[_num]++;\n  }\n  // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n  // \u5373 counter[_num]-1 \u662f _num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n  for (int i = 0; i < m; i++) {\n    counter[i + 1] += counter[i];\n  }\n  // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n  // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n  int n = nums.length;\n  List<int> res = List.filled(n, 0);\n  for (int i = n - 1; i >= 0; i--) {\n    int _num = nums[i];\n    res[counter[_num] - 1] = _num; // \u5c06 _num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n    counter[_num]--; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e _num \u7684\u7d22\u5f15\n  }\n  // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n  nums.setAll(0, res);\n}\n
    counting_sort.rs
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfn counting_sort(nums: &mut [i32]) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    let m = *nums.into_iter().max().unwrap();\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    let mut counter = vec![0; m as usize + 1];\n    for &num in &*nums {\n        counter[num as usize] += 1;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for i in 0..m as usize {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    let n = nums.len();\n    let mut res = vec![0; n];\n    for i in (0..n).rev() {\n        let num = nums[i];\n        res[counter[num as usize] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num as usize] -= 1; // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in 0..n {\n        nums[i] = res[i];\n    }\n}\n
    counting_sort.c
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nvoid countingSort(int nums[], int size) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    int m = 0;\n    for (int i = 0; i < size; i++) {\n        if (nums[i] > m) {\n            m = nums[i];\n        }\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    int *counter = calloc(m, sizeof(int));\n    for (int i = 0; i < size; i++) {\n        counter[nums[i]]++;\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (int i = 0; i < m; i++) {\n        counter[i + 1] += counter[i];\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    int *res = malloc(sizeof(int) * size);\n    for (int i = size - 1; i >= 0; i--) {\n        int num = nums[i];\n        res[counter[num] - 1] = num; // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]--;              // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    memcpy(nums, res, size * sizeof(int));\n    // 5. \u91ca\u653e\u5185\u5b58\n    free(counter);\n}\n
    counting_sort.kt
    /* \u8ba1\u6570\u6392\u5e8f */\n// \u5b8c\u6574\u5b9e\u73b0\uff0c\u53ef\u6392\u5e8f\u5bf9\u8c61\uff0c\u5e76\u4e14\u662f\u7a33\u5b9a\u6392\u5e8f\nfun countingSort(nums: IntArray) {\n    // 1. \u7edf\u8ba1\u6570\u7ec4\u6700\u5927\u5143\u7d20 m\n    var m = 0\n    for (num in nums) {\n        m = max(m, num)\n    }\n    // 2. \u7edf\u8ba1\u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    // counter[num] \u4ee3\u8868 num \u7684\u51fa\u73b0\u6b21\u6570\n    val counter = IntArray(m + 1)\n    for (num in nums) {\n        counter[num]++\n    }\n    // 3. \u6c42 counter \u7684\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u6b21\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u5c3e\u7d22\u5f15\u201d\n    // \u5373 counter[num]-1 \u662f num \u5728 res \u4e2d\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u7d22\u5f15\n    for (i in 0..<m) {\n        counter[i + 1] += counter[i]\n    }\n    // 4. \u5012\u5e8f\u904d\u5386 nums \uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165\u7ed3\u679c\u6570\u7ec4 res\n    // \u521d\u59cb\u5316\u6570\u7ec4 res \u7528\u4e8e\u8bb0\u5f55\u7ed3\u679c\n    val n = nums.size\n    val res = IntArray(n)\n    for (i in n - 1 downTo 0) {\n        val num = nums[i]\n        res[counter[num] - 1] = num // \u5c06 num \u653e\u7f6e\u5230\u5bf9\u5e94\u7d22\u5f15\u5904\n        counter[num]-- // \u4ee4\u524d\u7f00\u548c\u81ea\u51cf 1 \uff0c\u5f97\u5230\u4e0b\u6b21\u653e\u7f6e num \u7684\u7d22\u5f15\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u6570\u7ec4 res \u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (i in 0..<n) {\n        nums[i] = res[i]\n    }\n}\n
    counting_sort.rb
    [class]{}-[func]{counting_sort}\n
    counting_sort.zig
    [class]{}-[func]{countingSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/counting_sort/#1193","title":"11.9.3 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + m)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f \uff1a\u6d89\u53ca\u904d\u5386 nums \u548c\u904d\u5386 counter \uff0c\u90fd\u4f7f\u7528\u7ebf\u6027\u65f6\u95f4\u3002\u4e00\u822c\u60c5\u51b5\u4e0b \\(n \\gg m\\) \uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u4e8e \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + m)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u501f\u52a9\u4e86\u957f\u5ea6\u5206\u522b\u4e3a \\(n\\) \u548c \\(m\\) \u7684\u6570\u7ec4 res \u548c counter \u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u7531\u4e8e\u5411 res \u4e2d\u586b\u5145\u5143\u7d20\u7684\u987a\u5e8f\u662f\u201c\u4ece\u53f3\u5411\u5de6\u201d\u7684\uff0c\u56e0\u6b64\u5012\u5e8f\u904d\u5386 nums \u53ef\u4ee5\u907f\u514d\u6539\u53d8\u76f8\u7b49\u5143\u7d20\u4e4b\u95f4\u7684\u76f8\u5bf9\u4f4d\u7f6e\uff0c\u4ece\u800c\u5b9e\u73b0\u7a33\u5b9a\u6392\u5e8f\u3002\u5b9e\u9645\u4e0a\uff0c\u6b63\u5e8f\u904d\u5386 nums \u4e5f\u53ef\u4ee5\u5f97\u5230\u6b63\u786e\u7684\u6392\u5e8f\u7ed3\u679c\uff0c\u4f46\u7ed3\u679c\u662f\u975e\u7a33\u5b9a\u7684\u3002
    "},{"location":"chapter_sorting/counting_sort/#1194","title":"11.9.4 \u00a0 \u5c40\u9650\u6027","text":"

    \u770b\u5230\u8fd9\u91cc\uff0c\u4f60\u4e5f\u8bb8\u4f1a\u89c9\u5f97\u8ba1\u6570\u6392\u5e8f\u975e\u5e38\u5de7\u5999\uff0c\u4ec5\u901a\u8fc7\u7edf\u8ba1\u6570\u91cf\u5c31\u53ef\u4ee5\u5b9e\u73b0\u9ad8\u6548\u7684\u6392\u5e8f\u3002\u7136\u800c\uff0c\u4f7f\u7528\u8ba1\u6570\u6392\u5e8f\u7684\u524d\u7f6e\u6761\u4ef6\u76f8\u5bf9\u8f83\u4e3a\u4e25\u683c\u3002

    \u8ba1\u6570\u6392\u5e8f\u53ea\u9002\u7528\u4e8e\u975e\u8d1f\u6574\u6570\u3002\u82e5\u60f3\u5c06\u5176\u7528\u4e8e\u5176\u4ed6\u7c7b\u578b\u7684\u6570\u636e\uff0c\u9700\u8981\u786e\u4fdd\u8fd9\u4e9b\u6570\u636e\u53ef\u4ee5\u8f6c\u6362\u4e3a\u975e\u8d1f\u6574\u6570\uff0c\u5e76\u4e14\u5728\u8f6c\u6362\u8fc7\u7a0b\u4e2d\u4e0d\u80fd\u6539\u53d8\u5404\u4e2a\u5143\u7d20\u4e4b\u95f4\u7684\u76f8\u5bf9\u5927\u5c0f\u5173\u7cfb\u3002\u4f8b\u5982\uff0c\u5bf9\u4e8e\u5305\u542b\u8d1f\u6570\u7684\u6574\u6570\u6570\u7ec4\uff0c\u53ef\u4ee5\u5148\u7ed9\u6240\u6709\u6570\u5b57\u52a0\u4e0a\u4e00\u4e2a\u5e38\u6570\uff0c\u5c06\u5168\u90e8\u6570\u5b57\u8f6c\u5316\u4e3a\u6b63\u6570\uff0c\u6392\u5e8f\u5b8c\u6210\u540e\u518d\u8f6c\u6362\u56de\u53bb\u3002

    \u8ba1\u6570\u6392\u5e8f\u9002\u7528\u4e8e\u6570\u636e\u91cf\u5927\u4f46\u6570\u636e\u8303\u56f4\u8f83\u5c0f\u7684\u60c5\u51b5\u3002\u6bd4\u5982\uff0c\u5728\u4e0a\u8ff0\u793a\u4f8b\u4e2d \\(m\\) \u4e0d\u80fd\u592a\u5927\uff0c\u5426\u5219\u4f1a\u5360\u7528\u8fc7\u591a\u7a7a\u95f4\u3002\u800c\u5f53 \\(n \\ll m\\) \u65f6\uff0c\u8ba1\u6570\u6392\u5e8f\u4f7f\u7528 \\(O(m)\\) \u65f6\u95f4\uff0c\u53ef\u80fd\u6bd4 \\(O(n \\log n)\\) \u7684\u6392\u5e8f\u7b97\u6cd5\u8fd8\u8981\u6162\u3002

    "},{"location":"chapter_sorting/heap_sort/","title":"11.7 \u00a0 \u5806\u6392\u5e8f","text":"

    Tip

    \u9605\u8bfb\u672c\u8282\u524d\uff0c\u8bf7\u786e\u4fdd\u5df2\u5b66\u5b8c\u201c\u5806\u201c\u7ae0\u8282\u3002

    \u5806\u6392\u5e8f\uff08heap sort\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5806\u6570\u636e\u7ed3\u6784\u5b9e\u73b0\u7684\u9ad8\u6548\u6392\u5e8f\u7b97\u6cd5\u3002\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u5df2\u7ecf\u5b66\u8fc7\u7684\u201c\u5efa\u5806\u64cd\u4f5c\u201d\u548c\u201c\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\u201d\u5b9e\u73b0\u5806\u6392\u5e8f\u3002

    1. \u8f93\u5165\u6570\u7ec4\u5e76\u5efa\u7acb\u5c0f\u9876\u5806\uff0c\u6b64\u65f6\u6700\u5c0f\u5143\u7d20\u4f4d\u4e8e\u5806\u9876\u3002
    2. \u4e0d\u65ad\u6267\u884c\u51fa\u5806\u64cd\u4f5c\uff0c\u4f9d\u6b21\u8bb0\u5f55\u51fa\u5806\u5143\u7d20\uff0c\u5373\u53ef\u5f97\u5230\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u7684\u5e8f\u5217\u3002

    \u4ee5\u4e0a\u65b9\u6cd5\u867d\u7136\u53ef\u884c\uff0c\u4f46\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u989d\u5916\u6570\u7ec4\u6765\u4fdd\u5b58\u5f39\u51fa\u7684\u5143\u7d20\uff0c\u6bd4\u8f83\u6d6a\u8d39\u7a7a\u95f4\u3002\u5728\u5b9e\u9645\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f7f\u7528\u4e00\u79cd\u66f4\u52a0\u4f18\u96c5\u7684\u5b9e\u73b0\u65b9\u5f0f\u3002

    "},{"location":"chapter_sorting/heap_sort/#1171","title":"11.7.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u8bbe\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u5806\u6392\u5e8f\u7684\u6d41\u7a0b\u5982\u56fe 11-12 \u6240\u793a\u3002

    1. \u8f93\u5165\u6570\u7ec4\u5e76\u5efa\u7acb\u5927\u9876\u5806\u3002\u5b8c\u6210\u540e\uff0c\u6700\u5927\u5143\u7d20\u4f4d\u4e8e\u5806\u9876\u3002
    2. \u5c06\u5806\u9876\u5143\u7d20\uff08\u7b2c\u4e00\u4e2a\u5143\u7d20\uff09\u4e0e\u5806\u5e95\u5143\u7d20\uff08\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff09\u4ea4\u6362\u3002\u5b8c\u6210\u4ea4\u6362\u540e\uff0c\u5806\u7684\u957f\u5ea6\u51cf \\(1\\) \uff0c\u5df2\u6392\u5e8f\u5143\u7d20\u6570\u91cf\u52a0 \\(1\\) \u3002
    3. \u4ece\u5806\u9876\u5143\u7d20\u5f00\u59cb\uff0c\u4ece\u9876\u5230\u5e95\u6267\u884c\u5806\u5316\u64cd\u4f5c\uff08sift down\uff09\u3002\u5b8c\u6210\u5806\u5316\u540e\uff0c\u5806\u7684\u6027\u8d28\u5f97\u5230\u4fee\u590d\u3002
    4. \u5faa\u73af\u6267\u884c\u7b2c 2. \u6b65\u548c\u7b2c 3. \u6b65\u3002\u5faa\u73af \\(n - 1\\) \u8f6e\u540e\uff0c\u5373\u53ef\u5b8c\u6210\u6570\u7ec4\u6392\u5e8f\u3002

    Tip

    \u5b9e\u9645\u4e0a\uff0c\u5143\u7d20\u51fa\u5806\u64cd\u4f5c\u4e2d\u4e5f\u5305\u542b\u7b2c 2. \u6b65\u548c\u7b2c 3. \u6b65\uff0c\u53ea\u662f\u591a\u4e86\u4e00\u4e2a\u5f39\u51fa\u5143\u7d20\u7684\u6b65\u9aa4\u3002

    <1><2><3><4><5><6><7><8><9><10><11><12>

    \u56fe 11-12 \u00a0 \u5806\u6392\u5e8f\u6b65\u9aa4

    \u5728\u4ee3\u7801\u5b9e\u73b0\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e86\u4e0e\u201c\u5806\u201d\u7ae0\u8282\u76f8\u540c\u7684\u4ece\u9876\u81f3\u5e95\u5806\u5316 sift_down() \u51fd\u6570\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u7531\u4e8e\u5806\u7684\u957f\u5ea6\u4f1a\u968f\u7740\u63d0\u53d6\u6700\u5927\u5143\u7d20\u800c\u51cf\u5c0f\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u7ed9 sift_down() \u51fd\u6570\u6dfb\u52a0\u4e00\u4e2a\u957f\u5ea6\u53c2\u6570 \\(n\\) \uff0c\u7528\u4e8e\u6307\u5b9a\u5806\u7684\u5f53\u524d\u6709\u6548\u957f\u5ea6\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig heap_sort.py
    def sift_down(nums: list[int], n: int, i: int):\n    \"\"\"\u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316\"\"\"\n    while True:\n        # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l = 2 * i + 1\n        r = 2 * i + 2\n        ma = i\n        if l < n and nums[l] > nums[ma]:\n            ma = l\n        if r < n and nums[r] > nums[ma]:\n            ma = r\n        # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i:\n            break\n        # \u4ea4\u6362\u4e24\u8282\u70b9\n        nums[i], nums[ma] = nums[ma], nums[i]\n        # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n\ndef heap_sort(nums: list[int]):\n    \"\"\"\u5806\u6392\u5e8f\"\"\"\n    # \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in range(len(nums) // 2 - 1, -1, -1):\n        sift_down(nums, len(nums), i)\n    # \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in range(len(nums) - 1, 0, -1):\n        # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        nums[0], nums[i] = nums[i], nums[0]\n        # \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        sift_down(nums, i, 0)\n
    heap_sort.cpp
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(vector<int> &nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        swap(nums[i], nums[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(vector<int> &nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.size() / 2 - 1; i >= 0; --i) {\n        siftDown(nums, nums.size(), i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.size() - 1; i > 0; --i) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        swap(nums[0], nums[i]);\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.java
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int[] nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        int temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(int[] nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.length / 2 - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        int tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.cs
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid SiftDown(int[] nums, int n, int i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i)\n            break;\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        (nums[ma], nums[i]) = (nums[i], nums[ma]);\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid HeapSort(int[] nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = nums.Length / 2 - 1; i >= 0; i--) {\n        SiftDown(nums, nums.Length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = nums.Length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        (nums[i], nums[0]) = (nums[0], nums[i]);\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        SiftDown(nums, i, 0);\n    }\n}\n
    heap_sort.go
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(nums *[]int, n, i int) {\n    for true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        l := 2*i + 1\n        r := 2*i + 2\n        ma := i\n        if l < n && (*nums)[l] > (*nums)[ma] {\n            ma = l\n        }\n        if r < n && (*nums)[r] > (*nums)[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        (*nums)[i], (*nums)[ma] = (*nums)[ma], (*nums)[i]\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunc heapSort(nums *[]int) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i := len(*nums)/2 - 1; i >= 0; i-- {\n        siftDown(nums, len(*nums), i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i := len(*nums) - 1; i > 0; i-- {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        (*nums)[0], (*nums)[i] = (*nums)[i], (*nums)[0]\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0)\n    }\n}\n
    heap_sort.swift
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunc siftDown(nums: inout [Int], n: Int, i: Int) {\n    var i = i\n    while true {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1\n        let r = 2 * i + 2\n        var ma = i\n        if l < n, nums[l] > nums[ma] {\n            ma = l\n        }\n        if r < n, nums[r] > nums[ma] {\n            ma = r\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        nums.swapAt(i, ma)\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunc heapSort(nums: inout [Int]) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in stride(from: nums.count / 2 - 1, through: 0, by: -1) {\n        siftDown(nums: &nums, n: nums.count, i: i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in nums.indices.dropFirst().reversed() {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        nums.swapAt(0, i)\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums: &nums, n: i, i: 0)\n    }\n}\n
    heap_sort.js
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunction siftDown(nums, n, i) {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let ma = i;\n        if (l < n && nums[l] > nums[ma]) {\n            ma = l;\n        }\n        if (r < n && nums[r] > nums[ma]) {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        [nums[i], nums[ma]] = [nums[ma], nums[i]];\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunction heapSort(nums) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        [nums[0], nums[i]] = [nums[i], nums[0]];\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.ts
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfunction siftDown(nums: number[], n: number, i: number): void {\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let ma = i;\n        if (l < n && nums[l] > nums[ma]) {\n            ma = l;\n        }\n        if (r < n && nums[r] > nums[ma]) {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma === i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        [nums[i], nums[ma]] = [nums[ma], nums[i]];\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfunction heapSort(nums: number[]): void {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {\n        siftDown(nums, nums.length, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (let i = nums.length - 1; i > 0; i--) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        [nums[0], nums[i]] = [nums[i], nums[0]];\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.dart
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(List<int> nums, int n, int i) {\n  while (true) {\n    // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    int l = 2 * i + 1;\n    int r = 2 * i + 2;\n    int ma = i;\n    if (l < n && nums[l] > nums[ma]) ma = l;\n    if (r < n && nums[r] > nums[ma]) ma = r;\n    // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    if (ma == i) break;\n    // \u4ea4\u6362\u4e24\u8282\u70b9\n    int temp = nums[i];\n    nums[i] = nums[ma];\n    nums[ma] = temp;\n    // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma;\n  }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(List<int> nums) {\n  // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  for (int i = nums.length ~/ 2 - 1; i >= 0; i--) {\n    siftDown(nums, nums.length, i);\n  }\n  // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n  for (int i = nums.length - 1; i > 0; i--) {\n    // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    int tmp = nums[0];\n    nums[0] = nums[i];\n    nums[i] = tmp;\n    // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n    siftDown(nums, i, 0);\n  }\n}\n
    heap_sort.rs
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfn sift_down(nums: &mut [i32], n: usize, mut i: usize) {\n    loop {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        let l = 2 * i + 1;\n        let r = 2 * i + 2;\n        let mut ma = i;\n        if l < n && nums[l] > nums[ma] {\n            ma = l;\n        }\n        if r < n && nums[r] > nums[ma] {\n            ma = r;\n        }\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if ma == i {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        let temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfn heap_sort(nums: &mut [i32]) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for i in (0..=nums.len() / 2 - 1).rev() {\n        sift_down(nums, nums.len(), i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for i in (1..=nums.len() - 1).rev() {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        let tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        sift_down(nums, i, 0);\n    }\n}\n
    heap_sort.c
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nvoid siftDown(int nums[], int n, int i) {\n    while (1) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        int l = 2 * i + 1;\n        int r = 2 * i + 2;\n        int ma = i;\n        if (l < n && nums[l] > nums[ma])\n            ma = l;\n        if (r < n && nums[r] > nums[ma])\n            ma = r;\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) {\n            break;\n        }\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        int temp = nums[i];\n        nums[i] = nums[ma];\n        nums[ma] = temp;\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma;\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nvoid heapSort(int nums[], int n) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (int i = n / 2 - 1; i >= 0; --i) {\n        siftDown(nums, n, i);\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (int i = n - 1; i > 0; --i) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        int tmp = nums[0];\n        nums[0] = nums[i];\n        nums[i] = tmp;\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0);\n    }\n}\n
    heap_sort.kt
    /* \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 */\nfun siftDown(nums: IntArray, n: Int, li: Int) {\n    var i = li\n    while (true) {\n        // \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n        val l = 2 * i + 1\n        val r = 2 * i + 2\n        var ma = i\n        if (l < n && nums[l] > nums[ma]) \n            ma = l\n        if (r < n && nums[r] > nums[ma]) \n            ma = r\n        // \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n        if (ma == i) \n            break\n        // \u4ea4\u6362\u4e24\u8282\u70b9\n        val temp = nums[i]\n        nums[i] = nums[ma]\n        nums[ma] = temp\n        // \u5faa\u73af\u5411\u4e0b\u5806\u5316\n        i = ma\n    }\n}\n\n/* \u5806\u6392\u5e8f */\nfun heapSort(nums: IntArray) {\n    // \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n    for (i in nums.size / 2 - 1 downTo 0) {\n        siftDown(nums, nums.size, i)\n    }\n    // \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n    for (i in nums.size - 1 downTo 1) {\n        // \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n        val temp = nums[0]\n        nums[0] = nums[i]\n        nums[i] = temp\n        // \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n        siftDown(nums, i, 0)\n    }\n}\n
    heap_sort.rb
    ### \u5806\u7684\u957f\u5ea6\u4e3a n \uff0c\u4ece\u8282\u70b9 i \u5f00\u59cb\uff0c\u4ece\u9876\u81f3\u5e95\u5806\u5316 ###\ndef sift_down(nums, n, i)\n  while true\n    # \u5224\u65ad\u8282\u70b9 i, l, r \u4e2d\u503c\u6700\u5927\u7684\u8282\u70b9\uff0c\u8bb0\u4e3a ma\n    l = 2 * i + 1\n    r = 2 * i + 2\n    ma = i\n    ma = l if l < n && nums[l] > nums[ma]\n    ma = r if r < n && nums[r] > nums[ma]\n    # \u82e5\u8282\u70b9 i \u6700\u5927\u6216\u7d22\u5f15 l, r \u8d8a\u754c\uff0c\u5219\u65e0\u987b\u7ee7\u7eed\u5806\u5316\uff0c\u8df3\u51fa\n    break if ma == i\n    # \u4ea4\u6362\u4e24\u8282\u70b9\n    nums[i], nums[ma] = nums[ma], nums[i]\n    # \u5faa\u73af\u5411\u4e0b\u5806\u5316\n    i = ma\n  end\nend\n\n### \u5806\u6392\u5e8f ###\ndef heap_sort(nums)\n  # \u5efa\u5806\u64cd\u4f5c\uff1a\u5806\u5316\u9664\u53f6\u8282\u70b9\u4ee5\u5916\u7684\u5176\u4ed6\u6240\u6709\u8282\u70b9\n  (nums.length / 2 - 1).downto(0) do |i|\n    sift_down(nums, nums.length, i)\n  end\n  # \u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\uff0c\u5faa\u73af n-1 \u8f6e\n  (nums.length - 1).downto(1) do |i|\n    # \u4ea4\u6362\u6839\u8282\u70b9\u4e0e\u6700\u53f3\u53f6\u8282\u70b9\uff08\u4ea4\u6362\u9996\u5143\u7d20\u4e0e\u5c3e\u5143\u7d20\uff09\n    nums[0], nums[i] = nums[i], nums[0]\n    # \u4ee5\u6839\u8282\u70b9\u4e3a\u8d77\u70b9\uff0c\u4ece\u9876\u81f3\u5e95\u8fdb\u884c\u5806\u5316\n    sift_down(nums, i, 0)\n  end\nend\n
    heap_sort.zig
    [class]{}-[func]{siftDown}\n\n[class]{}-[func]{heapSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/heap_sort/#1172","title":"11.7.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5efa\u5806\u64cd\u4f5c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002\u4ece\u5806\u4e2d\u63d0\u53d6\u6700\u5927\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(\\log n)\\) \uff0c\u5171\u5faa\u73af \\(n - 1\\) \u8f6e\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u51e0\u4e2a\u6307\u9488\u53d8\u91cf\u4f7f\u7528 \\(O(1)\\) \u7a7a\u95f4\u3002\u5143\u7d20\u4ea4\u6362\u548c\u5806\u5316\u64cd\u4f5c\u90fd\u662f\u5728\u539f\u6570\u7ec4\u4e0a\u8fdb\u884c\u7684\u3002
    • \u975e\u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u4ea4\u6362\u5806\u9876\u5143\u7d20\u548c\u5806\u5e95\u5143\u7d20\u65f6\uff0c\u76f8\u7b49\u5143\u7d20\u7684\u76f8\u5bf9\u4f4d\u7f6e\u53ef\u80fd\u53d1\u751f\u53d8\u5316\u3002
    "},{"location":"chapter_sorting/insertion_sort/","title":"11.4 \u00a0 \u63d2\u5165\u6392\u5e8f","text":"

    \u63d2\u5165\u6392\u5e8f\uff08insertion sort\uff09\u662f\u4e00\u79cd\u7b80\u5355\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5b83\u7684\u5de5\u4f5c\u539f\u7406\u4e0e\u624b\u52a8\u6574\u7406\u4e00\u526f\u724c\u7684\u8fc7\u7a0b\u975e\u5e38\u76f8\u4f3c\u3002

    \u5177\u4f53\u6765\u8bf4\uff0c\u6211\u4eec\u5728\u672a\u6392\u5e8f\u533a\u95f4\u9009\u62e9\u4e00\u4e2a\u57fa\u51c6\u5143\u7d20\uff0c\u5c06\u8be5\u5143\u7d20\u4e0e\u5176\u5de6\u4fa7\u5df2\u6392\u5e8f\u533a\u95f4\u7684\u5143\u7d20\u9010\u4e00\u6bd4\u8f83\u5927\u5c0f\uff0c\u5e76\u5c06\u8be5\u5143\u7d20\u63d2\u5165\u5230\u6b63\u786e\u7684\u4f4d\u7f6e\u3002

    \u56fe 11-6 \u5c55\u793a\u4e86\u6570\u7ec4\u63d2\u5165\u5143\u7d20\u7684\u64cd\u4f5c\u6d41\u7a0b\u3002\u8bbe\u57fa\u51c6\u5143\u7d20\u4e3a base \uff0c\u6211\u4eec\u9700\u8981\u5c06\u4ece\u76ee\u6807\u7d22\u5f15\u5230 base \u4e4b\u95f4\u7684\u6240\u6709\u5143\u7d20\u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\uff0c\u7136\u540e\u5c06 base \u8d4b\u503c\u7ed9\u76ee\u6807\u7d22\u5f15\u3002

    \u56fe 11-6 \u00a0 \u5355\u6b21\u63d2\u5165\u64cd\u4f5c

    "},{"location":"chapter_sorting/insertion_sort/#1141","title":"11.4.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u63d2\u5165\u6392\u5e8f\u7684\u6574\u4f53\u6d41\u7a0b\u5982\u56fe 11-7 \u6240\u793a\u3002

    1. \u521d\u59cb\u72b6\u6001\u4e0b\uff0c\u6570\u7ec4\u7684\u7b2c 1 \u4e2a\u5143\u7d20\u5df2\u5b8c\u6210\u6392\u5e8f\u3002
    2. \u9009\u53d6\u6570\u7ec4\u7684\u7b2c 2 \u4e2a\u5143\u7d20\u4f5c\u4e3a base \uff0c\u5c06\u5176\u63d2\u5165\u5230\u6b63\u786e\u4f4d\u7f6e\u540e\uff0c\u6570\u7ec4\u7684\u524d 2 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    3. \u9009\u53d6\u7b2c 3 \u4e2a\u5143\u7d20\u4f5c\u4e3a base \uff0c\u5c06\u5176\u63d2\u5165\u5230\u6b63\u786e\u4f4d\u7f6e\u540e\uff0c\u6570\u7ec4\u7684\u524d 3 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    4. \u4ee5\u6b64\u7c7b\u63a8\uff0c\u5728\u6700\u540e\u4e00\u8f6e\u4e2d\uff0c\u9009\u53d6\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a base \uff0c\u5c06\u5176\u63d2\u5165\u5230\u6b63\u786e\u4f4d\u7f6e\u540e\uff0c\u6240\u6709\u5143\u7d20\u5747\u5df2\u6392\u5e8f\u3002

    \u56fe 11-7 \u00a0 \u63d2\u5165\u6392\u5e8f\u6d41\u7a0b

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig insertion_sort.py
    def insertion_sort(nums: list[int]):\n    \"\"\"\u63d2\u5165\u6392\u5e8f\"\"\"\n    # \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in range(1, len(nums)):\n        base = nums[i]\n        j = i - 1\n        # \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0 and nums[j] > base:\n            nums[j + 1] = nums[j]  # \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1\n        nums[j + 1] = base  # \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n
    insertion_sort.cpp
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(vector<int> &nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.size(); i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.java
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.length; i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base;        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.cs
    /* \u63d2\u5165\u6392\u5e8f */\nvoid InsertionSort(int[] nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < nums.Length; i++) {\n        int bas = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > bas) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = bas;         // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.go
    /* \u63d2\u5165\u6392\u5e8f */\nfunc insertionSort(nums []int) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i := 1; i < len(nums); i++ {\n        base := nums[i]\n        j := i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        for j >= 0 && nums[j] > base {\n            nums[j+1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--\n        }\n        nums[j+1] = base // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.swift
    /* \u63d2\u5165\u6392\u5e8f */\nfunc insertionSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in nums.indices.dropFirst() {\n        let base = nums[i]\n        var j = i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0, nums[j] > base {\n            nums[j + 1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1\n        }\n        nums[j + 1] = base // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.js
    /* \u63d2\u5165\u6392\u5e8f */\nfunction insertionSort(nums) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (let i = 1; i < nums.length; i++) {\n        let base = nums[i],\n            j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.ts
    /* \u63d2\u5165\u6392\u5e8f */\nfunction insertionSort(nums: number[]): void {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (let i = 1; i < nums.length; i++) {\n        const base = nums[i];\n        let j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--;\n        }\n        nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.dart
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(List<int> nums) {\n  // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n  for (int i = 1; i < nums.length; i++) {\n    int base = nums[i], j = i - 1;\n    // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n    while (j >= 0 && nums[j] > base) {\n      nums[j + 1] = nums[j]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n      j--;\n    }\n    nums[j + 1] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n  }\n}\n
    insertion_sort.rs
    /* \u63d2\u5165\u6392\u5e8f */\nfn insertion_sort(nums: &mut [i32]) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for i in 1..nums.len() {\n        let (base, mut j) = (nums[i], (i - 1) as i32);\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while j >= 0 && nums[j as usize] > base {\n            nums[(j + 1) as usize] = nums[j as usize]; // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j -= 1;\n        }\n        nums[(j + 1) as usize] = base; // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.c
    /* \u63d2\u5165\u6392\u5e8f */\nvoid insertionSort(int nums[], int size) {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    for (int i = 1; i < size; i++) {\n        int base = nums[i], j = i - 1;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            nums[j + 1] = nums[j];\n            j--;\n        }\n        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n        nums[j + 1] = base;\n    }\n}\n
    insertion_sort.kt
    /* \u63d2\u5165\u6392\u5e8f */\nfun insertionSort(nums: IntArray) {\n    //\u5916\u5faa\u73af: \u5df2\u6392\u5e8f\u5143\u7d20\u4e3a 1, 2, ..., n\n    for (i in nums.indices) {\n        val base = nums[i]\n        var j = i - 1\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 0 && nums[j] > base) {\n            nums[j + 1] = nums[j] // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n            j--\n        }\n        nums[j + 1] = base        // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    insertion_sort.rb
    ### \u63d2\u5165\u6392\u5e8f ###\ndef insertion_sort(nums)\n  n = nums.length\n  # \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n  for i in 1...n\n    base = nums[i]\n    j = i - 1\n    # \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n    while j >= 0 && nums[j] > base\n      nums[j + 1] = nums[j] # \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n      j -= 1\n    end\n    nums[j + 1] = base # \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n  end\nend\n
    insertion_sort.zig
    // \u63d2\u5165\u6392\u5e8f\nfn insertionSort(nums: []i32) void {\n    // \u5916\u5faa\u73af\uff1a\u5df2\u6392\u5e8f\u533a\u95f4\u4e3a [0, i-1]\n    var i: usize = 1;\n    while (i < nums.len) : (i += 1) {\n        var base = nums[i];\n        var j: usize = i;\n        // \u5185\u5faa\u73af\uff1a\u5c06 base \u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4 [0, i-1] \u4e2d\u7684\u6b63\u786e\u4f4d\u7f6e\n        while (j >= 1 and nums[j - 1] > base) : (j -= 1) {\n            nums[j] = nums[j - 1];  // \u5c06 nums[j] \u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n        }\n        nums[j] = base;             // \u5c06 base \u8d4b\u503c\u5230\u6b63\u786e\u4f4d\u7f6e\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/insertion_sort/#1142","title":"11.4.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\u3001\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u63d2\u5165\u64cd\u4f5c\u5206\u522b\u9700\u8981\u5faa\u73af \\(n - 1\\)\u3001\\(n-2\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \u6b21\uff0c\u6c42\u548c\u5f97\u5230 \\((n - 1) n / 2\\) \uff0c\u56e0\u6b64\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002\u5728\u9047\u5230\u6709\u5e8f\u6570\u636e\u65f6\uff0c\u63d2\u5165\u64cd\u4f5c\u4f1a\u63d0\u524d\u7ec8\u6b62\u3002\u5f53\u8f93\u5165\u6570\u7ec4\u5b8c\u5168\u6709\u5e8f\u65f6\uff0c\u63d2\u5165\u6392\u5e8f\u8fbe\u5230\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u63d2\u5165\u64cd\u4f5c\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u4f1a\u5c06\u5143\u7d20\u63d2\u5165\u5230\u76f8\u7b49\u5143\u7d20\u7684\u53f3\u4fa7\uff0c\u4e0d\u4f1a\u6539\u53d8\u5b83\u4eec\u7684\u987a\u5e8f\u3002
    "},{"location":"chapter_sorting/insertion_sort/#1143","title":"11.4.3 \u00a0 \u63d2\u5165\u6392\u5e8f\u7684\u4f18\u52bf","text":"

    \u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u800c\u6211\u4eec\u5373\u5c06\u5b66\u4e60\u7684\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002\u5c3d\u7ba1\u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u66f4\u9ad8\uff0c\u4f46\u5728\u6570\u636e\u91cf\u8f83\u5c0f\u7684\u60c5\u51b5\u4e0b\uff0c\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u66f4\u5feb\u3002

    \u8fd9\u4e2a\u7ed3\u8bba\u4e0e\u7ebf\u6027\u67e5\u627e\u548c\u4e8c\u5206\u67e5\u627e\u7684\u9002\u7528\u60c5\u51b5\u7684\u7ed3\u8bba\u7c7b\u4f3c\u3002\u5feb\u901f\u6392\u5e8f\u8fd9\u7c7b \\(O(n \\log n)\\) \u7684\u7b97\u6cd5\u5c5e\u4e8e\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5f80\u5f80\u5305\u542b\u66f4\u591a\u5355\u5143\u8ba1\u7b97\u64cd\u4f5c\u3002\u800c\u5728\u6570\u636e\u91cf\u8f83\u5c0f\u65f6\uff0c\\(n^2\\) \u548c \\(n \\log n\\) \u7684\u6570\u503c\u6bd4\u8f83\u63a5\u8fd1\uff0c\u590d\u6742\u5ea6\u4e0d\u5360\u4e3b\u5bfc\u5730\u4f4d\uff0c\u6bcf\u8f6e\u4e2d\u7684\u5355\u5143\u64cd\u4f5c\u6570\u91cf\u8d77\u5230\u51b3\u5b9a\u6027\u4f5c\u7528\u3002

    \u5b9e\u9645\u4e0a\uff0c\u8bb8\u591a\u7f16\u7a0b\u8bed\u8a00\uff08\u4f8b\u5982 Java\uff09\u7684\u5185\u7f6e\u6392\u5e8f\u51fd\u6570\u91c7\u7528\u4e86\u63d2\u5165\u6392\u5e8f\uff0c\u5927\u81f4\u601d\u8def\u4e3a\uff1a\u5bf9\u4e8e\u957f\u6570\u7ec4\uff0c\u91c7\u7528\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u4f8b\u5982\u5feb\u901f\u6392\u5e8f\uff1b\u5bf9\u4e8e\u77ed\u6570\u7ec4\uff0c\u76f4\u63a5\u4f7f\u7528\u63d2\u5165\u6392\u5e8f\u3002

    \u867d\u7136\u5192\u6ce1\u6392\u5e8f\u3001\u9009\u62e9\u6392\u5e8f\u548c\u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n^2)\\) \uff0c\u4f46\u5728\u5b9e\u9645\u60c5\u51b5\u4e2d\uff0c\u63d2\u5165\u6392\u5e8f\u7684\u4f7f\u7528\u9891\u7387\u663e\u8457\u9ad8\u4e8e\u5192\u6ce1\u6392\u5e8f\u548c\u9009\u62e9\u6392\u5e8f\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u5192\u6ce1\u6392\u5e8f\u57fa\u4e8e\u5143\u7d20\u4ea4\u6362\u5b9e\u73b0\uff0c\u9700\u8981\u501f\u52a9\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cf\uff0c\u5171\u6d89\u53ca 3 \u4e2a\u5355\u5143\u64cd\u4f5c\uff1b\u63d2\u5165\u6392\u5e8f\u57fa\u4e8e\u5143\u7d20\u8d4b\u503c\u5b9e\u73b0\uff0c\u4ec5\u9700 1 \u4e2a\u5355\u5143\u64cd\u4f5c\u3002\u56e0\u6b64\uff0c\u5192\u6ce1\u6392\u5e8f\u7684\u8ba1\u7b97\u5f00\u9500\u901a\u5e38\u6bd4\u63d2\u5165\u6392\u5e8f\u66f4\u9ad8\u3002
    • \u9009\u62e9\u6392\u5e8f\u5728\u4efb\u4f55\u60c5\u51b5\u4e0b\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(n^2)\\) \u3002\u5982\u679c\u7ed9\u5b9a\u4e00\u7ec4\u90e8\u5206\u6709\u5e8f\u7684\u6570\u636e\uff0c\u63d2\u5165\u6392\u5e8f\u901a\u5e38\u6bd4\u9009\u62e9\u6392\u5e8f\u6548\u7387\u66f4\u9ad8\u3002
    • \u9009\u62e9\u6392\u5e8f\u4e0d\u7a33\u5b9a\uff0c\u65e0\u6cd5\u5e94\u7528\u4e8e\u591a\u7ea7\u6392\u5e8f\u3002
    "},{"location":"chapter_sorting/merge_sort/","title":"11.6 \u00a0 \u5f52\u5e76\u6392\u5e8f","text":"

    \u5f52\u5e76\u6392\u5e8f\uff08merge sort\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5305\u542b\u56fe 11-10 \u6240\u793a\u7684\u201c\u5212\u5206\u201d\u548c\u201c\u5408\u5e76\u201d\u9636\u6bb5\u3002

    1. \u5212\u5206\u9636\u6bb5\uff1a\u901a\u8fc7\u9012\u5f52\u4e0d\u65ad\u5730\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5904\u5206\u5f00\uff0c\u5c06\u957f\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u8f6c\u6362\u4e3a\u77ed\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u3002
    2. \u5408\u5e76\u9636\u6bb5\uff1a\u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u5212\u5206\uff0c\u5f00\u59cb\u5408\u5e76\uff0c\u6301\u7eed\u5730\u5c06\u5de6\u53f3\u4e24\u4e2a\u8f83\u77ed\u7684\u6709\u5e8f\u6570\u7ec4\u5408\u5e76\u4e3a\u4e00\u4e2a\u8f83\u957f\u7684\u6709\u5e8f\u6570\u7ec4\uff0c\u76f4\u81f3\u7ed3\u675f\u3002

    \u56fe 11-10 \u00a0 \u5f52\u5e76\u6392\u5e8f\u7684\u5212\u5206\u4e0e\u5408\u5e76\u9636\u6bb5

    "},{"location":"chapter_sorting/merge_sort/#1161","title":"11.6.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u5982\u56fe 11-11 \u6240\u793a\uff0c\u201c\u5212\u5206\u9636\u6bb5\u201d\u4ece\u9876\u81f3\u5e95\u9012\u5f52\u5730\u5c06\u6570\u7ec4\u4ece\u4e2d\u70b9\u5207\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\u3002

    1. \u8ba1\u7b97\u6570\u7ec4\u4e2d\u70b9 mid \uff0c\u9012\u5f52\u5212\u5206\u5de6\u5b50\u6570\u7ec4\uff08\u533a\u95f4 [left, mid] \uff09\u548c\u53f3\u5b50\u6570\u7ec4\uff08\u533a\u95f4 [mid + 1, right] \uff09\u3002
    2. \u9012\u5f52\u6267\u884c\u6b65\u9aa4 1. \uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u533a\u95f4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u3002

    \u201c\u5408\u5e76\u9636\u6bb5\u201d\u4ece\u5e95\u81f3\u9876\u5730\u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u5408\u5e76\u4e3a\u4e00\u4e2a\u6709\u5e8f\u6570\u7ec4\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4ece\u957f\u5ea6\u4e3a 1 \u7684\u5b50\u6570\u7ec4\u5f00\u59cb\u5408\u5e76\uff0c\u5408\u5e76\u9636\u6bb5\u4e2d\u7684\u6bcf\u4e2a\u5b50\u6570\u7ec4\u90fd\u662f\u6709\u5e8f\u7684\u3002

    <1><2><3><4><5><6><7><8><9><10>

    \u56fe 11-11 \u00a0 \u5f52\u5e76\u6392\u5e8f\u6b65\u9aa4

    \u89c2\u5bdf\u53d1\u73b0\uff0c\u5f52\u5e76\u6392\u5e8f\u4e0e\u4e8c\u53c9\u6811\u540e\u5e8f\u904d\u5386\u7684\u9012\u5f52\u987a\u5e8f\u662f\u4e00\u81f4\u7684\u3002

    • \u540e\u5e8f\u904d\u5386\uff1a\u5148\u9012\u5f52\u5de6\u5b50\u6811\uff0c\u518d\u9012\u5f52\u53f3\u5b50\u6811\uff0c\u6700\u540e\u5904\u7406\u6839\u8282\u70b9\u3002
    • \u5f52\u5e76\u6392\u5e8f\uff1a\u5148\u9012\u5f52\u5de6\u5b50\u6570\u7ec4\uff0c\u518d\u9012\u5f52\u53f3\u5b50\u6570\u7ec4\uff0c\u6700\u540e\u5904\u7406\u5408\u5e76\u3002

    \u5f52\u5e76\u6392\u5e8f\u7684\u5b9e\u73b0\u5982\u4ee5\u4e0b\u4ee3\u7801\u6240\u793a\u3002\u8bf7\u6ce8\u610f\uff0cnums \u7684\u5f85\u5408\u5e76\u533a\u95f4\u4e3a [left, right] \uff0c\u800c tmp \u7684\u5bf9\u5e94\u533a\u95f4\u4e3a [0, right - left] \u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig merge_sort.py
    def merge(nums: list[int], left: int, mid: int, right: int):\n    \"\"\"\u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\"\"\"\n    # \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    # \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    tmp = [0] * (right - left + 1)\n    # \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    i, j, k = left, mid + 1, 0\n    # \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid and j <= right:\n        if nums[i] <= nums[j]:\n            tmp[k] = nums[i]\n            i += 1\n        else:\n            tmp[k] = nums[j]\n            j += 1\n        k += 1\n    # \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid:\n        tmp[k] = nums[i]\n        i += 1\n        k += 1\n    while j <= right:\n        tmp[k] = nums[j]\n        j += 1\n        k += 1\n    # \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in range(0, len(tmp)):\n        nums[left + k] = tmp[k]\n\ndef merge_sort(nums: list[int], left: int, right: int):\n    \"\"\"\u5f52\u5e76\u6392\u5e8f\"\"\"\n    # \u7ec8\u6b62\u6761\u4ef6\n    if left >= right:\n        return  # \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    # \u5212\u5206\u9636\u6bb5\n    mid = (left + right) // 2  # \u8ba1\u7b97\u4e2d\u70b9\n    merge_sort(nums, left, mid)  # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    merge_sort(nums, mid + 1, right)  # \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    # \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n
    merge_sort.cpp
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(vector<int> &nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    vector<int> tmp(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.size(); k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(vector<int> &nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.java
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(int[] nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int[] tmp = new int[right - left + 1];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(int[] nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2; // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.cs
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid Merge(int[] nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int[] tmp = new int[right - left + 1];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++];\n        else\n            tmp[k++] = nums[j++];\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.Length; ++k) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid MergeSort(int[] nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return;       // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    MergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    MergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    Merge(nums, left, mid, right);\n}\n
    merge_sort.go
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunc merge(nums []int, left, mid, right int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    tmp := make([]int, right-left+1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    i, j, k := left, mid+1, 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    for i <= mid && j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i]\n            i++\n        } else {\n            tmp[k] = nums[j]\n            j++\n        }\n        k++\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    for i <= mid {\n        tmp[k] = nums[i]\n        i++\n        k++\n    }\n    for j <= right {\n        tmp[k] = nums[j]\n        j++\n        k++\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k := 0; k < len(tmp); k++ {\n        nums[left+k] = tmp[k]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunc mergeSort(nums []int, left, right int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right {\n        return\n    }\n    // \u5212\u5206\u9636\u6bb5\n    mid := (left + right) / 2\n    mergeSort(nums, left, mid)\n    mergeSort(nums, mid+1, right)\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n}\n
    merge_sort.swift
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunc merge(nums: inout [Int], left: Int, mid: Int, right: Int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    var tmp = Array(repeating: 0, count: right - left + 1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    var i = left, j = mid + 1, k = 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid, j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i]\n            i += 1\n        } else {\n            tmp[k] = nums[j]\n            j += 1\n        }\n        k += 1\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid {\n        tmp[k] = nums[i]\n        i += 1\n        k += 1\n    }\n    while j <= right {\n        tmp[k] = nums[j]\n        j += 1\n        k += 1\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in tmp.indices {\n        nums[left + k] = tmp[k]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunc mergeSort(nums: inout [Int], left: Int, right: Int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right { // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n        return\n    }\n    // \u5212\u5206\u9636\u6bb5\n    let mid = (left + right) / 2 // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums: &nums, left: left, right: mid) // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums: &nums, left: mid + 1, right: right) // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums: &nums, left: left, mid: mid, right: right)\n}\n
    merge_sort.js
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunction merge(nums, left, mid, right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    const tmp = new Array(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let i = left,\n        j = mid + 1,\n        k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunction mergeSort(nums, left, right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    let mid = Math.floor((left + right) / 2); // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.ts
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfunction merge(nums: number[], left: number, mid: number, right: number): void {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    const tmp = new Array(right - left + 1);\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let i = left,\n        j = mid + 1,\n        k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmp.length; k++) {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfunction mergeSort(nums: number[], left: number, right: number): void {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    let mid = Math.floor((left + right) / 2); // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.dart
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(List<int> nums, int left, int mid, int right) {\n  // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n  // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n  List<int> tmp = List.filled(right - left + 1, 0);\n  // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n  int i = left, j = mid + 1, k = 0;\n  // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while (i <= mid && j <= right) {\n    if (nums[i] <= nums[j])\n      tmp[k++] = nums[i++];\n    else\n      tmp[k++] = nums[j++];\n  }\n  // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while (i <= mid) {\n    tmp[k++] = nums[i++];\n  }\n  while (j <= right) {\n    tmp[k++] = nums[j++];\n  }\n  // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n  for (k = 0; k < tmp.length; k++) {\n    nums[left + k] = tmp[k];\n  }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(List<int> nums, int left, int right) {\n  // \u7ec8\u6b62\u6761\u4ef6\n  if (left >= right) return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  // \u5212\u5206\u9636\u6bb5\n  int mid = (left + right) ~/ 2; // \u8ba1\u7b97\u4e2d\u70b9\n  mergeSort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n  mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n  // \u5408\u5e76\u9636\u6bb5\n  merge(nums, left, mid, right);\n}\n
    merge_sort.rs
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfn merge(nums: &mut [i32], left: usize, mid: usize, right: usize) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    let tmp_size = right - left + 1;\n    let mut tmp = vec![0; tmp_size];\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    let (mut i, mut j, mut k) = (left, mid + 1, 0);\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid && j <= right {\n        if nums[i] <= nums[j] {\n            tmp[k] = nums[i];\n            i += 1;\n        } else {\n            tmp[k] = nums[j];\n            j += 1;\n        }\n        k += 1;\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while i <= mid {\n        tmp[k] = nums[i];\n        k += 1;\n        i += 1;\n    }\n    while j <= right {\n        tmp[k] = nums[j];\n        k += 1;\n        j += 1;\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for k in 0..tmp_size {\n        nums[left + k] = tmp[k];\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfn merge_sort(nums: &mut [i32], left: usize, right: usize) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if left >= right {\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    }\n\n    // \u5212\u5206\u9636\u6bb5\n    let mid = (left + right) / 2; // \u8ba1\u7b97\u4e2d\u70b9\n    merge_sort(nums, left, mid); // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    merge_sort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.c
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nvoid merge(int *nums, int left, int mid, int right) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    int tmpSize = right - left + 1;\n    int *tmp = (int *)malloc(tmpSize * sizeof(int));\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    int i = left, j = mid + 1, k = 0;\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j]) {\n            tmp[k++] = nums[i++];\n        } else {\n            tmp[k++] = nums[j++];\n        }\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++];\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++];\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (k = 0; k < tmpSize; ++k) {\n        nums[left + k] = tmp[k];\n    }\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nvoid mergeSort(int *nums, int left, int right) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right)\n        return; // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    int mid = (left + right) / 2;    // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid);      // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right); // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right);\n}\n
    merge_sort.kt
    /* \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 */\nfun merge(nums: IntArray, left: Int, mid: Int, right: Int) {\n    // \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n    // \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp \uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n    val tmp = IntArray(right - left + 1)\n    // \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n    var i = left\n    var j = mid + 1\n    var k = 0\n    // \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid && j <= right) {\n        if (nums[i] <= nums[j])\n            tmp[k++] = nums[i++]\n        else \n            tmp[k++] = nums[j++]\n    }\n    // \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n    while (i <= mid) {\n        tmp[k++] = nums[i++]\n    }\n    while (j <= right) {\n        tmp[k++] = nums[j++]\n    }\n    // \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n    for (l in tmp.indices) {\n        nums[left + l] = tmp[l]\n    }\n}\n\n/* \u5f52\u5e76\u6392\u5e8f */\nfun mergeSort(nums: IntArray, left: Int, right: Int) {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return  // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    val mid = (left + right) / 2 // \u8ba1\u7b97\u4e2d\u70b9\n    mergeSort(nums, left, mid) // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    mergeSort(nums, mid + 1, right) // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    merge(nums, left, mid, right)\n}\n
    merge_sort.rb
    ### \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4 ###\ndef merge(nums, left, mid, right)\n  # \u5de6\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [left, mid], \u53f3\u5b50\u6570\u7ec4\u533a\u95f4\u4e3a [mid+1, right]\n  # \u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u6570\u7ec4 tmp\uff0c\u7528\u4e8e\u5b58\u653e\u5408\u5e76\u540e\u7684\u7ed3\u679c\n  tmp = Array.new(right - left + 1, 0)\n  # \u521d\u59cb\u5316\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\n  i, j, k = left, mid + 1, 0\n  # \u5f53\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u8fd8\u6709\u5143\u7d20\u65f6\uff0c\u8fdb\u884c\u6bd4\u8f83\u5e76\u5c06\u8f83\u5c0f\u7684\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while i <= mid && j <= right\n    if nums[i] <= nums[j]\n      tmp[k] = nums[i]\n      i += 1\n    else\n      tmp[k] = nums[j]\n      j += 1\n    end\n    k += 1\n  end\n  # \u5c06\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u7684\u5269\u4f59\u5143\u7d20\u590d\u5236\u5230\u4e34\u65f6\u6570\u7ec4\u4e2d\n  while i <= mid\n    tmp[k] = nums[i]\n    i += 1\n    k += 1\n  end\n  while j <= right\n    tmp[k] = nums[j]\n    j += 1\n    k += 1\n  end\n  # \u5c06\u4e34\u65f6\u6570\u7ec4 tmp \u4e2d\u7684\u5143\u7d20\u590d\u5236\u56de\u539f\u6570\u7ec4 nums \u7684\u5bf9\u5e94\u533a\u95f4\n  (0...tmp.length).each do |k|\n    nums[left + k] = tmp[k]\n  end\nend\n\n### \u5f52\u5e76\u6392\u5e8f ###\ndef merge_sort(nums, left, right)\n  # \u7ec8\u6b62\u6761\u4ef6\n  # \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  return if left >= right\n  # \u5212\u5206\u9636\u6bb5\n  mid = (left + right) / 2 # \u8ba1\u7b97\u4e2d\u70b9\n  merge_sort(nums, left, mid) # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n  merge_sort(nums, mid + 1, right) # \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n  # \u5408\u5e76\u9636\u6bb5\n  merge(nums, left, mid, right)\nend\n
    merge_sort.zig
    // \u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\n// \u5de6\u5b50\u6570\u7ec4\u533a\u95f4 [left, mid]\n// \u53f3\u5b50\u6570\u7ec4\u533a\u95f4 [mid + 1, right]\nfn merge(nums: []i32, left: usize, mid: usize, right: usize) !void {\n    // \u521d\u59cb\u5316\u8f85\u52a9\u6570\u7ec4\n    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);\n    defer mem_arena.deinit();\n    const mem_allocator = mem_arena.allocator();\n    var tmp = try mem_allocator.alloc(i32, right + 1 - left);\n    std.mem.copy(i32, tmp, nums[left..right+1]);\n    // \u5de6\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\u548c\u7ed3\u675f\u7d22\u5f15  \n    var leftStart = left - left;\n    var leftEnd = mid - left;\n    // \u53f3\u5b50\u6570\u7ec4\u7684\u8d77\u59cb\u7d22\u5f15\u548c\u7ed3\u675f\u7d22\u5f15       \n    var rightStart = mid + 1 - left;\n    var rightEnd = right - left;\n    // i, j \u5206\u522b\u6307\u5411\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\u7684\u9996\u5143\u7d20\n    var i = leftStart;\n    var j = rightStart;\n    // \u901a\u8fc7\u8986\u76d6\u539f\u6570\u7ec4 nums \u6765\u5408\u5e76\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\n    var k = left;\n    while (k <= right) : (k += 1) {\n        // \u82e5\u201c\u5de6\u5b50\u6570\u7ec4\u5df2\u5168\u90e8\u5408\u5e76\u5b8c\u201d\uff0c\u5219\u9009\u53d6\u53f3\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 j++\n        if (i > leftEnd) {\n            nums[k] = tmp[j];\n            j += 1;\n        // \u5426\u5219\uff0c\u82e5\u201c\u53f3\u5b50\u6570\u7ec4\u5df2\u5168\u90e8\u5408\u5e76\u5b8c\u201d\u6216\u201c\u5de6\u5b50\u6570\u7ec4\u5143\u7d20 <= \u53f3\u5b50\u6570\u7ec4\u5143\u7d20\u201d\uff0c\u5219\u9009\u53d6\u5de6\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 i++\n        } else if  (j > rightEnd or tmp[i] <= tmp[j]) {\n            nums[k] = tmp[i];\n            i += 1;\n        // \u5426\u5219\uff0c\u82e5\u201c\u5de6\u53f3\u5b50\u6570\u7ec4\u90fd\u672a\u5168\u90e8\u5408\u5e76\u5b8c\u201d\u4e14\u201c\u5de6\u5b50\u6570\u7ec4\u5143\u7d20 > \u53f3\u5b50\u6570\u7ec4\u5143\u7d20\u201d\uff0c\u5219\u9009\u53d6\u53f3\u5b50\u6570\u7ec4\u5143\u7d20\uff0c\u5e76\u4e14 j++\n        } else {\n            nums[k] = tmp[j];\n            j += 1;\n        }\n    }\n}\n\n// \u5f52\u5e76\u6392\u5e8f\nfn mergeSort(nums: []i32, left: usize, right: usize) !void {\n    // \u7ec8\u6b62\u6761\u4ef6\n    if (left >= right) return;              // \u5f53\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    // \u5212\u5206\u9636\u6bb5\n    var mid = (left + right) / 2;           // \u8ba1\u7b97\u4e2d\u70b9\n    try mergeSort(nums, left, mid);         // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\n    try mergeSort(nums, mid + 1, right);    // \u9012\u5f52\u53f3\u5b50\u6570\u7ec4\n    // \u5408\u5e76\u9636\u6bb5\n    try merge(nums, left, mid, right);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/merge_sort/#1162","title":"11.6.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5212\u5206\u4ea7\u751f\u9ad8\u5ea6\u4e3a \\(\\log n\\) \u7684\u9012\u5f52\u6811\uff0c\u6bcf\u5c42\u5408\u5e76\u7684\u603b\u64cd\u4f5c\u6570\u91cf\u4e3a \\(n\\) \uff0c\u56e0\u6b64\u603b\u4f53\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u9012\u5f52\u6df1\u5ea6\u4e3a \\(\\log n\\) \uff0c\u4f7f\u7528 \\(O(\\log n)\\) \u5927\u5c0f\u7684\u6808\u5e27\u7a7a\u95f4\u3002\u5408\u5e76\u64cd\u4f5c\u9700\u8981\u501f\u52a9\u8f85\u52a9\u6570\u7ec4\u5b9e\u73b0\uff0c\u4f7f\u7528 \\(O(n)\\) \u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u5408\u5e76\u8fc7\u7a0b\u4e2d\uff0c\u76f8\u7b49\u5143\u7d20\u7684\u6b21\u5e8f\u4fdd\u6301\u4e0d\u53d8\u3002
    "},{"location":"chapter_sorting/merge_sort/#1163","title":"11.6.3 \u00a0 \u94fe\u8868\u6392\u5e8f","text":"

    \u5bf9\u4e8e\u94fe\u8868\uff0c\u5f52\u5e76\u6392\u5e8f\u76f8\u8f83\u4e8e\u5176\u4ed6\u6392\u5e8f\u7b97\u6cd5\u5177\u6709\u663e\u8457\u4f18\u52bf\uff0c\u53ef\u4ee5\u5c06\u94fe\u8868\u6392\u5e8f\u4efb\u52a1\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(1)\\) \u3002

    • \u5212\u5206\u9636\u6bb5\uff1a\u53ef\u4ee5\u4f7f\u7528\u201c\u8fed\u4ee3\u201d\u66ff\u4ee3\u201c\u9012\u5f52\u201d\u6765\u5b9e\u73b0\u94fe\u8868\u5212\u5206\u5de5\u4f5c\uff0c\u4ece\u800c\u7701\u53bb\u9012\u5f52\u4f7f\u7528\u7684\u6808\u5e27\u7a7a\u95f4\u3002
    • \u5408\u5e76\u9636\u6bb5\uff1a\u5728\u94fe\u8868\u4e2d\uff0c\u8282\u70b9\u589e\u5220\u64cd\u4f5c\u4ec5\u9700\u6539\u53d8\u5f15\u7528\uff08\u6307\u9488\uff09\u5373\u53ef\u5b9e\u73b0\uff0c\u56e0\u6b64\u5408\u5e76\u9636\u6bb5\uff08\u5c06\u4e24\u4e2a\u77ed\u6709\u5e8f\u94fe\u8868\u5408\u5e76\u4e3a\u4e00\u4e2a\u957f\u6709\u5e8f\u94fe\u8868\uff09\u65e0\u987b\u521b\u5efa\u989d\u5916\u94fe\u8868\u3002

    \u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u6bd4\u8f83\u590d\u6742\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u67e5\u9605\u76f8\u5173\u8d44\u6599\u8fdb\u884c\u5b66\u4e60\u3002

    "},{"location":"chapter_sorting/quick_sort/","title":"11.5 \u00a0 \u5feb\u901f\u6392\u5e8f","text":"

    \u5feb\u901f\u6392\u5e8f\uff08quick sort\uff09\u662f\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b56\u7565\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u8fd0\u884c\u9ad8\u6548\uff0c\u5e94\u7528\u5e7f\u6cdb\u3002

    \u5feb\u901f\u6392\u5e8f\u7684\u6838\u5fc3\u64cd\u4f5c\u662f\u201c\u54e8\u5175\u5212\u5206\u201d\uff0c\u5176\u76ee\u6807\u662f\uff1a\u9009\u62e9\u6570\u7ec4\u4e2d\u7684\u67d0\u4e2a\u5143\u7d20\u4f5c\u4e3a\u201c\u57fa\u51c6\u6570\u201d\uff0c\u5c06\u6240\u6709\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\u79fb\u5230\u5176\u5de6\u4fa7\uff0c\u800c\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\u79fb\u5230\u5176\u53f3\u4fa7\u3002\u5177\u4f53\u6765\u8bf4\uff0c\u54e8\u5175\u5212\u5206\u7684\u6d41\u7a0b\u5982\u56fe 11-8 \u6240\u793a\u3002

    1. \u9009\u53d6\u6570\u7ec4\u6700\u5de6\u7aef\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u6570\uff0c\u521d\u59cb\u5316\u4e24\u4e2a\u6307\u9488 i \u548c j \u5206\u522b\u6307\u5411\u6570\u7ec4\u7684\u4e24\u7aef\u3002
    2. \u8bbe\u7f6e\u4e00\u4e2a\u5faa\u73af\uff0c\u5728\u6bcf\u8f6e\u4e2d\u4f7f\u7528 i\uff08j\uff09\u5206\u522b\u5bfb\u627e\u7b2c\u4e00\u4e2a\u6bd4\u57fa\u51c6\u6570\u5927\uff08\u5c0f\uff09\u7684\u5143\u7d20\uff0c\u7136\u540e\u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\u3002
    3. \u5faa\u73af\u6267\u884c\u6b65\u9aa4 2. \uff0c\u76f4\u5230 i \u548c j \u76f8\u9047\u65f6\u505c\u6b62\uff0c\u6700\u540e\u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u4e2a\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\u3002
    <1><2><3><4><5><6><7><8><9>

    \u56fe 11-8 \u00a0 \u54e8\u5175\u5212\u5206\u6b65\u9aa4

    \u54e8\u5175\u5212\u5206\u5b8c\u6210\u540e\uff0c\u539f\u6570\u7ec4\u88ab\u5212\u5206\u6210\u4e09\u90e8\u5206\uff1a\u5de6\u5b50\u6570\u7ec4\u3001\u57fa\u51c6\u6570\u3001\u53f3\u5b50\u6570\u7ec4\uff0c\u4e14\u6ee1\u8db3\u201c\u5de6\u5b50\u6570\u7ec4\u4efb\u610f\u5143\u7d20 \\(\\leq\\) \u57fa\u51c6\u6570 \\(\\leq\\) \u53f3\u5b50\u6570\u7ec4\u4efb\u610f\u5143\u7d20\u201d\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u63a5\u4e0b\u6765\u53ea\u9700\u5bf9\u8fd9\u4e24\u4e2a\u5b50\u6570\u7ec4\u8fdb\u884c\u6392\u5e8f\u3002

    \u5feb\u901f\u6392\u5e8f\u7684\u5206\u6cbb\u7b56\u7565

    \u54e8\u5175\u5212\u5206\u7684\u5b9e\u8d28\u662f\u5c06\u4e00\u4e2a\u8f83\u957f\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u7b80\u5316\u4e3a\u4e24\u4e2a\u8f83\u77ed\u6570\u7ec4\u7684\u6392\u5e8f\u95ee\u9898\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def partition(self, nums: list[int], left: int, right: int) -> int:\n    \"\"\"\u54e8\u5175\u5212\u5206\"\"\"\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j = left, right\n    while i < j:\n        while i < j and nums[j] >= nums[left]:\n            j -= 1  # \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while i < j and nums[i] <= nums[left]:\n            i += 1  # \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        # \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    # \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i  # \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n
    quick_sort.cpp
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(vector<int> &nums, int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(vector<int> &nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.java
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(int[] nums, int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(int[] nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.cs
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid Swap(int[] nums, int i, int j) {\n    (nums[j], nums[i]) = (nums[i], nums[j]);\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint Partition(int[] nums, int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        Swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    Swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.go
    /* \u54e8\u5175\u5212\u5206 */\nfunc (q *quickSort) partition(nums []int, left, right int) int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j := left, right\n    for i < j {\n        for i < j && nums[j] >= nums[left] {\n            j-- // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        for i < j && nums[i] <= nums[left] {\n            i++ // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    }\n    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.swift
    /* \u54e8\u5175\u5212\u5206 */\nfunc partition(nums: inout [Int], left: Int, right: Int) -> Int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while i < j {\n        while i < j, nums[j] >= nums[left] {\n            j -= 1 // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j, nums[i] <= nums[left] {\n            i += 1 // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swapAt(i, j) // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swapAt(i, left) // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.js
    /* \u5143\u7d20\u4ea4\u6362 */\nswap(nums, i, j) {\n    let tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\npartition(nums, left, right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.ts
    /* \u5143\u7d20\u4ea4\u6362 */\nswap(nums: number[], i: number, j: number): void {\n    let tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\npartition(nums: number[], left: number, right: number): number {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u5143\u7d20\u4ea4\u6362\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.dart
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid _swap(List<int> nums, int i, int j) {\n  int tmp = nums[i];\n  nums[i] = nums[j];\n  nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint _partition(List<int> nums, int left, int right) {\n  // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n  int i = left, j = right;\n  while (i < j) {\n    while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    _swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n  }\n  _swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n  return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rs
    /* \u54e8\u5175\u5212\u5206 */\nfn partition(nums: &mut [i32], left: usize, right: usize) -> usize {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let (mut i, mut j) = (left, right);\n    while i < j {\n        while i < j && nums[j] >= nums[left] {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j && nums[i] <= nums[left] {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swap(i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swap(i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.c
    /* \u5143\u7d20\u4ea4\u6362 */\nvoid swap(int nums[], int i, int j) {\n    int tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nint partition(int nums[], int left, int right) {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n        swap(nums, i, j);\n    }\n    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    swap(nums, i, left);\n    // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n    return i;\n}\n
    quick_sort.kt
    /* \u5143\u7d20\u4ea4\u6362 */\nfun swap(nums: IntArray, i: Int, j: Int) {\n    val temp = nums[i]\n    nums[i] = nums[j]\n    nums[j] = temp\n}\n\n/* \u54e8\u5175\u5212\u5206 */\nfun partition(nums: IntArray, left: Int, right: Int): Int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--           // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++           // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j)  // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left)   // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i              // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rb
    [class]{QuickSort}-[func]{partition}\n
    quick_sort.zig
    // \u5143\u7d20\u4ea4\u6362\nfn swap(nums: []i32, i: usize, j: usize) void {\n    var tmp = nums[i];\n    nums[i] = nums[j];\n    nums[j] = tmp;\n}\n\n// \u54e8\u5175\u5212\u5206\nfn partition(nums: []i32, left: usize, right: usize) usize {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left;\n    var j = right;\n    while (i < j) {\n        while (i < j and nums[j] >= nums[left]) j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j and nums[i] <= nums[left]) i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j);   // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;               // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/quick_sort/#1151","title":"11.5.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u5feb\u901f\u6392\u5e8f\u7684\u6574\u4f53\u6d41\u7a0b\u5982\u56fe 11-9 \u6240\u793a\u3002

    1. \u9996\u5148\uff0c\u5bf9\u539f\u6570\u7ec4\u6267\u884c\u4e00\u6b21\u201c\u54e8\u5175\u5212\u5206\u201d\uff0c\u5f97\u5230\u672a\u6392\u5e8f\u7684\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u3002
    2. \u7136\u540e\uff0c\u5bf9\u5de6\u5b50\u6570\u7ec4\u548c\u53f3\u5b50\u6570\u7ec4\u5206\u522b\u9012\u5f52\u6267\u884c\u201c\u54e8\u5175\u5212\u5206\u201d\u3002
    3. \u6301\u7eed\u9012\u5f52\uff0c\u76f4\u81f3\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\uff0c\u4ece\u800c\u5b8c\u6210\u6574\u4e2a\u6570\u7ec4\u7684\u6392\u5e8f\u3002

    \u56fe 11-9 \u00a0 \u5feb\u901f\u6392\u5e8f\u6d41\u7a0b

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):\n    \"\"\"\u5feb\u901f\u6392\u5e8f\"\"\"\n    # \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right:\n        return\n    # \u54e8\u5175\u5212\u5206\n    pivot = self.partition(nums, left, right)\n    # \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    self.quick_sort(nums, left, pivot - 1)\n    self.quick_sort(nums, pivot + 1, right)\n
    quick_sort.cpp
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(vector<int> &nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.java
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.cs
    /* \u5feb\u901f\u6392\u5e8f */\nvoid QuickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right)\n        return;\n    // \u54e8\u5175\u5212\u5206\n    int pivot = Partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    QuickSort(nums, left, pivot - 1);\n    QuickSort(nums, pivot + 1, right);\n}\n
    quick_sort.go
    /* \u5feb\u901f\u6392\u5e8f */\nfunc (q *quickSort) quickSort(nums []int, left, right int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return\n    }\n    // \u54e8\u5175\u5212\u5206\n    pivot := q.partition(nums, left, right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    q.quickSort(nums, left, pivot-1)\n    q.quickSort(nums, pivot+1, right)\n}\n
    quick_sort.swift
    /* \u5feb\u901f\u6392\u5e8f */\nfunc quickSort(nums: inout [Int], left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return\n    }\n    // \u54e8\u5175\u5212\u5206\n    let pivot = partition(nums: &nums, left: left, right: right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums: &nums, left: left, right: pivot - 1)\n    quickSort(nums: &nums, left: pivot + 1, right: right)\n}\n
    quick_sort.js
    /* \u5feb\u901f\u6392\u5e8f */\nquickSort(nums, left, right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return;\n    // \u54e8\u5175\u5212\u5206\n    const pivot = this.partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    this.quickSort(nums, left, pivot - 1);\n    this.quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.ts
    /* \u5feb\u901f\u6392\u5e8f */\nquickSort(nums: number[], left: number, right: number): void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    const pivot = this.partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    this.quickSort(nums, left, pivot - 1);\n    this.quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.dart
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(List<int> nums, int left, int right) {\n  // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n  if (left >= right) return;\n  // \u54e8\u5175\u5212\u5206\n  int pivot = _partition(nums, left, right);\n  // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n  quickSort(nums, left, pivot - 1);\n  quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.rs
    /* \u5feb\u901f\u6392\u5e8f */\npub fn quick_sort(left: i32, right: i32, nums: &mut [i32]) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if left >= right {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    let pivot = Self::partition(nums, left as usize, right as usize) as i32;\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    Self::quick_sort(left, pivot - 1, nums);\n    Self::quick_sort(pivot + 1, right, nums);\n}\n
    quick_sort.c
    /* \u5feb\u901f\u6392\u5e8f */\nvoid quickSort(int nums[], int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) {\n        return;\n    }\n    // \u54e8\u5175\u5212\u5206\n    int pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    quick_sort.kt
    /* \u5feb\u901f\u6392\u5e8f */\nfun quickSort(nums: IntArray, left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return\n    // \u54e8\u5175\u5212\u5206\n    val pivot = partition(nums, left, right)\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1)\n    quickSort(nums, pivot + 1, right)\n}\n
    quick_sort.rb
    [class]{QuickSort}-[func]{quick_sort}\n
    quick_sort.zig
    // \u5feb\u901f\u6392\u5e8f\nfn quickSort(nums: []i32, left: usize, right: usize) void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    if (left >= right) return;\n    // \u54e8\u5175\u5212\u5206\n    var pivot = partition(nums, left, right);\n    // \u9012\u5f52\u5de6\u5b50\u6570\u7ec4\u3001\u53f3\u5b50\u6570\u7ec4\n    quickSort(nums, left, pivot - 1);\n    quickSort(nums, pivot + 1, right);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/quick_sort/#1152","title":"11.5.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\)\u3001\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5728\u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u54e8\u5175\u5212\u5206\u7684\u9012\u5f52\u5c42\u6570\u4e3a \\(\\log n\\) \uff0c\u6bcf\u5c42\u4e2d\u7684\u603b\u5faa\u73af\u6570\u4e3a \\(n\\) \uff0c\u603b\u4f53\u4f7f\u7528 \\(O(n \\log n)\\) \u65f6\u95f4\u3002\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u90fd\u5c06\u957f\u5ea6\u4e3a \\(n\\) \u7684\u6570\u7ec4\u5212\u5206\u4e3a\u957f\u5ea6\u4e3a \\(0\\) \u548c \\(n - 1\\) \u7684\u4e24\u4e2a\u5b50\u6570\u7ec4\uff0c\u6b64\u65f6\u9012\u5f52\u5c42\u6570\u8fbe\u5230 \\(n\\) \uff0c\u6bcf\u5c42\u4e2d\u7684\u5faa\u73af\u6570\u4e3a \\(n\\) \uff0c\u603b\u4f53\u4f7f\u7528 \\(O(n^2)\\) \u65f6\u95f4\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u5728\u8f93\u5165\u6570\u7ec4\u5b8c\u5168\u5012\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0c\u8fbe\u5230\u6700\u5dee\u9012\u5f52\u6df1\u5ea6 \\(n\\) \uff0c\u4f7f\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002\u6392\u5e8f\u64cd\u4f5c\u662f\u5728\u539f\u6570\u7ec4\u4e0a\u8fdb\u884c\u7684\uff0c\u672a\u501f\u52a9\u989d\u5916\u6570\u7ec4\u3002
    • \u975e\u7a33\u5b9a\u6392\u5e8f\uff1a\u5728\u54e8\u5175\u5212\u5206\u7684\u6700\u540e\u4e00\u6b65\uff0c\u57fa\u51c6\u6570\u53ef\u80fd\u4f1a\u88ab\u4ea4\u6362\u81f3\u76f8\u7b49\u5143\u7d20\u7684\u53f3\u4fa7\u3002
    "},{"location":"chapter_sorting/quick_sort/#1153","title":"11.5.3 \u00a0 \u5feb\u901f\u6392\u5e8f\u4e3a\u4ec0\u4e48\u5feb","text":"

    \u4ece\u540d\u79f0\u4e0a\u5c31\u80fd\u770b\u51fa\uff0c\u5feb\u901f\u6392\u5e8f\u5728\u6548\u7387\u65b9\u9762\u5e94\u8be5\u5177\u6709\u4e00\u5b9a\u7684\u4f18\u52bf\u3002\u5c3d\u7ba1\u5feb\u901f\u6392\u5e8f\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u4e0e\u201c\u5f52\u5e76\u6392\u5e8f\u201d\u548c\u201c\u5806\u6392\u5e8f\u201d\u76f8\u540c\uff0c\u4f46\u901a\u5e38\u5feb\u901f\u6392\u5e8f\u7684\u6548\u7387\u66f4\u9ad8\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u539f\u56e0\u3002

    • \u51fa\u73b0\u6700\u5dee\u60c5\u51b5\u7684\u6982\u7387\u5f88\u4f4e\uff1a\u867d\u7136\u5feb\u901f\u6392\u5e8f\u7684\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u6ca1\u6709\u5f52\u5e76\u6392\u5e8f\u7a33\u5b9a\uff0c\u4f46\u5728\u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u80fd\u5728 \\(O(n \\log n)\\) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e0b\u8fd0\u884c\u3002
    • \u7f13\u5b58\u4f7f\u7528\u6548\u7387\u9ad8\uff1a\u5728\u6267\u884c\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u65f6\uff0c\u7cfb\u7edf\u53ef\u5c06\u6574\u4e2a\u5b50\u6570\u7ec4\u52a0\u8f7d\u5230\u7f13\u5b58\uff0c\u56e0\u6b64\u8bbf\u95ee\u5143\u7d20\u7684\u6548\u7387\u8f83\u9ad8\u3002\u800c\u50cf\u201c\u5806\u6392\u5e8f\u201d\u8fd9\u7c7b\u7b97\u6cd5\u9700\u8981\u8df3\u8dc3\u5f0f\u8bbf\u95ee\u5143\u7d20\uff0c\u4ece\u800c\u7f3a\u4e4f\u8fd9\u4e00\u7279\u6027\u3002
    • \u590d\u6742\u5ea6\u7684\u5e38\u6570\u7cfb\u6570\u5c0f\uff1a\u5728\u4e0a\u8ff0\u4e09\u79cd\u7b97\u6cd5\u4e2d\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u6bd4\u8f83\u3001\u8d4b\u503c\u3001\u4ea4\u6362\u7b49\u64cd\u4f5c\u7684\u603b\u6570\u91cf\u6700\u5c11\u3002\u8fd9\u4e0e\u201c\u63d2\u5165\u6392\u5e8f\u201d\u6bd4\u201c\u5192\u6ce1\u6392\u5e8f\u201d\u66f4\u5feb\u7684\u539f\u56e0\u7c7b\u4f3c\u3002
    "},{"location":"chapter_sorting/quick_sort/#1154","title":"11.5.4 \u00a0 \u57fa\u51c6\u6570\u4f18\u5316","text":"

    \u5feb\u901f\u6392\u5e8f\u5728\u67d0\u4e9b\u8f93\u5165\u4e0b\u7684\u65f6\u95f4\u6548\u7387\u53ef\u80fd\u964d\u4f4e\u3002\u4e3e\u4e00\u4e2a\u6781\u7aef\u4f8b\u5b50\uff0c\u5047\u8bbe\u8f93\u5165\u6570\u7ec4\u662f\u5b8c\u5168\u5012\u5e8f\u7684\uff0c\u7531\u4e8e\u6211\u4eec\u9009\u62e9\u6700\u5de6\u7aef\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u6570\uff0c\u90a3\u4e48\u5728\u54e8\u5175\u5212\u5206\u5b8c\u6210\u540e\uff0c\u57fa\u51c6\u6570\u88ab\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u53f3\u7aef\uff0c\u5bfc\u81f4\u5de6\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a \\(n - 1\\)\u3001\u53f3\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a \\(0\\) \u3002\u5982\u6b64\u9012\u5f52\u4e0b\u53bb\uff0c\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u540e\u90fd\u6709\u4e00\u4e2a\u5b50\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(0\\) \uff0c\u5206\u6cbb\u7b56\u7565\u5931\u6548\uff0c\u5feb\u901f\u6392\u5e8f\u9000\u5316\u4e3a\u201c\u5192\u6ce1\u6392\u5e8f\u201d\u7684\u8fd1\u4f3c\u5f62\u5f0f\u3002

    \u4e3a\u4e86\u5c3d\u91cf\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u53d1\u751f\uff0c\u6211\u4eec\u53ef\u4ee5\u4f18\u5316\u54e8\u5175\u5212\u5206\u4e2d\u7684\u57fa\u51c6\u6570\u7684\u9009\u53d6\u7b56\u7565\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u968f\u673a\u9009\u53d6\u4e00\u4e2a\u5143\u7d20\u4f5c\u4e3a\u57fa\u51c6\u6570\u3002\u7136\u800c\uff0c\u5982\u679c\u8fd0\u6c14\u4e0d\u4f73\uff0c\u6bcf\u6b21\u90fd\u9009\u5230\u4e0d\u7406\u60f3\u7684\u57fa\u51c6\u6570\uff0c\u6548\u7387\u4ecd\u7136\u4e0d\u5c3d\u5982\u4eba\u610f\u3002

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u7f16\u7a0b\u8bed\u8a00\u901a\u5e38\u751f\u6210\u7684\u662f\u201c\u4f2a\u968f\u673a\u6570\u201d\u3002\u5982\u679c\u6211\u4eec\u9488\u5bf9\u4f2a\u968f\u673a\u6570\u5e8f\u5217\u6784\u5efa\u4e00\u4e2a\u7279\u5b9a\u7684\u6d4b\u8bd5\u6837\u4f8b\uff0c\u90a3\u4e48\u5feb\u901f\u6392\u5e8f\u7684\u6548\u7387\u4ecd\u7136\u53ef\u80fd\u52a3\u5316\u3002

    \u4e3a\u4e86\u8fdb\u4e00\u6b65\u6539\u8fdb\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u6570\u7ec4\u4e2d\u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\uff08\u901a\u5e38\u4e3a\u6570\u7ec4\u7684\u9996\u3001\u5c3e\u3001\u4e2d\u70b9\u5143\u7d20\uff09\uff0c\u5e76\u5c06\u8fd9\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\u4f5c\u4e3a\u57fa\u51c6\u6570\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u57fa\u51c6\u6570\u201c\u65e2\u4e0d\u592a\u5c0f\u4e5f\u4e0d\u592a\u5927\u201d\u7684\u6982\u7387\u5c06\u5927\u5e45\u63d0\u5347\u3002\u5f53\u7136\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u9009\u53d6\u66f4\u591a\u5019\u9009\u5143\u7d20\uff0c\u4ee5\u8fdb\u4e00\u6b65\u63d0\u9ad8\u7b97\u6cd5\u7684\u7a33\u5065\u6027\u3002\u91c7\u7528\u8fd9\u79cd\u65b9\u6cd5\u540e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u52a3\u5316\u81f3 \\(O(n^2)\\) \u7684\u6982\u7387\u5927\u5927\u964d\u4f4e\u3002

    \u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:\n    \"\"\"\u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\"\"\"\n    l, m, r = nums[left], nums[mid], nums[right]\n    if (l <= m <= r) or (r <= m <= l):\n        return mid  # m \u5728 l \u548c r \u4e4b\u95f4\n    if (m <= l <= r) or (r <= l <= m):\n        return left  # l \u5728 m \u548c r \u4e4b\u95f4\n    return right\n\ndef partition(self, nums: list[int], left: int, right: int) -> int:\n    \"\"\"\u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09\"\"\"\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    med = self.median_three(nums, left, (left + right) // 2, right)\n    # \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums[left], nums[med] = nums[med], nums[left]\n    # \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j = left, right\n    while i < j:\n        while i < j and nums[j] >= nums[left]:\n            j -= 1  # \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while i < j and nums[i] <= nums[left]:\n            i += 1  # \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        # \u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    # \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i  # \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n
    quick_sort.cpp
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(vector<int> &nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partition(vector<int> &nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.java
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(int[] nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partition(int[] nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.cs
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint MedianThree(int[] nums, int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint Partition(int[] nums, int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = MedianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    Swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--;          // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        Swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    Swap(nums, i, left);  // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;             // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.go
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfunc (q *quickSortMedian) medianThree(nums []int, left, mid, right int) int {\n    l, m, r := nums[left], nums[mid], nums[right]\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09*/\nfunc (q *quickSortMedian) partition(nums []int, left, right int) int {\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    med := q.medianThree(nums, left, (left+right)/2, right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums[left], nums[med] = nums[med], nums[left]\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    i, j := left, right\n    for i < j {\n        for i < j && nums[j] >= nums[left] {\n            j-- //\u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        for i < j && nums[i] <= nums[left] {\n            i++ //\u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        //\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[j] = nums[j], nums[i]\n    }\n    //\u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    nums[i], nums[left] = nums[left], nums[i]\n    return i //\u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.swift
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfunc medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {\n    let l = nums[left]\n    let m = nums[mid]\n    let r = nums[right]\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfunc partitionMedian(nums: inout [Int], left: Int, right: Int) -> Int {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums.swapAt(left, med)\n    return partition(nums: &nums, left: left, right: right)\n}\n
    quick_sort.js
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nmedianThree(nums, left, mid, right) {\n    let l = nums[left],\n        m = nums[mid],\n        r = nums[right];\n    // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;\n    // l \u5728 m \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\npartition(nums, left, right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = this.medianThree(\n        nums,\n        left,\n        Math.floor((left + right) / 2),\n        right\n    );\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    this.swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.ts
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nmedianThree(\n    nums: number[],\n    left: number,\n    mid: number,\n    right: number\n): number {\n    let l = nums[left],\n        m = nums[mid],\n        r = nums[right];\n    // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l <= m && m <= r) || (r <= m && m <= l)) return mid;\n    // l \u5728 m \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m)) return left;\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\npartition(nums: number[], left: number, right: number): number {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = this.medianThree(\n        nums,\n        left,\n        Math.floor((left + right) / 2),\n        right\n    );\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    this.swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let i = left,\n        j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left]) {\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while (i < j && nums[i] <= nums[left]) {\n            i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        this.swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    this.swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.dart
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint _medianThree(List<int> nums, int left, int mid, int right) {\n  int l = nums[left], m = nums[mid], r = nums[right];\n  if ((l <= m && m <= r) || (r <= m && m <= l))\n    return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n  if ((m <= l && l <= r) || (r <= l && l <= m))\n    return left; // l \u5728 m \u548c r \u4e4b\u95f4\n  return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint _partition(List<int> nums, int left, int right) {\n  // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n  int med = _medianThree(nums, left, (left + right) ~/ 2, right);\n  // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n  _swap(nums, left, med);\n  // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n  int i = left, j = right;\n  while (i < j) {\n    while (i < j && nums[j] >= nums[left]) j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    while (i < j && nums[i] <= nums[left]) i++; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n    _swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n  }\n  _swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n  return i; // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rs
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfn median_three(nums: &mut [i32], left: usize, mid: usize, right: usize) -> usize {\n    let (l, m, r) = (nums[left], nums[mid], nums[right]);\n    if (l <= m && m <= r) || (r <= m && m <= l) {\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    }\n    if (m <= l && l <= r) || (r <= l && l <= m) {\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    }\n    right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfn partition(nums: &mut [i32], left: usize, right: usize) -> usize {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    let med = Self::median_three(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    nums.swap(left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    let (mut i, mut j) = (left, right);\n    while i < j {\n        while i < j && nums[j] >= nums[left] {\n            j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        while i < j && nums[i] <= nums[left] {\n            i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        }\n        nums.swap(i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    nums.swap(i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    i // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.c
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nint medianThree(int nums[], int left, int mid, int right) {\n    int l = nums[left], m = nums[mid], r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nint partitionMedian(int nums[], int left, int right) {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    int med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    int i = left, j = right;\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++;          // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j); // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left); // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;            // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.kt
    /* \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570 */\nfun medianThree(nums: IntArray, left: Int, mid: Int, right: Int): Int {\n    val l = nums[left]\n    val m = nums[mid]\n    val r = nums[right]\n    if ((m in l..r) || (m in r..l))\n        return mid  // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((l in m..r) || (l in r..m))\n        return left // l \u5728 m \u548c r \u4e4b\u95f4\n    return right\n}\n\n/* \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09 */\nfun partitionMedian(nums: IntArray, left: Int, right: Int): Int {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    val med = medianThree(nums, left, (left + right) / 2, right)\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med)\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left\n    var j = right\n    while (i < j) {\n        while (i < j && nums[j] >= nums[left])\n            j--                      // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j && nums[i] <= nums[left])\n            i++                      // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j)             // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left)              // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i                         // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    quick_sort.rb
    [class]{QuickSortMedian}-[func]{median_three}\n\n[class]{QuickSortMedian}-[func]{partition}\n
    quick_sort.zig
    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\nfn medianThree(nums: []i32, left: usize, mid: usize, right: usize) usize {\n    var l = nums[left];\n    var m = nums[mid];\n    var r = nums[right];\n    if ((l <= m && m <= r) || (r <= m && m <= l))\n        return mid; // m \u5728 l \u548c r \u4e4b\u95f4\n    if ((m <= l && l <= r) || (r <= l && l <= m))\n        return left; // l \u5728 m \u548c r \u4e4b\u95f4\n    return right;\n}\n\n// \u54e8\u5175\u5212\u5206\uff08\u4e09\u6570\u53d6\u4e2d\u503c\uff09\nfn partition(nums: []i32, left: usize, right: usize) usize {\n    // \u9009\u53d6\u4e09\u4e2a\u5019\u9009\u5143\u7d20\u7684\u4e2d\u4f4d\u6570\n    var med = medianThree(nums, left, (left + right) / 2, right);\n    // \u5c06\u4e2d\u4f4d\u6570\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\n    swap(nums, left, med);\n    // \u4ee5 nums[left] \u4e3a\u57fa\u51c6\u6570\n    var i = left;\n    var j = right;\n    while (i < j) {\n        while (i < j and nums[j] >= nums[left]) j -= 1; // \u4ece\u53f3\u5411\u5de6\u627e\u9996\u4e2a\u5c0f\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        while (i < j and nums[i] <= nums[left]) i += 1; // \u4ece\u5de6\u5411\u53f3\u627e\u9996\u4e2a\u5927\u4e8e\u57fa\u51c6\u6570\u7684\u5143\u7d20\n        swap(nums, i, j);   // \u4ea4\u6362\u8fd9\u4e24\u4e2a\u5143\u7d20\n    }\n    swap(nums, i, left);    // \u5c06\u57fa\u51c6\u6570\u4ea4\u6362\u81f3\u4e24\u5b50\u6570\u7ec4\u7684\u5206\u754c\u7ebf\n    return i;               // \u8fd4\u56de\u57fa\u51c6\u6570\u7684\u7d22\u5f15\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/quick_sort/#1155","title":"11.5.5 \u00a0 \u5c3e\u9012\u5f52\u4f18\u5316","text":"

    \u5728\u67d0\u4e9b\u8f93\u5165\u4e0b\uff0c\u5feb\u901f\u6392\u5e8f\u53ef\u80fd\u5360\u7528\u7a7a\u95f4\u8f83\u591a\u3002\u4ee5\u5b8c\u5168\u6709\u5e8f\u7684\u8f93\u5165\u6570\u7ec4\u4e3a\u4f8b\uff0c\u8bbe\u9012\u5f52\u4e2d\u7684\u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a \\(m\\) \uff0c\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u90fd\u5c06\u4ea7\u751f\u957f\u5ea6\u4e3a \\(0\\) \u7684\u5de6\u5b50\u6570\u7ec4\u548c\u957f\u5ea6\u4e3a \\(m - 1\\) \u7684\u53f3\u5b50\u6570\u7ec4\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u4e00\u5c42\u9012\u5f52\u8c03\u7528\u51cf\u5c11\u7684\u95ee\u9898\u89c4\u6a21\u975e\u5e38\u5c0f\uff08\u53ea\u51cf\u5c11\u4e00\u4e2a\u5143\u7d20\uff09\uff0c\u9012\u5f52\u6811\u7684\u9ad8\u5ea6\u4f1a\u8fbe\u5230 \\(n - 1\\) \uff0c\u6b64\u65f6\u9700\u8981\u5360\u7528 \\(O(n)\\) \u5927\u5c0f\u7684\u6808\u5e27\u7a7a\u95f4\u3002

    \u4e3a\u4e86\u9632\u6b62\u6808\u5e27\u7a7a\u95f4\u7684\u7d2f\u79ef\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u6bcf\u8f6e\u54e8\u5175\u6392\u5e8f\u5b8c\u6210\u540e\uff0c\u6bd4\u8f83\u4e24\u4e2a\u5b50\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u4ec5\u5bf9\u8f83\u77ed\u7684\u5b50\u6570\u7ec4\u8fdb\u884c\u9012\u5f52\u3002\u7531\u4e8e\u8f83\u77ed\u5b50\u6570\u7ec4\u7684\u957f\u5ea6\u4e0d\u4f1a\u8d85\u8fc7 \\(n / 2\\) \uff0c\u56e0\u6b64\u8fd9\u79cd\u65b9\u6cd5\u80fd\u786e\u4fdd\u9012\u5f52\u6df1\u5ea6\u4e0d\u8d85\u8fc7 \\(\\log n\\) \uff0c\u4ece\u800c\u5c06\u6700\u5dee\u7a7a\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u81f3 \\(O(\\log n)\\) \u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig quick_sort.py
    def quick_sort(self, nums: list[int], left: int, right: int):\n    \"\"\"\u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09\"\"\"\n    # \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right:\n        # \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        pivot = self.partition(nums, left, right)\n        # \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot - left < right - pivot:\n            self.quick_sort(nums, left, pivot - 1)  # \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1  # \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        else:\n            self.quick_sort(nums, pivot + 1, right)  # \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1  # \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n
    quick_sort.cpp
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(vector<int> &nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1;                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.java
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.cs
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid QuickSort(int[] nums, int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = Partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            QuickSort(nums, left, pivot - 1);  // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;  // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            QuickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.go
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09*/\nfunc (q *quickSortTailCall) quickSort(nums []int, left, right int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    for left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        pivot := q.partition(nums, left, right)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot-left < right-pivot {\n            q.quickSort(nums, left, pivot-1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            q.quickSort(nums, pivot+1, right) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1                 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.swift
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nfunc quickSortTailCall(nums: inout [Int], left: Int, right: Int) {\n    var left = left\n    var right = right\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = partition(nums: &nums, left: left, right: right)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left) < (right - pivot) {\n            quickSortTailCall(nums: &nums, left: left, right: pivot - 1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSortTailCall(nums: &nums, left: pivot + 1, right: right) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.js
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nquickSort(nums, left, right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = this.partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            this.quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            this.quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.ts
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nquickSort(nums: number[], left: number, right: number): void {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = this.partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            this.quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            this.quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.dart
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSort(List<int> nums, int left, int right) {\n  // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n  while (left < right) {\n    // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n    int pivot = _partition(nums, left, right);\n    // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n    if (pivot - left < right - pivot) {\n      quickSort(nums, left, pivot - 1); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n      left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n    } else {\n      quickSort(nums, pivot + 1, right); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n      right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n    }\n  }\n}\n
    quick_sort.rs
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\npub fn quick_sort(mut left: i32, mut right: i32, nums: &mut [i32]) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while left < right {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        let pivot = Self::partition(nums, left as usize, right as usize) as i32;\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if pivot - left < right - pivot {\n            Self::quick_sort(left, pivot - 1, nums); // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            Self::quick_sort(pivot + 1, right, nums); // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1; // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.c
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nvoid quickSortTailCall(int nums[], int left, int right) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        int pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            quickSortTailCall(nums, left, pivot - 1);\n            // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n            left = pivot + 1;\n        } else {\n            // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            quickSortTailCall(nums, pivot + 1, right);\n            // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n            right = pivot - 1;\n        }\n    }\n}\n
    quick_sort.kt
    /* \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09 */\nfun quickSortTailCall(nums: IntArray, left: Int, right: Int) {\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\n    var l = left\n    var r = right\n    while (l < r) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        val pivot = partition(nums, l, r)\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - l < r - pivot) {\n            quickSort(nums, l, pivot - 1) // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            l = pivot + 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, r) // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            r = pivot - 1 // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    quick_sort.rb
    [class]{QuickSortTailCall}-[func]{quick_sort}\n
    quick_sort.zig
    // \u5feb\u901f\u6392\u5e8f\uff08\u5c3e\u9012\u5f52\u4f18\u5316\uff09\nfn quickSort(nums: []i32, left_: usize, right_: usize) void {\n    var left = left_;\n    var right = right_;\n    // \u5b50\u6570\u7ec4\u957f\u5ea6\u4e3a 1 \u65f6\u7ec8\u6b62\u9012\u5f52\n    while (left < right) {\n        // \u54e8\u5175\u5212\u5206\u64cd\u4f5c\n        var pivot = partition(nums, left, right);\n        // \u5bf9\u4e24\u4e2a\u5b50\u6570\u7ec4\u4e2d\u8f83\u77ed\u7684\u90a3\u4e2a\u6267\u884c\u5feb\u901f\u6392\u5e8f\n        if (pivot - left < right - pivot) {\n            quickSort(nums, left, pivot - 1);   // \u9012\u5f52\u6392\u5e8f\u5de6\u5b50\u6570\u7ec4\n            left = pivot + 1;                   // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [pivot + 1, right]\n        } else {\n            quickSort(nums, pivot + 1, right);  // \u9012\u5f52\u6392\u5e8f\u53f3\u5b50\u6570\u7ec4\n            right = pivot - 1;                  // \u5269\u4f59\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [left, pivot - 1]\n        }\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/radix_sort/","title":"11.10 \u00a0 \u57fa\u6570\u6392\u5e8f","text":"

    \u4e0a\u4e00\u8282\u4ecb\u7ecd\u4e86\u8ba1\u6570\u6392\u5e8f\uff0c\u5b83\u9002\u7528\u4e8e\u6570\u636e\u91cf \\(n\\) \u8f83\u5927\u4f46\u6570\u636e\u8303\u56f4 \\(m\\) \u8f83\u5c0f\u7684\u60c5\u51b5\u3002\u5047\u8bbe\u6211\u4eec\u9700\u8981\u5bf9 \\(n = 10^6\\) \u4e2a\u5b66\u53f7\u8fdb\u884c\u6392\u5e8f\uff0c\u800c\u5b66\u53f7\u662f\u4e00\u4e2a \\(8\\) \u4f4d\u6570\u5b57\uff0c\u8fd9\u610f\u5473\u7740\u6570\u636e\u8303\u56f4 \\(m = 10^8\\) \u975e\u5e38\u5927\uff0c\u4f7f\u7528\u8ba1\u6570\u6392\u5e8f\u9700\u8981\u5206\u914d\u5927\u91cf\u5185\u5b58\u7a7a\u95f4\uff0c\u800c\u57fa\u6570\u6392\u5e8f\u53ef\u4ee5\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u3002

    \u57fa\u6570\u6392\u5e8f\uff08radix sort\uff09\u7684\u6838\u5fc3\u601d\u60f3\u4e0e\u8ba1\u6570\u6392\u5e8f\u4e00\u81f4\uff0c\u4e5f\u901a\u8fc7\u7edf\u8ba1\u4e2a\u6570\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u57fa\u6570\u6392\u5e8f\u5229\u7528\u6570\u5b57\u5404\u4f4d\u4e4b\u95f4\u7684\u9012\u8fdb\u5173\u7cfb\uff0c\u4f9d\u6b21\u5bf9\u6bcf\u4e00\u4f4d\u8fdb\u884c\u6392\u5e8f\uff0c\u4ece\u800c\u5f97\u5230\u6700\u7ec8\u7684\u6392\u5e8f\u7ed3\u679c\u3002

    "},{"location":"chapter_sorting/radix_sort/#11101","title":"11.10.1 \u00a0 \u7b97\u6cd5\u6d41\u7a0b","text":"

    \u4ee5\u5b66\u53f7\u6570\u636e\u4e3a\u4f8b\uff0c\u5047\u8bbe\u6570\u5b57\u7684\u6700\u4f4e\u4f4d\u662f\u7b2c \\(1\\) \u4f4d\uff0c\u6700\u9ad8\u4f4d\u662f\u7b2c \\(8\\) \u4f4d\uff0c\u57fa\u6570\u6392\u5e8f\u7684\u6d41\u7a0b\u5982\u56fe 11-18 \u6240\u793a\u3002

    1. \u521d\u59cb\u5316\u4f4d\u6570 \\(k = 1\\) \u3002
    2. \u5bf9\u5b66\u53f7\u7684\u7b2c \\(k\\) \u4f4d\u6267\u884c\u201c\u8ba1\u6570\u6392\u5e8f\u201d\u3002\u5b8c\u6210\u540e\uff0c\u6570\u636e\u4f1a\u6839\u636e\u7b2c \\(k\\) \u4f4d\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u3002
    3. \u5c06 \\(k\\) \u589e\u52a0 \\(1\\) \uff0c\u7136\u540e\u8fd4\u56de\u6b65\u9aa4 2. \u7ee7\u7eed\u8fed\u4ee3\uff0c\u76f4\u5230\u6240\u6709\u4f4d\u90fd\u6392\u5e8f\u5b8c\u6210\u540e\u7ed3\u675f\u3002

    \u56fe 11-18 \u00a0 \u57fa\u6570\u6392\u5e8f\u7b97\u6cd5\u6d41\u7a0b

    \u4e0b\u9762\u5256\u6790\u4ee3\u7801\u5b9e\u73b0\u3002\u5bf9\u4e8e\u4e00\u4e2a \\(d\\) \u8fdb\u5236\u7684\u6570\u5b57 \\(x\\) \uff0c\u8981\u83b7\u53d6\u5176\u7b2c \\(k\\) \u4f4d \\(x_k\\) \uff0c\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u8ba1\u7b97\u516c\u5f0f\uff1a

    \\[ x_k = \\lfloor\\frac{x}{d^{k-1}}\\rfloor \\bmod d \\]

    \u5176\u4e2d \\(\\lfloor a \\rfloor\\) \u8868\u793a\u5bf9\u6d6e\u70b9\u6570 \\(a\\) \u5411\u4e0b\u53d6\u6574\uff0c\u800c \\(\\bmod \\: d\\) \u8868\u793a\u5bf9 \\(d\\) \u53d6\u6a21\uff08\u53d6\u4f59\uff09\u3002\u5bf9\u4e8e\u5b66\u53f7\u6570\u636e\uff0c\\(d = 10\\) \u4e14 \\(k \\in [1, 8]\\) \u3002

    \u6b64\u5916\uff0c\u6211\u4eec\u9700\u8981\u5c0f\u5e45\u6539\u52a8\u8ba1\u6570\u6392\u5e8f\u4ee3\u7801\uff0c\u4f7f\u4e4b\u53ef\u4ee5\u6839\u636e\u6570\u5b57\u7684\u7b2c \\(k\\) \u4f4d\u8fdb\u884c\u6392\u5e8f\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig radix_sort.py
    def digit(num: int, exp: int) -> int:\n    \"\"\"\u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1)\"\"\"\n    # \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num // exp) % 10\n\ndef counting_sort_digit(nums: list[int], exp: int):\n    \"\"\"\u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09\"\"\"\n    # \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    counter = [0] * 10\n    n = len(nums)\n    # \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in range(n):\n        d = digit(nums[i], exp)  # \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1  # \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    # \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in range(1, 10):\n        counter[i] += counter[i - 1]\n    # \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    res = [0] * n\n    for i in range(n - 1, -1, -1):\n        d = digit(nums[i], exp)\n        j = counter[d] - 1  # \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]  # \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1  # \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    # \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in range(n):\n        nums[i] = res[i]\n\ndef radix_sort(nums: list[int]):\n    \"\"\"\u57fa\u6570\u6392\u5e8f\"\"\"\n    # \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    m = max(nums)\n    # \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    exp = 1\n    while exp <= m:\n        # \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        # k = 1 -> exp = 1\n        # k = 2 -> exp = 10\n        # \u5373 exp = 10^(k-1)\n        counting_sort_digit(nums, exp)\n        exp *= 10\n
    radix_sort.cpp
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(vector<int> &nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    vector<int> counter(10, 0);\n    int n = nums.size();\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    vector<int> res(n, 0);\n    for (int i = n - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++)\n        nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(vector<int> &nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = *max_element(nums.begin(), nums.end());\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10)\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n}\n
    radix_sort.java
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(int[] nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int[] counter = new int[10];\n    int n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++)\n        nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(int[] nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = Integer.MIN_VALUE;\n    for (int num : nums)\n        if (num > m)\n            m = num;\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.cs
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint Digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid CountingSortDigit(int[] nums, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int[] counter = new int[10];\n    int n = nums.Length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < n; i++) {\n        int d = Digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++;                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int[] res = new int[n];\n    for (int i = n - 1; i >= 0; i--) {\n        int d = Digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid RadixSort(int[] nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int m = int.MinValue;\n    foreach (int num in nums) {\n        if (num > m) m = num;\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        CountingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.go
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunc digit(num, exp int) int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunc countingSortDigit(nums []int, exp int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    counter := make([]int, 10)\n    n := len(nums)\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i := 0; i < n; i++ {\n        d := digit(nums[i], exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++             // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i := 1; i < 10; i++ {\n        counter[i] += counter[i-1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    res := make([]int, n)\n    for i := n - 1; i >= 0; i-- {\n        d := digit(nums[i], exp)\n        j := counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]    // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--        // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i := 0; i < n; i++ {\n        nums[i] = res[i]\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunc radixSort(nums []int) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    max := math.MinInt\n    for _, num := range nums {\n        if num > max {\n            max = num\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for exp := 1; max >= exp; exp *= 10 {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp)\n    }\n}\n
    radix_sort.swift
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunc digit(num: Int, exp: Int) -> Int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunc countingSortDigit(nums: inout [Int], exp: Int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    var counter = Array(repeating: 0, count: 10)\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in nums.indices {\n        let d = digit(num: nums[i], exp: exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1 // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in 1 ..< 10 {\n        counter[i] += counter[i - 1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    var res = Array(repeating: 0, count: nums.count)\n    for i in nums.indices.reversed() {\n        let d = digit(num: nums[i], exp: exp)\n        let j = counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i] // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1 // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in nums.indices {\n        nums[i] = res[i]\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunc radixSort(nums: inout [Int]) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m = Int.min\n    for num in nums {\n        if num > m {\n            m = num\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for exp in sequence(first: 1, next: { m >= ($0 * 10) ? $0 * 10 : nil }) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums: &nums, exp: exp)\n    }\n}\n
    radix_sort.js
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunction digit(num, exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return Math.floor(num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunction countingSortDigit(nums, exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    const counter = new Array(10).fill(0);\n    const n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (let i = 0; i < n; i++) {\n        const d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (let i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    const res = new Array(n).fill(0);\n    for (let i = n - 1; i >= 0; i--) {\n        const d = digit(nums[i], exp);\n        const j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunction radixSort(nums) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = Number.MIN_VALUE;\n    for (const num of nums) {\n        if (num > m) {\n            m = num;\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (let exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.ts
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfunction digit(num: number, exp: number): number {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return Math.floor(num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfunction countingSortDigit(nums: number[], exp: number): void {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    const counter = new Array(10).fill(0);\n    const n = nums.length;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (let i = 0; i < n; i++) {\n        const d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (let i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    const res = new Array(n).fill(0);\n    for (let i = n - 1; i >= 0; i--) {\n        const d = digit(nums[i], exp);\n        const j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (let i = 0; i < n; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfunction radixSort(nums: number[]): void {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = Number.MIN_VALUE;\n    for (const num of nums) {\n        if (num > m) {\n            m = num;\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (let exp = 1; exp <= m; exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp);\n    }\n}\n
    radix_sort.dart
    /* \u83b7\u53d6\u5143\u7d20 _num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int _num, int exp) {\n  // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n  return (_num ~/ exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(List<int> nums, int exp) {\n  // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n  List<int> counter = List<int>.filled(10, 0);\n  int n = nums.length;\n  // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n  for (int i = 0; i < n; i++) {\n    int d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n    counter[d]++; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n  }\n  // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n  for (int i = 1; i < 10; i++) {\n    counter[i] += counter[i - 1];\n  }\n  // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n  List<int> res = List<int>.filled(n, 0);\n  for (int i = n - 1; i >= 0; i--) {\n    int d = digit(nums[i], exp);\n    int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n    res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n    counter[d]--; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n  }\n  // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n  for (int i = 0; i < n; i++) nums[i] = res[i];\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(List<int> nums) {\n  // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n  // dart \u4e2d int \u7684\u957f\u5ea6\u662f 64 \u4f4d\u7684\n  int m = -1 << 63;\n  for (int _num in nums) if (_num > m) m = _num;\n  // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n  for (int exp = 1; exp <= m; exp *= 10)\n    // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n    // k = 1 -> exp = 1\n    // k = 2 -> exp = 10\n    // \u5373 exp = 10^(k-1)\n    countingSortDigit(nums, exp);\n}\n
    radix_sort.rs
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfn digit(num: i32, exp: i32) -> usize {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return ((num / exp) % 10) as usize;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfn counting_sort_digit(nums: &mut [i32], exp: i32) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    let mut counter = [0; 10];\n    let n = nums.len();\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for i in 0..n {\n        let d = digit(nums[i], exp); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for i in 1..10 {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    let mut res = vec![0; n];\n    for i in (0..n).rev() {\n        let d = digit(nums[i], exp);\n        let j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]; // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1; // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for i in 0..n {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfn radix_sort(nums: &mut [i32]) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    let m = *nums.into_iter().max().unwrap();\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    let mut exp = 1;\n    while exp <= m {\n        counting_sort_digit(nums, exp);\n        exp *= 10;\n    }\n}\n
    radix_sort.c
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nint digit(int num, int exp) {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10;\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nvoid countingSortDigit(int nums[], int size, int exp) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    int *counter = (int *)malloc((sizeof(int) * 10));\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (int i = 0; i < size; i++) {\n        // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        int d = digit(nums[i], exp);\n        // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n        counter[d]++;\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (int i = 1; i < 10; i++) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    int *res = (int *)malloc(sizeof(int) * size);\n    for (int i = size - 1; i >= 0; i--) {\n        int d = digit(nums[i], exp);\n        int j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--;           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (int i = 0; i < size; i++) {\n        nums[i] = res[i];\n    }\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nvoid radixSort(int nums[], int size) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    int max = INT32_MIN;\n    for (size_t i = 0; i < size - 1; i++) {\n        if (nums[i] > max) {\n            max = nums[i];\n        }\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    for (int exp = 1; max >= exp; exp *= 10)\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, size, exp);\n}\n
    radix_sort.kt
    /* \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1) */\nfun digit(num: Int, exp: Int): Int {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return (num / exp) % 10\n}\n\n/* \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09 */\nfun countingSortDigit(nums: IntArray, exp: Int) {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    val counter = IntArray(10)\n    val n = nums.size\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (i in 0..<n) {\n        val d = digit(nums[i], exp) // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d]++                // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    for (i in 1..9) {\n        counter[i] += counter[i - 1]\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    val res = IntArray(n)\n    for (i in n - 1 downTo 0) {\n        val d = digit(nums[i], exp)\n        val j = counter[d] - 1 // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i]       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d]--           // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    for (i in 0..<n)\n        nums[i] = res[i]\n}\n\n/* \u57fa\u6570\u6392\u5e8f */\nfun radixSort(nums: IntArray) {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m = Int.MIN_VALUE\n    for (num in nums) if (num > m) m = num\n    var exp = 1\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    while (exp <= m) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        countingSortDigit(nums, exp)\n        exp *= 10\n    }\n}\n
    radix_sort.rb
    [class]{}-[func]{digit}\n\n[class]{}-[func]{counting_sort_digit}\n\n[class]{}-[func]{radix_sort}\n
    radix_sort.zig
    // \u83b7\u53d6\u5143\u7d20 num \u7684\u7b2c k \u4f4d\uff0c\u5176\u4e2d exp = 10^(k-1)\nfn digit(num: i32, exp: i32) i32 {\n    // \u4f20\u5165 exp \u800c\u975e k \u53ef\u4ee5\u907f\u514d\u5728\u6b64\u91cd\u590d\u6267\u884c\u6602\u8d35\u7684\u6b21\u65b9\u8ba1\u7b97\n    return @mod(@divFloor(num, exp), 10);\n}\n\n// \u8ba1\u6570\u6392\u5e8f\uff08\u6839\u636e nums \u7b2c k \u4f4d\u6392\u5e8f\uff09\nfn countingSortDigit(nums: []i32, exp: i32) !void {\n    // \u5341\u8fdb\u5236\u7684\u4f4d\u8303\u56f4\u4e3a 0~9 \uff0c\u56e0\u6b64\u9700\u8981\u957f\u5ea6\u4e3a 10 \u7684\u6876\u6570\u7ec4\n    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);\n    // defer mem_arena.deinit();\n    const mem_allocator = mem_arena.allocator();\n    var counter = try mem_allocator.alloc(usize, 10);\n    @memset(counter, 0);\n    var n = nums.len;\n    // \u7edf\u8ba1 0~9 \u5404\u6570\u5b57\u7684\u51fa\u73b0\u6b21\u6570\n    for (nums) |num| {\n        var d: u32 = @bitCast(digit(num, exp)); // \u83b7\u53d6 nums[i] \u7b2c k \u4f4d\uff0c\u8bb0\u4e3a d\n        counter[d] += 1; // \u7edf\u8ba1\u6570\u5b57 d \u7684\u51fa\u73b0\u6b21\u6570\n    }\n    // \u6c42\u524d\u7f00\u548c\uff0c\u5c06\u201c\u51fa\u73b0\u4e2a\u6570\u201d\u8f6c\u6362\u4e3a\u201c\u6570\u7ec4\u7d22\u5f15\u201d\n    var i: usize = 1;\n    while (i < 10) : (i += 1) {\n        counter[i] += counter[i - 1];\n    }\n    // \u5012\u5e8f\u904d\u5386\uff0c\u6839\u636e\u6876\u5185\u7edf\u8ba1\u7ed3\u679c\uff0c\u5c06\u5404\u5143\u7d20\u586b\u5165 res\n    var res = try mem_allocator.alloc(i32, n);\n    i = n - 1;\n    while (i >= 0) : (i -= 1) {\n        var d: u32 = @bitCast(digit(nums[i], exp));\n        var j = counter[d] - 1; // \u83b7\u53d6 d \u5728\u6570\u7ec4\u4e2d\u7684\u7d22\u5f15 j\n        res[j] = nums[i];       // \u5c06\u5f53\u524d\u5143\u7d20\u586b\u5165\u7d22\u5f15 j\n        counter[d] -= 1;        // \u5c06 d \u7684\u6570\u91cf\u51cf 1\n        if (i == 0) break;\n    }\n    // \u4f7f\u7528\u7ed3\u679c\u8986\u76d6\u539f\u6570\u7ec4 nums\n    i = 0;\n    while (i < n) : (i += 1) {\n        nums[i] = res[i];\n    }\n}\n\n// \u57fa\u6570\u6392\u5e8f\nfn radixSort(nums: []i32) !void {\n    // \u83b7\u53d6\u6570\u7ec4\u7684\u6700\u5927\u5143\u7d20\uff0c\u7528\u4e8e\u5224\u65ad\u6700\u5927\u4f4d\u6570\n    var m: i32 = std.math.minInt(i32);\n    for (nums) |num| {\n        if (num > m) m = num;\n    }\n    // \u6309\u7167\u4ece\u4f4e\u4f4d\u5230\u9ad8\u4f4d\u7684\u987a\u5e8f\u904d\u5386\n    var exp: i32 = 1;\n    while (exp <= m) : (exp *= 10) {\n        // \u5bf9\u6570\u7ec4\u5143\u7d20\u7684\u7b2c k \u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\n        // k = 1 -> exp = 1\n        // k = 2 -> exp = 10\n        // \u5373 exp = 10^(k-1)\n        try countingSortDigit(nums, exp);    \n    }\n} \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4e3a\u4ec0\u4e48\u4ece\u6700\u4f4e\u4f4d\u5f00\u59cb\u6392\u5e8f\uff1f

    \u5728\u8fde\u7eed\u7684\u6392\u5e8f\u8f6e\u6b21\u4e2d\uff0c\u540e\u4e00\u8f6e\u6392\u5e8f\u4f1a\u8986\u76d6\u524d\u4e00\u8f6e\u6392\u5e8f\u7684\u7ed3\u679c\u3002\u4e3e\u4f8b\u6765\u8bf4\uff0c\u5982\u679c\u7b2c\u4e00\u8f6e\u6392\u5e8f\u7ed3\u679c \\(a < b\\) \uff0c\u800c\u7b2c\u4e8c\u8f6e\u6392\u5e8f\u7ed3\u679c \\(a > b\\) \uff0c\u90a3\u4e48\u7b2c\u4e8c\u8f6e\u7684\u7ed3\u679c\u5c06\u53d6\u4ee3\u7b2c\u4e00\u8f6e\u7684\u7ed3\u679c\u3002\u7531\u4e8e\u6570\u5b57\u7684\u9ad8\u4f4d\u4f18\u5148\u7ea7\u9ad8\u4e8e\u4f4e\u4f4d\uff0c\u56e0\u6b64\u5e94\u8be5\u5148\u6392\u5e8f\u4f4e\u4f4d\u518d\u6392\u5e8f\u9ad8\u4f4d\u3002

    "},{"location":"chapter_sorting/radix_sort/#11102","title":"11.10.2 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"

    \u76f8\u8f83\u4e8e\u8ba1\u6570\u6392\u5e8f\uff0c\u57fa\u6570\u6392\u5e8f\u9002\u7528\u4e8e\u6570\u503c\u8303\u56f4\u8f83\u5927\u7684\u60c5\u51b5\uff0c\u4f46\u524d\u63d0\u662f\u6570\u636e\u5fc5\u987b\u53ef\u4ee5\u8868\u793a\u4e3a\u56fa\u5b9a\u4f4d\u6570\u7684\u683c\u5f0f\uff0c\u4e14\u4f4d\u6570\u4e0d\u80fd\u8fc7\u5927\u3002\u4f8b\u5982\uff0c\u6d6e\u70b9\u6570\u4e0d\u9002\u5408\u4f7f\u7528\u57fa\u6570\u6392\u5e8f\uff0c\u56e0\u4e3a\u5176\u4f4d\u6570 \\(k\\) \u8fc7\u5927\uff0c\u53ef\u80fd\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6 \\(O(nk) \\gg O(n^2)\\) \u3002

    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(nk)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u8bbe\u6570\u636e\u91cf\u4e3a \\(n\\)\u3001\u6570\u636e\u4e3a \\(d\\) \u8fdb\u5236\u3001\u6700\u5927\u4f4d\u6570\u4e3a \\(k\\) \uff0c\u5219\u5bf9\u67d0\u4e00\u4f4d\u6267\u884c\u8ba1\u6570\u6392\u5e8f\u4f7f\u7528 \\(O(n + d)\\) \u65f6\u95f4\uff0c\u6392\u5e8f\u6240\u6709 \\(k\\) \u4f4d\u4f7f\u7528 \\(O((n + d)k)\\) \u65f6\u95f4\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\\(d\\) \u548c \\(k\\) \u90fd\u76f8\u5bf9\u8f83\u5c0f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u8d8b\u5411 \\(O(n)\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n + d)\\)\u3001\u975e\u539f\u5730\u6392\u5e8f\uff1a\u4e0e\u8ba1\u6570\u6392\u5e8f\u76f8\u540c\uff0c\u57fa\u6570\u6392\u5e8f\u9700\u8981\u501f\u52a9\u957f\u5ea6\u4e3a \\(n\\) \u548c \\(d\\) \u7684\u6570\u7ec4 res \u548c counter \u3002
    • \u7a33\u5b9a\u6392\u5e8f\uff1a\u5f53\u8ba1\u6570\u6392\u5e8f\u7a33\u5b9a\u65f6\uff0c\u57fa\u6570\u6392\u5e8f\u4e5f\u7a33\u5b9a\uff1b\u5f53\u8ba1\u6570\u6392\u5e8f\u4e0d\u7a33\u5b9a\u65f6\uff0c\u57fa\u6570\u6392\u5e8f\u65e0\u6cd5\u4fdd\u8bc1\u5f97\u5230\u6b63\u786e\u7684\u6392\u5e8f\u7ed3\u679c\u3002
    "},{"location":"chapter_sorting/selection_sort/","title":"11.2 \u00a0 \u9009\u62e9\u6392\u5e8f","text":"

    \u9009\u62e9\u6392\u5e8f\uff08selection sort\uff09\u7684\u5de5\u4f5c\u539f\u7406\u975e\u5e38\u7b80\u5355\uff1a\u5f00\u542f\u4e00\u4e2a\u5faa\u73af\uff0c\u6bcf\u8f6e\u4ece\u672a\u6392\u5e8f\u533a\u95f4\u9009\u62e9\u6700\u5c0f\u7684\u5143\u7d20\uff0c\u5c06\u5176\u653e\u5230\u5df2\u6392\u5e8f\u533a\u95f4\u7684\u672b\u5c3e\u3002

    \u8bbe\u6570\u7ec4\u7684\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u9009\u62e9\u6392\u5e8f\u7684\u7b97\u6cd5\u6d41\u7a0b\u5982\u56fe 11-2 \u6240\u793a\u3002

    1. \u521d\u59cb\u72b6\u6001\u4e0b\uff0c\u6240\u6709\u5143\u7d20\u672a\u6392\u5e8f\uff0c\u5373\u672a\u6392\u5e8f\uff08\u7d22\u5f15\uff09\u533a\u95f4\u4e3a \\([0, n-1]\\) \u3002
    2. \u9009\u53d6\u533a\u95f4 \\([0, n-1]\\) \u4e2d\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5c06\u5176\u4e0e\u7d22\u5f15 \\(0\\) \u5904\u7684\u5143\u7d20\u4ea4\u6362\u3002\u5b8c\u6210\u540e\uff0c\u6570\u7ec4\u524d 1 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    3. \u9009\u53d6\u533a\u95f4 \\([1, n-1]\\) \u4e2d\u7684\u6700\u5c0f\u5143\u7d20\uff0c\u5c06\u5176\u4e0e\u7d22\u5f15 \\(1\\) \u5904\u7684\u5143\u7d20\u4ea4\u6362\u3002\u5b8c\u6210\u540e\uff0c\u6570\u7ec4\u524d 2 \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    4. \u4ee5\u6b64\u7c7b\u63a8\u3002\u7ecf\u8fc7 \\(n - 1\\) \u8f6e\u9009\u62e9\u4e0e\u4ea4\u6362\u540e\uff0c\u6570\u7ec4\u524d \\(n - 1\\) \u4e2a\u5143\u7d20\u5df2\u6392\u5e8f\u3002
    5. \u4ec5\u5269\u7684\u4e00\u4e2a\u5143\u7d20\u5fc5\u5b9a\u662f\u6700\u5927\u5143\u7d20\uff0c\u65e0\u987b\u6392\u5e8f\uff0c\u56e0\u6b64\u6570\u7ec4\u6392\u5e8f\u5b8c\u6210\u3002
    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 11-2 \u00a0 \u9009\u62e9\u6392\u5e8f\u6b65\u9aa4

    \u5728\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u7528 \\(k\\) \u6765\u8bb0\u5f55\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig selection_sort.py
    def selection_sort(nums: list[int]):\n    \"\"\"\u9009\u62e9\u6392\u5e8f\"\"\"\n    n = len(nums)\n    # \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in range(n - 1):\n        # \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        k = i\n        for j in range(i + 1, n):\n            if nums[j] < nums[k]:\n                k = j  # \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        # \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[k] = nums[k], nums[i]\n
    selection_sort.cpp
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(vector<int> &nums) {\n    int n = nums.size();\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        swap(nums[i], nums[k]);\n    }\n}\n
    selection_sort.java
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(int[] nums) {\n    int n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        int temp = nums[i];\n        nums[i] = nums[k];\n        nums[k] = temp;\n    }\n}\n
    selection_sort.cs
    /* \u9009\u62e9\u6392\u5e8f */\nvoid SelectionSort(int[] nums) {\n    int n = nums.Length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        (nums[k], nums[i]) = (nums[i], nums[k]);\n    }\n}\n
    selection_sort.go
    /* \u9009\u62e9\u6392\u5e8f */\nfunc selectionSort(nums []int) {\n    n := len(nums)\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i := 0; i < n-1; i++ {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        k := i\n        for j := i + 1; j < n; j++ {\n            if nums[j] < nums[k] {\n                // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n                k = j\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums[i], nums[k] = nums[k], nums[i]\n\n    }\n}\n
    selection_sort.swift
    /* \u9009\u62e9\u6392\u5e8f */\nfunc selectionSort(nums: inout [Int]) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in nums.indices.dropLast() {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        var k = i\n        for j in nums.indices.dropFirst(i + 1) {\n            if nums[j] < nums[k] {\n                k = j // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums.swapAt(i, k)\n    }\n}\n
    selection_sort.js
    /* \u9009\u62e9\u6392\u5e8f */\nfunction selectionSort(nums) {\n    let n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (let i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let k = i;\n        for (let j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k]) {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        [nums[i], nums[k]] = [nums[k], nums[i]];\n    }\n}\n
    selection_sort.ts
    /* \u9009\u62e9\u6392\u5e8f */\nfunction selectionSort(nums: number[]): void {\n    let n = nums.length;\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (let i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let k = i;\n        for (let j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k]) {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        [nums[i], nums[k]] = [nums[k], nums[i]];\n    }\n}\n
    selection_sort.dart
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(List<int> nums) {\n  int n = nums.length;\n  // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n  for (int i = 0; i < n - 1; i++) {\n    // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n    int k = i;\n    for (int j = i + 1; j < n; j++) {\n      if (nums[j] < nums[k]) k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n    }\n    // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n    int temp = nums[i];\n    nums[i] = nums[k];\n    nums[k] = temp;\n  }\n}\n
    selection_sort.rs
    /* \u9009\u62e9\u6392\u5e8f */\nfn selection_sort(nums: &mut [i32]) {\n    if nums.is_empty() {\n        return;\n    }\n    let n = nums.len();\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for i in 0..n - 1 {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        let mut k = i;\n        for j in i + 1..n {\n            if nums[j] < nums[k] {\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n            }\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        nums.swap(i, k);\n    }\n}\n
    selection_sort.c
    /* \u9009\u62e9\u6392\u5e8f */\nvoid selectionSort(int nums[], int n) {\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (int i = 0; i < n - 1; i++) {\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        int k = i;\n        for (int j = i + 1; j < n; j++) {\n            if (nums[j] < nums[k])\n                k = j; // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        int temp = nums[i];\n        nums[i] = nums[k];\n        nums[k] = temp;\n    }\n}\n
    selection_sort.kt
    /* \u9009\u62e9\u6392\u5e8f */\nfun selectionSort(nums: IntArray) {\n    val n = nums.size\n    // \u5916\u5faa\u73af\uff1a\u672a\u6392\u5e8f\u533a\u95f4\u4e3a [i, n-1]\n    for (i in 0..<n - 1) {\n        var k = i\n        // \u5185\u5faa\u73af\uff1a\u627e\u5230\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u6700\u5c0f\u5143\u7d20\n        for (j in i + 1..<n) {\n            if (nums[j] < nums[k])\n                k = j // \u8bb0\u5f55\u6700\u5c0f\u5143\u7d20\u7684\u7d22\u5f15\n        }\n        // \u5c06\u8be5\u6700\u5c0f\u5143\u7d20\u4e0e\u672a\u6392\u5e8f\u533a\u95f4\u7684\u9996\u4e2a\u5143\u7d20\u4ea4\u6362\n        val temp = nums[i]\n        nums[i] = nums[k]\n        nums[k] = temp\n    }\n}\n
    selection_sort.rb
    [class]{}-[func]{selection_sort}\n
    selection_sort.zig
    [class]{}-[func]{selectionSort}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_sorting/selection_sort/#1121","title":"11.2.1 \u00a0 \u7b97\u6cd5\u7279\u6027","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\u3001\u975e\u81ea\u9002\u5e94\u6392\u5e8f\uff1a\u5916\u5faa\u73af\u5171 \\(n - 1\\) \u8f6e\uff0c\u7b2c\u4e00\u8f6e\u7684\u672a\u6392\u5e8f\u533a\u95f4\u957f\u5ea6\u4e3a \\(n\\) \uff0c\u6700\u540e\u4e00\u8f6e\u7684\u672a\u6392\u5e8f\u533a\u95f4\u957f\u5ea6\u4e3a \\(2\\) \uff0c\u5373\u5404\u8f6e\u5916\u5faa\u73af\u5206\u522b\u5305\u542b \\(n\\)\u3001\\(n - 1\\)\u3001\\(\\dots\\)\u3001\\(3\\)\u3001\\(2\\) \u8f6e\u5185\u5faa\u73af\uff0c\u6c42\u548c\u4e3a \\(\\frac{(n - 1)(n + 2)}{2}\\) \u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(1)\\)\u3001\u539f\u5730\u6392\u5e8f\uff1a\u6307\u9488 \\(i\\) \u548c \\(j\\) \u4f7f\u7528\u5e38\u6570\u5927\u5c0f\u7684\u989d\u5916\u7a7a\u95f4\u3002
    • \u975e\u7a33\u5b9a\u6392\u5e8f\uff1a\u5982\u56fe 11-3 \u6240\u793a\uff0c\u5143\u7d20 nums[i] \u6709\u53ef\u80fd\u88ab\u4ea4\u6362\u81f3\u4e0e\u5176\u76f8\u7b49\u7684\u5143\u7d20\u7684\u53f3\u8fb9\uff0c\u5bfc\u81f4\u4e24\u8005\u7684\u76f8\u5bf9\u987a\u5e8f\u53d1\u751f\u6539\u53d8\u3002

    \u56fe 11-3 \u00a0 \u9009\u62e9\u6392\u5e8f\u975e\u7a33\u5b9a\u793a\u4f8b

    "},{"location":"chapter_sorting/sorting_algorithm/","title":"11.1 \u00a0 \u6392\u5e8f\u7b97\u6cd5","text":"

    \u6392\u5e8f\u7b97\u6cd5\uff08sorting algorithm\uff09\u7528\u4e8e\u5bf9\u4e00\u7ec4\u6570\u636e\u6309\u7167\u7279\u5b9a\u987a\u5e8f\u8fdb\u884c\u6392\u5217\u3002\u6392\u5e8f\u7b97\u6cd5\u6709\u7740\u5e7f\u6cdb\u7684\u5e94\u7528\uff0c\u56e0\u4e3a\u6709\u5e8f\u6570\u636e\u901a\u5e38\u80fd\u591f\u88ab\u66f4\u9ad8\u6548\u5730\u67e5\u627e\u3001\u5206\u6790\u548c\u5904\u7406\u3002

    \u5982\u56fe 11-1 \u6240\u793a\uff0c\u6392\u5e8f\u7b97\u6cd5\u4e2d\u7684\u6570\u636e\u7c7b\u578b\u53ef\u4ee5\u662f\u6574\u6570\u3001\u6d6e\u70b9\u6570\u3001\u5b57\u7b26\u6216\u5b57\u7b26\u4e32\u7b49\u3002\u6392\u5e8f\u7684\u5224\u65ad\u89c4\u5219\u53ef\u6839\u636e\u9700\u6c42\u8bbe\u5b9a\uff0c\u5982\u6570\u5b57\u5927\u5c0f\u3001\u5b57\u7b26 ASCII \u7801\u987a\u5e8f\u6216\u81ea\u5b9a\u4e49\u89c4\u5219\u3002

    \u56fe 11-1 \u00a0 \u6570\u636e\u7c7b\u578b\u548c\u5224\u65ad\u89c4\u5219\u793a\u4f8b

    "},{"location":"chapter_sorting/sorting_algorithm/#1111","title":"11.1.1 \u00a0 \u8bc4\u4ef7\u7ef4\u5ea6","text":"

    \u8fd0\u884c\u6548\u7387\uff1a\u6211\u4eec\u671f\u671b\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5c3d\u91cf\u4f4e\uff0c\u4e14\u603b\u4f53\u64cd\u4f5c\u6570\u91cf\u8f83\u5c11\uff08\u65f6\u95f4\u590d\u6742\u5ea6\u4e2d\u7684\u5e38\u6570\u9879\u53d8\u5c0f\uff09\u3002\u5bf9\u4e8e\u5927\u6570\u636e\u91cf\u7684\u60c5\u51b5\uff0c\u8fd0\u884c\u6548\u7387\u663e\u5f97\u5c24\u4e3a\u91cd\u8981\u3002

    \u5c31\u5730\u6027\uff1a\u987e\u540d\u601d\u4e49\uff0c\u539f\u5730\u6392\u5e8f\u901a\u8fc7\u5728\u539f\u6570\u7ec4\u4e0a\u76f4\u63a5\u64cd\u4f5c\u5b9e\u73b0\u6392\u5e8f\uff0c\u65e0\u987b\u501f\u52a9\u989d\u5916\u7684\u8f85\u52a9\u6570\u7ec4\uff0c\u4ece\u800c\u8282\u7701\u5185\u5b58\u3002\u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u539f\u5730\u6392\u5e8f\u7684\u6570\u636e\u642c\u8fd0\u64cd\u4f5c\u8f83\u5c11\uff0c\u8fd0\u884c\u901f\u5ea6\u4e5f\u66f4\u5feb\u3002

    \u7a33\u5b9a\u6027\uff1a\u7a33\u5b9a\u6392\u5e8f\u5728\u5b8c\u6210\u6392\u5e8f\u540e\uff0c\u76f8\u7b49\u5143\u7d20\u5728\u6570\u7ec4\u4e2d\u7684\u76f8\u5bf9\u987a\u5e8f\u4e0d\u53d1\u751f\u6539\u53d8\u3002

    \u7a33\u5b9a\u6392\u5e8f\u662f\u591a\u7ea7\u6392\u5e8f\u573a\u666f\u7684\u5fc5\u8981\u6761\u4ef6\u3002\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u5b58\u50a8\u5b66\u751f\u4fe1\u606f\u7684\u8868\u683c\uff0c\u7b2c 1 \u5217\u548c\u7b2c 2 \u5217\u5206\u522b\u662f\u59d3\u540d\u548c\u5e74\u9f84\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u975e\u7a33\u5b9a\u6392\u5e8f\u53ef\u80fd\u5bfc\u81f4\u8f93\u5165\u6570\u636e\u7684\u6709\u5e8f\u6027\u4e27\u5931\uff1a

    # \u8f93\u5165\u6570\u636e\u662f\u6309\u7167\u59d3\u540d\u6392\u5e8f\u597d\u7684\n# (name, age)\n  ('A', 19)\n  ('B', 18)\n  ('C', 21)\n  ('D', 19)\n  ('E', 23)\n\n# \u5047\u8bbe\u4f7f\u7528\u975e\u7a33\u5b9a\u6392\u5e8f\u7b97\u6cd5\u6309\u5e74\u9f84\u6392\u5e8f\u5217\u8868\uff0c\n# \u7ed3\u679c\u4e2d ('D', 19) \u548c ('A', 19) \u7684\u76f8\u5bf9\u4f4d\u7f6e\u6539\u53d8\uff0c\n# \u8f93\u5165\u6570\u636e\u6309\u59d3\u540d\u6392\u5e8f\u7684\u6027\u8d28\u4e22\u5931\n  ('B', 18)\n  ('D', 19)\n  ('A', 19)\n  ('C', 21)\n  ('E', 23)\n

    \u81ea\u9002\u5e94\u6027\uff1a\u81ea\u9002\u5e94\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u53d7\u8f93\u5165\u6570\u636e\u7684\u5f71\u54cd\uff0c\u5373\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u3001\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u3001\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u5e76\u4e0d\u5b8c\u5168\u76f8\u7b49\u3002

    \u81ea\u9002\u5e94\u6027\u9700\u8981\u6839\u636e\u5177\u4f53\u60c5\u51b5\u6765\u8bc4\u4f30\u3002\u5982\u679c\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u5dee\u4e8e\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u8bf4\u660e\u6392\u5e8f\u7b97\u6cd5\u5728\u67d0\u4e9b\u6570\u636e\u4e0b\u6027\u80fd\u53ef\u80fd\u52a3\u5316\uff0c\u56e0\u6b64\u88ab\u89c6\u4e3a\u8d1f\u9762\u5c5e\u6027\uff1b\u800c\u5982\u679c\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u4e8e\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\uff0c\u5219\u88ab\u89c6\u4e3a\u6b63\u9762\u5c5e\u6027\u3002

    \u662f\u5426\u57fa\u4e8e\u6bd4\u8f83\uff1a\u57fa\u4e8e\u6bd4\u8f83\u7684\u6392\u5e8f\u4f9d\u8d56\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff08\\(<\\)\u3001\\(=\\)\u3001\\(>\\)\uff09\u6765\u5224\u65ad\u5143\u7d20\u7684\u76f8\u5bf9\u987a\u5e8f\uff0c\u4ece\u800c\u6392\u5e8f\u6574\u4e2a\u6570\u7ec4\uff0c\u7406\u8bba\u6700\u4f18\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n \\log n)\\) \u3002\u800c\u975e\u6bd4\u8f83\u6392\u5e8f\u4e0d\u4f7f\u7528\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u8fbe \\(O(n)\\) \uff0c\u4f46\u5176\u901a\u7528\u6027\u76f8\u5bf9\u8f83\u5dee\u3002

    "},{"location":"chapter_sorting/sorting_algorithm/#1112","title":"11.1.2 \u00a0 \u7406\u60f3\u6392\u5e8f\u7b97\u6cd5","text":"

    \u8fd0\u884c\u5feb\u3001\u539f\u5730\u3001\u7a33\u5b9a\u3001\u6b63\u5411\u81ea\u9002\u5e94\u3001\u901a\u7528\u6027\u597d\u3002\u663e\u7136\uff0c\u8fc4\u4eca\u4e3a\u6b62\u5c1a\u672a\u53d1\u73b0\u517c\u5177\u4ee5\u4e0a\u6240\u6709\u7279\u6027\u7684\u6392\u5e8f\u7b97\u6cd5\u3002\u56e0\u6b64\uff0c\u5728\u9009\u62e9\u6392\u5e8f\u7b97\u6cd5\u65f6\uff0c\u9700\u8981\u6839\u636e\u5177\u4f53\u7684\u6570\u636e\u7279\u70b9\u548c\u95ee\u9898\u9700\u6c42\u6765\u51b3\u5b9a\u3002

    \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u5171\u540c\u5b66\u4e60\u5404\u79cd\u6392\u5e8f\u7b97\u6cd5\uff0c\u5e76\u57fa\u4e8e\u4e0a\u8ff0\u8bc4\u4ef7\u7ef4\u5ea6\u5bf9\u5404\u4e2a\u6392\u5e8f\u7b97\u6cd5\u7684\u4f18\u7f3a\u70b9\u8fdb\u884c\u5206\u6790\u3002

    "},{"location":"chapter_sorting/summary/","title":"11.11 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_sorting/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u5192\u6ce1\u6392\u5e8f\u901a\u8fc7\u4ea4\u6362\u76f8\u90bb\u5143\u7d20\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u6807\u5fd7\u4f4d\u6765\u5b9e\u73b0\u63d0\u524d\u8fd4\u56de\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u5192\u6ce1\u6392\u5e8f\u7684\u6700\u4f73\u65f6\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u5230 \\(O(n)\\) \u3002
    • \u63d2\u5165\u6392\u5e8f\u6bcf\u8f6e\u5c06\u672a\u6392\u5e8f\u533a\u95f4\u5185\u7684\u5143\u7d20\u63d2\u5165\u5230\u5df2\u6392\u5e8f\u533a\u95f4\u7684\u6b63\u786e\u4f4d\u7f6e\uff0c\u4ece\u800c\u5b8c\u6210\u6392\u5e8f\u3002\u867d\u7136\u63d2\u5165\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \uff0c\u4f46\u7531\u4e8e\u5355\u5143\u64cd\u4f5c\u76f8\u5bf9\u8f83\u5c11\uff0c\u56e0\u6b64\u5728\u5c0f\u6570\u636e\u91cf\u7684\u6392\u5e8f\u4efb\u52a1\u4e2d\u975e\u5e38\u53d7\u6b22\u8fce\u3002
    • \u5feb\u901f\u6392\u5e8f\u57fa\u4e8e\u54e8\u5175\u5212\u5206\u64cd\u4f5c\u5b9e\u73b0\u6392\u5e8f\u3002\u5728\u54e8\u5175\u5212\u5206\u4e2d\uff0c\u6709\u53ef\u80fd\u6bcf\u6b21\u90fd\u9009\u53d6\u5230\u6700\u5dee\u7684\u57fa\u51c6\u6570\uff0c\u5bfc\u81f4\u65f6\u95f4\u590d\u6742\u5ea6\u52a3\u5316\u81f3 \\(O(n^2)\\) \u3002\u5f15\u5165\u4e2d\u4f4d\u6570\u57fa\u51c6\u6570\u6216\u968f\u673a\u57fa\u51c6\u6570\u53ef\u4ee5\u964d\u4f4e\u8fd9\u79cd\u52a3\u5316\u7684\u6982\u7387\u3002\u5c3e\u9012\u5f52\u65b9\u6cd5\u53ef\u4ee5\u6709\u6548\u5730\u51cf\u5c11\u9012\u5f52\u6df1\u5ea6\uff0c\u5c06\u7a7a\u95f4\u590d\u6742\u5ea6\u4f18\u5316\u5230 \\(O(\\log n)\\) \u3002
    • \u5f52\u5e76\u6392\u5e8f\u5305\u62ec\u5212\u5206\u548c\u5408\u5e76\u4e24\u4e2a\u9636\u6bb5\uff0c\u5178\u578b\u5730\u4f53\u73b0\u4e86\u5206\u6cbb\u7b56\u7565\u3002\u5728\u5f52\u5e76\u6392\u5e8f\u4e2d\uff0c\u6392\u5e8f\u6570\u7ec4\u9700\u8981\u521b\u5efa\u8f85\u52a9\u6570\u7ec4\uff0c\u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1b\u7136\u800c\u6392\u5e8f\u94fe\u8868\u7684\u7a7a\u95f4\u590d\u6742\u5ea6\u53ef\u4ee5\u4f18\u5316\u81f3 \\(O(1)\\) \u3002
    • \u6876\u6392\u5e8f\u5305\u542b\u4e09\u4e2a\u6b65\u9aa4\uff1a\u6570\u636e\u5206\u6876\u3001\u6876\u5185\u6392\u5e8f\u548c\u5408\u5e76\u7ed3\u679c\u3002\u5b83\u540c\u6837\u4f53\u73b0\u4e86\u5206\u6cbb\u7b56\u7565\uff0c\u9002\u7528\u4e8e\u6570\u636e\u4f53\u91cf\u5f88\u5927\u7684\u60c5\u51b5\u3002\u6876\u6392\u5e8f\u7684\u5173\u952e\u5728\u4e8e\u5bf9\u6570\u636e\u8fdb\u884c\u5e73\u5747\u5206\u914d\u3002
    • \u8ba1\u6570\u6392\u5e8f\u662f\u6876\u6392\u5e8f\u7684\u4e00\u4e2a\u7279\u4f8b\uff0c\u5b83\u901a\u8fc7\u7edf\u8ba1\u6570\u636e\u51fa\u73b0\u7684\u6b21\u6570\u6765\u5b9e\u73b0\u6392\u5e8f\u3002\u8ba1\u6570\u6392\u5e8f\u9002\u7528\u4e8e\u6570\u636e\u91cf\u5927\u4f46\u6570\u636e\u8303\u56f4\u6709\u9650\u7684\u60c5\u51b5\uff0c\u5e76\u4e14\u8981\u6c42\u6570\u636e\u80fd\u591f\u8f6c\u6362\u4e3a\u6b63\u6574\u6570\u3002
    • \u57fa\u6570\u6392\u5e8f\u901a\u8fc7\u9010\u4f4d\u6392\u5e8f\u6765\u5b9e\u73b0\u6570\u636e\u6392\u5e8f\uff0c\u8981\u6c42\u6570\u636e\u80fd\u591f\u8868\u793a\u4e3a\u56fa\u5b9a\u4f4d\u6570\u7684\u6570\u5b57\u3002
    • \u603b\u7684\u6765\u8bf4\uff0c\u6211\u4eec\u5e0c\u671b\u627e\u5230\u4e00\u79cd\u6392\u5e8f\u7b97\u6cd5\uff0c\u5177\u6709\u9ad8\u6548\u7387\u3001\u7a33\u5b9a\u3001\u539f\u5730\u4ee5\u53ca\u6b63\u5411\u81ea\u9002\u5e94\u6027\u7b49\u4f18\u70b9\u3002\u7136\u800c\uff0c\u6b63\u5982\u5176\u4ed6\u6570\u636e\u7ed3\u6784\u548c\u7b97\u6cd5\u4e00\u6837\uff0c\u6ca1\u6709\u4e00\u79cd\u6392\u5e8f\u7b97\u6cd5\u80fd\u591f\u540c\u65f6\u6ee1\u8db3\u6240\u6709\u8fd9\u4e9b\u6761\u4ef6\u3002\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u6570\u636e\u7684\u7279\u6027\u6765\u9009\u62e9\u5408\u9002\u7684\u6392\u5e8f\u7b97\u6cd5\u3002
    • \u56fe 11-19 \u5bf9\u6bd4\u4e86\u4e3b\u6d41\u6392\u5e8f\u7b97\u6cd5\u7684\u6548\u7387\u3001\u7a33\u5b9a\u6027\u3001\u5c31\u5730\u6027\u548c\u81ea\u9002\u5e94\u6027\u7b49\u3002

    \u56fe 11-19 \u00a0 \u6392\u5e8f\u7b97\u6cd5\u5bf9\u6bd4

    "},{"location":"chapter_sorting/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6392\u5e8f\u7b97\u6cd5\u7a33\u5b9a\u6027\u5728\u4ec0\u4e48\u60c5\u51b5\u4e0b\u662f\u5fc5\u9700\u7684\uff1f

    \u5728\u73b0\u5b9e\u4e2d\uff0c\u6211\u4eec\u6709\u53ef\u80fd\u57fa\u4e8e\u5bf9\u8c61\u7684\u67d0\u4e2a\u5c5e\u6027\u8fdb\u884c\u6392\u5e8f\u3002\u4f8b\u5982\uff0c\u5b66\u751f\u6709\u59d3\u540d\u548c\u8eab\u9ad8\u4e24\u4e2a\u5c5e\u6027\uff0c\u6211\u4eec\u5e0c\u671b\u5b9e\u73b0\u4e00\u4e2a\u591a\u7ea7\u6392\u5e8f\uff1a\u5148\u6309\u7167\u59d3\u540d\u8fdb\u884c\u6392\u5e8f\uff0c\u5f97\u5230 (A, 180) (B, 185) (C, 170) (D, 170) \uff1b\u518d\u5bf9\u8eab\u9ad8\u8fdb\u884c\u6392\u5e8f\u3002\u7531\u4e8e\u6392\u5e8f\u7b97\u6cd5\u4e0d\u7a33\u5b9a\uff0c\u56e0\u6b64\u53ef\u80fd\u5f97\u5230 (D, 170) (C, 170) (A, 180) (B, 185) \u3002

    \u53ef\u4ee5\u53d1\u73b0\uff0c\u5b66\u751f D \u548c C \u7684\u4f4d\u7f6e\u53d1\u751f\u4e86\u4ea4\u6362\uff0c\u59d3\u540d\u7684\u6709\u5e8f\u6027\u88ab\u7834\u574f\u4e86\uff0c\u800c\u8fd9\u662f\u6211\u4eec\u4e0d\u5e0c\u671b\u770b\u5230\u7684\u3002

    Q\uff1a\u54e8\u5175\u5212\u5206\u4e2d\u201c\u4ece\u53f3\u5f80\u5de6\u67e5\u627e\u201d\u4e0e\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\u7684\u987a\u5e8f\u53ef\u4ee5\u4ea4\u6362\u5417\uff1f

    \u4e0d\u884c\uff0c\u5f53\u6211\u4eec\u4ee5\u6700\u5de6\u7aef\u5143\u7d20\u4e3a\u57fa\u51c6\u6570\u65f6\uff0c\u5fc5\u987b\u5148\u201c\u4ece\u53f3\u5f80\u5de6\u67e5\u627e\u201d\u518d\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\u3002\u8fd9\u4e2a\u7ed3\u8bba\u6709\u4e9b\u53cd\u76f4\u89c9\uff0c\u6211\u4eec\u6765\u5256\u6790\u4e00\u4e0b\u539f\u56e0\u3002

    \u54e8\u5175\u5212\u5206 partition() \u7684\u6700\u540e\u4e00\u6b65\u662f\u4ea4\u6362 nums[left] \u548c nums[i] \u3002\u5b8c\u6210\u4ea4\u6362\u540e\uff0c\u57fa\u51c6\u6570\u5de6\u8fb9\u7684\u5143\u7d20\u90fd <= \u57fa\u51c6\u6570\uff0c\u8fd9\u5c31\u8981\u6c42\u6700\u540e\u4e00\u6b65\u4ea4\u6362\u524d nums[left] >= nums[i] \u5fc5\u987b\u6210\u7acb\u3002\u5047\u8bbe\u6211\u4eec\u5148\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\uff0c\u90a3\u4e48\u5982\u679c\u627e\u4e0d\u5230\u6bd4\u57fa\u51c6\u6570\u66f4\u5927\u7684\u5143\u7d20\uff0c\u5219\u4f1a\u5728 i == j \u65f6\u8df3\u51fa\u5faa\u73af\uff0c\u6b64\u65f6\u53ef\u80fd nums[j] == nums[i] > nums[left]\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u6b64\u65f6\u6700\u540e\u4e00\u6b65\u4ea4\u6362\u64cd\u4f5c\u4f1a\u628a\u4e00\u4e2a\u6bd4\u57fa\u51c6\u6570\u66f4\u5927\u7684\u5143\u7d20\u4ea4\u6362\u81f3\u6570\u7ec4\u6700\u5de6\u7aef\uff0c\u5bfc\u81f4\u54e8\u5175\u5212\u5206\u5931\u8d25\u3002

    \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u7ed9\u5b9a\u6570\u7ec4 [0, 0, 0, 0, 1] \uff0c\u5982\u679c\u5148\u201c\u4ece\u5de6\u5411\u53f3\u67e5\u627e\u201d\uff0c\u54e8\u5175\u5212\u5206\u540e\u6570\u7ec4\u4e3a [1, 0, 0, 0, 0] \uff0c\u8fd9\u4e2a\u7ed3\u679c\u662f\u4e0d\u6b63\u786e\u7684\u3002

    \u518d\u6df1\u5165\u601d\u8003\u4e00\u4e0b\uff0c\u5982\u679c\u6211\u4eec\u9009\u62e9 nums[right] \u4e3a\u57fa\u51c6\u6570\uff0c\u90a3\u4e48\u6b63\u597d\u53cd\u8fc7\u6765\uff0c\u5fc5\u987b\u5148\u201c\u4ece\u5de6\u5f80\u53f3\u67e5\u627e\u201d\u3002

    Q\uff1a\u5173\u4e8e\u5c3e\u9012\u5f52\u4f18\u5316\uff0c\u4e3a\u4ec0\u4e48\u9009\u77ed\u7684\u6570\u7ec4\u80fd\u4fdd\u8bc1\u9012\u5f52\u6df1\u5ea6\u4e0d\u8d85\u8fc7 \\(\\log n\\) \uff1f

    \u9012\u5f52\u6df1\u5ea6\u5c31\u662f\u5f53\u524d\u672a\u8fd4\u56de\u7684\u9012\u5f52\u65b9\u6cd5\u7684\u6570\u91cf\u3002\u6bcf\u8f6e\u54e8\u5175\u5212\u5206\u6211\u4eec\u5c06\u539f\u6570\u7ec4\u5212\u5206\u4e3a\u4e24\u4e2a\u5b50\u6570\u7ec4\u3002\u5728\u5c3e\u9012\u5f52\u4f18\u5316\u540e\uff0c\u5411\u4e0b\u9012\u5f52\u7684\u5b50\u6570\u7ec4\u957f\u5ea6\u6700\u5927\u4e3a\u539f\u6570\u7ec4\u957f\u5ea6\u7684\u4e00\u534a\u3002\u5047\u8bbe\u6700\u5dee\u60c5\u51b5\uff0c\u4e00\u76f4\u4e3a\u4e00\u534a\u957f\u5ea6\uff0c\u90a3\u4e48\u6700\u7ec8\u7684\u9012\u5f52\u6df1\u5ea6\u5c31\u662f \\(\\log n\\) \u3002

    \u56de\u987e\u539f\u59cb\u7684\u5feb\u901f\u6392\u5e8f\uff0c\u6211\u4eec\u6709\u53ef\u80fd\u4f1a\u8fde\u7eed\u5730\u9012\u5f52\u957f\u5ea6\u8f83\u5927\u7684\u6570\u7ec4\uff0c\u6700\u5dee\u60c5\u51b5\u4e0b\u4e3a \\(n\\)\u3001\\(n - 1\\)\u3001\\(\\dots\\)\u3001\\(2\\)\u3001\\(1\\) \uff0c\u9012\u5f52\u6df1\u5ea6\u4e3a \\(n\\) \u3002\u5c3e\u9012\u5f52\u4f18\u5316\u53ef\u4ee5\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\u51fa\u73b0\u3002

    Q\uff1a\u5f53\u6570\u7ec4\u4e2d\u6240\u6709\u5143\u7d20\u90fd\u76f8\u7b49\u65f6\uff0c\u5feb\u901f\u6392\u5e8f\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u662f \\(O(n^2)\\) \u5417\uff1f\u8be5\u5982\u4f55\u5904\u7406\u8fd9\u79cd\u9000\u5316\u60c5\u51b5\uff1f

    \u662f\u7684\u3002\u5bf9\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u53ef\u4ee5\u8003\u8651\u901a\u8fc7\u54e8\u5175\u5212\u5206\u5c06\u6570\u7ec4\u5212\u5206\u4e3a\u4e09\u4e2a\u90e8\u5206\uff1a\u5c0f\u4e8e\u3001\u7b49\u4e8e\u3001\u5927\u4e8e\u57fa\u51c6\u6570\u3002\u4ec5\u5411\u4e0b\u9012\u5f52\u5c0f\u4e8e\u548c\u5927\u4e8e\u7684\u4e24\u90e8\u5206\u3002\u5728\u8be5\u65b9\u6cd5\u4e0b\uff0c\u8f93\u5165\u5143\u7d20\u5168\u90e8\u76f8\u7b49\u7684\u6570\u7ec4\uff0c\u4ec5\u4e00\u8f6e\u54e8\u5175\u5212\u5206\u5373\u53ef\u5b8c\u6210\u6392\u5e8f\u3002

    Q\uff1a\u6876\u6392\u5e8f\u7684\u6700\u5dee\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a\u4ec0\u4e48\u662f \\(O(n^2)\\) \uff1f

    \u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u5143\u7d20\u88ab\u5206\u81f3\u540c\u4e00\u4e2a\u6876\u4e2d\u3002\u5982\u679c\u6211\u4eec\u91c7\u7528\u4e00\u4e2a \\(O(n^2)\\) \u7b97\u6cd5\u6765\u6392\u5e8f\u8fd9\u4e9b\u5143\u7d20\uff0c\u5219\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\) \u3002

    "},{"location":"chapter_stack_and_queue/","title":"\u7b2c 5 \u7ae0 \u00a0 \u6808\u4e0e\u961f\u5217","text":"

    Abstract

    \u6808\u5982\u540c\u53e0\u732b\u732b\uff0c\u800c\u961f\u5217\u5c31\u50cf\u732b\u732b\u6392\u961f\u3002

    \u4e24\u8005\u5206\u522b\u4ee3\u8868\u5148\u5165\u540e\u51fa\u548c\u5148\u5165\u5148\u51fa\u7684\u903b\u8f91\u5173\u7cfb\u3002

    "},{"location":"chapter_stack_and_queue/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 5.1 \u00a0 \u6808
    • 5.2 \u00a0 \u961f\u5217
    • 5.3 \u00a0 \u53cc\u5411\u961f\u5217
    • 5.4 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_stack_and_queue/deque/","title":"5.3 \u00a0 \u53cc\u5411\u961f\u5217","text":"

    \u5728\u961f\u5217\u4e2d\uff0c\u6211\u4eec\u4ec5\u80fd\u5220\u9664\u5934\u90e8\u5143\u7d20\u6216\u5728\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\u3002\u5982\u56fe 5-7 \u6240\u793a\uff0c\u53cc\u5411\u961f\u5217\uff08double-ended queue\uff09\u63d0\u4f9b\u4e86\u66f4\u9ad8\u7684\u7075\u6d3b\u6027\uff0c\u5141\u8bb8\u5728\u5934\u90e8\u548c\u5c3e\u90e8\u6267\u884c\u5143\u7d20\u7684\u6dfb\u52a0\u6216\u5220\u9664\u64cd\u4f5c\u3002

    \u56fe 5-7 \u00a0 \u53cc\u5411\u961f\u5217\u7684\u64cd\u4f5c

    "},{"location":"chapter_stack_and_queue/deque/#531","title":"5.3.1 \u00a0 \u53cc\u5411\u961f\u5217\u5e38\u7528\u64cd\u4f5c","text":"

    \u53cc\u5411\u961f\u5217\u7684\u5e38\u7528\u64cd\u4f5c\u5982\u8868 5-3 \u6240\u793a\uff0c\u5177\u4f53\u7684\u65b9\u6cd5\u540d\u79f0\u9700\u8981\u6839\u636e\u6240\u4f7f\u7528\u7684\u7f16\u7a0b\u8bed\u8a00\u6765\u786e\u5b9a\u3002

    \u8868 5-3 \u00a0 \u53cc\u5411\u961f\u5217\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5\u540d \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push_first() \u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u961f\u9996 \\(O(1)\\) push_last() \u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u961f\u5c3e \\(O(1)\\) pop_first() \u5220\u9664\u961f\u9996\u5143\u7d20 \\(O(1)\\) pop_last() \u5220\u9664\u961f\u5c3e\u5143\u7d20 \\(O(1)\\) peek_first() \u8bbf\u95ee\u961f\u9996\u5143\u7d20 \\(O(1)\\) peek_last() \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 \\(O(1)\\)

    \u540c\u6837\u5730\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u4e2d\u5df2\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\u7c7b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig deque.py
    from collections import deque\n\n# \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217\ndeq: deque[int] = deque()\n\n# \u5143\u7d20\u5165\u961f\ndeq.append(2)      # \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeq.append(5)\ndeq.append(4)\ndeq.appendleft(3)  # \u6dfb\u52a0\u81f3\u961f\u9996\ndeq.appendleft(1)\n\n# \u8bbf\u95ee\u5143\u7d20\nfront: int = deq[0]  # \u961f\u9996\u5143\u7d20\nrear: int = deq[-1]  # \u961f\u5c3e\u5143\u7d20\n\n# \u5143\u7d20\u51fa\u961f\npop_front: int = deq.popleft()  # \u961f\u9996\u5143\u7d20\u51fa\u961f\npop_rear: int = deq.pop()       # \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n# \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\nsize: int = len(deq)\n\n# \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = len(deq) == 0\n
    deque.cpp
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\ndeque<int> deque;\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push_back(2);   // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3);  // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.push_front(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint front = deque.front(); // \u961f\u9996\u5143\u7d20\nint back = deque.back();   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\ndeque.pop_front();  // \u961f\u9996\u5143\u7d20\u51fa\u961f\ndeque.pop_back();   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.size();\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty = deque.empty();\n
    deque.java
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\nDeque<Integer> deque = new LinkedList<>();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.offerLast(2);   // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.offerLast(5);\ndeque.offerLast(4);\ndeque.offerFirst(3);  // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.offerFirst(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint peekFirst = deque.peekFirst();  // \u961f\u9996\u5143\u7d20\nint peekLast = deque.peekLast();    // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\nint popFirst = deque.pollFirst();  // \u961f\u9996\u5143\u7d20\u51fa\u961f\nint popLast = deque.pollLast();    // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.size();\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = deque.isEmpty();\n
    deque.cs
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 C# \u4e2d\uff0c\u5c06\u94fe\u8868 LinkedList \u770b\u4f5c\u53cc\u5411\u961f\u5217\u6765\u4f7f\u7528\nLinkedList<int> deque = new();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.AddLast(2);   // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.AddLast(5);\ndeque.AddLast(4);\ndeque.AddFirst(3);  // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.AddFirst(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint peekFirst = deque.First.Value;  // \u961f\u9996\u5143\u7d20\nint peekLast = deque.Last.Value;    // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\ndeque.RemoveFirst();  // \u961f\u9996\u5143\u7d20\u51fa\u961f\ndeque.RemoveLast();   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.Count;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = deque.Count == 0;\n
    deque_test.go
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 Go \u4e2d\uff0c\u5c06 list \u4f5c\u4e3a\u53cc\u5411\u961f\u5217\u4f7f\u7528\ndeque := list.New()\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.PushBack(2)      // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.PushBack(5)\ndeque.PushBack(4)\ndeque.PushFront(3)     // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.PushFront(1)\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nfront := deque.Front() // \u961f\u9996\u5143\u7d20\nrear := deque.Back()   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\ndeque.Remove(front)    // \u961f\u9996\u5143\u7d20\u51fa\u961f\ndeque.Remove(rear)     // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nsize := deque.Len()\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nisEmpty := deque.Len() == 0\n
    deque.swift
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// Swift \u6ca1\u6709\u5185\u7f6e\u7684\u53cc\u5411\u961f\u5217\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u53cc\u5411\u961f\u5217\u6765\u4f7f\u7528\nvar deque: [Int] = []\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.append(2) // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.append(5)\ndeque.append(4)\ndeque.insert(3, at: 0) // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.insert(1, at: 0)\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nlet peekFirst = deque.first! // \u961f\u9996\u5143\u7d20\nlet peekLast = deque.last! // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u4f7f\u7528 Array \u6a21\u62df\u65f6 popFirst \u7684\u590d\u6742\u5ea6\u4e3a O(n)\nlet popFirst = deque.removeFirst() // \u961f\u9996\u5143\u7d20\u51fa\u961f\nlet popLast = deque.removeLast() // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = deque.count\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = deque.isEmpty\n
    deque.js
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// JavaScript \u6ca1\u6709\u5185\u7f6e\u7684\u53cc\u7aef\u961f\u5217\uff0c\u53ea\u80fd\u628a Array \u5f53\u4f5c\u53cc\u7aef\u961f\u5217\u6765\u4f7f\u7528\nconst deque = [];\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cunshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nconst peekFirst = deque[0];\nconst peekLast = deque[deque.length - 1];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst popFront = deque.shift();\nconst popBack = deque.pop();\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nconst size = deque.length;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst isEmpty = size === 0;\n
    deque.ts
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// TypeScript \u6ca1\u6709\u5185\u7f6e\u7684\u53cc\u7aef\u961f\u5217\uff0c\u53ea\u80fd\u628a Array \u5f53\u4f5c\u53cc\u7aef\u961f\u5217\u6765\u4f7f\u7528\nconst deque: number[] = [];\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push(2);\ndeque.push(5);\ndeque.push(4);\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cunshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\ndeque.unshift(3);\ndeque.unshift(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nconst peekFirst: number = deque[0];\nconst peekLast: number = deque[deque.length - 1];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cshift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst popFront: number = deque.shift() as number;\nconst popBack: number = deque.pop() as number;\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nconst size: number = deque.length;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst isEmpty: boolean = size === 0;\n
    deque.dart
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 Dart \u4e2d\uff0cQueue \u88ab\u5b9a\u4e49\u4e3a\u53cc\u5411\u961f\u5217\nQueue<int> deque = Queue<int>();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.addLast(2);  // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.addLast(5);\ndeque.addLast(4);\ndeque.addFirst(3); // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.addFirst(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nint peekFirst = deque.first; // \u961f\u9996\u5143\u7d20\nint peekLast = deque.last;   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\nint popFirst = deque.removeFirst(); // \u961f\u9996\u5143\u7d20\u51fa\u961f\nint popLast = deque.removeLast();   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size = deque.length;\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = deque.isEmpty;\n
    deque.rs
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push_back(2);  // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.push_back(5);\ndeque.push_back(4);\ndeque.push_front(3); // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.push_front(1);\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nif let Some(front) = deque.front() { // \u961f\u9996\u5143\u7d20\n}\nif let Some(rear) = deque.back() {   // \u961f\u5c3e\u5143\u7d20\n}\n\n/* \u5143\u7d20\u51fa\u961f */\nif let Some(pop_front) = deque.pop_front() { // \u961f\u9996\u5143\u7d20\u51fa\u961f\n}\nif let Some(pop_rear) = deque.pop_back() {   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = deque.len();\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = deque.is_empty();\n
    deque.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u53cc\u5411\u961f\u5217\n
    deque.kt
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\nval deque = LinkedList<Int>()\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.offerLast(2)  // \u6dfb\u52a0\u81f3\u961f\u5c3e\ndeque.offerLast(5)\ndeque.offerLast(4)\ndeque.offerFirst(3) // \u6dfb\u52a0\u81f3\u961f\u9996\ndeque.offerFirst(1)\n\n/* \u8bbf\u95ee\u5143\u7d20 */\nval peekFirst = deque.peekFirst() // \u961f\u9996\u5143\u7d20\nval peekLast = deque.peekLast()   // \u961f\u5c3e\u5143\u7d20\n\n/* \u5143\u7d20\u51fa\u961f */\nval popFirst = deque.pollFirst() // \u961f\u9996\u5143\u7d20\u51fa\u961f\nval popLast = deque.pollLast()   // \u961f\u5c3e\u5143\u7d20\u51fa\u961f\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nval size = deque.size\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = deque.isEmpty()\n
    deque.rb
    # \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217\n# Ruby \u6ca1\u6709\u5185\u76f4\u7684\u53cc\u7aef\u961f\u5217\uff0c\u53ea\u80fd\u628a Array \u5f53\u4f5c\u53cc\u7aef\u961f\u5217\u6765\u4f7f\u7528\ndeque = []\n\n# \u5143\u7d20\u5982\u961f\ndeque << 2\ndeque << 5\ndeque << 4\n# \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cArray#unshift \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\ndeque.unshift(3)\ndeque.unshift(1)\n\n# \u8bbf\u95ee\u5143\u7d20\npeek_first = deque.first\npeek_last = deque.last\n\n# \u5143\u7d20\u51fa\u961f\n# \u8bf7\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0c Array#shift \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\npop_front = deque.shift\npop_back = deque.pop\n\n# \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\nsize = deque.length\n\n# \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty = size.zero?\n
    deque.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/deque/#532","title":"5.3.2 \u00a0 \u53cc\u5411\u961f\u5217\u5b9e\u73b0 *","text":"

    \u53cc\u5411\u961f\u5217\u7684\u5b9e\u73b0\u4e0e\u961f\u5217\u7c7b\u4f3c\uff0c\u53ef\u4ee5\u9009\u62e9\u94fe\u8868\u6216\u6570\u7ec4\u4f5c\u4e3a\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u3002

    "},{"location":"chapter_stack_and_queue/deque/#1","title":"1. \u00a0 \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0","text":"

    \u56de\u987e\u4e0a\u4e00\u8282\u5185\u5bb9\uff0c\u6211\u4eec\u4f7f\u7528\u666e\u901a\u5355\u5411\u94fe\u8868\u6765\u5b9e\u73b0\u961f\u5217\uff0c\u56e0\u4e3a\u5b83\u53ef\u4ee5\u65b9\u4fbf\u5730\u5220\u9664\u5934\u8282\u70b9\uff08\u5bf9\u5e94\u51fa\u961f\u64cd\u4f5c\uff09\u548c\u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0\u65b0\u8282\u70b9\uff08\u5bf9\u5e94\u5165\u961f\u64cd\u4f5c\uff09\u3002

    \u5bf9\u4e8e\u53cc\u5411\u961f\u5217\u800c\u8a00\uff0c\u5934\u90e8\u548c\u5c3e\u90e8\u90fd\u53ef\u4ee5\u6267\u884c\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u53cc\u5411\u961f\u5217\u9700\u8981\u5b9e\u73b0\u53e6\u4e00\u4e2a\u5bf9\u79f0\u65b9\u5411\u7684\u64cd\u4f5c\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u91c7\u7528\u201c\u53cc\u5411\u94fe\u8868\u201d\u4f5c\u4e3a\u53cc\u5411\u961f\u5217\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u3002

    \u5982\u56fe 5-8 \u6240\u793a\uff0c\u6211\u4eec\u5c06\u53cc\u5411\u94fe\u8868\u7684\u5934\u8282\u70b9\u548c\u5c3e\u8282\u70b9\u89c6\u4e3a\u53cc\u5411\u961f\u5217\u7684\u961f\u9996\u548c\u961f\u5c3e\uff0c\u540c\u65f6\u5b9e\u73b0\u5728\u4e24\u7aef\u6dfb\u52a0\u548c\u5220\u9664\u8282\u70b9\u7684\u529f\u80fd\u3002

    LinkedListDequepush_last()push_first()pop_last()pop_first()

    \u56fe 5-8 \u00a0 \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u53cc\u5411\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_deque.py
    class ListNode:\n    \"\"\"\u53cc\u5411\u94fe\u8868\u8282\u70b9\"\"\"\n\n    def __init__(self, val: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self.val: int = val\n        self.next: ListNode | None = None  # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n        self.prev: ListNode | None = None  # \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\nclass LinkedListDeque:\n    \"\"\"\u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0  # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int, is_front: bool):\n        \"\"\"\u5165\u961f\u64cd\u4f5c\"\"\"\n        node = ListNode(num)\n        # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if self.is_empty():\n            self._front = self._rear = node\n        # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        elif is_front:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            self._front.prev = node\n            node.next = self._front\n            self._front = node  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else:\n            # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            self._rear.next = node\n            node.prev = self._rear\n            self._rear = node  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size += 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        self.push(num, True)\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        self.push(num, False)\n\n    def pop(self, is_front: bool) -> int:\n        \"\"\"\u51fa\u961f\u64cd\u4f5c\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front:\n            val: int = self._front.val  # \u6682\u5b58\u5934\u8282\u70b9\u503c\n            # \u5220\u9664\u5934\u8282\u70b9\n            fnext: ListNode | None = self._front.next\n            if fnext != None:\n                fnext.prev = None\n                self._front.next = None\n            self._front = fnext  # \u66f4\u65b0\u5934\u8282\u70b9\n        # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else:\n            val: int = self._rear.val  # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            # \u5220\u9664\u5c3e\u8282\u70b9\n            rprev: ListNode | None = self._rear.prev\n            if rprev != None:\n                rprev.next = None\n                self._rear.prev = None\n            self._rear = rprev  # \u66f4\u65b0\u5c3e\u8282\u70b9\n        self._size -= 1  # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        return self.pop(True)\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        return self.pop(False)\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._rear.val\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        node = self._front\n        res = [0] * self.size()\n        for i in range(self.size()):\n            res[i] = node.val\n            node = node.next\n        return res\n
    linkedlist_deque.cpp
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nstruct DoublyListNode {\n    int val;              // \u8282\u70b9\u503c\n    DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\u6307\u9488\n    DoublyListNode(int val) : val(val), prev(nullptr), next(nullptr) {\n    }\n};\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n  private:\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize = 0;              // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    LinkedListDeque() : front(nullptr), rear(nullptr) {\n    }\n\n    /* \u6790\u6784\u65b9\u6cd5 */\n    ~LinkedListDeque() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        DoublyListNode *pre, *cur = front;\n        while (cur != nullptr) {\n            pre = cur;\n            cur = cur->next;\n            delete pre;\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void push(int num, bool isFront) {\n        DoublyListNode *node = new DoublyListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front->prev = node;\n            node->next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear->next = node;\n            node->prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int pop(bool isFront) {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front->val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            DoublyListNode *fNext = front->next;\n            if (fNext != nullptr) {\n                fNext->prev = nullptr;\n                front->next = nullptr;\n            }\n            delete front;\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear->val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            DoublyListNode *rPrev = rear->prev;\n            if (rPrev != nullptr) {\n                rPrev->next = nullptr;\n                rear->prev = nullptr;\n            }\n            delete rear;\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return rear->val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        DoublyListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_deque.java
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    int val; // \u8282\u70b9\u503c\n    ListNode next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    ListNode prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    ListNode(int val) {\n        this.val = val;\n        prev = next = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private void push(int num, boolean isFront) {\n        ListNode node = new ListNode(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty())\n            front = rear = node;\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear.next = node;\n            node.prev = rear;\n            rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private int pop(boolean isFront) {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        int val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode fNext = front.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front.next = null;\n            }\n            front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            val = rear.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode rPrev = rear.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear.prev = null;\n            }\n            rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        return pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        return pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return rear.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_deque.cs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(int val) {\n    public int val = val;       // \u8282\u70b9\u503c\n    public ListNode? next = null; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    public ListNode? prev = null; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    ListNode? front, rear; // \u5934\u8282\u70b9 front, \u5c3e\u8282\u70b9 rear\n    int queSize = 0;      // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    public LinkedListDeque() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    void Push(int num, bool isFront) {\n        ListNode node = new(num);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (IsEmpty()) {\n            front = node;\n            rear = node;\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front!.prev = node;\n            node.next = front;\n            front = node; // \u66f4\u65b0\u5934\u8282\u70b9                           \n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear!.next = node;\n            node.prev = rear;\n            rear = node;  // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        Push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        Push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    int? Pop(bool isFront) {\n        if (IsEmpty())\n            throw new Exception();\n        int? val;\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            val = front?.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            ListNode? fNext = front?.next;\n            if (fNext != null) {\n                fNext.prev = null;\n                front!.next = null;\n            }\n            front = fNext;   // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear?.val;  // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            ListNode? rPrev = rear?.prev;\n            if (rPrev != null) {\n                rPrev.next = null;\n                rear!.prev = null;\n            }\n            rear = rPrev;    // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n\n        queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int? PopFirst() {\n        return Pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int? PopLast() {\n        return Pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int? PeekFirst() {\n        if (IsEmpty())\n            throw new Exception();\n        return front?.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int? PeekLast() {\n        if (IsEmpty())\n            throw new Exception();\n        return rear?.val;\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int?[] ToArray() {\n        ListNode? node = front;\n        int?[] res = new int?[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node?.val;\n            node = node?.next;\n        }\n\n        return res;\n    }\n}\n
    linkedlist_deque.go
    /* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype linkedListDeque struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u53cc\u7aef\u961f\u5217 */\nfunc newLinkedListDeque() *linkedListDeque {\n    return &linkedListDeque{\n        data: list.New(),\n    }\n}\n\n/* \u961f\u9996\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushFirst(value any) {\n    s.data.PushFront(value)\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u5165\u961f */\nfunc (s *linkedListDeque) pushLast(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u961f\u9996\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u961f\u5c3e\u5143\u7d20\u51fa\u961f */\nfunc (s *linkedListDeque) popLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListDeque) peekFirst() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (s *linkedListDeque) peekLast() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListDeque) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListDeque) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListDeque) toList() *list.List {\n    return s.data\n}\n
    linkedlist_deque.swift
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    var val: Int // \u8282\u70b9\u503c\n    var next: ListNode? // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    weak var prev: ListNode? // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n    init(val: Int) {\n        self.val = val\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? // \u5934\u8282\u70b9 front\n    private var rear: ListNode? // \u5c3e\u8282\u70b9 rear\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    private func push(num: Int, isFront: Bool) {\n        let node = ListNode(val: num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if isEmpty() {\n            front = node\n            rear = node\n        }\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        else if isFront {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size += 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        push(num: num, isFront: true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        push(num: num, isFront: false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    private func pop(isFront: Bool) -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        let val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if isFront {\n            val = front!.val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            let fNext = front?.next\n            if fNext != nil {\n                fNext?.prev = nil\n                front?.next = nil\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            val = rear!.val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            let rPrev = rear?.prev\n            if rPrev != nil {\n                rPrev?.next = nil\n                rear?.prev = nil\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        _size -= 1 // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        pop(isFront: true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        pop(isFront: false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return rear!.val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.js
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val; // \u8282\u70b9\u503c\n\n    constructor(val) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    #front; // \u5934\u8282\u70b9 front\n    #rear; // \u5c3e\u8282\u70b9 rear\n    #queSize; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n        this.#queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.#rear.next = node;\n            node.prev = this.#rear;\n            this.#rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val) {\n        const node = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.#queSize === 0) {\n            this.#front = node;\n            this.#rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.#front.prev = node;\n            node.next = this.#front;\n            this.#front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp = this.#rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.#rear.prev = null;\n        }\n        this.#rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst() {\n        if (this.#queSize === 0) {\n            return null;\n        }\n        const value = this.#front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp = this.#front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.#front.next = null;\n        }\n        this.#front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.#queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        return this.#queSize === 0 ? null : this.#rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        return this.#queSize === 0 ? null : this.#front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print() {\n        const arr = [];\n        let temp = this.#front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.ts
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n    prev: ListNode; // \u524d\u9a71\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    next: ListNode; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528 (\u6307\u9488)\n    val: number; // \u8282\u70b9\u503c\n\n    constructor(val: number) {\n        this.val = val;\n        this.next = null;\n        this.prev = null;\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private front: ListNode; // \u5934\u8282\u70b9 front\n    private rear: ListNode; // \u5c3e\u8282\u70b9 rear\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n        this.queSize = 0;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f\u64cd\u4f5c */\n    pushLast(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            this.rear.next = node;\n            node.prev = this.rear;\n            this.rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u5165\u961f\u64cd\u4f5c */\n    pushFirst(val: number): void {\n        const node: ListNode = new ListNode(val);\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (this.queSize === 0) {\n            this.front = node;\n            this.rear = node;\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            this.front.prev = node;\n            node.next = this.front;\n            this.front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n        }\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c */\n    popLast(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.rear.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5c3e\u8282\u70b9\n        let temp: ListNode = this.rear.prev;\n        if (temp !== null) {\n            temp.next = null;\n            this.rear.prev = null;\n        }\n        this.rear = temp; // \u66f4\u65b0\u5c3e\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u961f\u9996\u51fa\u961f\u64cd\u4f5c */\n    popFirst(): number {\n        if (this.queSize === 0) {\n            return null;\n        }\n        const value: number = this.front.val; // \u5b58\u50a8\u5c3e\u8282\u70b9\u503c\n        // \u5220\u9664\u5934\u8282\u70b9\n        let temp: ListNode = this.front.next;\n        if (temp !== null) {\n            temp.prev = null;\n            this.front.next = null;\n        }\n        this.front = temp; // \u66f4\u65b0\u5934\u8282\u70b9\n        this.queSize--;\n        return value;\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        return this.queSize === 0 ? null : this.rear.val;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        return this.queSize === 0 ? null : this.front.val;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u6253\u5370\u53cc\u5411\u961f\u5217 */\n    print(): void {\n        const arr: number[] = [];\n        let temp: ListNode = this.front;\n        while (temp !== null) {\n            arr.push(temp.val);\n            temp = temp.next;\n        }\n        console.log('[' + arr.join(', ') + ']');\n    }\n}\n
    linkedlist_deque.dart
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode {\n  int val; // \u8282\u70b9\u503c\n  ListNode? next; // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  ListNode? prev; // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n\n  ListNode(this.val, {this.next, this.prev});\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u5bf9\u5217 */\nclass LinkedListDeque {\n  late ListNode? _front; // \u5934\u8282\u70b9 _front\n  late ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n  LinkedListDeque() {\n    this._front = null;\n    this._rear = null;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u957f\u5ea6 */\n  int size() {\n    return this._queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return size() == 0;\n  }\n\n  /* \u5165\u961f\u64cd\u4f5c */\n  void push(int _num, bool isFront) {\n    final ListNode node = ListNode(_num);\n    if (isEmpty()) {\n      // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 _front \u548c _rear \u90fd\u6307\u5411 node\n      _front = _rear = node;\n    } else if (isFront) {\n      // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      _front!.prev = node;\n      node.next = _front;\n      _front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n      // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      _rear!.next = node;\n      node.prev = _rear;\n      _rear = node; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    push(_num, true);\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    push(_num, false);\n  }\n\n  /* \u51fa\u961f\u64cd\u4f5c */\n  int? pop(bool isFront) {\n    // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de null\n    if (isEmpty()) {\n      return null;\n    }\n    final int val;\n    if (isFront) {\n      // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n      val = _front!.val; // \u6682\u5b58\u5934\u8282\u70b9\u503c\n      // \u5220\u9664\u5934\u8282\u70b9\n      ListNode? fNext = _front!.next;\n      if (fNext != null) {\n        fNext.prev = null;\n        _front!.next = null;\n      }\n      _front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    } else {\n      // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n      val = _rear!.val; // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      // \u5220\u9664\u5c3e\u8282\u70b9\n      ListNode? rPrev = _rear!.prev;\n      if (rPrev != null) {\n        rPrev.next = null;\n        _rear!.prev = null;\n      }\n      _rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    _queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int? popFirst() {\n    return pop(true);\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int? popLast() {\n    return pop(false);\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int? peekFirst() {\n    return _front?.val;\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int? peekLast() {\n    return _rear?.val;\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> res = [];\n    for (int i = 0; i < _queSize; i++) {\n      res.add(node!.val);\n      node = node.next;\n    }\n    return res;\n  }\n}\n
    linkedlist_deque.rs
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\npub struct ListNode<T> {\n    pub val: T,                                 // \u8282\u70b9\u503c\n    pub next: Option<Rc<RefCell<ListNode<T>>>>, // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n    pub prev: Option<Rc<RefCell<ListNode<T>>>>, // \u524d\u9a71\u8282\u70b9\u6307\u9488\n}\n\nimpl<T> ListNode<T> {\n    pub fn new(val: T) -> Rc<RefCell<ListNode<T>>> {\n        Rc::new(RefCell::new(ListNode {\n            val,\n            next: None,\n            prev: None,\n        }))\n    }\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListDeque<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListDeque<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    pub fn push(&mut self, num: T, is_front: bool) {\n        let node = ListNode::new(num);\n        // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        if is_front {\n            match self.front.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.rear = Some(node.clone());\n                    self.front = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                Some(old_front) => {\n                    old_front.borrow_mut().prev = Some(node.clone());\n                    node.borrow_mut().next = Some(old_front);\n                    self.front = Some(node); // \u66f4\u65b0\u5934\u8282\u70b9\n                }\n            }\n        }\n        // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        else {\n            match self.rear.take() {\n                // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n                None => {\n                    self.front = Some(node.clone());\n                    self.rear = Some(node);\n                }\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                Some(old_rear) => {\n                    old_rear.borrow_mut().next = Some(node.clone());\n                    node.borrow_mut().prev = Some(old_rear);\n                    self.rear = Some(node); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                }\n            }\n        }\n        self.que_size += 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: T) {\n        self.push(num, true);\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: T) {\n        self.push(num, false);\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    pub fn pop(&mut self, is_front: bool) -> Option<T> {\n        // \u82e5\u961f\u5217\u4e3a\u7a7a\uff0c\u76f4\u63a5\u8fd4\u56de None\n        if self.is_empty() {\n            return None;\n        };\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if is_front {\n            self.front.take().map(|old_front| {\n                match old_front.borrow_mut().next.take() {\n                    Some(new_front) => {\n                        new_front.borrow_mut().prev.take();\n                        self.front = Some(new_front); // \u66f4\u65b0\u5934\u8282\u70b9\n                    }\n                    None => {\n                        self.rear.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n            })\n        }\n        // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        else {\n            self.rear.take().map(|old_rear| {\n                match old_rear.borrow_mut().prev.take() {\n                    Some(new_rear) => {\n                        new_rear.borrow_mut().next.take();\n                        self.rear = Some(new_rear); // \u66f4\u65b0\u5c3e\u8282\u70b9\n                    }\n                    None => {\n                        self.front.take();\n                    }\n                }\n                self.que_size -= 1; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n                Rc::try_unwrap(old_rear).ok().unwrap().into_inner().val\n            })\n        }\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    pub fn pop_first(&mut self) -> Option<T> {\n        return self.pop(true);\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    pub fn pop_last(&mut self) -> Option<T> {\n        return self.pop(false);\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek_first(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    pub fn peek_last(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.rear.as_ref()\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_deque.c
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\ntypedef struct DoublyListNode {\n    int val;                     // \u8282\u70b9\u503c\n    struct DoublyListNode *next; // \u540e\u7ee7\u8282\u70b9\n    struct DoublyListNode *prev; // \u524d\u9a71\u8282\u70b9\n} DoublyListNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nDoublyListNode *newDoublyListNode(int num) {\n    DoublyListNode *new = (DoublyListNode *)malloc(sizeof(DoublyListNode));\n    new->val = num;\n    new->next = NULL;\n    new->prev = NULL;\n    return new;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delDoublyListNode(DoublyListNode *node) {\n    free(node);\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    DoublyListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;                  // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n} LinkedListDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListDeque *newLinkedListDeque() {\n    LinkedListDeque *deque = (LinkedListDeque *)malloc(sizeof(LinkedListDeque));\n    deque->front = NULL;\n    deque->rear = NULL;\n    deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListdeque(LinkedListDeque *deque) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    for (int i = 0; i < deque->queSize && deque->front != NULL; i++) {\n        DoublyListNode *tmp = deque->front;\n        deque->front = deque->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e deque \u7ed3\u6784\u4f53\n    free(deque);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListDeque *deque) {\n    return (size(deque) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListDeque *deque, int num, bool isFront) {\n    DoublyListNode *node = newDoublyListNode(num);\n    // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411node\n    if (empty(deque)) {\n        deque->front = deque->rear = node;\n    }\n    // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    else if (isFront) {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n        deque->front->prev = node;\n        node->next = deque->front;\n        deque->front = node; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else {\n        // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n        deque->rear->next = node;\n        node->prev = deque->rear;\n        deque->rear = node;\n    }\n    deque->queSize++; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(LinkedListDeque *deque, int num) {\n    push(deque, num, true);\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(LinkedListDeque *deque, int num) {\n    push(deque, num, false);\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(LinkedListDeque *deque) {\n    assert(size(deque) && deque->front);\n    return deque->front->val;\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(LinkedListDeque *deque) {\n    assert(size(deque) && deque->rear);\n    return deque->rear->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListDeque *deque, bool isFront) {\n    if (empty(deque))\n        return -1;\n    int val;\n    // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if (isFront) {\n        val = peekFirst(deque); // \u6682\u5b58\u5934\u8282\u70b9\u503c\n        DoublyListNode *fNext = deque->front->next;\n        if (fNext) {\n            fNext->prev = NULL;\n            deque->front->next = NULL;\n        }\n        delDoublyListNode(deque->front);\n        deque->front = fNext; // \u66f4\u65b0\u5934\u8282\u70b9\n    }\n    // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else {\n        val = peekLast(deque); // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n        DoublyListNode *rPrev = deque->rear->prev;\n        if (rPrev) {\n            rPrev->next = NULL;\n            deque->rear->prev = NULL;\n        }\n        delDoublyListNode(deque->rear);\n        deque->rear = rPrev; // \u66f4\u65b0\u5c3e\u8282\u70b9\n    }\n    deque->queSize--; // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    return val;\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(LinkedListDeque *deque) {\n    return pop(deque, true);\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(LinkedListDeque *deque) {\n    return pop(deque, false);\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListDeque(LinkedListDeque *deque) {\n    int *arr = malloc(sizeof(int) * deque->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    DoublyListNode *node;\n    for (i = 0, node = deque->front; i < deque->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, deque->queSize);\n    free(arr);\n}\n
    linkedlist_deque.kt
    /* \u53cc\u5411\u94fe\u8868\u8282\u70b9 */\nclass ListNode(var _val: Int) {\n    // \u8282\u70b9\u503c\n    var next: ListNode? = null // \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n    var prev: ListNode? = null // \u524d\u9a71\u8282\u70b9\u5f15\u7528\n}\n\n/* \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass LinkedListDeque {\n    private var front: ListNode? = null // \u5934\u8282\u70b9 front\n    private var rear: ListNode? = null // \u5c3e\u8282\u70b9 rear\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f\u64cd\u4f5c */\n    fun push(num: Int, isFront: Boolean) {\n        val node = ListNode(num)\n        // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n        if (isEmpty()) {\n            rear = node\n            front = rear\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n        } else if (isFront) {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n            front?.prev = node\n            node.next = front\n            front = node // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n        } else {\n            // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n            rear?.next = node\n            node.prev = rear\n            rear = node // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize++ // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        push(num, true)\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        push(num, false)\n    }\n\n    /* \u51fa\u961f\u64cd\u4f5c */\n    fun pop(isFront: Boolean): Int {\n        if (isEmpty()) \n            throw IndexOutOfBoundsException()\n        val _val: Int\n        // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n        if (isFront) {\n            _val = front!!._val // \u6682\u5b58\u5934\u8282\u70b9\u503c\n            // \u5220\u9664\u5934\u8282\u70b9\n            val fNext = front!!.next\n            if (fNext != null) {\n                fNext.prev = null\n                front!!.next = null\n            }\n            front = fNext // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n        } else {\n            _val = rear!!._val // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n            // \u5220\u9664\u5c3e\u8282\u70b9\n            val rPrev = rear!!.prev\n            if (rPrev != null) {\n                rPrev.next = null\n                rear!!.prev = null\n            }\n            rear = rPrev // \u66f4\u65b0\u5c3e\u8282\u70b9\n        }\n        queSize-- // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        return _val\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        return pop(true)\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        return pop(false)\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return rear!!._val\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_deque.rb
    =begin\nFile: linkedlist_deque.rb\nCreated Time: 2024-04-06\nAuthor: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)\n=end\n\n### \u53cc\u5411\u94fe\u8868\u8282\u70b9\nclass ListNode\n  attr_accessor :val\n  attr_accessor :next # \u540e\u7ee7\u8282\u70b9\u5f15\u7528\n  attr_accessor :prev # \u524d\u8eaf\u8282\u70b9\u5f15\u7528\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(val)\n    @val = val\n  end\nend\n\n### \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass LinkedListDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0     # \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f\u64cd\u4f5c ###\n  def push(num, is_front)\n    node = ListNode.new(num)\n    # \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c \u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n    if is_empty?\n      @front = @rear = node\n    # \u961f\u9996\u5165\u961f\u64cd\u4f5c\n    elsif is_front\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n      @front.prev = node\n      node.next = @front\n      @front = node # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n    else\n      # \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n      @rear.next = node\n      node.prev = @rear\n      @rear = node # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size += 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    push(num, true)\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    push(num, false)\n  end\n\n  ### \u51fa\u961f\u64cd\u4f5c ###\n  def pop(is_front)\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n    if is_front\n      val = @front.val # \u6682\u5b58\u5934\u8282\u70b9\u503c\n      # \u5220\u9664\u5934\u8282\u70b9\n      fnext = @front.next\n      unless fnext.nil?\n        fnext.prev = nil\n        @front.next = nil\n      end\n      @front = fnext # \u66f4\u65b0\u5934\u8282\u70b9\n    # \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n    else\n      val = @rear.val # \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n      # \u5220\u9664\u5c3e\u8282\u70b9\n      rprev = @rear.prev\n      unless rprev.nil?\n        rprev.next = nil\n        @rear.prev = nil\n      end\n      @rear = rprev # \u66f4\u65b0\u5c3e\u8282\u70b9\n    end\n    @size -= 1 # \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n\n    val\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    pop(true)\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_last\n    pop(false)\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @rear.val\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    node = @front\n    res = Array.new(size, 0)\n    for i in 0...size\n      res[i] = node.val\n      node = node.next\n    end\n    res\n  end\nend\n
    linkedlist_deque.zig
    // \u53cc\u5411\u94fe\u8868\u8282\u70b9\nfn ListNode(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        val: T = undefined,     // \u8282\u70b9\u503c\n        next: ?*Self = null,    // \u540e\u7ee7\u8282\u70b9\u6307\u9488\n        prev: ?*Self = null,    // \u524d\u9a71\u8282\u70b9\u6307\u9488\n\n        // Initialize a list node with specific value\n        pub fn init(self: *Self, x: i32) void {\n            self.val = x;\n            self.next = null;\n            self.prev = null;\n        }\n    };\n}\n\n// \u57fa\u4e8e\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\nfn LinkedListDeque(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*ListNode(T) = null,                    // \u5934\u8282\u70b9 front\n        rear: ?*ListNode(T) = null,                     // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                             // \u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u5165\u961f\u64cd\u4f5c\n        pub fn push(self: *Self, num: T, is_front: bool) !void {\n            var node = try self.mem_allocator.create(ListNode(T));\n            node.init(num);\n            // \u82e5\u94fe\u8868\u4e3a\u7a7a\uff0c\u5219\u4ee4 front \u548c rear \u90fd\u6307\u5411 node\n            if (self.isEmpty()) {\n                self.front = node;\n                self.rear = node;\n            // \u961f\u9996\u5165\u961f\u64cd\u4f5c\n            } else if (is_front) {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5934\u90e8\n                self.front.?.prev = node;\n                node.next = self.front;\n                self.front = node;  // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u5165\u961f\u64cd\u4f5c\n            } else {\n                // \u5c06 node \u6dfb\u52a0\u81f3\u94fe\u8868\u5c3e\u90e8\n                self.rear.?.next = node;\n                node.prev = self.rear;\n                self.rear = node;   // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size += 1;      // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n        } \n\n        // \u961f\u9996\u5165\u961f\n        pub fn pushFirst(self: *Self, num: T) !void {\n            try self.push(num, true);\n        } \n\n        // \u961f\u5c3e\u5165\u961f\n        pub fn pushLast(self: *Self, num: T) !void {\n            try self.push(num, false);\n        } \n\n        // \u51fa\u961f\u64cd\u4f5c\n        pub fn pop(self: *Self, is_front: bool) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            var val: T = undefined;\n            // \u961f\u9996\u51fa\u961f\u64cd\u4f5c\n            if (is_front) {\n                val = self.front.?.val;     // \u6682\u5b58\u5934\u8282\u70b9\u503c\n                // \u5220\u9664\u5934\u8282\u70b9\n                var fNext = self.front.?.next;\n                if (fNext != null) {\n                    fNext.?.prev = null;\n                    self.front.?.next = null;\n                }\n                self.front = fNext;         // \u66f4\u65b0\u5934\u8282\u70b9\n            // \u961f\u5c3e\u51fa\u961f\u64cd\u4f5c\n            } else {\n                val = self.rear.?.val;      // \u6682\u5b58\u5c3e\u8282\u70b9\u503c\n                // \u5220\u9664\u5c3e\u8282\u70b9\n                var rPrev = self.rear.?.prev;\n                if (rPrev != null) {\n                    rPrev.?.next = null;\n                    self.rear.?.prev = null;\n                }\n                self.rear = rPrev;          // \u66f4\u65b0\u5c3e\u8282\u70b9\n            }\n            self.que_size -= 1;              // \u66f4\u65b0\u961f\u5217\u957f\u5ea6\n            return val;\n        } \n\n        // \u961f\u9996\u51fa\u961f\n        pub fn popFirst(self: *Self) T {\n            return self.pop(true);\n        } \n\n        // \u961f\u5c3e\u51fa\u961f\n        pub fn popLast(self: *Self) T {\n            return self.pop(false);\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peekFirst(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\n        pub fn peekLast(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n            return self.rear.?.val;\n        }\n\n        // \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    "},{"location":"chapter_stack_and_queue/deque/#2","title":"2. \u00a0 \u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0","text":"

    \u5982\u56fe 5-9 \u6240\u793a\uff0c\u4e0e\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u961f\u5217\u7c7b\u4f3c\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u4f7f\u7528\u73af\u5f62\u6570\u7ec4\u6765\u5b9e\u73b0\u53cc\u5411\u961f\u5217\u3002

    ArrayDequepush_last()push_first()pop_last()pop_first()

    \u56fe 5-9 \u00a0 \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u53cc\u5411\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u5728\u961f\u5217\u7684\u5b9e\u73b0\u57fa\u7840\u4e0a\uff0c\u4ec5\u9700\u589e\u52a0\u201c\u961f\u9996\u5165\u961f\u201d\u548c\u201c\u961f\u5c3e\u51fa\u961f\u201d\u7684\u65b9\u6cd5\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_deque.py
    class ArrayDeque:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217\"\"\"\n\n    def __init__(self, capacity: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * capacity\n        self._front: int = 0\n        self._size: int = 0\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def index(self, i: int) -> int:\n        \"\"\"\u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15\"\"\"\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + self.capacity()) % self.capacity()\n\n    def push_first(self, num: int):\n        \"\"\"\u961f\u9996\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self._front = self.index(self._front - 1)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self._nums[self._front] = num\n        self._size += 1\n\n    def push_last(self, num: int):\n        \"\"\"\u961f\u5c3e\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        rear = self.index(self._front + self._size)\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop_first(self) -> int:\n        \"\"\"\u961f\u9996\u51fa\u961f\"\"\"\n        num = self.peek_first()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self._front = self.index(self._front + 1)\n        self._size -= 1\n        return num\n\n    def pop_last(self) -> int:\n        \"\"\"\u961f\u5c3e\u51fa\u961f\"\"\"\n        num = self.peek_last()\n        self._size -= 1\n        return num\n\n    def peek_first(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def peek_last(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u5c3e\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        last = self.index(self._front + self._size - 1)\n        return self._nums[last]\n\n    def to_array(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370\"\"\"\n        # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        res = []\n        for i in range(self._size):\n            res.append(self._nums[self.index(self._front + i)])\n        return res\n
    array_deque.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  private:\n    vector<int> nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;      // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayDeque(int capacity) {\n        nums.resize(capacity);\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return nums.size();\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    void pushFirst(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    void pushLast(int num) {\n        if (queSize == capacity()) {\n            cout << \"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peekFirst() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    int peekLast() {\n        if (isEmpty())\n            throw out_of_range(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> res(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n};\n
    array_deque.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        this.nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private int index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void pushFirst(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void pushLast(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int popFirst() {\n        int num = peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int popLast() {\n        int num = peekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peekFirst() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int peekLast() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayDeque(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    int Index(int i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + Capacity()) % Capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    public void PushFirst(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = Index(front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num;\n        queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    public void PushLast(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        int rear = Index(front + queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    public int PopFirst() {\n        int num = PeekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = Index(front + 1);\n        queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    public int PopLast() {\n        int num = PeekLast();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int PeekFirst() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        return nums[front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    public int PeekLast() {\n        if (IsEmpty()) {\n            throw new InvalidOperationException();\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        int last = Index(front + queSize - 1);\n        return nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[Index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntype arrayDeque struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayDeque(queCapacity int) *arrayDeque {\n    return &arrayDeque{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayDeque) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayDeque) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nfunc (q *arrayDeque) index(i int) int {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + q.queCapacity) % q.queCapacity\n}\n\n/* \u961f\u9996\u5165\u961f */\nfunc (q *arrayDeque) pushFirst(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    q.front = q.index(q.front - 1)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    q.nums[q.front] = num\n    q.queSize++\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nfunc (q *arrayDeque) pushLast(num int) {\n    if q.queSize == q.queCapacity {\n        fmt.Println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear := q.index(q.front + q.queSize)\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u961f\u9996\u51fa\u961f */\nfunc (q *arrayDeque) popFirst() any {\n    num := q.peekFirst()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    q.front = q.index(q.front + 1)\n    q.queSize--\n    return num\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nfunc (q *arrayDeque) popLast() any {\n    num := q.peekLast()\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayDeque) peekFirst() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nfunc (q *arrayDeque) peekLast() any {\n    if q.isEmpty() {\n        return nil\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last := q.index(q.front + q.queSize - 1)\n    return q.nums[last]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayDeque) toSlice() []int {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res := make([]int, q.queSize)\n    for i, j := 0, q.front; i < q.queSize; i++ {\n        res[i] = q.nums[q.index(j)]\n        j++\n    }\n    return res\n}\n
    array_deque.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(capacity: Int) {\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private func index(i: Int) -> Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    func pushFirst(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(i: front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        _size += 1\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    func pushLast(num: Int) {\n        if size() == capacity() {\n            print(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = index(i: front + size())\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    func popFirst() -> Int {\n        let num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(i: front + 1)\n        _size -= 1\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    func popLast() -> Int {\n        let num = peekLast()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peekFirst() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    func peekLast() -> Int {\n        if isEmpty() {\n            fatalError(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        }\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = index(i: front + size() - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[index(i: $0)] }\n    }\n}\n
    array_deque.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n        this.#front = 0;\n        this.#queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i) {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.#front = this.index(this.#front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.#nums[this.#front] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num) {\n        if (this.#queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear = this.index(this.#front + this.#queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst() {\n        const num = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.#front = this.index(this.#front + 1);\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast() {\n        const num = this.peekLast();\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.#front + this.#queSize - 1);\n        return this.#nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res = [];\n        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {\n            res[i] = this.#nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = 0;\n        this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    index(i: number): number {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + this.capacity()) % this.capacity();\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pushFirst(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        this.front = this.index(this.front - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        this.nums[this.front] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pushLast(num: number): void {\n        if (this.queSize === this.capacity()) {\n            console.log('\u53cc\u5411\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        const rear: number = this.index(this.front + this.queSize);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    popFirst(): number {\n        const num: number = this.peekFirst();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        this.front = this.index(this.front + 1);\n        this.queSize--;\n        return num;\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    popLast(): number {\n        const num: number = this.peekLast();\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peekFirst(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.nums[this.front];\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    peekLast(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        const last = this.index(this.front + this.queSize - 1);\n        return this.nums[last];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const res: number[] = [];\n        for (let i = 0, j = this.front; i < this.queSize; i++, j++) {\n            res[i] = this.nums[this.index(j)];\n        }\n        return res;\n    }\n}\n
    array_deque.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nclass ArrayDeque {\n  late List<int> _nums; // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayDeque(int capacity) {\n    this._nums = List.filled(capacity, 0);\n    this._front = this._queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n  int capacity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n  int index(int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return (i + capacity()) % capacity();\n  }\n\n  /* \u961f\u9996\u5165\u961f */\n  void pushFirst(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 _front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    _front = index(_front - 1);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u9996\n    _nums[_front] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u5c3e\u5165\u961f */\n  void pushLast(int _num) {\n    if (_queSize == capacity()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = index(_front + _queSize);\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u961f\u9996\u51fa\u961f */\n  int popFirst() {\n    int _num = peekFirst();\n    // \u961f\u9996\u6307\u9488\u5411\u53f3\u79fb\u52a8\u4e00\u4f4d\n    _front = index(_front + 1);\n    _queSize--;\n    return _num;\n  }\n\n  /* \u961f\u5c3e\u51fa\u961f */\n  int popLast() {\n    int _num = peekLast();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peekFirst() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n  int peekLast() {\n    if (isEmpty()) {\n      throw Exception(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\");\n    }\n    // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    int last = index(_front + _queSize - 1);\n    return _nums[last];\n  }\n\n  /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[index(j)];\n    }\n    return res;\n  }\n}\n
    array_deque.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\nstruct ArrayDeque {\n    nums: Vec<i32>,  // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: usize,    // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: usize, // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n}\n\nimpl ArrayDeque {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    pub fn new(capacity: usize) -> Self {\n        Self {\n            nums: vec![0; capacity],\n            front: 0,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    pub fn capacity(&self) -> usize {\n        self.nums.len()\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    fn index(&self, i: i32) -> usize {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return ((i + self.capacity() as i32) % self.capacity() as i32) as usize;\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    pub fn push_first(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        self.front = self.index(self.front as i32 - 1);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        self.nums[self.front] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    pub fn push_last(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        let rear = self.index(self.front as i32 + self.que_size as i32);\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear] = num;\n        self.que_size += 1;\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fn pop_first(&mut self) -> i32 {\n        let num = self.peek_first();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        self.front = self.index(self.front as i32 + 1);\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fn pop_last(&mut self) -> i32 {\n        let num = self.peek_last();\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek_first(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        self.nums[self.front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fn peek_last(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\")\n        };\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        let last = self.index(self.front as i32 + self.que_size as i32 - 1);\n        self.nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fn to_array(&self) -> Vec<i32> {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        let mut res = vec![0; self.que_size];\n        let mut j = self.front;\n        for i in 0..self.que_size {\n            res[i] = self.nums[self.index(j as i32)];\n            j += 1;\n        }\n        res\n    }\n}\n
    array_deque.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayDeque;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayDeque *newArrayDeque(int capacity) {\n    ArrayDeque *deque = (ArrayDeque *)malloc(sizeof(ArrayDeque));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    deque->queCapacity = capacity;\n    deque->nums = (int *)malloc(sizeof(int) * deque->queCapacity);\n    deque->front = deque->queSize = 0;\n    return deque;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayDeque(ArrayDeque *deque) {\n    free(deque->nums);\n    free(deque);\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayDeque *deque) {\n    return deque->queCapacity;\n}\n\n/* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayDeque *deque) {\n    return deque->queSize;\n}\n\n/* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayDeque *deque) {\n    return deque->queSize == 0;\n}\n\n/* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\nint dequeIndex(ArrayDeque *deque, int i) {\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u56de\u5230\u5934\u90e8\n    // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    return ((i + capacity(deque)) % capacity(deque));\n}\n\n/* \u961f\u9996\u5165\u961f */\nvoid pushFirst(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u56de\u5230\u5c3e\u90e8\n    deque->front = dequeIndex(deque, deque->front - 1);\n    // \u5c06 num \u6dfb\u52a0\u5230\u961f\u9996\n    deque->nums[deque->front] = num;\n    deque->queSize++;\n}\n\n/* \u961f\u5c3e\u5165\u961f */\nvoid pushLast(ArrayDeque *deque, int num) {\n    if (deque->queSize == capacity(deque)) {\n        printf(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    int rear = dequeIndex(deque, deque->front + deque->queSize);\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    deque->nums[rear] = num;\n    deque->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peekFirst(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    return deque->nums[deque->front];\n}\n\n/* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\nint peekLast(ArrayDeque *deque) {\n    // \u8bbf\u95ee\u5f02\u5e38\uff1a\u53cc\u5411\u961f\u5217\u4e3a\u7a7a\n    assert(empty(deque) == 0);\n    int last = dequeIndex(deque, deque->front + deque->queSize - 1);\n    return deque->nums[last];\n}\n\n/* \u961f\u9996\u51fa\u961f */\nint popFirst(ArrayDeque *deque) {\n    int num = peekFirst(deque);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    deque->front = dequeIndex(deque, deque->front + 1);\n    deque->queSize--;\n    return num;\n}\n\n/* \u961f\u5c3e\u51fa\u961f */\nint popLast(ArrayDeque *deque) {\n    int num = peekLast(deque);\n    deque->queSize--;\n    return num;\n}\n
    array_deque.kt
    /* \u6784\u9020\u65b9\u6cd5 */\nclass ArrayDeque(capacity: Int) {\n    private var nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u53cc\u5411\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u53cc\u5411\u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 */\n    private fun index(i: Int): Int {\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n        // \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n        return (i + capacity()) % capacity()\n    }\n\n    /* \u961f\u9996\u5165\u961f */\n    fun pushFirst(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n        front = index(front - 1)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n        nums[front] = num\n        queSize++\n    }\n\n    /* \u961f\u5c3e\u5165\u961f */\n    fun pushLast(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u53cc\u5411\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        val rear = index(front + queSize)\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u961f\u9996\u51fa\u961f */\n    fun popFirst(): Int {\n        val num = peekFirst()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n        front = index(front + 1)\n        queSize--\n        return num\n    }\n\n    /* \u961f\u5c3e\u51fa\u961f */\n    fun popLast(): Int {\n        val num = peekLast()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peekFirst(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 */\n    fun peekLast(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        // \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n        val last = index(front + queSize - 1)\n        return nums[last]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[index(j)]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_deque.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u53cc\u5411\u961f\u5217 ###\nclass ArrayDeque\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(capacity)\n    @nums = Array.new(capacity, 0)\n    @front = 0\n    @size = 0\n  end\n\n  ### \u83b7\u53d6\u53cc\u5411\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u53cc\u5411\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u961f\u9996\u5165\u961f ###\n  def push_first(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u961f\u9996\u6307\u9488\u5411\u5de6\u79fb\u52a8\u4e00\u4f4d\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 front \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\u56de\u5230\u5c3e\u90e8\n    @front = index(@front - 1)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u9996\n    @nums[@front] = num\n    @size += 1\n  end\n\n  ### \u961f\u5c3e\u5165\u961f ###\n  def push_last(num)\n    if size == capacity\n      puts '\u53cc\u5411\u961f\u5217\u5df2\u6ee1'\n      return\n    end\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    rear = index(@front + size)\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u961f\u9996\u51fa\u961f ###\n  def pop_first\n    num = peek_first\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\n    @front = index(@front + 1)\n    @size -= 1\n    num\n  end\n\n  ### \u961f\u5c3e\u51fa\u961f ###\n  def pop_last\n    num = peek_last\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek_first\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8bbf\u95ee\u961f\u5c3e\u5143\u7d20 ###\n  def peek_last\n    raise IndexError, '\u53cc\u5411\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    # \u8ba1\u7b97\u5c3e\u5143\u7d20\u7d22\u5f15\n    last = index(@front + size - 1)\n    @nums[last]\n  end\n\n  ### \u8fd4\u56de\u6570\u7ec4\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    # \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    res = []\n    for i in 0...size\n      res << @nums[index(@front + i)]\n    end\n    res\n  end\n\n  private\n\n  ### \u8ba1\u7b97\u73af\u5f62\u6570\u7ec4\u7d22\u5f15 ###\n  def index(i)\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0\u6570\u7ec4\u9996\u5c3e\u76f8\u8fde\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\uff0c\u56de\u5230\u5934\u90e8\n    # \u5f53 i \u8d8a\u8fc7\u6570\u7ec4\u5934\u90e8\u540e\uff0c\u56de\u5230\u5c3e\u90e8\n    (i + capacity) % capacity\n  end\nend\n
    array_deque.zig
    [class]{ArrayDeque}-[func]{}\n
    "},{"location":"chapter_stack_and_queue/deque/#533","title":"5.3.3 \u00a0 \u53cc\u5411\u961f\u5217\u5e94\u7528","text":"

    \u53cc\u5411\u961f\u5217\u517c\u5177\u6808\u4e0e\u961f\u5217\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u5b83\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u4e24\u8005\u7684\u6240\u6709\u5e94\u7528\u573a\u666f\uff0c\u540c\u65f6\u63d0\u4f9b\u66f4\u9ad8\u7684\u81ea\u7531\u5ea6\u3002

    \u6211\u4eec\u77e5\u9053\uff0c\u8f6f\u4ef6\u7684\u201c\u64a4\u9500\u201d\u529f\u80fd\u901a\u5e38\u4f7f\u7528\u6808\u6765\u5b9e\u73b0\uff1a\u7cfb\u7edf\u5c06\u6bcf\u6b21\u66f4\u6539\u64cd\u4f5c push \u5230\u6808\u4e2d\uff0c\u7136\u540e\u901a\u8fc7 pop \u5b9e\u73b0\u64a4\u9500\u3002\u7136\u800c\uff0c\u8003\u8651\u5230\u7cfb\u7edf\u8d44\u6e90\u7684\u9650\u5236\uff0c\u8f6f\u4ef6\u901a\u5e38\u4f1a\u9650\u5236\u64a4\u9500\u7684\u6b65\u6570\uff08\u4f8b\u5982\u4ec5\u5141\u8bb8\u4fdd\u5b58 \\(50\\) \u6b65\uff09\u3002\u5f53\u6808\u7684\u957f\u5ea6\u8d85\u8fc7 \\(50\\) \u65f6\uff0c\u8f6f\u4ef6\u9700\u8981\u5728\u6808\u5e95\uff08\u961f\u9996\uff09\u6267\u884c\u5220\u9664\u64cd\u4f5c\u3002\u4f46\u6808\u65e0\u6cd5\u5b9e\u73b0\u8be5\u529f\u80fd\uff0c\u6b64\u65f6\u5c31\u9700\u8981\u4f7f\u7528\u53cc\u5411\u961f\u5217\u6765\u66ff\u4ee3\u6808\u3002\u8bf7\u6ce8\u610f\uff0c\u201c\u64a4\u9500\u201d\u7684\u6838\u5fc3\u903b\u8f91\u4ecd\u7136\u9075\u5faa\u6808\u7684\u5148\u5165\u540e\u51fa\u539f\u5219\uff0c\u53ea\u662f\u53cc\u5411\u961f\u5217\u80fd\u591f\u66f4\u52a0\u7075\u6d3b\u5730\u5b9e\u73b0\u4e00\u4e9b\u989d\u5916\u903b\u8f91\u3002

    "},{"location":"chapter_stack_and_queue/queue/","title":"5.2 \u00a0 \u961f\u5217","text":"

    \u961f\u5217\uff08queue\uff09\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u5148\u51fa\u89c4\u5219\u7684\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002\u987e\u540d\u601d\u4e49\uff0c\u961f\u5217\u6a21\u62df\u4e86\u6392\u961f\u73b0\u8c61\uff0c\u5373\u65b0\u6765\u7684\u4eba\u4e0d\u65ad\u52a0\u5165\u961f\u5217\u5c3e\u90e8\uff0c\u800c\u4f4d\u4e8e\u961f\u5217\u5934\u90e8\u7684\u4eba\u9010\u4e2a\u79bb\u5f00\u3002

    \u5982\u56fe 5-4 \u6240\u793a\uff0c\u6211\u4eec\u5c06\u961f\u5217\u5934\u90e8\u79f0\u4e3a\u201c\u961f\u9996\u201d\uff0c\u5c3e\u90e8\u79f0\u4e3a\u201c\u961f\u5c3e\u201d\uff0c\u5c06\u628a\u5143\u7d20\u52a0\u5165\u961f\u5c3e\u7684\u64cd\u4f5c\u79f0\u4e3a\u201c\u5165\u961f\u201d\uff0c\u5220\u9664\u961f\u9996\u5143\u7d20\u7684\u64cd\u4f5c\u79f0\u4e3a\u201c\u51fa\u961f\u201d\u3002

    \u56fe 5-4 \u00a0 \u961f\u5217\u7684\u5148\u5165\u5148\u51fa\u89c4\u5219

    "},{"location":"chapter_stack_and_queue/queue/#521","title":"5.2.1 \u00a0 \u961f\u5217\u5e38\u7528\u64cd\u4f5c","text":"

    \u961f\u5217\u7684\u5e38\u89c1\u64cd\u4f5c\u5982\u8868 5-2 \u6240\u793a\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u7684\u65b9\u6cd5\u540d\u79f0\u53ef\u80fd\u4f1a\u6709\u6240\u4e0d\u540c\u3002\u6211\u4eec\u5728\u6b64\u91c7\u7528\u4e0e\u6808\u76f8\u540c\u7684\u65b9\u6cd5\u547d\u540d\u3002

    \u8868 5-2 \u00a0 \u961f\u5217\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5\u540d \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push() \u5143\u7d20\u5165\u961f\uff0c\u5373\u5c06\u5143\u7d20\u6dfb\u52a0\u81f3\u961f\u5c3e \\(O(1)\\) pop() \u961f\u9996\u5143\u7d20\u51fa\u961f \\(O(1)\\) peek() \u8bbf\u95ee\u961f\u9996\u5143\u7d20 \\(O(1)\\)

    \u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u4e2d\u73b0\u6210\u7684\u961f\u5217\u7c7b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig queue.py
    from collections import deque\n\n# \u521d\u59cb\u5316\u961f\u5217\n# \u5728 Python \u4e2d\uff0c\u6211\u4eec\u4e00\u822c\u5c06\u53cc\u5411\u961f\u5217\u7c7b deque \u5f53\u4f5c\u961f\u5217\u4f7f\u7528\n# \u867d\u7136 queue.Queue() \u662f\u7eaf\u6b63\u7684\u961f\u5217\u7c7b\uff0c\u4f46\u4e0d\u592a\u597d\u7528\uff0c\u56e0\u6b64\u4e0d\u63a8\u8350\nque: deque[int] = deque()\n\n# \u5143\u7d20\u5165\u961f\nque.append(1)\nque.append(3)\nque.append(2)\nque.append(5)\nque.append(4)\n\n# \u8bbf\u95ee\u961f\u9996\u5143\u7d20\nfront: int = que[0]\n\n# \u5143\u7d20\u51fa\u961f\npop: int = que.popleft()\n\n# \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\nsize: int = len(que)\n\n# \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = len(que) == 0\n
    queue.cpp
    /* \u521d\u59cb\u5316\u961f\u5217 */\nqueue<int> queue;\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint front = queue.front();\n\n/* \u5143\u7d20\u51fa\u961f */\nqueue.pop();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.size();\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty = queue.empty();\n
    queue.java
    /* \u521d\u59cb\u5316\u961f\u5217 */\nQueue<Integer> queue = new LinkedList<>();\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.offer(1);\nqueue.offer(3);\nqueue.offer(2);\nqueue.offer(5);\nqueue.offer(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek = queue.peek();\n\n/* \u5143\u7d20\u51fa\u961f */\nint pop = queue.poll();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.size();\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = queue.isEmpty();\n
    queue.cs
    /* \u521d\u59cb\u5316\u961f\u5217 */\nQueue<int> queue = new();\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.Enqueue(1);\nqueue.Enqueue(3);\nqueue.Enqueue(2);\nqueue.Enqueue(5);\nqueue.Enqueue(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek = queue.Peek();\n\n/* \u5143\u7d20\u51fa\u961f */\nint pop = queue.Dequeue();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.Count;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = queue.Count == 0;\n
    queue_test.go
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// \u5728 Go \u4e2d\uff0c\u5c06 list \u4f5c\u4e3a\u961f\u5217\u6765\u4f7f\u7528\nqueue := list.New()\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.PushBack(1)\nqueue.PushBack(3)\nqueue.PushBack(2)\nqueue.PushBack(5)\nqueue.PushBack(4)\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\npeek := queue.Front()\n\n/* \u5143\u7d20\u51fa\u961f */\npop := queue.Front()\nqueue.Remove(pop)\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nsize := queue.Len()\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nisEmpty := queue.Len() == 0\n
    queue.swift
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// Swift \u6ca1\u6709\u5185\u7f6e\u7684\u961f\u5217\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nvar queue: [Int] = []\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.append(1)\nqueue.append(3)\nqueue.append(2)\nqueue.append(5)\nqueue.append(4)\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nlet peek = queue.first!\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u7531\u4e8e\u662f\u6570\u7ec4\uff0c\u56e0\u6b64 removeFirst \u7684\u590d\u6742\u5ea6\u4e3a O(n)\nlet pool = queue.removeFirst()\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = queue.count\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = queue.isEmpty\n
    queue.js
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// JavaScript \u6ca1\u6709\u5185\u7f6e\u7684\u961f\u5217\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nconst queue = [];\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nconst peek = queue[0];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u56e0\u6b64 shift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst pop = queue.shift();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nconst size = queue.length;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst empty = queue.length === 0;\n
    queue.ts
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// TypeScript \u6ca1\u6709\u5185\u7f6e\u7684\u961f\u5217\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nconst queue: number[] = [];\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.push(1);\nqueue.push(3);\nqueue.push(2);\nqueue.push(5);\nqueue.push(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nconst peek = queue[0];\n\n/* \u5143\u7d20\u51fa\u961f */\n// \u5e95\u5c42\u662f\u6570\u7ec4\uff0c\u56e0\u6b64 shift() \u65b9\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\nconst pop = queue.shift();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nconst size = queue.length;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nconst empty = queue.length === 0;\n
    queue.dart
    /* \u521d\u59cb\u5316\u961f\u5217 */\n// \u5728 Dart \u4e2d\uff0c\u961f\u5217\u7c7b Qeque \u662f\u53cc\u5411\u961f\u5217\uff0c\u4e5f\u53ef\u4f5c\u4e3a\u961f\u5217\u4f7f\u7528\nQueue<int> queue = Queue();\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.add(1);\nqueue.add(3);\nqueue.add(2);\nqueue.add(5);\nqueue.add(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek = queue.first;\n\n/* \u5143\u7d20\u51fa\u961f */\nint pop = queue.removeFirst();\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size = queue.length;\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = queue.isEmpty;\n
    queue.rs
    /* \u521d\u59cb\u5316\u53cc\u5411\u961f\u5217 */\n// \u5728 Rust \u4e2d\u4f7f\u7528\u53cc\u5411\u961f\u5217\u4f5c\u4e3a\u666e\u901a\u961f\u5217\u6765\u4f7f\u7528\nlet mut deque: VecDeque<u32> = VecDeque::new();\n\n/* \u5143\u7d20\u5165\u961f */\ndeque.push_back(1);\ndeque.push_back(3);\ndeque.push_back(2);\ndeque.push_back(5);\ndeque.push_back(4);\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nif let Some(front) = deque.front() {\n}\n\n/* \u5143\u7d20\u51fa\u961f */\nif let Some(pop) = deque.pop_front() {\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nlet size = deque.len();\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = deque.is_empty();\n
    queue.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u961f\u5217\n
    queue.kt
    /* \u521d\u59cb\u5316\u961f\u5217 */\nval queue = LinkedList<Int>()\n\n/* \u5143\u7d20\u5165\u961f */\nqueue.offer(1)\nqueue.offer(3)\nqueue.offer(2)\nqueue.offer(5)\nqueue.offer(4)\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nval peek = queue.peek()\n\n/* \u5143\u7d20\u51fa\u961f */\nval pop = queue.poll()\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nval size = queue.size\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = queue.isEmpty()\n
    queue.rb
    # \u521d\u59cb\u5316\u961f\u5217\n# Ruby \u5185\u7f6e\u7684\u961f\u5217\uff08Thread::Queue) \u6ca1\u6709 peek \u548c\u904d\u5386\u65b9\u6cd5\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u961f\u5217\u6765\u4f7f\u7528\nqueue = []\n\n# \u5143\u7d20\u5165\u961f\nqueue.push(1)\nqueue.push(3)\nqueue.push(2)\nqueue.push(5)\nqueue.push(4)\n\n# \u8bbf\u95ee\u961f\u5217\u5143\u7d20\npeek = queue.first\n\n# \u5143\u7d20\u51fa\u961f\n# \u6e05\u6ce8\u610f\uff0c\u7531\u4e8e\u662f\u6570\u7ec4\uff0cArray#shift \u65b9\u6cd5\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a O(n)\npop = queue.shift\n\n# \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\nsize = queue.length\n\n# \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\nis_empty = queue.empty?\n
    queue.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/queue/#522","title":"5.2.2 \u00a0 \u961f\u5217\u5b9e\u73b0","text":"

    \u4e3a\u4e86\u5b9e\u73b0\u961f\u5217\uff0c\u6211\u4eec\u9700\u8981\u4e00\u79cd\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u4ee5\u5728\u4e00\u7aef\u6dfb\u52a0\u5143\u7d20\uff0c\u5e76\u5728\u53e6\u4e00\u7aef\u5220\u9664\u5143\u7d20\uff0c\u94fe\u8868\u548c\u6570\u7ec4\u90fd\u7b26\u5408\u8981\u6c42\u3002

    "},{"location":"chapter_stack_and_queue/queue/#1","title":"1. \u00a0 \u57fa\u4e8e\u94fe\u8868\u7684\u5b9e\u73b0","text":"

    \u5982\u56fe 5-5 \u6240\u793a\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u94fe\u8868\u7684\u201c\u5934\u8282\u70b9\u201d\u548c\u201c\u5c3e\u8282\u70b9\u201d\u5206\u522b\u89c6\u4e3a\u201c\u961f\u9996\u201d\u548c\u201c\u961f\u5c3e\u201d\uff0c\u89c4\u5b9a\u961f\u5c3e\u4ec5\u53ef\u6dfb\u52a0\u8282\u70b9\uff0c\u961f\u9996\u4ec5\u53ef\u5220\u9664\u8282\u70b9\u3002

    LinkedListQueuepush()pop()

    \u56fe 5-5 \u00a0 \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u4ee5\u4e0b\u662f\u7528\u94fe\u8868\u5b9e\u73b0\u961f\u5217\u7684\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_queue.py
    class LinkedListQueue:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._front: ListNode | None = None  # \u5934\u8282\u70b9 front\n        self._rear: ListNode | None = None  # \u5c3e\u8282\u70b9 rear\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        node = ListNode(num)\n        # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if self._front is None:\n            self._front = node\n            self._rear = node\n        # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else:\n            self._rear.next = node\n            self._rear = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num = self.peek()\n        # \u5220\u9664\u5934\u8282\u70b9\n        self._front = self._front.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._front.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        queue = []\n        temp = self._front\n        while temp:\n            queue.append(temp.val)\n            temp = temp.next\n        return queue\n
    linkedlist_queue.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  private:\n    ListNode *front, *rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    int queSize;\n\n  public:\n    LinkedListQueue() {\n        front = nullptr;\n        rear = nullptr;\n        queSize = 0;\n    }\n\n    ~LinkedListQueue() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(front);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode *node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == nullptr) {\n            front = node;\n            rear = node;\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear->next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        ListNode *tmp = front;\n        front = front->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (size() == 0)\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return front->val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = front;\n        vector<int> res(size());\n        for (int i = 0; i < res.size(); i++) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_queue.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private ListNode front, rear; // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = front;\n        int[] res = new int[size()];\n        for (int i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    ListNode? front, rear;  // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear \n    int queSize = 0;\n\n    public LinkedListQueue() {\n        front = null;\n        rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        ListNode node = new(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node;\n            rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else if (rear != null) {\n            rear.next = node;\n            rear = node;\n        }\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (front == null)\n            return [];\n\n        ListNode? node = front;\n        int[] res = new int[Size()];\n        for (int i = 0; i < res.Length; i++) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntype linkedListQueue struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u961f\u5217\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newLinkedListQueue() *linkedListQueue {\n    return &linkedListQueue{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u961f */\nfunc (s *linkedListQueue) push(value any) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u961f */\nfunc (s *linkedListQueue) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (s *linkedListQueue) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Front()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (s *linkedListQueue) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListQueue) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListQueue) toList() *list.List {\n    return s.data\n}\n
    linkedlist_queue.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private var front: ListNode? // \u5934\u8282\u70b9\n    private var rear: ListNode? // \u5c3e\u8282\u70b9\n    private var _size: Int\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let node = ListNode(x: num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if front == nil {\n            front = node\n            rear = node\n        }\n        // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        else {\n            rear?.next = node\n            rear = node\n        }\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return front!.val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = front\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    #front; // \u5934\u8282\u70b9 #front\n    #rear; // \u5c3e\u8282\u70b9 #rear\n    #queSize = 0;\n\n    constructor() {\n        this.#front = null;\n        this.#rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.#front) {\n            this.#front = node;\n            this.#rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.#rear.next = node;\n            this.#rear = node;\n        }\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.#front = this.#front.next;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#front.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#front;\n        const res = new Array(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n    private front: ListNode | null; // \u5934\u8282\u70b9 front\n    private rear: ListNode | null; // \u5c3e\u8282\u70b9 rear\n    private queSize: number = 0;\n\n    constructor() {\n        this.front = null;\n        this.rear = null;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        const node = new ListNode(num);\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (!this.front) {\n            this.front = node;\n            this.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            this.rear!.next = node;\n            this.rear = node;\n        }\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        if (!this.front) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        // \u5220\u9664\u5934\u8282\u70b9\n        this.front = this.front.next;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.size === 0) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.front!.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.front;\n        const res = new Array<number>(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_queue.dart
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue {\n  ListNode? _front; // \u5934\u8282\u70b9 _front\n  ListNode? _rear; // \u5c3e\u8282\u70b9 _rear\n  int _queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n  LinkedListQueue() {\n    _front = null;\n    _rear = null;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 _num\n    final node = ListNode(_num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (_front == null) {\n      _front = node;\n      _rear = node;\n    } else {\n      // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n      _rear!.next = node;\n      _rear = node;\n    }\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    final int _num = peek();\n    // \u5220\u9664\u5934\u8282\u70b9\n    _front = _front!.next;\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (_queSize == 0) {\n      throw Exception('\u961f\u5217\u4e3a\u7a7a');\n    }\n    return _front!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() {\n    ListNode? node = _front;\n    final List<int> queue = [];\n    while (node != null) {\n      queue.add(node.val);\n      node = node.next;\n    }\n    return queue;\n  }\n}\n
    linkedlist_queue.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\n#[allow(dead_code)]\npub struct LinkedListQueue<T> {\n    front: Option<Rc<RefCell<ListNode<T>>>>, // \u5934\u8282\u70b9 front\n    rear: Option<Rc<RefCell<ListNode<T>>>>,  // \u5c3e\u8282\u70b9 rear\n    que_size: usize,                         // \u961f\u5217\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListQueue<T> {\n    pub fn new() -> Self {\n        Self {\n            front: None,\n            rear: None,\n            que_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.que_size;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u961f */\n    pub fn push(&mut self, num: T) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        let new_rear = ListNode::new(num);\n        match self.rear.take() {\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            Some(old_rear) => {\n                old_rear.borrow_mut().next = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            None => {\n                self.front = Some(new_rear.clone());\n                self.rear = Some(new_rear);\n            }\n        }\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    pub fn pop(&mut self) -> Option<T> {\n        self.front.take().map(|old_front| {\n            match old_front.borrow_mut().next.take() {\n                Some(new_front) => {\n                    self.front = Some(new_front);\n                }\n                None => {\n                    self.rear.take();\n                }\n            }\n            self.que_size -= 1;\n            Rc::try_unwrap(old_front).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.front.as_ref()\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.insert(0, node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_queue.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    ListNode *front, *rear;\n    int queSize;\n} LinkedListQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListQueue *newLinkedListQueue() {\n    LinkedListQueue *queue = (LinkedListQueue *)malloc(sizeof(LinkedListQueue));\n    queue->front = NULL;\n    queue->rear = NULL;\n    queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListQueue(LinkedListQueue *queue) {\n    // \u91ca\u653e\u6240\u6709\u8282\u70b9\n    while (queue->front != NULL) {\n        ListNode *tmp = queue->front;\n        queue->front = queue->front->next;\n        free(tmp);\n    }\n    // \u91ca\u653e queue \u7ed3\u6784\u4f53\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(LinkedListQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(LinkedListQueue *queue) {\n    return (size(queue) == 0);\n}\n\n/* \u5165\u961f */\nvoid push(LinkedListQueue *queue, int num) {\n    // \u5c3e\u8282\u70b9\u5904\u6dfb\u52a0 node\n    ListNode *node = newListNode(num);\n    // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if (queue->front == NULL) {\n        queue->front = node;\n        queue->rear = node;\n    }\n    // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else {\n        queue->rear->next = node;\n        queue->rear = node;\n    }\n    queue->queSize++;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(LinkedListQueue *queue) {\n    assert(size(queue) && queue->front);\n    return queue->front->val;\n}\n\n/* \u51fa\u961f */\nint pop(LinkedListQueue *queue) {\n    int num = peek(queue);\n    ListNode *tmp = queue->front;\n    queue->front = queue->front->next;\n    free(tmp);\n    queue->queSize--;\n    return num;\n}\n\n/* \u6253\u5370\u961f\u5217 */\nvoid printLinkedListQueue(LinkedListQueue *queue) {\n    int *arr = malloc(sizeof(int) * queue->queSize);\n    // \u62f7\u8d1d\u94fe\u8868\u4e2d\u7684\u6570\u636e\u5230\u6570\u7ec4\n    int i;\n    ListNode *node;\n    for (i = 0, node = queue->front; i < queue->queSize; i++) {\n        arr[i] = node->val;\n        node = node->next;\n    }\n    printArray(arr, queue->queSize);\n    free(arr);\n}\n
    linkedlist_queue.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217 */\nclass LinkedListQueue(\n    // \u5934\u8282\u70b9 front \uff0c\u5c3e\u8282\u70b9 rear\n    private var front: ListNode? = null,\n    private var rear: ListNode? = null,\n    private var queSize: Int = 0\n) {\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n        val node = ListNode(num)\n        // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n        if (front == null) {\n            front = node\n            rear = node\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n        } else {\n            rear?.next = node\n            rear = node\n        }\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u5220\u9664\u5934\u8282\u70b9\n        front = front?.next\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return front!!._val\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = front\n        val res = IntArray(size())\n        for (i in res.indices) {\n            res[i] = node!!._val\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_queue.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5934\u73b0\u7684\u961f\u5217 ###\nclass LinkedListQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @front = nil  # \u5934\u8282\u70b9 front\n    @rear = nil   # \u5c3e\u8282\u70b9 rear\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @front.nil?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    # \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n    node = ListNode.new(num)\n\n    # \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\uff0c\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n    if @front.nil?\n      @front = node\n      @rear = node\n    # \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u4ee4\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n    else\n      @rear.next = node\n      @rear = node\n    end\n\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u5220\u9664\u5934\u8282\u70b9\n    @front = @front.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @front.val\n  end\n\n  ### \u5c06\u94fe\u8868\u4e3a Array \u5e76\u8fd4\u56de ###\n  def to_array\n    queue = []\n    temp = @front\n    while temp\n      queue << temp.val\n      temp = temp.next\n    end\n    queue\n  end\nend\n
    linkedlist_queue.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u961f\u5217\nfn LinkedListQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        front: ?*inc.ListNode(T) = null,                // \u5934\u8282\u70b9 front\n        rear: ?*inc.ListNode(T) = null,                 // \u5c3e\u8282\u70b9 rear\n        que_size: usize = 0,                            // \u961f\u5217\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u961f\u5217\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.front = null;\n            self.rear = null;\n            self.que_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.que_size;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.front.?.val;\n        }  \n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            // \u5982\u679c\u961f\u5217\u4e3a\u7a7a\uff0c\u5219\u4ee4\u5934\u3001\u5c3e\u8282\u70b9\u90fd\u6307\u5411\u8be5\u8282\u70b9\n            if (self.front == null) {\n                self.front = node;\n                self.rear = node;\n            // \u5982\u679c\u961f\u5217\u4e0d\u4e3a\u7a7a\uff0c\u5219\u5c06\u8be5\u8282\u70b9\u6dfb\u52a0\u5230\u5c3e\u8282\u70b9\u540e\n            } else {\n                self.rear.?.next = node;\n                self.rear = node;\n            }\n            self.que_size += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u5220\u9664\u5934\u8282\u70b9\n            self.front = self.front.?.next;\n            self.que_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u94fe\u8868\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.front;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[i] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/queue/#2","title":"2. \u00a0 \u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0","text":"

    \u5728\u6570\u7ec4\u4e2d\u5220\u9664\u9996\u5143\u7d20\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff0c\u8fd9\u4f1a\u5bfc\u81f4\u51fa\u961f\u64cd\u4f5c\u6548\u7387\u8f83\u4f4e\u3002\u7136\u800c\uff0c\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u4ee5\u4e0b\u5de7\u5999\u65b9\u6cd5\u6765\u907f\u514d\u8fd9\u4e2a\u95ee\u9898\u3002

    \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u53d8\u91cf front \u6307\u5411\u961f\u9996\u5143\u7d20\u7684\u7d22\u5f15\uff0c\u5e76\u7ef4\u62a4\u4e00\u4e2a\u53d8\u91cf size \u7528\u4e8e\u8bb0\u5f55\u961f\u5217\u957f\u5ea6\u3002\u5b9a\u4e49 rear = front + size \uff0c\u8fd9\u4e2a\u516c\u5f0f\u8ba1\u7b97\u51fa\u7684 rear \u6307\u5411\u961f\u5c3e\u5143\u7d20\u4e4b\u540e\u7684\u4e0b\u4e00\u4e2a\u4f4d\u7f6e\u3002

    \u57fa\u4e8e\u6b64\u8bbe\u8ba1\uff0c\u6570\u7ec4\u4e2d\u5305\u542b\u5143\u7d20\u7684\u6709\u6548\u533a\u95f4\u4e3a [front, rear - 1]\uff0c\u5404\u79cd\u64cd\u4f5c\u7684\u5b9e\u73b0\u65b9\u6cd5\u5982\u56fe 5-6 \u6240\u793a\u3002

    • \u5165\u961f\u64cd\u4f5c\uff1a\u5c06\u8f93\u5165\u5143\u7d20\u8d4b\u503c\u7ed9 rear \u7d22\u5f15\u5904\uff0c\u5e76\u5c06 size \u589e\u52a0 1 \u3002
    • \u51fa\u961f\u64cd\u4f5c\uff1a\u53ea\u9700\u5c06 front \u589e\u52a0 1 \uff0c\u5e76\u5c06 size \u51cf\u5c11 1 \u3002

    \u53ef\u4ee5\u770b\u5230\uff0c\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u90fd\u53ea\u9700\u8fdb\u884c\u4e00\u6b21\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(1)\\) \u3002

    ArrayQueuepush()pop()

    \u56fe 5-6 \u00a0 \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u961f\u5217\u7684\u5165\u961f\u51fa\u961f\u64cd\u4f5c

    \u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0\u4e00\u4e2a\u95ee\u9898\uff1a\u5728\u4e0d\u65ad\u8fdb\u884c\u5165\u961f\u548c\u51fa\u961f\u7684\u8fc7\u7a0b\u4e2d\uff0cfront \u548c rear \u90fd\u5728\u5411\u53f3\u79fb\u52a8\uff0c\u5f53\u5b83\u4eec\u5230\u8fbe\u6570\u7ec4\u5c3e\u90e8\u65f6\u5c31\u65e0\u6cd5\u7ee7\u7eed\u79fb\u52a8\u4e86\u3002\u4e3a\u4e86\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u7ec4\u89c6\u4e3a\u9996\u5c3e\u76f8\u63a5\u7684\u201c\u73af\u5f62\u6570\u7ec4\u201d\u3002

    \u5bf9\u4e8e\u73af\u5f62\u6570\u7ec4\uff0c\u6211\u4eec\u9700\u8981\u8ba9 front \u6216 rear \u5728\u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u65f6\uff0c\u76f4\u63a5\u56de\u5230\u6570\u7ec4\u5934\u90e8\u7ee7\u7eed\u904d\u5386\u3002\u8fd9\u79cd\u5468\u671f\u6027\u89c4\u5f8b\u53ef\u4ee5\u901a\u8fc7\u201c\u53d6\u4f59\u64cd\u4f5c\u201d\u6765\u5b9e\u73b0\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_queue.py
    class ArrayQueue:\n    \"\"\"\u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\"\"\"\n\n    def __init__(self, size: int):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._nums: list[int] = [0] * size  # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n        self._front: int = 0  # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        self._size: int = 0  # \u961f\u5217\u957f\u5ea6\n\n    def capacity(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\"\"\"\n        return len(self._nums)\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, num: int):\n        \"\"\"\u5165\u961f\"\"\"\n        if self._size == self.capacity():\n            raise IndexError(\"\u961f\u5217\u5df2\u6ee1\")\n        # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        rear: int = (self._front + self._size) % self.capacity()\n        # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self._nums[rear] = num\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u961f\"\"\"\n        num: int = self.peek()\n        # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self._front = (self._front + 1) % self.capacity()\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u961f\u9996\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u961f\u5217\u4e3a\u7a7a\")\n        return self._nums[self._front]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        res = [0] * self.size()\n        j: int = self._front\n        for i in range(self.size()):\n            res[i] = self._nums[(j % self.capacity())]\n            j += 1\n        return res\n
    array_queue.cpp
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  private:\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u961f\u5217\u957f\u5ea6\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n\n  public:\n    ArrayQueue(int capacity) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = new int[capacity];\n        queCapacity = capacity;\n        front = queSize = 0;\n    }\n\n    ~ArrayQueue() {\n        delete[] nums;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int capacity() {\n        return queCapacity;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u961f */\n    void push(int num) {\n        if (queSize == queCapacity) {\n            cout << \"\u961f\u5217\u5df2\u6ee1\" << endl;\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % queCapacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % queCapacity;\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    int peek() {\n        if (isEmpty())\n            throw out_of_range(\"\u961f\u5217\u4e3a\u7a7a\");\n        return nums[front];\n    }\n\n    /* \u5c06\u6570\u7ec4\u8f6c\u5316\u4e3a Vector \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        vector<int> arr(queSize);\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            arr[i] = nums[j % queCapacity];\n        }\n        return arr;\n    }\n};\n
    array_queue.java
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private int[] nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private int front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    public int capacity() {\n        return nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void push(int num) {\n        if (queSize == capacity()) {\n            System.out.println(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int pop() {\n        int num = peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.cs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    int[] nums;  // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize; // \u961f\u5217\u957f\u5ea6\n\n    public ArrayQueue(int capacity) {\n        nums = new int[capacity];\n        front = queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    int Capacity() {\n        return nums.Length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    public int Size() {\n        return queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return queSize == 0;\n    }\n\n    /* \u5165\u961f */\n    public void Push(int num) {\n        if (queSize == Capacity()) {\n            Console.WriteLine(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        int rear = (front + queSize) % Capacity();\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num;\n        queSize++;\n    }\n\n    /* \u51fa\u961f */\n    public int Pop() {\n        int num = Peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % Capacity();\n        queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return nums[front];\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    public int[] ToArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        int[] res = new int[queSize];\n        for (int i = 0, j = front; i < queSize; i++, j++) {\n            res[i] = nums[j % this.Capacity()];\n        }\n        return res;\n    }\n}\n
    array_queue.go
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntype arrayQueue struct {\n    nums        []int // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front       int   // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    queSize     int   // \u961f\u5217\u957f\u5ea6\n    queCapacity int   // \u961f\u5217\u5bb9\u91cf\uff08\u5373\u6700\u5927\u5bb9\u7eb3\u5143\u7d20\u6570\u91cf\uff09\n}\n\n/* \u521d\u59cb\u5316\u961f\u5217 */\nfunc newArrayQueue(queCapacity int) *arrayQueue {\n    return &arrayQueue{\n        nums:        make([]int, queCapacity),\n        queCapacity: queCapacity,\n        front:       0,\n        queSize:     0,\n    }\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nfunc (q *arrayQueue) size() int {\n    return q.queSize\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nfunc (q *arrayQueue) isEmpty() bool {\n    return q.queSize == 0\n}\n\n/* \u5165\u961f */\nfunc (q *arrayQueue) push(num int) {\n    // \u5f53 rear == queCapacity \u8868\u793a\u961f\u5217\u5df2\u6ee1\n    if q.queSize == q.queCapacity {\n        return\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear := (q.front + q.queSize) % q.queCapacity\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    q.nums[rear] = num\n    q.queSize++\n}\n\n/* \u51fa\u961f */\nfunc (q *arrayQueue) pop() any {\n    num := q.peek()\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    q.front = (q.front + 1) % q.queCapacity\n    q.queSize--\n    return num\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nfunc (q *arrayQueue) peek() any {\n    if q.isEmpty() {\n        return nil\n    }\n    return q.nums[q.front]\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (q *arrayQueue) toSlice() []int {\n    rear := (q.front + q.queSize)\n    if rear >= q.queCapacity {\n        rear %= q.queCapacity\n        return append(q.nums[q.front:], q.nums[:rear]...)\n    }\n    return q.nums[q.front:rear]\n}\n
    array_queue.swift
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private var nums: [Int] // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var _size: Int // \u961f\u5217\u957f\u5ea6\n\n    init(capacity: Int) {\n        // \u521d\u59cb\u5316\u6570\u7ec4\n        nums = Array(repeating: 0, count: capacity)\n        front = 0\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    func capacity() -> Int {\n        nums.count\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u961f */\n    func push(num: Int) {\n        if size() == capacity() {\n            print(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (front + size()) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        _size += 1\n    }\n\n    /* \u51fa\u961f */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u961f\u5217\u4e3a\u7a7a\")\n        }\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    func toArray() -> [Int] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        (front ..< front + size()).map { nums[$0 % capacity()] }\n    }\n}\n
    array_queue.js
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    #nums; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    #front = 0; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    #queSize = 0; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity) {\n        this.#nums = new Array(capacity);\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity() {\n        return this.#nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num) {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.#front + this.size) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.#nums[rear] = num;\n        this.#queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop() {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.#front = (this.#front + 1) % this.capacity;\n        this.#queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek() {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.#nums[this.#front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.#front; i < this.size; i++, j++) {\n            arr[i] = this.#nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.ts
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n    private nums: number[]; // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private front: number; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private queSize: number; // \u961f\u5217\u957f\u5ea6\n\n    constructor(capacity: number) {\n        this.nums = new Array(capacity);\n        this.front = this.queSize = 0;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    get capacity(): number {\n        return this.nums.length;\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.queSize;\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.queSize === 0;\n    }\n\n    /* \u5165\u961f */\n    push(num: number): void {\n        if (this.size === this.capacity) {\n            console.log('\u961f\u5217\u5df2\u6ee1');\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        const rear = (this.front + this.queSize) % this.capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* \u51fa\u961f */\n    pop(): number {\n        const num = this.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        this.front = (this.front + 1) % this.capacity;\n        this.queSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    peek(): number {\n        if (this.isEmpty()) throw new Error('\u961f\u5217\u4e3a\u7a7a');\n        return this.nums[this.front];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray(): number[] {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.front; i < this.size; i++, j++) {\n            arr[i] = this.nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n
    array_queue.dart
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue {\n  late List<int> _nums; // \u7528\u4e8e\u50a8\u5b58\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n  late int _front; // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n  late int _queSize; // \u961f\u5217\u957f\u5ea6\n\n  ArrayQueue(int capacity) {\n    _nums = List.filled(capacity, 0);\n    _front = _queSize = 0;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n  int capaCity() {\n    return _nums.length;\n  }\n\n  /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n  int size() {\n    return _queSize;\n  }\n\n  /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _queSize == 0;\n  }\n\n  /* \u5165\u961f */\n  void push(int _num) {\n    if (_queSize == capaCity()) {\n      throw Exception(\"\u961f\u5217\u5df2\u6ee1\");\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (_front + _queSize) % capaCity();\n    // \u5c06 _num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    _nums[rear] = _num;\n    _queSize++;\n  }\n\n  /* \u51fa\u961f */\n  int pop() {\n    int _num = peek();\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    _front = (_front + 1) % capaCity();\n    _queSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u961f\u5217\u4e3a\u7a7a\");\n    }\n    return _nums[_front];\n  }\n\n  /* \u8fd4\u56de Array */\n  List<int> toArray() {\n    // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n    final List<int> res = List.filled(_queSize, 0);\n    for (int i = 0, j = _front; i < _queSize; i++, j++) {\n      res[i] = _nums[j % capaCity()];\n    }\n    return res;\n  }\n}\n
    array_queue.rs
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nstruct ArrayQueue {\n    nums: Vec<i32>,    // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    front: i32,        // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    que_size: i32,     // \u961f\u5217\u957f\u5ea6\n    que_capacity: i32, // \u961f\u5217\u5bb9\u91cf\n}\n\nimpl ArrayQueue {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(capacity: i32) -> ArrayQueue {\n        ArrayQueue {\n            nums: vec![0; capacity as usize],\n            front: 0,\n            que_size: 0,\n            que_capacity: capacity,\n        }\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fn capacity(&self) -> i32 {\n        self.que_capacity\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fn size(&self) -> i32 {\n        self.que_size\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.que_size == 0\n    }\n\n    /* \u5165\u961f */\n    fn push(&mut self, num: i32) {\n        if self.que_size == self.capacity() {\n            println!(\"\u961f\u5217\u5df2\u6ee1\");\n            return;\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        let rear = (self.front + self.que_size) % self.que_capacity;\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        self.nums[rear as usize] = num;\n        self.que_size += 1;\n    }\n\n    /* \u51fa\u961f */\n    fn pop(&mut self) -> i32 {\n        let num = self.peek();\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        self.front = (self.front + 1) % self.que_capacity;\n        self.que_size -= 1;\n        num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fn peek(&self) -> i32 {\n        if self.is_empty() {\n            panic!(\"index out of bounds\");\n        }\n        self.nums[self.front as usize]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fn to_vector(&self) -> Vec<i32> {\n        let cap = self.que_capacity;\n        let mut j = self.front;\n        let mut arr = vec![0; self.que_size as usize];\n        for i in 0..self.que_size {\n            arr[i as usize] = self.nums[(j % cap) as usize];\n            j += 1;\n        }\n        arr\n    }\n}\n
    array_queue.c
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\ntypedef struct {\n    int *nums;       // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    int front;       // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    int queSize;     // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n    int queCapacity; // \u961f\u5217\u5bb9\u91cf\n} ArrayQueue;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayQueue *newArrayQueue(int capacity) {\n    ArrayQueue *queue = (ArrayQueue *)malloc(sizeof(ArrayQueue));\n    // \u521d\u59cb\u5316\u6570\u7ec4\n    queue->queCapacity = capacity;\n    queue->nums = (int *)malloc(sizeof(int) * queue->queCapacity);\n    queue->front = queue->queSize = 0;\n    return queue;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayQueue(ArrayQueue *queue) {\n    free(queue->nums);\n    free(queue);\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\nint capacity(ArrayQueue *queue) {\n    return queue->queCapacity;\n}\n\n/* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\nint size(ArrayQueue *queue) {\n    return queue->queSize;\n}\n\n/* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\nbool empty(ArrayQueue *queue) {\n    return queue->queSize == 0;\n}\n\n/* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\nint peek(ArrayQueue *queue) {\n    assert(size(queue) != 0);\n    return queue->nums[queue->front];\n}\n\n/* \u5165\u961f */\nvoid push(ArrayQueue *queue, int num) {\n    if (size(queue) == capacity(queue)) {\n        printf(\"\u961f\u5217\u5df2\u6ee1\\r\\n\");\n        return;\n    }\n    // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    int rear = (queue->front + queue->queSize) % queue->queCapacity;\n    // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    queue->nums[rear] = num;\n    queue->queSize++;\n}\n\n/* \u51fa\u961f */\nint pop(ArrayQueue *queue) {\n    int num = peek(queue);\n    // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    queue->front = (queue->front + 1) % queue->queCapacity;\n    queue->queSize--;\n    return num;\n}\n
    array_queue.kt
    /* \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 */\nclass ArrayQueue(capacity: Int) {\n    private val nums: IntArray = IntArray(capacity) // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    private var front: Int = 0 // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    private var queSize: Int = 0 // \u961f\u5217\u957f\u5ea6\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf */\n    fun capacity(): Int {\n        return nums.size\n    }\n\n    /* \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return queSize\n    }\n\n    /* \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return queSize == 0\n    }\n\n    /* \u5165\u961f */\n    fun push(num: Int) {\n        if (queSize == capacity()) {\n            println(\"\u961f\u5217\u5df2\u6ee1\")\n            return\n        }\n        // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n        // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n        val rear = (front + queSize) % capacity()\n        // \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n        nums[rear] = num\n        queSize++\n    }\n\n    /* \u51fa\u961f */\n    fun pop(): Int {\n        val num = peek()\n        // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n        front = (front + 1) % capacity()\n        queSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u961f\u9996\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return nums[front]\n    }\n\n    /* \u8fd4\u56de\u6570\u7ec4 */\n    fun toArray(): IntArray {\n        // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n        val res = IntArray(queSize)\n        var i = 0\n        var j = front\n        while (i < queSize) {\n            res[i] = nums[j % capacity()]\n            i++\n            j++\n        }\n        return res\n    }\n}\n
    array_queue.rb
    ### \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217 ###\nclass ArrayQueue\n  ### \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6 ###\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(size)\n    @nums = Array.new(size, 0) # \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4\n    @front = 0 # \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n    @size = 0 # \u961f\u5217\u957f\u5ea6\n  end\n\n  ### \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf ###\n  def capacity\n    @nums.length\n  end\n\n  ### \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    size.zero?\n  end\n\n  ### \u5165\u961f ###\n  def push(num)\n    raise IndexError, '\u961f\u5217\u5df2\u6ee1' if size == capacity\n\n    # \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n    # \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n    rear = (@front + size) % capacity\n    # \u5c06 num \u6dfb\u52a0\u81f3\u961f\u5c3e\n    @nums[rear] = num\n    @size += 1\n  end\n\n  ### \u51fa\u961f ###\n  def pop\n    num = peek\n    # \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n    @front = (@front + 1) % capacity\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u961f\u9996\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u961f\u5217\u4e3a\u7a7a' if is_empty?\n\n    @nums[@front]\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    res = Array.new(size, 0)\n    j = @front\n\n    for i in 0...size\n      res[i] = @nums[j % capacity]\n      j += 1\n    end\n\n    res\n  end\nend\n
    array_queue.zig
    // \u57fa\u4e8e\u73af\u5f62\u6570\u7ec4\u5b9e\u73b0\u7684\u961f\u5217\nfn ArrayQueue(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        nums: []T = undefined,                          // \u7528\u4e8e\u5b58\u50a8\u961f\u5217\u5143\u7d20\u7684\u6570\u7ec4     \n        cap: usize = 0,                                 // \u961f\u5217\u5bb9\u91cf\n        front: usize = 0,                               // \u961f\u9996\u6307\u9488\uff0c\u6307\u5411\u961f\u9996\u5143\u7d20\n        queSize: usize = 0,                             // \u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e + 1\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,   // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6570\u7ec4\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator, cap: usize) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.cap = cap;\n            self.nums = try self.mem_allocator.alloc(T, self.cap);\n            @memset(self.nums, @as(T, 0));\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u5bb9\u91cf\n        pub fn capacity(self: *Self) usize {\n            return self.cap;\n        }\n\n        // \u83b7\u53d6\u961f\u5217\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.queSize;\n        }\n\n        // \u5224\u65ad\u961f\u5217\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.queSize == 0;\n        }\n\n        // \u5165\u961f\n        pub fn push(self: *Self, num: T) !void {\n            if (self.size() == self.capacity()) {\n                std.debug.print(\"\u961f\u5217\u5df2\u6ee1\\n\", .{});\n                return;\n            }\n            // \u8ba1\u7b97\u961f\u5c3e\u6307\u9488\uff0c\u6307\u5411\u961f\u5c3e\u7d22\u5f15 + 1\n            // \u901a\u8fc7\u53d6\u4f59\u64cd\u4f5c\u5b9e\u73b0 rear \u8d8a\u8fc7\u6570\u7ec4\u5c3e\u90e8\u540e\u56de\u5230\u5934\u90e8\n            var rear = (self.front + self.queSize) % self.capacity();\n            // \u5728\u5c3e\u8282\u70b9\u540e\u6dfb\u52a0 num\n            self.nums[rear] = num;\n            self.queSize += 1;\n        } \n\n        // \u51fa\u961f\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            // \u961f\u9996\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4f4d\uff0c\u82e5\u8d8a\u8fc7\u5c3e\u90e8\uff0c\u5219\u8fd4\u56de\u5230\u6570\u7ec4\u5934\u90e8\n            self.front = (self.front + 1) % self.capacity();\n            self.queSize -= 1;\n            return num;\n        } \n\n        // \u8bbf\u95ee\u961f\u9996\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u961f\u5217\u4e3a\u7a7a\");\n            return self.nums[self.front];\n        } \n\n        // \u8fd4\u56de\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            // \u4ec5\u8f6c\u6362\u6709\u6548\u957f\u5ea6\u8303\u56f4\u5185\u7684\u5217\u8868\u5143\u7d20\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            var j: usize = self.front;\n            while (i < self.size()) : ({ i += 1; j += 1; }) {\n                res[i] = self.nums[j % self.capacity()];\n            }\n            return res;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4ee5\u4e0a\u5b9e\u73b0\u7684\u961f\u5217\u4ecd\u7136\u5177\u6709\u5c40\u9650\u6027\uff1a\u5176\u957f\u5ea6\u4e0d\u53ef\u53d8\u3002\u7136\u800c\uff0c\u8fd9\u4e2a\u95ee\u9898\u4e0d\u96be\u89e3\u51b3\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u7ec4\u66ff\u6362\u4e3a\u52a8\u6001\u6570\u7ec4\uff0c\u4ece\u800c\u5f15\u5165\u6269\u5bb9\u673a\u5236\u3002\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u5c1d\u8bd5\u81ea\u884c\u5b9e\u73b0\u3002

    \u4e24\u79cd\u5b9e\u73b0\u7684\u5bf9\u6bd4\u7ed3\u8bba\u4e0e\u6808\u4e00\u81f4\uff0c\u5728\u6b64\u4e0d\u518d\u8d58\u8ff0\u3002

    "},{"location":"chapter_stack_and_queue/queue/#523","title":"5.2.3 \u00a0 \u961f\u5217\u5178\u578b\u5e94\u7528","text":"
    • \u6dd8\u5b9d\u8ba2\u5355\u3002\u8d2d\u7269\u8005\u4e0b\u5355\u540e\uff0c\u8ba2\u5355\u5c06\u52a0\u5165\u961f\u5217\u4e2d\uff0c\u7cfb\u7edf\u968f\u540e\u4f1a\u6839\u636e\u987a\u5e8f\u5904\u7406\u961f\u5217\u4e2d\u7684\u8ba2\u5355\u3002\u5728\u53cc\u5341\u4e00\u671f\u95f4\uff0c\u77ed\u65f6\u95f4\u5185\u4f1a\u4ea7\u751f\u6d77\u91cf\u8ba2\u5355\uff0c\u9ad8\u5e76\u53d1\u6210\u4e3a\u5de5\u7a0b\u5e08\u4eec\u9700\u8981\u91cd\u70b9\u653b\u514b\u7684\u95ee\u9898\u3002
    • \u5404\u7c7b\u5f85\u529e\u4e8b\u9879\u3002\u4efb\u4f55\u9700\u8981\u5b9e\u73b0\u201c\u5148\u6765\u540e\u5230\u201d\u529f\u80fd\u7684\u573a\u666f\uff0c\u4f8b\u5982\u6253\u5370\u673a\u7684\u4efb\u52a1\u961f\u5217\u3001\u9910\u5385\u7684\u51fa\u9910\u961f\u5217\u7b49\uff0c\u961f\u5217\u5728\u8fd9\u4e9b\u573a\u666f\u4e2d\u53ef\u4ee5\u6709\u6548\u5730\u7ef4\u62a4\u5904\u7406\u987a\u5e8f\u3002
    "},{"location":"chapter_stack_and_queue/stack/","title":"5.1 \u00a0 \u6808","text":"

    \u6808\uff08stack\uff09\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u540e\u51fa\u903b\u8f91\u7684\u7ebf\u6027\u6570\u636e\u7ed3\u6784\u3002

    \u6211\u4eec\u53ef\u4ee5\u5c06\u6808\u7c7b\u6bd4\u4e3a\u684c\u9762\u4e0a\u7684\u4e00\u645e\u76d8\u5b50\uff0c\u5982\u679c\u60f3\u53d6\u51fa\u5e95\u90e8\u7684\u76d8\u5b50\uff0c\u5219\u9700\u8981\u5148\u5c06\u4e0a\u9762\u7684\u76d8\u5b50\u4f9d\u6b21\u79fb\u8d70\u3002\u6211\u4eec\u5c06\u76d8\u5b50\u66ff\u6362\u4e3a\u5404\u79cd\u7c7b\u578b\u7684\u5143\u7d20\uff08\u5982\u6574\u6570\u3001\u5b57\u7b26\u3001\u5bf9\u8c61\u7b49\uff09\uff0c\u5c31\u5f97\u5230\u4e86\u6808\u8fd9\u79cd\u6570\u636e\u7ed3\u6784\u3002

    \u5982\u56fe 5-1 \u6240\u793a\uff0c\u6211\u4eec\u628a\u5806\u53e0\u5143\u7d20\u7684\u9876\u90e8\u79f0\u4e3a\u201c\u6808\u9876\u201d\uff0c\u5e95\u90e8\u79f0\u4e3a\u201c\u6808\u5e95\u201d\u3002\u5c06\u628a\u5143\u7d20\u6dfb\u52a0\u5230\u6808\u9876\u7684\u64cd\u4f5c\u53eb\u4f5c\u201c\u5165\u6808\u201d\uff0c\u5220\u9664\u6808\u9876\u5143\u7d20\u7684\u64cd\u4f5c\u53eb\u4f5c\u201c\u51fa\u6808\u201d\u3002

    \u56fe 5-1 \u00a0 \u6808\u7684\u5148\u5165\u540e\u51fa\u89c4\u5219

    "},{"location":"chapter_stack_and_queue/stack/#511","title":"5.1.1 \u00a0 \u6808\u7684\u5e38\u7528\u64cd\u4f5c","text":"

    \u6808\u7684\u5e38\u7528\u64cd\u4f5c\u5982\u8868 5-1 \u6240\u793a\uff0c\u5177\u4f53\u7684\u65b9\u6cd5\u540d\u9700\u8981\u6839\u636e\u6240\u4f7f\u7528\u7684\u7f16\u7a0b\u8bed\u8a00\u6765\u786e\u5b9a\u3002\u5728\u6b64\uff0c\u6211\u4eec\u4ee5\u5e38\u89c1\u7684 push()\u3001pop()\u3001peek() \u547d\u540d\u4e3a\u4f8b\u3002

    \u8868 5-1 \u00a0 \u6808\u7684\u64cd\u4f5c\u6548\u7387

    \u65b9\u6cd5 \u63cf\u8ff0 \u65f6\u95f4\u590d\u6742\u5ea6 push() \u5143\u7d20\u5165\u6808\uff08\u6dfb\u52a0\u81f3\u6808\u9876\uff09 \\(O(1)\\) pop() \u6808\u9876\u5143\u7d20\u51fa\u6808 \\(O(1)\\) peek() \u8bbf\u95ee\u6808\u9876\u5143\u7d20 \\(O(1)\\)

    \u901a\u5e38\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u7f16\u7a0b\u8bed\u8a00\u5185\u7f6e\u7684\u6808\u7c7b\u3002\u7136\u800c\uff0c\u67d0\u4e9b\u8bed\u8a00\u53ef\u80fd\u6ca1\u6709\u4e13\u95e8\u63d0\u4f9b\u6808\u7c7b\uff0c\u8fd9\u65f6\u6211\u4eec\u53ef\u4ee5\u5c06\u8be5\u8bed\u8a00\u7684\u201c\u6570\u7ec4\u201d\u6216\u201c\u94fe\u8868\u201d\u5f53\u4f5c\u6808\u6765\u4f7f\u7528\uff0c\u5e76\u5728\u7a0b\u5e8f\u903b\u8f91\u4e0a\u5ffd\u7565\u4e0e\u6808\u65e0\u5173\u7684\u64cd\u4f5c\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig stack.py
    # \u521d\u59cb\u5316\u6808\n# Python \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a list \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nstack: list[int] = []\n\n# \u5143\u7d20\u5165\u6808\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n# \u8bbf\u95ee\u6808\u9876\u5143\u7d20\npeek: int = stack[-1]\n\n# \u5143\u7d20\u51fa\u6808\npop: int = stack.pop()\n\n# \u83b7\u53d6\u6808\u7684\u957f\u5ea6\nsize: int = len(stack)\n\n# \u5224\u65ad\u662f\u5426\u4e3a\u7a7a\nis_empty: bool = len(stack) == 0\n
    stack.cpp
    /* \u521d\u59cb\u5316\u6808 */\nstack<int> stack;\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint top = stack.top();\n\n/* \u5143\u7d20\u51fa\u6808 */\nstack.pop(); // \u65e0\u8fd4\u56de\u503c\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.size();\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nbool empty = stack.empty();\n
    stack.java
    /* \u521d\u59cb\u5316\u6808 */\nStack<Integer> stack = new Stack<>();\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek = stack.peek();\n\n/* \u5143\u7d20\u51fa\u6808 */\nint pop = stack.pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.size();\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nboolean isEmpty = stack.isEmpty();\n
    stack.cs
    /* \u521d\u59cb\u5316\u6808 */\nStack<int> stack = new();\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.Push(1);\nstack.Push(3);\nstack.Push(2);\nstack.Push(5);\nstack.Push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek = stack.Peek();\n\n/* \u5143\u7d20\u51fa\u6808 */\nint pop = stack.Pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.Count;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = stack.Count == 0;\n
    stack_test.go
    /* \u521d\u59cb\u5316\u6808 */\n// \u5728 Go \u4e2d\uff0c\u63a8\u8350\u5c06 Slice \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nvar stack []int\n\n/* \u5143\u7d20\u5165\u6808 */\nstack = append(stack, 1)\nstack = append(stack, 3)\nstack = append(stack, 2)\nstack = append(stack, 5)\nstack = append(stack, 4)\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\npeek := stack[len(stack)-1]\n\n/* \u5143\u7d20\u51fa\u6808 */\npop := stack[len(stack)-1]\nstack = stack[:len(stack)-1]\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nsize := len(stack)\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nisEmpty := len(stack) == 0\n
    stack.swift
    /* \u521d\u59cb\u5316\u6808 */\n// Swift \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nvar stack: [Int] = []\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.append(1)\nstack.append(3)\nstack.append(2)\nstack.append(5)\nstack.append(4)\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nlet peek = stack.last!\n\n/* \u5143\u7d20\u51fa\u6808 */\nlet pop = stack.removeLast()\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nlet size = stack.count\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nlet isEmpty = stack.isEmpty\n
    stack.js
    /* \u521d\u59cb\u5316\u6808 */\n// JavaScript \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nconst stack = [];\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nconst peek = stack[stack.length-1];\n\n/* \u5143\u7d20\u51fa\u6808 */\nconst pop = stack.pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nconst size = stack.length;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nconst is_empty = stack.length === 0;\n
    stack.ts
    /* \u521d\u59cb\u5316\u6808 */\n// TypeScript \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nconst stack: number[] = [];\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nconst peek = stack[stack.length - 1];\n\n/* \u5143\u7d20\u51fa\u6808 */\nconst pop = stack.pop();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nconst size = stack.length;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nconst is_empty = stack.length === 0;\n
    stack.dart
    /* \u521d\u59cb\u5316\u6808 */\n// Dart \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a List \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nList<int> stack = [];\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.add(1);\nstack.add(3);\nstack.add(2);\nstack.add(5);\nstack.add(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek = stack.last;\n\n/* \u5143\u7d20\u51fa\u6808 */\nint pop = stack.removeLast();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size = stack.length;\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty = stack.isEmpty;\n
    stack.rs
    /* \u521d\u59cb\u5316\u6808 */\n// \u628a Vec \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nlet mut stack: Vec<i32> = Vec::new();\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1);\nstack.push(3);\nstack.push(2);\nstack.push(5);\nstack.push(4);\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nlet top = stack.last().unwrap();\n\n/* \u5143\u7d20\u51fa\u6808 */\nlet pop = stack.pop().unwrap();\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nlet size = stack.len();\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nlet is_empty = stack.is_empty();\n
    stack.c
    // C \u672a\u63d0\u4f9b\u5185\u7f6e\u6808\n
    stack.kt
    /* \u521d\u59cb\u5316\u6808 */\nval stack = Stack<Int>()\n\n/* \u5143\u7d20\u5165\u6808 */\nstack.push(1)\nstack.push(3)\nstack.push(2)\nstack.push(5)\nstack.push(4)\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nval peek = stack.peek()\n\n/* \u5143\u7d20\u51fa\u6808 */\nval pop = stack.pop()\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nval size = stack.size\n\n/* \u5224\u65ad\u662f\u5426\u4e3a\u7a7a */\nval isEmpty = stack.isEmpty()\n
    stack.rb
    # \u521d\u59cb\u5316\u6808\n# Ruby \u6ca1\u6709\u5185\u7f6e\u7684\u6808\u7c7b\uff0c\u53ef\u4ee5\u628a Array \u5f53\u4f5c\u6808\u6765\u4f7f\u7528\nstack = []\n\n# \u5143\u7d20\u5165\u6808\nstack << 1\nstack << 3\nstack << 2\nstack << 5\nstack << 4\n\n# \u8bbf\u95ee\u6808\u9876\u5143\u7d20\npeek = stack.last\n\n# \u5143\u7d20\u51fa\u6808\npop = stack.pop\n\n# \u83b7\u53d6\u6808\u7684\u957f\u5ea6\nsize = stack.length\n\n# \u5224\u65ad\u662f\u5426\u4e3a\u7a7a\nis_empty = stack.empty?\n
    stack.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/stack/#512","title":"5.1.2 \u00a0 \u6808\u7684\u5b9e\u73b0","text":"

    \u4e3a\u4e86\u6df1\u5165\u4e86\u89e3\u6808\u7684\u8fd0\u884c\u673a\u5236\uff0c\u6211\u4eec\u6765\u5c1d\u8bd5\u81ea\u5df1\u5b9e\u73b0\u4e00\u4e2a\u6808\u7c7b\u3002

    \u6808\u9075\u5faa\u5148\u5165\u540e\u51fa\u7684\u539f\u5219\uff0c\u56e0\u6b64\u6211\u4eec\u53ea\u80fd\u5728\u6808\u9876\u6dfb\u52a0\u6216\u5220\u9664\u5143\u7d20\u3002\u7136\u800c\uff0c\u6570\u7ec4\u548c\u94fe\u8868\u90fd\u53ef\u4ee5\u5728\u4efb\u610f\u4f4d\u7f6e\u6dfb\u52a0\u548c\u5220\u9664\u5143\u7d20\uff0c\u56e0\u6b64\u6808\u53ef\u4ee5\u89c6\u4e3a\u4e00\u79cd\u53d7\u9650\u5236\u7684\u6570\u7ec4\u6216\u94fe\u8868\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6211\u4eec\u53ef\u4ee5\u201c\u5c4f\u853d\u201d\u6570\u7ec4\u6216\u94fe\u8868\u7684\u90e8\u5206\u65e0\u5173\u64cd\u4f5c\uff0c\u4f7f\u5176\u5bf9\u5916\u8868\u73b0\u7684\u903b\u8f91\u7b26\u5408\u6808\u7684\u7279\u6027\u3002

    "},{"location":"chapter_stack_and_queue/stack/#1","title":"1. \u00a0 \u57fa\u4e8e\u94fe\u8868\u7684\u5b9e\u73b0","text":"

    \u4f7f\u7528\u94fe\u8868\u5b9e\u73b0\u6808\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u94fe\u8868\u7684\u5934\u8282\u70b9\u89c6\u4e3a\u6808\u9876\uff0c\u5c3e\u8282\u70b9\u89c6\u4e3a\u6808\u5e95\u3002

    \u5982\u56fe 5-2 \u6240\u793a\uff0c\u5bf9\u4e8e\u5165\u6808\u64cd\u4f5c\uff0c\u6211\u4eec\u53ea\u9700\u5c06\u5143\u7d20\u63d2\u5165\u94fe\u8868\u5934\u90e8\uff0c\u8fd9\u79cd\u8282\u70b9\u63d2\u5165\u65b9\u6cd5\u88ab\u79f0\u4e3a\u201c\u5934\u63d2\u6cd5\u201d\u3002\u800c\u5bf9\u4e8e\u51fa\u6808\u64cd\u4f5c\uff0c\u53ea\u9700\u5c06\u5934\u8282\u70b9\u4ece\u94fe\u8868\u4e2d\u5220\u9664\u5373\u53ef\u3002

    LinkedListStackpush()pop()

    \u56fe 5-2 \u00a0 \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u6808\u7684\u5165\u6808\u51fa\u6808\u64cd\u4f5c

    \u4ee5\u4e0b\u662f\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u6808\u7684\u793a\u4f8b\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig linkedlist_stack.py
    class LinkedListStack:\n    \"\"\"\u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._peek: ListNode | None = None\n        self._size: int = 0\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return self._size\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self._size == 0\n\n    def push(self, val: int):\n        \"\"\"\u5165\u6808\"\"\"\n        node = ListNode(val)\n        node.next = self._peek\n        self._peek = node\n        self._size += 1\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        num = self.peek()\n        self._peek = self._peek.next\n        self._size -= 1\n        return num\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._peek.val\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8f6c\u5316\u4e3a\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        arr = []\n        node = self._peek\n        while node:\n            arr.append(node.val)\n            node = node.next\n        arr.reverse()\n        return arr\n
    linkedlist_stack.cpp
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  private:\n    ListNode *stackTop; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize;        // \u6808\u7684\u957f\u5ea6\n\n  public:\n    LinkedListStack() {\n        stackTop = nullptr;\n        stkSize = 0;\n    }\n\n    ~LinkedListStack() {\n        // \u904d\u5386\u94fe\u8868\u5220\u9664\u8282\u70b9\uff0c\u91ca\u653e\u5185\u5b58\n        freeMemoryLinkedList(stackTop);\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        ListNode *node = new ListNode(num);\n        node->next = stackTop;\n        stackTop = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        ListNode *tmp = stackTop;\n        stackTop = stackTop->next;\n        // \u91ca\u653e\u5185\u5b58\n        delete tmp;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stackTop->val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    vector<int> toVector() {\n        ListNode *node = stackTop;\n        vector<int> res(size());\n        for (int i = res.size() - 1; i >= 0; i--) {\n            res[i] = node->val;\n            node = node->next;\n        }\n        return res;\n    }\n};\n
    linkedlist_stack.java
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private ListNode stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private int stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        ListNode node = new ListNode(num);\n        node.next = stackPeek;\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        int num = peek();\n        stackPeek = stackPeek.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stackPeek.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] toArray() {\n        ListNode node = stackPeek;\n        int[] res = new int[size()];\n        for (int i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.cs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    ListNode? stackPeek;  // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int stkSize = 0;   // \u6808\u7684\u957f\u5ea6\n\n    public LinkedListStack() {\n        stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        ListNode node = new(num) {\n            next = stackPeek\n        };\n        stackPeek = node;\n        stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        int num = Peek();\n        stackPeek = stackPeek!.next;\n        stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stackPeek!.val;\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        if (stackPeek == null)\n            return [];\n\n        ListNode? node = stackPeek;\n        int[] res = new int[Size()];\n        for (int i = res.Length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.go
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntype linkedListStack struct {\n    // \u4f7f\u7528\u5185\u7f6e\u5305 list \u6765\u5b9e\u73b0\u6808\n    data *list.List\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newLinkedListStack() *linkedListStack {\n    return &linkedListStack{\n        data: list.New(),\n    }\n}\n\n/* \u5165\u6808 */\nfunc (s *linkedListStack) push(value int) {\n    s.data.PushBack(value)\n}\n\n/* \u51fa\u6808 */\nfunc (s *linkedListStack) pop() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    s.data.Remove(e)\n    return e.Value\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nfunc (s *linkedListStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    e := s.data.Back()\n    return e.Value\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nfunc (s *linkedListStack) size() int {\n    return s.data.Len()\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *linkedListStack) isEmpty() bool {\n    return s.data.Len() == 0\n}\n\n/* \u83b7\u53d6 List \u7528\u4e8e\u6253\u5370 */\nfunc (s *linkedListStack) toList() *list.List {\n    return s.data\n}\n
    linkedlist_stack.swift
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private var _peek: ListNode? // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var _size: Int // \u6808\u7684\u957f\u5ea6\n\n    init() {\n        _size = 0\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        _size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        size() == 0\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        let node = ListNode(x: num)\n        node.next = _peek\n        _peek = node\n        _size += 1\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        let num = peek()\n        _peek = _peek?.next\n        _size -= 1\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return _peek!.val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        var node = _peek\n        var res = Array(repeating: 0, count: size())\n        for i in res.indices.reversed() {\n            res[i] = node!.val\n            node = node?.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.js
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    #stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    #stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.#stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        const node = new ListNode(num);\n        node.next = this.#stackPeek;\n        this.#stackPeek = node;\n        this.#stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        const num = this.peek();\n        this.#stackPeek = this.#stackPeek.next;\n        this.#stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek() {\n        if (!this.#stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray() {\n        let node = this.#stackPeek;\n        const res = new Array(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node.val;\n            node = node.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.ts
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n    private stackPeek: ListNode | null; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private stkSize: number = 0; // \u6808\u7684\u957f\u5ea6\n\n    constructor() {\n        this.stackPeek = null;\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stkSize;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        const node = new ListNode(num);\n        node.next = this.stackPeek;\n        this.stackPeek = node;\n        this.stkSize++;\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        this.stackPeek = this.stackPeek.next;\n        this.stkSize--;\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    peek(): number {\n        if (!this.stackPeek) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stackPeek.val;\n    }\n\n    /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    toArray(): number[] {\n        let node = this.stackPeek;\n        const res = new Array<number>(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node!.next;\n        }\n        return res;\n    }\n}\n
    linkedlist_stack.dart
    /* \u57fa\u4e8e\u94fe\u8868\u7c7b\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack {\n  ListNode? _stackPeek; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n  int _stkSize = 0; // \u6808\u7684\u957f\u5ea6\n\n  LinkedListStack() {\n    _stackPeek = null;\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stkSize;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stkSize == 0;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    final ListNode node = ListNode(_num);\n    node.next = _stackPeek;\n    _stackPeek = node;\n    _stkSize++;\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    final int _num = peek();\n    _stackPeek = _stackPeek!.next;\n    _stkSize--;\n    return _num;\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (_stackPeek == null) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stackPeek!.val;\n  }\n\n  /* \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a List \u5e76\u8fd4\u56de */\n  List<int> toList() {\n    ListNode? node = _stackPeek;\n    List<int> list = [];\n    while (node != null) {\n      list.add(node.val);\n      node = node.next;\n    }\n    list = list.reversed.toList();\n    return list;\n  }\n}\n
    linkedlist_stack.rs
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\n#[allow(dead_code)]\npub struct LinkedListStack<T> {\n    stack_peek: Option<Rc<RefCell<ListNode<T>>>>, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    stk_size: usize,                              // \u6808\u7684\u957f\u5ea6\n}\n\nimpl<T: Copy> LinkedListStack<T> {\n    pub fn new() -> Self {\n        Self {\n            stack_peek: None,\n            stk_size: 0,\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    pub fn size(&self) -> usize {\n        return self.stk_size;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    pub fn is_empty(&self) -> bool {\n        return self.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    pub fn push(&mut self, num: T) {\n        let node = ListNode::new(num);\n        node.borrow_mut().next = self.stack_peek.take();\n        self.stack_peek = Some(node);\n        self.stk_size += 1;\n    }\n\n    /* \u51fa\u6808 */\n    pub fn pop(&mut self) -> Option<T> {\n        self.stack_peek.take().map(|old_head| {\n            match old_head.borrow_mut().next.take() {\n                Some(new_head) => {\n                    self.stack_peek = Some(new_head);\n                }\n                None => {\n                    self.stack_peek = None;\n                }\n            }\n            self.stk_size -= 1;\n            Rc::try_unwrap(old_head).ok().unwrap().into_inner().val\n        })\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> {\n        self.stack_peek.as_ref()\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> {\n        if let Some(node) = head {\n            let mut nums = self.to_array(node.borrow().next.as_ref());\n            nums.push(node.borrow().val);\n            return nums;\n        }\n        return Vec::new();\n    }\n}\n
    linkedlist_stack.c
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    ListNode *top; // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    int size;      // \u6808\u7684\u957f\u5ea6\n} LinkedListStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nLinkedListStack *newLinkedListStack() {\n    LinkedListStack *s = malloc(sizeof(LinkedListStack));\n    s->top = NULL;\n    s->size = 0;\n    return s;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delLinkedListStack(LinkedListStack *s) {\n    while (s->top) {\n        ListNode *n = s->top->next;\n        free(s->top);\n        s->top = n;\n    }\n    free(s);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(LinkedListStack *s) {\n    return s->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(LinkedListStack *s) {\n    return size(s) == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(LinkedListStack *s, int num) {\n    ListNode *node = (ListNode *)malloc(sizeof(ListNode));\n    node->next = s->top; // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6307\u9488\u57df\n    node->val = num;     // \u66f4\u65b0\u65b0\u52a0\u8282\u70b9\u6570\u636e\u57df\n    s->top = node;       // \u66f4\u65b0\u6808\u9876\n    s->size++;           // \u66f4\u65b0\u6808\u5927\u5c0f\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(LinkedListStack *s) {\n    if (s->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return s->top->val;\n}\n\n/* \u51fa\u6808 */\nint pop(LinkedListStack *s) {\n    int val = peek(s);\n    ListNode *tmp = s->top;\n    s->top = s->top->next;\n    // \u91ca\u653e\u5185\u5b58\n    free(tmp);\n    s->size--;\n    return val;\n}\n
    linkedlist_stack.kt
    /* \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 */\nclass LinkedListStack(\n    private var stackPeek: ListNode? = null, // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n    private var stkSize: Int = 0 // \u6808\u7684\u957f\u5ea6\n) {\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stkSize\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        val node = ListNode(num)\n        node.next = stackPeek\n        stackPeek = node\n        stkSize++\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int? {\n        val num = peek()\n        stackPeek = stackPeek?.next\n        stkSize--\n        return num\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int? {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stackPeek?._val\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): IntArray {\n        var node = stackPeek\n        val res = IntArray(size())\n        for (i in res.size - 1 downTo 0) {\n            res[i] = node?._val!!\n            node = node.next\n        }\n        return res\n    }\n}\n
    linkedlist_stack.rb
    ### \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808 ###\nclass LinkedListStack\n  attr_reader :size\n\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @size = 0\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @peek.nil?\n  end\n\n  ### \u5165\u6808 ###\n  def push(val)\n    node = ListNode.new(val)\n    node.next = @peek\n    @peek = node\n    @size += 1\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    num = peek\n    @peek = @peek.next\n    @size -= 1\n    num\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @peek.val\n  end\n\n  ### \u5c06\u94fe\u8868\u8f6c\u5316\u4e3a Array \u5e76\u53cd\u56de ###\n  def to_array\n    arr = []\n    node = @peek\n    while node\n      arr << node.val\n      node = node.next\n    end\n    arr.reverse\n  end\nend\n
    linkedlist_stack.zig
    // \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\nfn LinkedListStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack_top: ?*inc.ListNode(T) = null,             // \u5c06\u5934\u8282\u70b9\u4f5c\u4e3a\u6808\u9876\n        stk_size: usize = 0,                             // \u6808\u7684\u957f\u5ea6\n        mem_arena: ?std.heap.ArenaAllocator = null,\n        mem_allocator: std.mem.Allocator = undefined,    // \u5185\u5b58\u5206\u914d\u5668\n\n        // \u6784\u9020\u51fd\u6570\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) !void {\n            if (self.mem_arena == null) {\n                self.mem_arena = std.heap.ArenaAllocator.init(allocator);\n                self.mem_allocator = self.mem_arena.?.allocator();\n            }\n            self.stack_top = null;\n            self.stk_size = 0;\n        }\n\n        // \u6790\u6784\u51fd\u6570\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.mem_arena == null) return;\n            self.mem_arena.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stk_size;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.size() == 0) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack_top.?.val;\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            var node = try self.mem_allocator.create(inc.ListNode(T));\n            node.init(num);\n            node.next = self.stack_top;\n            self.stack_top = node;\n            self.stk_size += 1;\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.peek();\n            self.stack_top = self.stack_top.?.next;\n            self.stk_size -= 1;\n            return num;\n        } \n\n        // \u5c06\u6808\u8f6c\u6362\u4e3a\u6570\u7ec4\n        pub fn toArray(self: *Self) ![]T {\n            var node = self.stack_top;\n            var res = try self.mem_allocator.alloc(T, self.size());\n            @memset(res, @as(T, 0));\n            var i: usize = 0;\n            while (i < res.len) : (i += 1) {\n                res[res.len - i - 1] = node.?.val;\n                node = node.?.next;\n            }\n            return res;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/stack/#2","title":"2. \u00a0 \u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0","text":"

    \u4f7f\u7528\u6570\u7ec4\u5b9e\u73b0\u6808\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u6570\u7ec4\u7684\u5c3e\u90e8\u4f5c\u4e3a\u6808\u9876\u3002\u5982\u56fe 5-3 \u6240\u793a\uff0c\u5165\u6808\u4e0e\u51fa\u6808\u64cd\u4f5c\u5206\u522b\u5bf9\u5e94\u5728\u6570\u7ec4\u5c3e\u90e8\u6dfb\u52a0\u5143\u7d20\u4e0e\u5220\u9664\u5143\u7d20\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u4e3a \\(O(1)\\) \u3002

    ArrayStackpush()pop()

    \u56fe 5-3 \u00a0 \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u6808\u7684\u5165\u6808\u51fa\u6808\u64cd\u4f5c

    \u7531\u4e8e\u5165\u6808\u7684\u5143\u7d20\u53ef\u80fd\u4f1a\u6e90\u6e90\u4e0d\u65ad\u5730\u589e\u52a0\uff0c\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u52a8\u6001\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u65e0\u987b\u81ea\u884c\u5904\u7406\u6570\u7ec4\u6269\u5bb9\u95ee\u9898\u3002\u4ee5\u4e0b\u4e3a\u793a\u4f8b\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_stack.py
    class ArrayStack:\n    \"\"\"\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\"\"\"\n\n    def __init__(self):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._stack: list[int] = []\n\n    def size(self) -> int:\n        \"\"\"\u83b7\u53d6\u6808\u7684\u957f\u5ea6\"\"\"\n        return len(self._stack)\n\n    def is_empty(self) -> bool:\n        \"\"\"\u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\"\"\"\n        return self.size() == 0\n\n    def push(self, item: int):\n        \"\"\"\u5165\u6808\"\"\"\n        self._stack.append(item)\n\n    def pop(self) -> int:\n        \"\"\"\u51fa\u6808\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack.pop()\n\n    def peek(self) -> int:\n        \"\"\"\u8bbf\u95ee\u6808\u9876\u5143\u7d20\"\"\"\n        if self.is_empty():\n            raise IndexError(\"\u6808\u4e3a\u7a7a\")\n        return self._stack[-1]\n\n    def to_list(self) -> list[int]:\n        \"\"\"\u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370\"\"\"\n        return self._stack\n
    array_stack.cpp
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  private:\n    vector<int> stack;\n\n  public:\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    bool isEmpty() {\n        return stack.size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    void push(int num) {\n        stack.push_back(num);\n    }\n\n    /* \u51fa\u6808 */\n    int pop() {\n        int num = top();\n        stack.pop_back();\n        return num;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    int top() {\n        if (isEmpty())\n            throw out_of_range(\"\u6808\u4e3a\u7a7a\");\n        return stack.back();\n    }\n\n    /* \u8fd4\u56de Vector */\n    vector<int> toVector() {\n        return stack;\n    }\n};\n
    array_stack.java
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private ArrayList<Integer> stack;\n\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = new ArrayList<>();\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int size() {\n        return stack.size();\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public boolean isEmpty() {\n        return size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void push(int num) {\n        stack.add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int pop() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.remove(size() - 1);\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int peek() {\n        if (isEmpty())\n            throw new IndexOutOfBoundsException();\n        return stack.get(size() - 1);\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public Object[] toArray() {\n        return stack.toArray();\n    }\n}\n
    array_stack.cs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    List<int> stack;\n    public ArrayStack() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    public int Size() {\n        return stack.Count;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    public bool IsEmpty() {\n        return Size() == 0;\n    }\n\n    /* \u5165\u6808 */\n    public void Push(int num) {\n        stack.Add(num);\n    }\n\n    /* \u51fa\u6808 */\n    public int Pop() {\n        if (IsEmpty())\n            throw new Exception();\n        var val = Peek();\n        stack.RemoveAt(Size() - 1);\n        return val;\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    public int Peek() {\n        if (IsEmpty())\n            throw new Exception();\n        return stack[Size() - 1];\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    public int[] ToArray() {\n        return [.. stack];\n    }\n}\n
    array_stack.go
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntype arrayStack struct {\n    data []int // \u6570\u636e\n}\n\n/* \u521d\u59cb\u5316\u6808 */\nfunc newArrayStack() *arrayStack {\n    return &arrayStack{\n        // \u8bbe\u7f6e\u6808\u7684\u957f\u5ea6\u4e3a 0\uff0c\u5bb9\u91cf\u4e3a 16\n        data: make([]int, 0, 16),\n    }\n}\n\n/* \u6808\u7684\u957f\u5ea6 */\nfunc (s *arrayStack) size() int {\n    return len(s.data)\n}\n\n/* \u6808\u662f\u5426\u4e3a\u7a7a */\nfunc (s *arrayStack) isEmpty() bool {\n    return s.size() == 0\n}\n\n/* \u5165\u6808 */\nfunc (s *arrayStack) push(v int) {\n    // \u5207\u7247\u4f1a\u81ea\u52a8\u6269\u5bb9\n    s.data = append(s.data, v)\n}\n\n/* \u51fa\u6808 */\nfunc (s *arrayStack) pop() any {\n    val := s.peek()\n    s.data = s.data[:len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6\u6808\u9876\u5143\u7d20 */\nfunc (s *arrayStack) peek() any {\n    if s.isEmpty() {\n        return nil\n    }\n    val := s.data[len(s.data)-1]\n    return val\n}\n\n/* \u83b7\u53d6 Slice \u7528\u4e8e\u6253\u5370 */\nfunc (s *arrayStack) toSlice() []int {\n    return s.data\n}\n
    array_stack.swift
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private var stack: [Int]\n\n    init() {\n        // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n        stack = []\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    func size() -> Int {\n        stack.count\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    func isEmpty() -> Bool {\n        stack.isEmpty\n    }\n\n    /* \u5165\u6808 */\n    func push(num: Int) {\n        stack.append(num)\n    }\n\n    /* \u51fa\u6808 */\n    @discardableResult\n    func pop() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.removeLast()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    func peek() -> Int {\n        if isEmpty() {\n            fatalError(\"\u6808\u4e3a\u7a7a\")\n        }\n        return stack.last!\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    func toArray() -> [Int] {\n        stack\n    }\n}\n
    array_stack.js
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    #stack;\n    constructor() {\n        this.#stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size() {\n        return this.#stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty() {\n        return this.#stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num) {\n        this.#stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top() {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.#stack[this.#stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.#stack;\n    }\n}\n
    array_stack.ts
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    private stack: number[];\n    constructor() {\n        this.stack = [];\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    get size(): number {\n        return this.stack.length;\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    isEmpty(): boolean {\n        return this.stack.length === 0;\n    }\n\n    /* \u5165\u6808 */\n    push(num: number): void {\n        this.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    pop(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack.pop();\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    top(): number | undefined {\n        if (this.isEmpty()) throw new Error('\u6808\u4e3a\u7a7a');\n        return this.stack[this.stack.length - 1];\n    }\n\n    /* \u8fd4\u56de Array */\n    toArray() {\n        return this.stack;\n    }\n}\n
    array_stack.dart
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n  late List<int> _stack;\n  ArrayStack() {\n    _stack = [];\n  }\n\n  /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n  int size() {\n    return _stack.length;\n  }\n\n  /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n  bool isEmpty() {\n    return _stack.isEmpty;\n  }\n\n  /* \u5165\u6808 */\n  void push(int _num) {\n    _stack.add(_num);\n  }\n\n  /* \u51fa\u6808 */\n  int pop() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.removeLast();\n  }\n\n  /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n  int peek() {\n    if (isEmpty()) {\n      throw Exception(\"\u6808\u4e3a\u7a7a\");\n    }\n    return _stack.last;\n  }\n\n  /* \u5c06\u6808\u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n  List<int> toArray() => _stack;\n}\n
    array_stack.rs
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nstruct ArrayStack<T> {\n    stack: Vec<T>,\n}\n\nimpl<T> ArrayStack<T> {\n    /* \u521d\u59cb\u5316\u6808 */\n    fn new() -> ArrayStack<T> {\n        ArrayStack::<T> {\n            stack: Vec::<T>::new(),\n        }\n    }\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fn size(&self) -> usize {\n        self.stack.len()\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fn is_empty(&self) -> bool {\n        self.size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fn push(&mut self, num: T) {\n        self.stack.push(num);\n    }\n\n    /* \u51fa\u6808 */\n    fn pop(&mut self) -> Option<T> {\n        self.stack.pop()\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fn peek(&self) -> Option<&T> {\n        if self.is_empty() {\n            panic!(\"\u6808\u4e3a\u7a7a\")\n        };\n        self.stack.last()\n    }\n\n    /* \u8fd4\u56de &Vec */\n    fn to_array(&self) -> &Vec<T> {\n        &self.stack\n    }\n}\n
    array_stack.c
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\ntypedef struct {\n    int *data;\n    int size;\n} ArrayStack;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayStack *newArrayStack() {\n    ArrayStack *stack = malloc(sizeof(ArrayStack));\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5927\u5bb9\u91cf\uff0c\u907f\u514d\u6269\u5bb9\n    stack->data = malloc(sizeof(int) * MAX_SIZE);\n    stack->size = 0;\n    return stack;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayStack(ArrayStack *stack) {\n    free(stack->data);\n    free(stack);\n}\n\n/* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\nint size(ArrayStack *stack) {\n    return stack->size;\n}\n\n/* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\nbool isEmpty(ArrayStack *stack) {\n    return stack->size == 0;\n}\n\n/* \u5165\u6808 */\nvoid push(ArrayStack *stack, int num) {\n    if (stack->size == MAX_SIZE) {\n        printf(\"\u6808\u5df2\u6ee1\\n\");\n        return;\n    }\n    stack->data[stack->size] = num;\n    stack->size++;\n}\n\n/* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\nint peek(ArrayStack *stack) {\n    if (stack->size == 0) {\n        printf(\"\u6808\u4e3a\u7a7a\\n\");\n        return INT_MAX;\n    }\n    return stack->data[stack->size - 1];\n}\n\n/* \u51fa\u6808 */\nint pop(ArrayStack *stack) {\n    int val = peek(stack);\n    stack->size--;\n    return val;\n}\n
    array_stack.kt
    /* \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 */\nclass ArrayStack {\n    // \u521d\u59cb\u5316\u5217\u8868\uff08\u52a8\u6001\u6570\u7ec4\uff09\n    private val stack = mutableListOf<Int>()\n\n    /* \u83b7\u53d6\u6808\u7684\u957f\u5ea6 */\n    fun size(): Int {\n        return stack.size\n    }\n\n    /* \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a */\n    fun isEmpty(): Boolean {\n        return size() == 0\n    }\n\n    /* \u5165\u6808 */\n    fun push(num: Int) {\n        stack.add(num)\n    }\n\n    /* \u51fa\u6808 */\n    fun pop(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack.removeAt(size() - 1)\n    }\n\n    /* \u8bbf\u95ee\u6808\u9876\u5143\u7d20 */\n    fun peek(): Int {\n        if (isEmpty()) throw IndexOutOfBoundsException()\n        return stack[size() - 1]\n    }\n\n    /* \u5c06 List \u8f6c\u5316\u4e3a Array \u5e76\u8fd4\u56de */\n    fun toArray(): Array<Any> {\n        return stack.toTypedArray()\n    }\n}\n
    array_stack.rb
    ### \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808 ###\nclass ArrayStack\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize\n    @stack = []\n  end\n\n  ### \u83b7\u53d6\u6808\u7684\u957f\u5ea6 ###\n  def size\n    @stack.length\n  end\n\n  ### \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a ###\n  def is_empty?\n    @stack.empty?\n  end\n\n  ### \u5165\u6808 ###\n  def push(item)\n    @stack << item\n  end\n\n  ### \u51fa\u6808 ###\n  def pop\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.pop\n  end\n\n  ### \u8bbf\u95ee\u6808\u9876\u5143\u7d20 ###\n  def peek\n    raise IndexError, '\u6808\u4e3a\u7a7a' if is_empty?\n\n    @stack.last\n  end\n\n  ### \u8fd4\u56de\u5217\u8868\u7528\u4e8e\u6253\u5370 ###\n  def to_array\n    @stack\n  end\nend\n
    array_stack.zig
    // \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\nfn ArrayStack(comptime T: type) type {\n    return struct {\n        const Self = @This();\n\n        stack: ?std.ArrayList(T) = null,     \n\n        // \u6784\u9020\u65b9\u6cd5\uff08\u5206\u914d\u5185\u5b58+\u521d\u59cb\u5316\u6808\uff09\n        pub fn init(self: *Self, allocator: std.mem.Allocator) void {\n            if (self.stack == null) {\n                self.stack = std.ArrayList(T).init(allocator);\n            }\n        }\n\n        // \u6790\u6784\u65b9\u6cd5\uff08\u91ca\u653e\u5185\u5b58\uff09\n        pub fn deinit(self: *Self) void {\n            if (self.stack == null) return;\n            self.stack.?.deinit();\n        }\n\n        // \u83b7\u53d6\u6808\u7684\u957f\u5ea6\n        pub fn size(self: *Self) usize {\n            return self.stack.?.items.len;\n        }\n\n        // \u5224\u65ad\u6808\u662f\u5426\u4e3a\u7a7a\n        pub fn isEmpty(self: *Self) bool {\n            return self.size() == 0;\n        }\n\n        // \u8bbf\u95ee\u6808\u9876\u5143\u7d20\n        pub fn peek(self: *Self) T {\n            if (self.isEmpty()) @panic(\"\u6808\u4e3a\u7a7a\");\n            return self.stack.?.items[self.size() - 1];\n        }  \n\n        // \u5165\u6808\n        pub fn push(self: *Self, num: T) !void {\n            try self.stack.?.append(num);\n        } \n\n        // \u51fa\u6808\n        pub fn pop(self: *Self) T {\n            var num = self.stack.?.pop();\n            return num;\n        } \n\n        // \u8fd4\u56de ArrayList\n        pub fn toList(self: *Self) std.ArrayList(T) {\n            return self.stack.?;\n        }\n    };\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_stack_and_queue/stack/#513","title":"5.1.3 \u00a0 \u4e24\u79cd\u5b9e\u73b0\u5bf9\u6bd4","text":"

    \u652f\u6301\u64cd\u4f5c

    \u4e24\u79cd\u5b9e\u73b0\u90fd\u652f\u6301\u6808\u5b9a\u4e49\u4e2d\u7684\u5404\u9879\u64cd\u4f5c\u3002\u6570\u7ec4\u5b9e\u73b0\u989d\u5916\u652f\u6301\u968f\u673a\u8bbf\u95ee\uff0c\u4f46\u8fd9\u5df2\u8d85\u51fa\u4e86\u6808\u7684\u5b9a\u4e49\u8303\u7574\uff0c\u56e0\u6b64\u4e00\u822c\u4e0d\u4f1a\u7528\u5230\u3002

    \u65f6\u95f4\u6548\u7387

    \u5728\u57fa\u4e8e\u6570\u7ec4\u7684\u5b9e\u73b0\u4e2d\uff0c\u5165\u6808\u548c\u51fa\u6808\u64cd\u4f5c\u90fd\u5728\u9884\u5148\u5206\u914d\u597d\u7684\u8fde\u7eed\u5185\u5b58\u4e2d\u8fdb\u884c\uff0c\u5177\u6709\u5f88\u597d\u7684\u7f13\u5b58\u672c\u5730\u6027\uff0c\u56e0\u6b64\u6548\u7387\u8f83\u9ad8\u3002\u7136\u800c\uff0c\u5982\u679c\u5165\u6808\u65f6\u8d85\u51fa\u6570\u7ec4\u5bb9\u91cf\uff0c\u4f1a\u89e6\u53d1\u6269\u5bb9\u673a\u5236\uff0c\u5bfc\u81f4\u8be5\u6b21\u5165\u6808\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u53d8\u4e3a \\(O(n)\\) \u3002

    \u5728\u57fa\u4e8e\u94fe\u8868\u7684\u5b9e\u73b0\u4e2d\uff0c\u94fe\u8868\u7684\u6269\u5bb9\u975e\u5e38\u7075\u6d3b\uff0c\u4e0d\u5b58\u5728\u4e0a\u8ff0\u6570\u7ec4\u6269\u5bb9\u65f6\u6548\u7387\u964d\u4f4e\u7684\u95ee\u9898\u3002\u4f46\u662f\uff0c\u5165\u6808\u64cd\u4f5c\u9700\u8981\u521d\u59cb\u5316\u8282\u70b9\u5bf9\u8c61\u5e76\u4fee\u6539\u6307\u9488\uff0c\u56e0\u6b64\u6548\u7387\u76f8\u5bf9\u8f83\u4f4e\u3002\u4e0d\u8fc7\uff0c\u5982\u679c\u5165\u6808\u5143\u7d20\u672c\u8eab\u5c31\u662f\u8282\u70b9\u5bf9\u8c61\uff0c\u90a3\u4e48\u53ef\u4ee5\u7701\u53bb\u521d\u59cb\u5316\u6b65\u9aa4\uff0c\u4ece\u800c\u63d0\u9ad8\u6548\u7387\u3002

    \u7efc\u4e0a\u6240\u8ff0\uff0c\u5f53\u5165\u6808\u4e0e\u51fa\u6808\u64cd\u4f5c\u7684\u5143\u7d20\u662f\u57fa\u672c\u6570\u636e\u7c7b\u578b\u65f6\uff0c\u4f8b\u5982 int \u6216 double \uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u51fa\u4ee5\u4e0b\u7ed3\u8bba\u3002

    • \u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\u5728\u89e6\u53d1\u6269\u5bb9\u65f6\u6548\u7387\u4f1a\u964d\u4f4e\uff0c\u4f46\u7531\u4e8e\u6269\u5bb9\u662f\u4f4e\u9891\u64cd\u4f5c\uff0c\u56e0\u6b64\u5e73\u5747\u6548\u7387\u66f4\u9ad8\u3002
    • \u57fa\u4e8e\u94fe\u8868\u5b9e\u73b0\u7684\u6808\u53ef\u4ee5\u63d0\u4f9b\u66f4\u52a0\u7a33\u5b9a\u7684\u6548\u7387\u8868\u73b0\u3002

    \u7a7a\u95f4\u6548\u7387

    \u5728\u521d\u59cb\u5316\u5217\u8868\u65f6\uff0c\u7cfb\u7edf\u4f1a\u4e3a\u5217\u8868\u5206\u914d\u201c\u521d\u59cb\u5bb9\u91cf\u201d\uff0c\u8be5\u5bb9\u91cf\u53ef\u80fd\u8d85\u51fa\u5b9e\u9645\u9700\u6c42\uff1b\u5e76\u4e14\uff0c\u6269\u5bb9\u673a\u5236\u901a\u5e38\u662f\u6309\u7167\u7279\u5b9a\u500d\u7387\uff08\u4f8b\u5982 2 \u500d\uff09\u8fdb\u884c\u6269\u5bb9\u7684\uff0c\u6269\u5bb9\u540e\u7684\u5bb9\u91cf\u4e5f\u53ef\u80fd\u8d85\u51fa\u5b9e\u9645\u9700\u6c42\u3002\u56e0\u6b64\uff0c\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u6808\u53ef\u80fd\u9020\u6210\u4e00\u5b9a\u7684\u7a7a\u95f4\u6d6a\u8d39\u3002

    \u7136\u800c\uff0c\u7531\u4e8e\u94fe\u8868\u8282\u70b9\u9700\u8981\u989d\u5916\u5b58\u50a8\u6307\u9488\uff0c\u56e0\u6b64\u94fe\u8868\u8282\u70b9\u5360\u7528\u7684\u7a7a\u95f4\u76f8\u5bf9\u8f83\u5927\u3002

    \u7efc\u4e0a\uff0c\u6211\u4eec\u4e0d\u80fd\u7b80\u5355\u5730\u786e\u5b9a\u54ea\u79cd\u5b9e\u73b0\u66f4\u52a0\u8282\u7701\u5185\u5b58\uff0c\u9700\u8981\u9488\u5bf9\u5177\u4f53\u60c5\u51b5\u8fdb\u884c\u5206\u6790\u3002

    "},{"location":"chapter_stack_and_queue/stack/#514","title":"5.1.4 \u00a0 \u6808\u7684\u5178\u578b\u5e94\u7528","text":"
    • \u6d4f\u89c8\u5668\u4e2d\u7684\u540e\u9000\u4e0e\u524d\u8fdb\u3001\u8f6f\u4ef6\u4e2d\u7684\u64a4\u9500\u4e0e\u53cd\u64a4\u9500\u3002\u6bcf\u5f53\u6211\u4eec\u6253\u5f00\u65b0\u7684\u7f51\u9875\uff0c\u6d4f\u89c8\u5668\u5c31\u4f1a\u5bf9\u4e0a\u4e00\u4e2a\u7f51\u9875\u6267\u884c\u5165\u6808\uff0c\u8fd9\u6837\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u540e\u9000\u64cd\u4f5c\u56de\u5230\u4e0a\u4e00\u4e2a\u7f51\u9875\u3002\u540e\u9000\u64cd\u4f5c\u5b9e\u9645\u4e0a\u662f\u5728\u6267\u884c\u51fa\u6808\u3002\u5982\u679c\u8981\u540c\u65f6\u652f\u6301\u540e\u9000\u548c\u524d\u8fdb\uff0c\u90a3\u4e48\u9700\u8981\u4e24\u4e2a\u6808\u6765\u914d\u5408\u5b9e\u73b0\u3002
    • \u7a0b\u5e8f\u5185\u5b58\u7ba1\u7406\u3002\u6bcf\u6b21\u8c03\u7528\u51fd\u6570\u65f6\uff0c\u7cfb\u7edf\u90fd\u4f1a\u5728\u6808\u9876\u6dfb\u52a0\u4e00\u4e2a\u6808\u5e27\uff0c\u7528\u4e8e\u8bb0\u5f55\u51fd\u6570\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f\u3002\u5728\u9012\u5f52\u51fd\u6570\u4e2d\uff0c\u5411\u4e0b\u9012\u63a8\u9636\u6bb5\u4f1a\u4e0d\u65ad\u6267\u884c\u5165\u6808\u64cd\u4f5c\uff0c\u800c\u5411\u4e0a\u56de\u6eaf\u9636\u6bb5\u5219\u4f1a\u4e0d\u65ad\u6267\u884c\u51fa\u6808\u64cd\u4f5c\u3002
    "},{"location":"chapter_stack_and_queue/summary/","title":"5.4 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_stack_and_queue/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u6808\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u540e\u51fa\u539f\u5219\u7684\u6570\u636e\u7ed3\u6784\uff0c\u53ef\u901a\u8fc7\u6570\u7ec4\u6216\u94fe\u8868\u6765\u5b9e\u73b0\u3002
    • \u5728\u65f6\u95f4\u6548\u7387\u65b9\u9762\uff0c\u6808\u7684\u6570\u7ec4\u5b9e\u73b0\u5177\u6709\u8f83\u9ad8\u7684\u5e73\u5747\u6548\u7387\uff0c\u4f46\u5728\u6269\u5bb9\u8fc7\u7a0b\u4e2d\uff0c\u5355\u6b21\u5165\u6808\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u52a3\u5316\u81f3 \\(O(n)\\) \u3002\u76f8\u6bd4\u4e4b\u4e0b\uff0c\u6808\u7684\u94fe\u8868\u5b9e\u73b0\u5177\u6709\u66f4\u4e3a\u7a33\u5b9a\u7684\u6548\u7387\u8868\u73b0\u3002
    • \u5728\u7a7a\u95f4\u6548\u7387\u65b9\u9762\uff0c\u6808\u7684\u6570\u7ec4\u5b9e\u73b0\u53ef\u80fd\u5bfc\u81f4\u4e00\u5b9a\u7a0b\u5ea6\u7684\u7a7a\u95f4\u6d6a\u8d39\u3002\u4f46\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u94fe\u8868\u8282\u70b9\u6240\u5360\u7528\u7684\u5185\u5b58\u7a7a\u95f4\u6bd4\u6570\u7ec4\u5143\u7d20\u66f4\u5927\u3002
    • \u961f\u5217\u662f\u4e00\u79cd\u9075\u5faa\u5148\u5165\u5148\u51fa\u539f\u5219\u7684\u6570\u636e\u7ed3\u6784\uff0c\u540c\u6837\u53ef\u4ee5\u901a\u8fc7\u6570\u7ec4\u6216\u94fe\u8868\u6765\u5b9e\u73b0\u3002\u5728\u65f6\u95f4\u6548\u7387\u548c\u7a7a\u95f4\u6548\u7387\u7684\u5bf9\u6bd4\u4e0a\uff0c\u961f\u5217\u7684\u7ed3\u8bba\u4e0e\u524d\u8ff0\u6808\u7684\u7ed3\u8bba\u76f8\u4f3c\u3002
    • \u53cc\u5411\u961f\u5217\u662f\u4e00\u79cd\u5177\u6709\u66f4\u9ad8\u81ea\u7531\u5ea6\u7684\u961f\u5217\uff0c\u5b83\u5141\u8bb8\u5728\u4e24\u7aef\u8fdb\u884c\u5143\u7d20\u7684\u6dfb\u52a0\u548c\u5220\u9664\u64cd\u4f5c\u3002
    "},{"location":"chapter_stack_and_queue/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u6d4f\u89c8\u5668\u7684\u524d\u8fdb\u540e\u9000\u662f\u5426\u662f\u53cc\u5411\u94fe\u8868\u5b9e\u73b0\uff1f

    \u6d4f\u89c8\u5668\u7684\u524d\u8fdb\u540e\u9000\u529f\u80fd\u672c\u8d28\u4e0a\u662f\u201c\u6808\u201d\u7684\u4f53\u73b0\u3002\u5f53\u7528\u6237\u8bbf\u95ee\u4e00\u4e2a\u65b0\u9875\u9762\u65f6\uff0c\u8be5\u9875\u9762\u4f1a\u88ab\u6dfb\u52a0\u5230\u6808\u9876\uff1b\u5f53\u7528\u6237\u70b9\u51fb\u540e\u9000\u6309\u94ae\u65f6\uff0c\u8be5\u9875\u9762\u4f1a\u4ece\u6808\u9876\u5f39\u51fa\u3002\u4f7f\u7528\u53cc\u5411\u961f\u5217\u53ef\u4ee5\u65b9\u4fbf\u5730\u5b9e\u73b0\u4e00\u4e9b\u989d\u5916\u64cd\u4f5c\uff0c\u8fd9\u4e2a\u5728\u201c\u53cc\u5411\u961f\u5217\u201d\u7ae0\u8282\u6709\u63d0\u5230\u3002

    Q\uff1a\u5728\u51fa\u6808\u540e\uff0c\u662f\u5426\u9700\u8981\u91ca\u653e\u51fa\u6808\u8282\u70b9\u7684\u5185\u5b58\uff1f

    \u5982\u679c\u540e\u7eed\u4ecd\u9700\u8981\u4f7f\u7528\u5f39\u51fa\u8282\u70b9\uff0c\u5219\u4e0d\u9700\u8981\u91ca\u653e\u5185\u5b58\u3002\u82e5\u4e4b\u540e\u4e0d\u9700\u8981\u7528\u5230\uff0cJava \u548c Python \u7b49\u8bed\u8a00\u62e5\u6709\u81ea\u52a8\u5783\u573e\u56de\u6536\u673a\u5236\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u624b\u52a8\u91ca\u653e\u5185\u5b58\uff1b\u5728 C \u548c C++ \u4e2d\u9700\u8981\u624b\u52a8\u91ca\u653e\u5185\u5b58\u3002

    Q\uff1a\u53cc\u5411\u961f\u5217\u50cf\u662f\u4e24\u4e2a\u6808\u62fc\u63a5\u5728\u4e86\u4e00\u8d77\uff0c\u5b83\u7684\u7528\u9014\u662f\u4ec0\u4e48\uff1f

    \u53cc\u5411\u961f\u5217\u5c31\u50cf\u662f\u6808\u548c\u961f\u5217\u7684\u7ec4\u5408\u6216\u4e24\u4e2a\u6808\u62fc\u5728\u4e86\u4e00\u8d77\u3002\u5b83\u8868\u73b0\u7684\u662f\u6808 + \u961f\u5217\u7684\u903b\u8f91\uff0c\u56e0\u6b64\u53ef\u4ee5\u5b9e\u73b0\u6808\u4e0e\u961f\u5217\u7684\u6240\u6709\u5e94\u7528\uff0c\u5e76\u4e14\u66f4\u52a0\u7075\u6d3b\u3002

    Q\uff1a\u64a4\u9500\uff08undo\uff09\u548c\u53cd\u64a4\u9500\uff08redo\uff09\u5177\u4f53\u662f\u5982\u4f55\u5b9e\u73b0\u7684\uff1f

    \u4f7f\u7528\u4e24\u4e2a\u6808\uff0c\u6808 A \u7528\u4e8e\u64a4\u9500\uff0c\u6808 B \u7528\u4e8e\u53cd\u64a4\u9500\u3002

    1. \u6bcf\u5f53\u7528\u6237\u6267\u884c\u4e00\u4e2a\u64cd\u4f5c\uff0c\u5c06\u8fd9\u4e2a\u64cd\u4f5c\u538b\u5165\u6808 A \uff0c\u5e76\u6e05\u7a7a\u6808 B \u3002
    2. \u5f53\u7528\u6237\u6267\u884c\u201c\u64a4\u9500\u201d\u65f6\uff0c\u4ece\u6808 A \u4e2d\u5f39\u51fa\u6700\u8fd1\u7684\u64cd\u4f5c\uff0c\u5e76\u5c06\u5176\u538b\u5165\u6808 B \u3002
    3. \u5f53\u7528\u6237\u6267\u884c\u201c\u53cd\u64a4\u9500\u201d\u65f6\uff0c\u4ece\u6808 B \u4e2d\u5f39\u51fa\u6700\u8fd1\u7684\u64cd\u4f5c\uff0c\u5e76\u5c06\u5176\u538b\u5165\u6808 A \u3002
    "},{"location":"chapter_tree/","title":"\u7b2c 7 \u7ae0 \u00a0 \u6811","text":"

    Abstract

    \u53c2\u5929\u5927\u6811\u5145\u6ee1\u751f\u547d\u529b\uff0c\u6839\u6df1\u53f6\u8302\uff0c\u5206\u679d\u6276\u758f\u3002

    \u5b83\u4e3a\u6211\u4eec\u5c55\u73b0\u4e86\u6570\u636e\u5206\u6cbb\u7684\u751f\u52a8\u5f62\u6001\u3002

    "},{"location":"chapter_tree/#_1","title":"\u672c\u7ae0\u5185\u5bb9","text":"
    • 7.1 \u00a0 \u4e8c\u53c9\u6811
    • 7.2 \u00a0 \u4e8c\u53c9\u6811\u904d\u5386
    • 7.3 \u00a0 \u4e8c\u53c9\u6811\u6570\u7ec4\u8868\u793a
    • 7.4 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811
    • 7.5 \u00a0 AVL \u6811 *
    • 7.6 \u00a0 \u5c0f\u7ed3
    "},{"location":"chapter_tree/array_representation_of_tree/","title":"7.3 \u00a0 \u4e8c\u53c9\u6811\u6570\u7ec4\u8868\u793a","text":"

    \u5728\u94fe\u8868\u8868\u793a\u4e0b\uff0c\u4e8c\u53c9\u6811\u7684\u5b58\u50a8\u5355\u5143\u4e3a\u8282\u70b9 TreeNode \uff0c\u8282\u70b9\u4e4b\u95f4\u901a\u8fc7\u6307\u9488\u76f8\u8fde\u63a5\u3002\u4e0a\u4e00\u8282\u4ecb\u7ecd\u4e86\u94fe\u8868\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7684\u5404\u9879\u57fa\u672c\u64cd\u4f5c\u3002

    \u90a3\u4e48\uff0c\u6211\u4eec\u80fd\u5426\u7528\u6570\u7ec4\u6765\u8868\u793a\u4e8c\u53c9\u6811\u5462\uff1f\u7b54\u6848\u662f\u80af\u5b9a\u7684\u3002

    "},{"location":"chapter_tree/array_representation_of_tree/#731","title":"7.3.1 \u00a0 \u8868\u793a\u5b8c\u7f8e\u4e8c\u53c9\u6811","text":"

    \u5148\u5206\u6790\u4e00\u4e2a\u7b80\u5355\u6848\u4f8b\u3002\u7ed9\u5b9a\u4e00\u68f5\u5b8c\u7f8e\u4e8c\u53c9\u6811\uff0c\u6211\u4eec\u5c06\u6240\u6709\u8282\u70b9\u6309\u7167\u5c42\u5e8f\u904d\u5386\u7684\u987a\u5e8f\u5b58\u50a8\u5728\u4e00\u4e2a\u6570\u7ec4\u4e2d\uff0c\u5219\u6bcf\u4e2a\u8282\u70b9\u90fd\u5bf9\u5e94\u552f\u4e00\u7684\u6570\u7ec4\u7d22\u5f15\u3002

    \u6839\u636e\u5c42\u5e8f\u904d\u5386\u7684\u7279\u6027\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u5bfc\u51fa\u7236\u8282\u70b9\u7d22\u5f15\u4e0e\u5b50\u8282\u70b9\u7d22\u5f15\u4e4b\u95f4\u7684\u201c\u6620\u5c04\u516c\u5f0f\u201d\uff1a\u82e5\u67d0\u8282\u70b9\u7684\u7d22\u5f15\u4e3a \\(i\\) \uff0c\u5219\u8be5\u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7d22\u5f15\u4e3a \\(2i + 1\\) \uff0c\u53f3\u5b50\u8282\u70b9\u7d22\u5f15\u4e3a \\(2i + 2\\) \u3002\u56fe 7-12 \u5c55\u793a\u4e86\u5404\u4e2a\u8282\u70b9\u7d22\u5f15\u4e4b\u95f4\u7684\u6620\u5c04\u5173\u7cfb\u3002

    \u56fe 7-12 \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a

    \u6620\u5c04\u516c\u5f0f\u7684\u89d2\u8272\u76f8\u5f53\u4e8e\u94fe\u8868\u4e2d\u7684\u8282\u70b9\u5f15\u7528\uff08\u6307\u9488\uff09\u3002\u7ed9\u5b9a\u6570\u7ec4\u4e2d\u7684\u4efb\u610f\u4e00\u4e2a\u8282\u70b9\uff0c\u6211\u4eec\u90fd\u53ef\u4ee5\u901a\u8fc7\u6620\u5c04\u516c\u5f0f\u6765\u8bbf\u95ee\u5b83\u7684\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\u3002

    "},{"location":"chapter_tree/array_representation_of_tree/#732","title":"7.3.2 \u00a0 \u8868\u793a\u4efb\u610f\u4e8c\u53c9\u6811","text":"

    \u5b8c\u7f8e\u4e8c\u53c9\u6811\u662f\u4e00\u4e2a\u7279\u4f8b\uff0c\u5728\u4e8c\u53c9\u6811\u7684\u4e2d\u95f4\u5c42\u901a\u5e38\u5b58\u5728\u8bb8\u591a None \u3002\u7531\u4e8e\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u5e76\u4e0d\u5305\u542b\u8fd9\u4e9b None \uff0c\u56e0\u6b64\u6211\u4eec\u65e0\u6cd5\u4ec5\u51ed\u8be5\u5e8f\u5217\u6765\u63a8\u6d4b None \u7684\u6570\u91cf\u548c\u5206\u5e03\u4f4d\u7f6e\u3002\u8fd9\u610f\u5473\u7740\u5b58\u5728\u591a\u79cd\u4e8c\u53c9\u6811\u7ed3\u6784\u90fd\u7b26\u5408\u8be5\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u3002

    \u5982\u56fe 7-13 \u6240\u793a\uff0c\u7ed9\u5b9a\u4e00\u68f5\u975e\u5b8c\u7f8e\u4e8c\u53c9\u6811\uff0c\u4e0a\u8ff0\u6570\u7ec4\u8868\u793a\u65b9\u6cd5\u5df2\u7ecf\u5931\u6548\u3002

    \u56fe 7-13 \u00a0 \u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u5bf9\u5e94\u591a\u79cd\u4e8c\u53c9\u6811\u53ef\u80fd\u6027

    \u4e3a\u4e86\u89e3\u51b3\u6b64\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u8003\u8651\u5728\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u4e2d\u663e\u5f0f\u5730\u5199\u51fa\u6240\u6709 None \u3002\u5982\u56fe 7-14 \u6240\u793a\uff0c\u8fd9\u6837\u5904\u7406\u540e\uff0c\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u5c31\u53ef\u4ee5\u552f\u4e00\u8868\u793a\u4e8c\u53c9\u6811\u4e86\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    # \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a\n# \u4f7f\u7528 None \u6765\u8868\u793a\u7a7a\u4f4d\ntree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int \u6700\u5927\u503c INT_MAX \u6807\u8bb0\u7a7a\u4f4d\nvector<int> tree = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int \u7684\u5305\u88c5\u7c7b Integer \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 null \u6765\u6807\u8bb0\u7a7a\u4f4d\nInteger[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int? \u53ef\u7a7a\u7c7b\u578b \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 null \u6765\u6807\u8bb0\u7a7a\u4f4d\nint?[] tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 any \u7c7b\u578b\u7684\u5207\u7247, \u5c31\u53ef\u4ee5\u4f7f\u7528 nil \u6765\u6807\u8bb0\u7a7a\u4f4d\ntree := []any{1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15}\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 Int? \u53ef\u7a7a\u7c7b\u578b \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 nil \u6765\u6807\u8bb0\u7a7a\u4f4d\nlet tree: [Int?] = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 null \u6765\u8868\u793a\u7a7a\u4f4d\nlet tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 null \u6765\u8868\u793a\u7a7a\u4f4d\nlet tree: (number | null)[] = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int? \u53ef\u7a7a\u7c7b\u578b \uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 null \u6765\u6807\u8bb0\u7a7a\u4f4d\nList<int?> tree = [1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 None \u6765\u6807\u8bb0\u7a7a\u4f4d\nlet tree = [Some(1), Some(2), Some(3), Some(4), None, Some(6), Some(7), Some(8), Some(9), None, None, Some(12), None, None, Some(15)];\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 int \u6700\u5927\u503c\u6807\u8bb0\u7a7a\u4f4d\uff0c\u56e0\u6b64\u8981\u6c42\u8282\u70b9\u503c\u4e0d\u80fd\u4e3a INT_MAX\nint tree[] = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};\n
    /* \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a */\n// \u4f7f\u7528 null \u6765\u8868\u793a\u7a7a\u4f4d\nval tree = arrayOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )\n
    ### \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a ###\n# \u4f7f\u7528 nil \u6765\u8868\u793a\u7a7a\u4f4d\ntree = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]\n
    \n

    \u56fe 7-14 \u00a0 \u4efb\u610f\u7c7b\u578b\u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a

    \u503c\u5f97\u8bf4\u660e\u7684\u662f\uff0c\u5b8c\u5168\u4e8c\u53c9\u6811\u975e\u5e38\u9002\u5408\u4f7f\u7528\u6570\u7ec4\u6765\u8868\u793a\u3002\u56de\u987e\u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u5b9a\u4e49\uff0cNone \u53ea\u51fa\u73b0\u5728\u6700\u5e95\u5c42\u4e14\u9760\u53f3\u7684\u4f4d\u7f6e\uff0c\u56e0\u6b64\u6240\u6709 None \u4e00\u5b9a\u51fa\u73b0\u5728\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u7684\u672b\u5c3e\u3002

    \u8fd9\u610f\u5473\u7740\u4f7f\u7528\u6570\u7ec4\u8868\u793a\u5b8c\u5168\u4e8c\u53c9\u6811\u65f6\uff0c\u53ef\u4ee5\u7701\u7565\u5b58\u50a8\u6240\u6709 None \uff0c\u975e\u5e38\u65b9\u4fbf\u3002\u56fe 7-15 \u7ed9\u51fa\u4e86\u4e00\u4e2a\u4f8b\u5b50\u3002

    \u56fe 7-15 \u00a0 \u5b8c\u5168\u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a

    \u4ee5\u4e0b\u4ee3\u7801\u5b9e\u73b0\u4e86\u4e00\u68f5\u57fa\u4e8e\u6570\u7ec4\u8868\u793a\u7684\u4e8c\u53c9\u6811\uff0c\u5305\u62ec\u4ee5\u4e0b\u51e0\u79cd\u64cd\u4f5c\u3002

    • \u7ed9\u5b9a\u67d0\u8282\u70b9\uff0c\u83b7\u53d6\u5b83\u7684\u503c\u3001\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\u3001\u7236\u8282\u70b9\u3002
    • \u83b7\u53d6\u524d\u5e8f\u904d\u5386\u3001\u4e2d\u5e8f\u904d\u5386\u3001\u540e\u5e8f\u904d\u5386\u3001\u5c42\u5e8f\u904d\u5386\u5e8f\u5217\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig array_binary_tree.py
    class ArrayBinaryTree:\n    \"\"\"\u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b\"\"\"\n\n    def __init__(self, arr: list[int | None]):\n        \"\"\"\u6784\u9020\u65b9\u6cd5\"\"\"\n        self._tree = list(arr)\n\n    def size(self):\n        \"\"\"\u5217\u8868\u5bb9\u91cf\"\"\"\n        return len(self._tree)\n\n    def val(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c\"\"\"\n        # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 or i >= self.size():\n            return None\n        return self._tree[i]\n\n    def left(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 1\n\n    def right(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return 2 * i + 2\n\n    def parent(self, i: int) -> int | None:\n        \"\"\"\u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15\"\"\"\n        return (i - 1) // 2\n\n    def level_order(self) -> list[int]:\n        \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in range(self.size()):\n            if self.val(i) is not None:\n                self.res.append(self.val(i))\n        return self.res\n\n    def dfs(self, i: int, order: str):\n        \"\"\"\u6df1\u5ea6\u4f18\u5148\u904d\u5386\"\"\"\n        if self.val(i) is None:\n            return\n        # \u524d\u5e8f\u904d\u5386\n        if order == \"pre\":\n            self.res.append(self.val(i))\n        self.dfs(self.left(i), order)\n        # \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\":\n            self.res.append(self.val(i))\n        self.dfs(self.right(i), order)\n        # \u540e\u5e8f\u904d\u5386\n        if order == \"post\":\n            self.res.append(self.val(i))\n\n    def pre_order(self) -> list[int]:\n        \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"pre\")\n        return self.res\n\n    def in_order(self) -> list[int]:\n        \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"in\")\n        return self.res\n\n    def post_order(self) -> list[int]:\n        \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n        self.res = []\n        self.dfs(0, order=\"post\")\n        return self.res\n
    array_binary_tree.cpp
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  public:\n    /* \u6784\u9020\u65b9\u6cd5 */\n    ArrayBinaryTree(vector<int> arr) {\n        tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    int val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return INT_MAX;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    int right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    int parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    vector<int> levelOrder() {\n        vector<int> res;\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != INT_MAX)\n                res.push_back(val(i));\n        }\n        return res;\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    vector<int> preOrder() {\n        vector<int> res;\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    vector<int> inOrder() {\n        vector<int> res;\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    vector<int> postOrder() {\n        vector<int> res;\n        dfs(0, \"post\", res);\n        return res;\n    }\n\n  private:\n    vector<int> tree;\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void dfs(int i, string order, vector<int> &res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == INT_MAX)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.push_back(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.push_back(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.push_back(val(i));\n    }\n};\n
    array_binary_tree.java
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private List<Integer> tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    public ArrayBinaryTree(List<Integer> arr) {\n        tree = new ArrayList<>(arr);\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int size() {\n        return tree.size();\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public Integer val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size())\n            return null;\n        return tree.get(i);\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public Integer parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<Integer> levelOrder() {\n        List<Integer> res = new ArrayList<>();\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < size(); i++) {\n            if (val(i) != null)\n                res.add(val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private void dfs(Integer i, String order, List<Integer> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (val(i) == null)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\".equals(order))\n            res.add(val(i));\n        dfs(left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\".equals(order))\n            res.add(val(i));\n        dfs(right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\".equals(order))\n            res.add(val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<Integer> preOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<Integer> inOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<Integer> postOrder() {\n        List<Integer> res = new ArrayList<>();\n        dfs(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.cs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(List<int?> arr) {\n    List<int?> tree = new(arr);\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    public int Size() {\n        return tree.Count;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    public int? Val(int i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= Size())\n            return null;\n        return tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Left(int i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Right(int i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    public int Parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    public List<int> LevelOrder() {\n        List<int> res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (int i = 0; i < Size(); i++) {\n            if (Val(i).HasValue)\n                res.Add(Val(i)!.Value);\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    void DFS(int i, string order, List<int> res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (!Val(i).HasValue)\n            return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order == \"pre\")\n            res.Add(Val(i)!.Value);\n        DFS(Left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order == \"in\")\n            res.Add(Val(i)!.Value);\n        DFS(Right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order == \"post\")\n            res.Add(Val(i)!.Value);\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    public List<int> PreOrder() {\n        List<int> res = [];\n        DFS(0, \"pre\", res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    public List<int> InOrder() {\n        List<int> res = [];\n        DFS(0, \"in\", res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    public List<int> PostOrder() {\n        List<int> res = [];\n        DFS(0, \"post\", res);\n        return res;\n    }\n}\n
    array_binary_tree.go
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\ntype arrayBinaryTree struct {\n    tree []any\n}\n\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc newArrayBinaryTree(arr []any) *arrayBinaryTree {\n    return &arrayBinaryTree{\n        tree: arr,\n    }\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nfunc (abt *arrayBinaryTree) size() int {\n    return len(abt.tree)\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nfunc (abt *arrayBinaryTree) val(i int) any {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if i < 0 || i >= abt.size() {\n        return nil\n    }\n    return abt.tree[i]\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) left(i int) int {\n    return 2*i + 1\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) right(i int) int {\n    return 2*i + 2\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\nfunc (abt *arrayBinaryTree) parent(i int) int {\n    return (i - 1) / 2\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) levelOrder() []any {\n    var res []any\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i := 0; i < abt.size(); i++ {\n        if abt.val(i) != nil {\n            res = append(res, abt.val(i))\n        }\n    }\n    return res\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nfunc (abt *arrayBinaryTree) dfs(i int, order string, res *[]any) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if abt.val(i) == nil {\n        return\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if order == \"pre\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.left(i), order, res)\n    // \u4e2d\u5e8f\u904d\u5386\n    if order == \"in\" {\n        *res = append(*res, abt.val(i))\n    }\n    abt.dfs(abt.right(i), order, res)\n    // \u540e\u5e8f\u904d\u5386\n    if order == \"post\" {\n        *res = append(*res, abt.val(i))\n    }\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) preOrder() []any {\n    var res []any\n    abt.dfs(0, \"pre\", &res)\n    return res\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) inOrder() []any {\n    var res []any\n    abt.dfs(0, \"in\", &res)\n    return res\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc (abt *arrayBinaryTree) postOrder() []any {\n    var res []any\n    abt.dfs(0, \"post\", &res)\n    return res\n}\n
    array_binary_tree.swift
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    private var tree: [Int?]\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    init(arr: [Int?]) {\n        tree = arr\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    func size() -> Int {\n        tree.count\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    func val(i: Int) -> Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= size() {\n            return nil\n        }\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func left(i: Int) -> Int {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    func right(i: Int) -> Int {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    func parent(i: Int) -> Int {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    func levelOrder() -> [Int] {\n        var res: [Int] = []\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0 ..< size() {\n            if let val = val(i: i) {\n                res.append(val)\n            }\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    private func dfs(i: Int, order: String, res: inout [Int]) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        guard let val = val(i: i) else {\n            return\n        }\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.append(val)\n        }\n        dfs(i: left(i: i), order: order, res: &res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.append(val)\n        }\n        dfs(i: right(i: i), order: order, res: &res)\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.append(val)\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    func preOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"pre\", res: &res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    func inOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"in\", res: &res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    func postOrder() -> [Int] {\n        var res: [Int] = []\n        dfs(i: 0, order: \"post\", res: &res)\n        return res\n    }\n}\n
    array_binary_tree.js
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree;\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size() {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i) {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i) {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i) {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i) {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder() {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i, order, res) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder() {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder() {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder() {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.ts
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n    #tree: (number | null)[];\n\n    /* \u6784\u9020\u65b9\u6cd5 */\n    constructor(arr: (number | null)[]) {\n        this.#tree = arr;\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    size(): number {\n        return this.#tree.length;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    val(i: number): number | null {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= this.size()) return null;\n        return this.#tree[i];\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    left(i: number): number {\n        return 2 * i + 1;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    right(i: number): number {\n        return 2 * i + 2;\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    parent(i: number): number {\n        return Math.floor((i - 1) / 2); // \u5411\u4e0b\u6574\u9664\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    levelOrder(): number[] {\n        let res = [];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (let i = 0; i < this.size(); i++) {\n            if (this.val(i) !== null) res.push(this.val(i));\n        }\n        return res;\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    #dfs(i: number, order: Order, res: (number | null)[]): void {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (this.val(i) === null) return;\n        // \u524d\u5e8f\u904d\u5386\n        if (order === 'pre') res.push(this.val(i));\n        this.#dfs(this.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if (order === 'in') res.push(this.val(i));\n        this.#dfs(this.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if (order === 'post') res.push(this.val(i));\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    preOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'pre', res);\n        return res;\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    inOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'in', res);\n        return res;\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    postOrder(): (number | null)[] {\n        const res = [];\n        this.#dfs(0, 'post', res);\n        return res;\n    }\n}\n
    array_binary_tree.dart
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree {\n  late List<int?> _tree;\n\n  /* \u6784\u9020\u65b9\u6cd5 */\n  ArrayBinaryTree(this._tree);\n\n  /* \u5217\u8868\u5bb9\u91cf */\n  int size() {\n    return _tree.length;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n  int? val(int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size()) {\n      return null;\n    }\n    return _tree[i];\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? left(int i) {\n    return 2 * i + 1;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? right(int i) {\n    return 2 * i + 2;\n  }\n\n  /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n  int? parent(int i) {\n    return (i - 1) ~/ 2;\n  }\n\n  /* \u5c42\u5e8f\u904d\u5386 */\n  List<int> levelOrder() {\n    List<int> res = [];\n    for (int i = 0; i < size(); i++) {\n      if (val(i) != null) {\n        res.add(val(i)!);\n      }\n    }\n    return res;\n  }\n\n  /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n  void dfs(int i, String order, List<int?> res) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(i) == null) {\n      return;\n    }\n    // \u524d\u5e8f\u904d\u5386\n    if (order == 'pre') {\n      res.add(val(i));\n    }\n    dfs(left(i)!, order, res);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (order == 'in') {\n      res.add(val(i));\n    }\n    dfs(right(i)!, order, res);\n    // \u540e\u5e8f\u904d\u5386\n    if (order == 'post') {\n      res.add(val(i));\n    }\n  }\n\n  /* \u524d\u5e8f\u904d\u5386 */\n  List<int?> preOrder() {\n    List<int?> res = [];\n    dfs(0, 'pre', res);\n    return res;\n  }\n\n  /* \u4e2d\u5e8f\u904d\u5386 */\n  List<int?> inOrder() {\n    List<int?> res = [];\n    dfs(0, 'in', res);\n    return res;\n  }\n\n  /* \u540e\u5e8f\u904d\u5386 */\n  List<int?> postOrder() {\n    List<int?> res = [];\n    dfs(0, 'post', res);\n    return res;\n  }\n}\n
    array_binary_tree.rs
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nstruct ArrayBinaryTree {\n    tree: Vec<Option<i32>>,\n}\n\nimpl ArrayBinaryTree {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(arr: Vec<Option<i32>>) -> Self {\n        Self { tree: arr }\n    }\n\n    /* \u5217\u8868\u5bb9\u91cf */\n    fn size(&self) -> i32 {\n        self.tree.len() as i32\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fn val(&self, i: i32) -> Option<i32> {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de None \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if i < 0 || i >= self.size() {\n            None\n        } else {\n            self.tree[i as usize]\n        }\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn left(&self, i: i32) -> i32 {\n        2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn right(&self, i: i32) -> i32 {\n        2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fn parent(&self, i: i32) -> i32 {\n        (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fn level_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for i in 0..self.size() {\n            if let Some(val) = self.val(i) {\n                res.push(val)\n            }\n        }\n        res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fn dfs(&self, i: i32, order: &str, res: &mut Vec<i32>) {\n        if self.val(i).is_none() {\n            return;\n        }\n        let val = self.val(i).unwrap();\n        // \u524d\u5e8f\u904d\u5386\n        if order == \"pre\" {\n            res.push(val);\n        }\n        self.dfs(self.left(i), order, res);\n        // \u4e2d\u5e8f\u904d\u5386\n        if order == \"in\" {\n            res.push(val);\n        }\n        self.dfs(self.right(i), order, res);\n        // \u540e\u5e8f\u904d\u5386\n        if order == \"post\" {\n            res.push(val);\n        }\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fn pre_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"pre\", &mut res);\n        res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fn in_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"in\", &mut res);\n        res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fn post_order(&self) -> Vec<i32> {\n        let mut res = vec![];\n        self.dfs(0, \"post\", &mut res);\n        res\n    }\n}\n
    array_binary_tree.c
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7ed3\u6784\u4f53 */\ntypedef struct {\n    int *tree;\n    int size;\n} ArrayBinaryTree;\n\n/* \u6784\u9020\u51fd\u6570 */\nArrayBinaryTree *newArrayBinaryTree(int *arr, int arrSize) {\n    ArrayBinaryTree *abt = (ArrayBinaryTree *)malloc(sizeof(ArrayBinaryTree));\n    abt->tree = malloc(sizeof(int) * arrSize);\n    memcpy(abt->tree, arr, sizeof(int) * arrSize);\n    abt->size = arrSize;\n    return abt;\n}\n\n/* \u6790\u6784\u51fd\u6570 */\nvoid delArrayBinaryTree(ArrayBinaryTree *abt) {\n    free(abt->tree);\n    free(abt);\n}\n\n/* \u5217\u8868\u5bb9\u91cf */\nint size(ArrayBinaryTree *abt) {\n    return abt->size;\n}\n\n/* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\nint val(ArrayBinaryTree *abt, int i) {\n    // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de INT_MAX \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    if (i < 0 || i >= size(abt))\n        return INT_MAX;\n    return abt->tree[i];\n}\n\n/* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for (int i = 0; i < size(abt); i++) {\n        if (val(abt, i) != INT_MAX)\n            res[index++] = val(abt, i);\n    }\n    *returnSize = index;\n    return res;\n}\n\n/* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\nvoid dfs(ArrayBinaryTree *abt, int i, char *order, int *res, int *index) {\n    // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n    if (val(abt, i) == INT_MAX)\n        return;\n    // \u524d\u5e8f\u904d\u5386\n    if (strcmp(order, \"pre\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, left(i), order, res, index);\n    // \u4e2d\u5e8f\u904d\u5386\n    if (strcmp(order, \"in\") == 0)\n        res[(*index)++] = val(abt, i);\n    dfs(abt, right(i), order, res, index);\n    // \u540e\u5e8f\u904d\u5386\n    if (strcmp(order, \"post\") == 0)\n        res[(*index)++] = val(abt, i);\n}\n\n/* \u524d\u5e8f\u904d\u5386 */\nint *preOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"pre\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nint *inOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"in\", res, &index);\n    *returnSize = index;\n    return res;\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nint *postOrder(ArrayBinaryTree *abt, int *returnSize) {\n    int *res = (int *)malloc(sizeof(int) * size(abt));\n    int index = 0;\n    dfs(abt, 0, \"post\", res, &index);\n    *returnSize = index;\n    return res;\n}\n
    array_binary_tree.kt
    /* \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b */\nclass ArrayBinaryTree(val tree: MutableList<Int?>) {\n    /* \u5217\u8868\u5bb9\u91cf */\n    fun size(): Int {\n        return tree.size\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c */\n    fun _val(i: Int): Int? {\n        // \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de null \uff0c\u4ee3\u8868\u7a7a\u4f4d\n        if (i < 0 || i >= size()) return null\n        return tree[i]\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun left(i: Int): Int {\n        return 2 * i + 1\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun right(i: Int): Int {\n        return 2 * i + 2\n    }\n\n    /* \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 */\n    fun parent(i: Int): Int {\n        return (i - 1) / 2\n    }\n\n    /* \u5c42\u5e8f\u904d\u5386 */\n    fun levelOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        // \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n        for (i in 0..<size()) {\n            if (_val(i) != null)\n                res.add(_val(i))\n        }\n        return res\n    }\n\n    /* \u6df1\u5ea6\u4f18\u5148\u904d\u5386 */\n    fun dfs(i: Int, order: String, res: MutableList<Int?>) {\n        // \u82e5\u4e3a\u7a7a\u4f4d\uff0c\u5219\u8fd4\u56de\n        if (_val(i) == null)\n            return\n        // \u524d\u5e8f\u904d\u5386\n        if (\"pre\" == order)\n            res.add(_val(i))\n        dfs(left(i), order, res)\n        // \u4e2d\u5e8f\u904d\u5386\n        if (\"in\" == order)\n            res.add(_val(i))\n        dfs(right(i), order, res)\n        // \u540e\u5e8f\u904d\u5386\n        if (\"post\" == order)\n            res.add(_val(i))\n    }\n\n    /* \u524d\u5e8f\u904d\u5386 */\n    fun preOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"pre\", res)\n        return res\n    }\n\n    /* \u4e2d\u5e8f\u904d\u5386 */\n    fun inOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"in\", res)\n        return res\n    }\n\n    /* \u540e\u5e8f\u904d\u5386 */\n    fun postOrder(): MutableList<Int?> {\n        val res = mutableListOf<Int?>()\n        dfs(0, \"post\", res)\n        return res\n    }\n}\n
    array_binary_tree.rb
    ### \u6570\u7ec4\u8868\u793a\u4e0b\u7684\u4e8c\u53c9\u6811\u7c7b ###\nclass ArrayBinaryTree\n  ### \u6784\u9020\u65b9\u6cd5 ###\n  def initialize(arr)\n    @tree = arr.to_a\n  end\n\n  ### \u5217\u8868\u5bb9\u91cf ###\n  def size\n    @tree.length\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u503c ###\n  def val(i)\n    # \u82e5\u7d22\u5f15\u8d8a\u754c\uff0c\u5219\u8fd4\u56de nil \uff0c\u4ee3\u8868\u7a7a\u4f4d\n    return if i < 0 || i >= size\n\n    @tree[i]\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def left(i)\n    2 * i + 1\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u53f3\u5b50\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def right(i)\n    2 * i + 2\n  end\n\n  ### \u83b7\u53d6\u7d22\u5f15\u4e3a i \u8282\u70b9\u7684\u7236\u8282\u70b9\u7684\u7d22\u5f15 ###\n  def parent(i)\n    (i - 1) / 2\n  end\n\n  ### \u5c42\u5e8f\u904d\u5386 ###\n  def level_order\n    @res = []\n\n    # \u76f4\u63a5\u904d\u5386\u6570\u7ec4\n    for i in 0...size\n      @res << val(i) unless val(i).nil?\n    end\n\n    @res\n  end\n\n  ### \u6df1\u5ea6\u4f18\u5148\u904d\u5386 ###\n  def dfs(i, order)\n    return if val(i).nil?\n    # \u524d\u5e8f\u904d\u5386\n    @res << val(i) if order == :pre\n    dfs(left(i), order)\n    # \u4e2d\u5e8f\u904d\u5386\n    @res << val(i) if order == :in\n    dfs(right(i), order)\n    # \u540e\u5e8f\u904d\u5386\n    @res << val(i) if order == :post\n  end\n\n  ### \u524d\u5e8f\u904d\u5386 ###\n  def pre_order\n    @res = []\n    dfs(0, :pre)\n    @res\n  end\n\n  ### \u4e2d\u5e8f\u904d\u5386 ###\n  def in_order\n    @res = []\n    dfs(0, :in)\n    @res\n  end\n\n  ### \u540e\u5e8f\u904d\u5386 ###\n  def post_order\n    @res = []\n    dfs(0, :post)\n    @res\n  end\nend\n
    array_binary_tree.zig
    [class]{ArrayBinaryTree}-[func]{}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/array_representation_of_tree/#733","title":"7.3.3 \u00a0 \u4f18\u70b9\u4e0e\u5c40\u9650\u6027","text":"

    \u4e8c\u53c9\u6811\u7684\u6570\u7ec4\u8868\u793a\u4e3b\u8981\u6709\u4ee5\u4e0b\u4f18\u70b9\u3002

    • \u6570\u7ec4\u5b58\u50a8\u5728\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\u4e2d\uff0c\u5bf9\u7f13\u5b58\u53cb\u597d\uff0c\u8bbf\u95ee\u4e0e\u904d\u5386\u901f\u5ea6\u8f83\u5feb\u3002
    • \u4e0d\u9700\u8981\u5b58\u50a8\u6307\u9488\uff0c\u6bd4\u8f83\u8282\u7701\u7a7a\u95f4\u3002
    • \u5141\u8bb8\u968f\u673a\u8bbf\u95ee\u8282\u70b9\u3002

    \u7136\u800c\uff0c\u6570\u7ec4\u8868\u793a\u4e5f\u5b58\u5728\u4e00\u4e9b\u5c40\u9650\u6027\u3002

    • \u6570\u7ec4\u5b58\u50a8\u9700\u8981\u8fde\u7eed\u5185\u5b58\u7a7a\u95f4\uff0c\u56e0\u6b64\u4e0d\u9002\u5408\u5b58\u50a8\u6570\u636e\u91cf\u8fc7\u5927\u7684\u6811\u3002
    • \u589e\u5220\u8282\u70b9\u9700\u8981\u901a\u8fc7\u6570\u7ec4\u63d2\u5165\u4e0e\u5220\u9664\u64cd\u4f5c\u5b9e\u73b0\uff0c\u6548\u7387\u8f83\u4f4e\u3002
    • \u5f53\u4e8c\u53c9\u6811\u4e2d\u5b58\u5728\u5927\u91cf None \u65f6\uff0c\u6570\u7ec4\u4e2d\u5305\u542b\u7684\u8282\u70b9\u6570\u636e\u6bd4\u91cd\u8f83\u4f4e\uff0c\u7a7a\u95f4\u5229\u7528\u7387\u8f83\u4f4e\u3002
    "},{"location":"chapter_tree/avl_tree/","title":"7.5 \u00a0 AVL \u6811 *","text":"

    \u5728\u201c\u4e8c\u53c9\u641c\u7d22\u6811\u201d\u7ae0\u8282\u4e2d\u6211\u4eec\u63d0\u5230\uff0c\u5728\u591a\u6b21\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u540e\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u53ef\u80fd\u9000\u5316\u4e3a\u94fe\u8868\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5c06\u4ece \\(O(\\log n)\\) \u52a3\u5316\u4e3a \\(O(n)\\) \u3002

    \u5982\u56fe 7-24 \u6240\u793a\uff0c\u7ecf\u8fc7\u4e24\u6b21\u5220\u9664\u8282\u70b9\u64cd\u4f5c\uff0c\u8fd9\u68f5\u4e8c\u53c9\u641c\u7d22\u6811\u4fbf\u4f1a\u9000\u5316\u4e3a\u94fe\u8868\u3002

    \u56fe 7-24 \u00a0 AVL \u6811\u5728\u5220\u9664\u8282\u70b9\u540e\u53d1\u751f\u9000\u5316

    \u518d\u4f8b\u5982\uff0c\u5728\u56fe 7-25 \u6240\u793a\u7684\u5b8c\u7f8e\u4e8c\u53c9\u6811\u4e2d\u63d2\u5165\u4e24\u4e2a\u8282\u70b9\u540e\uff0c\u6811\u5c06\u4e25\u91cd\u5411\u5de6\u503e\u659c\uff0c\u67e5\u627e\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u968f\u4e4b\u52a3\u5316\u3002

    \u56fe 7-25 \u00a0 AVL \u6811\u5728\u63d2\u5165\u8282\u70b9\u540e\u53d1\u751f\u9000\u5316

    1962 \u5e74 G. M. Adelson-Velsky \u548c E. M. Landis \u5728\u8bba\u6587\u201cAn algorithm for the organization of information\u201d\u4e2d\u63d0\u51fa\u4e86 AVL \u6811\u3002\u8bba\u6587\u4e2d\u8be6\u7ec6\u63cf\u8ff0\u4e86\u4e00\u7cfb\u5217\u64cd\u4f5c\uff0c\u786e\u4fdd\u5728\u6301\u7eed\u6dfb\u52a0\u548c\u5220\u9664\u8282\u70b9\u540e\uff0cAVL \u6811\u4e0d\u4f1a\u9000\u5316\uff0c\u4ece\u800c\u4f7f\u5f97\u5404\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4fdd\u6301\u5728 \\(O(\\log n)\\) \u7ea7\u522b\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u5728\u9700\u8981\u9891\u7e41\u8fdb\u884c\u589e\u5220\u67e5\u6539\u64cd\u4f5c\u7684\u573a\u666f\u4e2d\uff0cAVL \u6811\u80fd\u59cb\u7ec8\u4fdd\u6301\u9ad8\u6548\u7684\u6570\u636e\u64cd\u4f5c\u6027\u80fd\uff0c\u5177\u6709\u5f88\u597d\u7684\u5e94\u7528\u4ef7\u503c\u3002

    "},{"location":"chapter_tree/avl_tree/#751-avl","title":"7.5.1 \u00a0 AVL \u6811\u5e38\u89c1\u672f\u8bed","text":"

    AVL \u6811\u65e2\u662f\u4e8c\u53c9\u641c\u7d22\u6811\uff0c\u4e5f\u662f\u5e73\u8861\u4e8c\u53c9\u6811\uff0c\u540c\u65f6\u6ee1\u8db3\u8fd9\u4e24\u7c7b\u4e8c\u53c9\u6811\u7684\u6240\u6709\u6027\u8d28\uff0c\u56e0\u6b64\u662f\u4e00\u79cd\u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811\uff08balanced binary search tree\uff09\u3002

    "},{"location":"chapter_tree/avl_tree/#1","title":"1. \u00a0 \u8282\u70b9\u9ad8\u5ea6","text":"

    \u7531\u4e8e AVL \u6811\u7684\u76f8\u5173\u64cd\u4f5c\u9700\u8981\u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u4e3a\u8282\u70b9\u7c7b\u6dfb\u52a0 height \u53d8\u91cf\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"AVL \u6811\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                 # \u8282\u70b9\u503c\n        self.height: int = 0                # \u8282\u70b9\u9ad8\u5ea6\n        self.left: TreeNode | None = None   # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n        self.right: TreeNode | None = None  # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nstruct TreeNode {\n    int val{};          // \u8282\u70b9\u503c\n    int height = 0;     // \u8282\u70b9\u9ad8\u5ea6\n    TreeNode *left{};   // \u5de6\u5b50\u8282\u70b9\n    TreeNode *right{};  // \u53f3\u5b50\u8282\u70b9\n    TreeNode() = default;\n    explicit TreeNode(int x) : val(x){}\n};\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    public int val;        // \u8282\u70b9\u503c\n    public int height;     // \u8282\u70b9\u9ad8\u5ea6\n    public TreeNode left;  // \u5de6\u5b50\u8282\u70b9\n    public TreeNode right; // \u53f3\u5b50\u8282\u70b9\n    public TreeNode(int x) { val = x; }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode(int? x) {\n    public int? val = x;    // \u8282\u70b9\u503c\n    public int height;      // \u8282\u70b9\u9ad8\u5ea6\n    public TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    public TreeNode? right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    /* AVL \u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype TreeNode struct {\n    Val    int       // \u8282\u70b9\u503c\n    Height int       // \u8282\u70b9\u9ad8\u5ea6\n    Left   *TreeNode // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    Right  *TreeNode // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    var val: Int // \u8282\u70b9\u503c\n    var height: Int // \u8282\u70b9\u9ad8\u5ea6\n    var left: TreeNode? // \u5de6\u5b50\u8282\u70b9\n    var right: TreeNode? // \u53f3\u5b50\u8282\u70b9\n\n    init(x: Int) {\n        val = x\n        height = 0\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val; // \u8282\u70b9\u503c\n    height; //\u8282\u70b9\u9ad8\u5ea6\n    left; // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    right; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    constructor(val, left, right, height) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val: number;            // \u8282\u70b9\u503c\n    height: number;         // \u8282\u70b9\u9ad8\u5ea6\n    left: TreeNode | null;  // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    right: TreeNode | null; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    constructor(val?: number, height?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val;\n        this.height = height === undefined ? 0 : height;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n  int val;         // \u8282\u70b9\u503c\n  int height;      // \u8282\u70b9\u9ad8\u5ea6\n  TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\n  TreeNode? right; // \u53f3\u5b50\u8282\u70b9\n  TreeNode(this.val, [this.height = 0, this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* AVL \u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct TreeNode {\n    val: i32,                               // \u8282\u70b9\u503c\n    height: i32,                            // \u8282\u70b9\u9ad8\u5ea6\n    left: Option<Rc<RefCell<TreeNode>>>,    // \u5de6\u5b50\u8282\u70b9\n    right: Option<Rc<RefCell<TreeNode>>>,   // \u53f3\u5b50\u8282\u70b9\n}\n\nimpl TreeNode {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            height: 0,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* AVL \u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nTreeNode struct TreeNode {\n    int val;\n    int height;\n    struct TreeNode *left;\n    struct TreeNode *right;\n} TreeNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* AVL \u6811\u8282\u70b9\u7c7b */\nclass TreeNode(val _val: Int) {  // \u8282\u70b9\u503c\n    val height: Int = 0          // \u8282\u70b9\u9ad8\u5ea6\n    val left: TreeNode? = null   // \u5de6\u5b50\u8282\u70b9\n    val right: TreeNode? = null  // \u53f3\u5b50\u8282\u70b9\n}\n
    ### AVL \u6811\u8282\u70b9\u7c7b ###\nclass TreeNode\n  attr_accessor :val    # \u8282\u70b9\u503c\n  attr_accessor :height # \u8282\u70b9\u9ad8\u5ea6\n  attr_accessor :left   # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n  attr_accessor :right  # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n\n  def initialize(val)\n    @val = val\n    @height = 0\n  end\nend\n
    \n

    \u201c\u8282\u70b9\u9ad8\u5ea6\u201d\u662f\u6307\u4ece\u8be5\u8282\u70b9\u5230\u5b83\u7684\u6700\u8fdc\u53f6\u8282\u70b9\u7684\u8ddd\u79bb\uff0c\u5373\u6240\u7ecf\u8fc7\u7684\u201c\u8fb9\u201d\u7684\u6570\u91cf\u3002\u9700\u8981\u7279\u522b\u6ce8\u610f\u7684\u662f\uff0c\u53f6\u8282\u70b9\u7684\u9ad8\u5ea6\u4e3a \\(0\\) \uff0c\u800c\u7a7a\u8282\u70b9\u7684\u9ad8\u5ea6\u4e3a \\(-1\\) \u3002\u6211\u4eec\u5c06\u521b\u5efa\u4e24\u4e2a\u5de5\u5177\u51fd\u6570\uff0c\u5206\u522b\u7528\u4e8e\u83b7\u53d6\u548c\u66f4\u65b0\u8282\u70b9\u7684\u9ad8\u5ea6\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def height(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node is not None:\n        return node.height\n    return -1\n\ndef update_height(self, node: TreeNode | None):\n    \"\"\"\u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\"\"\"\n    # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = max([self.height(node.left), self.height(node.right)]) + 1\n
    avl_tree.cpp
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == nullptr ? -1 : node->height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node->height = max(height(node->left), height(node->right)) + 1;\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint Height(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid UpdateHeight(TreeNode node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height = Math.Max(Height(node.left), Height(node.right)) + 1;\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) height(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if node != nil {\n        return node.Height\n    }\n    return -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc (t *aVLTree) updateHeight(node *TreeNode) {\n    lh := t.height(node.Left)\n    rh := t.height(node.Right)\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if lh > rh {\n        node.Height = lh + 1\n    } else {\n        node.Height = rh + 1\n    }\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfunc height(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    node?.height ?? -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfunc updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node: node?.left), height(node: node?.right)) + 1\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\n#updateHeight(node) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nheight(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node === null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nupdateHeight(node: TreeNode): void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.height =\n        Math.max(this.height(node.left), this.height(node.right)) + 1;\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node == null ? -1 : node.height;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode? node) {\n  // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node!.height = max(height(node.left), height(node.right)) + 1;\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfn height(node: OptionTreeNodeRc) -> i32 {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    match node {\n        Some(node) => node.borrow().height,\n        None => -1,\n    }\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfn update_height(node: OptionTreeNodeRc) {\n    if let Some(node) = node {\n        let left = node.borrow().left.clone();\n        let right = node.borrow().right.clone();\n        // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n        node.borrow_mut().height = std::cmp::max(Self::height(left), Self::height(right)) + 1;\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nint height(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    if (node != NULL) {\n        return node->height;\n    }\n    return -1;\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nvoid updateHeight(TreeNode *node) {\n    int lh = height(node->left);\n    int rh = height(node->right);\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    if (lh > rh) {\n        node->height = lh + 1;\n    } else {\n        node->height = rh + 1;\n    }\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 */\nfun height(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return node?.height ?: -1\n}\n\n/* \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 */\nfun updateHeight(node: TreeNode?) {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node?.height = max(height(node?.left), height(node?.right)) + 1\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6 ###\ndef height(node)\n  # \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n  return node.height unless node.nil?\n\n  -1\nend\n\n### \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6 ###\ndef update_height(node)\n  # \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n  node.height = [height(node.left), height(node.right)].max + 1\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u8282\u70b9\u9ad8\u5ea6\nfn height(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    _ = self;\n    // \u7a7a\u8282\u70b9\u9ad8\u5ea6\u4e3a -1 \uff0c\u53f6\u8282\u70b9\u9ad8\u5ea6\u4e3a 0\n    return if (node == null) -1 else node.?.height;\n}\n\n// \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\nfn updateHeight(self: *Self, node: ?*inc.TreeNode(T)) void {\n    // \u8282\u70b9\u9ad8\u5ea6\u7b49\u4e8e\u6700\u9ad8\u5b50\u6811\u9ad8\u5ea6 + 1\n    node.?.height = @max(self.height(node.?.left), self.height(node.?.right)) + 1;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2","title":"2. \u00a0 \u8282\u70b9\u5e73\u8861\u56e0\u5b50","text":"

    \u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\uff08balance factor\uff09\u5b9a\u4e49\u4e3a\u8282\u70b9\u5de6\u5b50\u6811\u7684\u9ad8\u5ea6\u51cf\u53bb\u53f3\u5b50\u6811\u7684\u9ad8\u5ea6\uff0c\u540c\u65f6\u89c4\u5b9a\u7a7a\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u4e3a \\(0\\) \u3002\u6211\u4eec\u540c\u6837\u5c06\u83b7\u53d6\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u7684\u529f\u80fd\u5c01\u88c5\u6210\u51fd\u6570\uff0c\u65b9\u4fbf\u540e\u7eed\u4f7f\u7528\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def balance_factor(self, node: TreeNode | None) -> int:\n    \"\"\"\u83b7\u53d6\u5e73\u8861\u56e0\u5b50\"\"\"\n    # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node is None:\n        return 0\n    # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.left) - self.height(node.right)\n
    avl_tree.cpp
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == nullptr)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.java
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null)\n        return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right);\n}\n
    avl_tree.cs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint BalanceFactor(TreeNode? node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return Height(node.left) - Height(node.right);\n}\n
    avl_tree.go
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc (t *aVLTree) balanceFactor(node *TreeNode) int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if node == nil {\n        return 0\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return t.height(node.Left) - t.height(node.Right)\n}\n
    avl_tree.swift
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfunc balanceFactor(node: TreeNode?) -> Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    guard let node = node else { return 0 }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node: node.left) - height(node: node.right)\n}\n
    avl_tree.js
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.ts
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nbalanceFactor(node: TreeNode): number {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node === null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return this.height(node.left) - this.height(node.right);\n}\n
    avl_tree.dart
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode? node) {\n  // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  if (node == null) return 0;\n  // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  return height(node.left) - height(node.right);\n}\n
    avl_tree.rs
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfn balance_factor(node: OptionTreeNodeRc) -> i32 {\n    match node {\n        // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n        None => 0,\n        // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n        Some(node) => {\n            Self::height(node.borrow().left.clone()) - Self::height(node.borrow().right.clone())\n        }\n    }\n}\n
    avl_tree.c
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nint balanceFactor(TreeNode *node) {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == NULL) {\n        return 0;\n    }\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node->left) - height(node->right);\n}\n
    avl_tree.kt
    /* \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 */\nfun balanceFactor(node: TreeNode?): Int {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return height(node.left) - height(node.right)\n}\n
    avl_tree.rb
    ### \u83b7\u53d6\u5e73\u8861\u56e0\u5b50 ###\ndef balance_factor(node)\n  # \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n  return 0 if node.nil?\n\n  # \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n  height(node.left) - height(node.right)\nend\n
    avl_tree.zig
    // \u83b7\u53d6\u5e73\u8861\u56e0\u5b50\nfn balanceFactor(self: *Self, node: ?*inc.TreeNode(T)) i32 {\n    // \u7a7a\u8282\u70b9\u5e73\u8861\u56e0\u5b50\u4e3a 0\n    if (node == null) return 0;\n    // \u8282\u70b9\u5e73\u8861\u56e0\u5b50 = \u5de6\u5b50\u6811\u9ad8\u5ea6 - \u53f3\u5b50\u6811\u9ad8\u5ea6\n    return self.height(node.?.left) - self.height(node.?.right);\n}\n

    Tip

    \u8bbe\u5e73\u8861\u56e0\u5b50\u4e3a \\(f\\) \uff0c\u5219\u4e00\u68f5 AVL \u6811\u7684\u4efb\u610f\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u7686\u6ee1\u8db3 \\(-1 \\le f \\le 1\\) \u3002

    "},{"location":"chapter_tree/avl_tree/#752-avl","title":"7.5.2 \u00a0 AVL \u6811\u65cb\u8f6c","text":"

    AVL \u6811\u7684\u7279\u70b9\u5728\u4e8e\u201c\u65cb\u8f6c\u201d\u64cd\u4f5c\uff0c\u5b83\u80fd\u591f\u5728\u4e0d\u5f71\u54cd\u4e8c\u53c9\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217\u7684\u524d\u63d0\u4e0b\uff0c\u4f7f\u5931\u8861\u8282\u70b9\u91cd\u65b0\u6062\u590d\u5e73\u8861\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u65cb\u8f6c\u64cd\u4f5c\u65e2\u80fd\u4fdd\u6301\u201c\u4e8c\u53c9\u641c\u7d22\u6811\u201d\u7684\u6027\u8d28\uff0c\u4e5f\u80fd\u4f7f\u6811\u91cd\u65b0\u53d8\u4e3a\u201c\u5e73\u8861\u4e8c\u53c9\u6811\u201d\u3002

    \u6211\u4eec\u5c06\u5e73\u8861\u56e0\u5b50\u7edd\u5bf9\u503c \\(> 1\\) \u7684\u8282\u70b9\u79f0\u4e3a\u201c\u5931\u8861\u8282\u70b9\u201d\u3002\u6839\u636e\u8282\u70b9\u5931\u8861\u60c5\u51b5\u7684\u4e0d\u540c\uff0c\u65cb\u8f6c\u64cd\u4f5c\u5206\u4e3a\u56db\u79cd\uff1a\u53f3\u65cb\u3001\u5de6\u65cb\u3001\u5148\u53f3\u65cb\u540e\u5de6\u65cb\u3001\u5148\u5de6\u65cb\u540e\u53f3\u65cb\u3002\u4e0b\u9762\u8be6\u7ec6\u4ecb\u7ecd\u8fd9\u4e9b\u65cb\u8f6c\u64cd\u4f5c\u3002

    "},{"location":"chapter_tree/avl_tree/#1_1","title":"1. \u00a0 \u53f3\u65cb","text":"

    \u5982\u56fe 7-26 \u6240\u793a\uff0c\u8282\u70b9\u4e0b\u65b9\u4e3a\u5e73\u8861\u56e0\u5b50\u3002\u4ece\u5e95\u81f3\u9876\u770b\uff0c\u4e8c\u53c9\u6811\u4e2d\u9996\u4e2a\u5931\u8861\u8282\u70b9\u662f\u201c\u8282\u70b9 3\u201d\u3002\u6211\u4eec\u5173\u6ce8\u4ee5\u8be5\u5931\u8861\u8282\u70b9\u4e3a\u6839\u8282\u70b9\u7684\u5b50\u6811\uff0c\u5c06\u8be5\u8282\u70b9\u8bb0\u4e3a node \uff0c\u5176\u5de6\u5b50\u8282\u70b9\u8bb0\u4e3a child \uff0c\u6267\u884c\u201c\u53f3\u65cb\u201d\u64cd\u4f5c\u3002\u5b8c\u6210\u53f3\u65cb\u540e\uff0c\u5b50\u6811\u6062\u590d\u5e73\u8861\uff0c\u5e76\u4e14\u4ecd\u7136\u4fdd\u6301\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6027\u8d28\u3002

    <1><2><3><4>

    \u56fe 7-26 \u00a0 \u53f3\u65cb\u64cd\u4f5c\u6b65\u9aa4

    \u5982\u56fe 7-27 \u6240\u793a\uff0c\u5f53\u8282\u70b9 child \u6709\u53f3\u5b50\u8282\u70b9\uff08\u8bb0\u4e3a grand_child \uff09\u65f6\uff0c\u9700\u8981\u5728\u53f3\u65cb\u4e2d\u6dfb\u52a0\u4e00\u6b65\uff1a\u5c06 grand_child \u4f5c\u4e3a node \u7684\u5de6\u5b50\u8282\u70b9\u3002

    \u56fe 7-27 \u00a0 \u6709 grand_child \u7684\u53f3\u65cb\u64cd\u4f5c

    \u201c\u5411\u53f3\u65cb\u8f6c\u201d\u662f\u4e00\u79cd\u5f62\u8c61\u5316\u7684\u8bf4\u6cd5\uff0c\u5b9e\u9645\u4e0a\u9700\u8981\u901a\u8fc7\u4fee\u6539\u8282\u70b9\u6307\u9488\u6765\u5b9e\u73b0\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def right_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u53f3\u65cb\u64cd\u4f5c\"\"\"\n    child = node.left\n    grand_child = child.right\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child = node->left;\n    TreeNode *grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode rightRotate(TreeNode node) {\n    TreeNode child = node.left;\n    TreeNode grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? RightRotate(TreeNode? node) {\n    TreeNode? child = node?.left;\n    TreeNode? grandChild = child?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) rightRotate(node *TreeNode) *TreeNode {\n    child := node.Left\n    grandChild := child.Right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.Right = node\n    node.Left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u53f3\u65cb\u64cd\u4f5c */\nfunc rightRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.left\n    let grandChild = child?.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child?.right = node\n    node?.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u53f3\u65cb\u64cd\u4f5c */\n#rightRotate(node) {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u53f3\u65cb\u64cd\u4f5c */\nrightRotate(node: TreeNode): TreeNode {\n    const child = node.left;\n    const grandChild = child.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node;\n    node.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode? rightRotate(TreeNode? node) {\n  TreeNode? child = node!.left;\n  TreeNode? grandChild = child!.right;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node;\n  node.left = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u53f3\u65cb\u64cd\u4f5c */\nfn right_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().left.clone().unwrap();\n            let grand_child = child.borrow().right.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n            child.borrow_mut().right = Some(node.clone());\n            node.borrow_mut().left = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u53f3\u65cb\u64cd\u4f5c */\nTreeNode *rightRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->left;\n    grandChild = child->right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child->right = node;\n    node->left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u53f3\u65cb\u64cd\u4f5c */\nfun rightRotate(node: TreeNode?): TreeNode {\n    val child = node!!.left\n    val grandChild = child!!.right\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.right = node\n    node.left = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u53f3\u65cb\u64cd\u4f5c ###\ndef right_rotate(node)\n  child = node.left\n  grand_child = child.right\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n  child.right = node\n  node.left = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u53f3\u65cb\u64cd\u4f5c\nfn rightRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.left;\n    var grandChild = child.?.right;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u53f3\u65cb\u8f6c\n    child.?.right = node;\n    node.?.left = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2_1","title":"2. \u00a0 \u5de6\u65cb","text":"

    \u76f8\u5e94\u5730\uff0c\u5982\u679c\u8003\u8651\u4e0a\u8ff0\u5931\u8861\u4e8c\u53c9\u6811\u7684\u201c\u955c\u50cf\u201d\uff0c\u5219\u9700\u8981\u6267\u884c\u56fe 7-28 \u6240\u793a\u7684\u201c\u5de6\u65cb\u201d\u64cd\u4f5c\u3002

    \u56fe 7-28 \u00a0 \u5de6\u65cb\u64cd\u4f5c

    \u540c\u7406\uff0c\u5982\u56fe 7-29 \u6240\u793a\uff0c\u5f53\u8282\u70b9 child \u6709\u5de6\u5b50\u8282\u70b9\uff08\u8bb0\u4e3a grand_child \uff09\u65f6\uff0c\u9700\u8981\u5728\u5de6\u65cb\u4e2d\u6dfb\u52a0\u4e00\u6b65\uff1a\u5c06 grand_child \u4f5c\u4e3a node \u7684\u53f3\u5b50\u8282\u70b9\u3002

    \u56fe 7-29 \u00a0 \u6709 grand_child \u7684\u5de6\u65cb\u64cd\u4f5c

    \u53ef\u4ee5\u89c2\u5bdf\u5230\uff0c\u53f3\u65cb\u548c\u5de6\u65cb\u64cd\u4f5c\u5728\u903b\u8f91\u4e0a\u662f\u955c\u50cf\u5bf9\u79f0\u7684\uff0c\u5b83\u4eec\u5206\u522b\u89e3\u51b3\u7684\u4e24\u79cd\u5931\u8861\u60c5\u51b5\u4e5f\u662f\u5bf9\u79f0\u7684\u3002\u57fa\u4e8e\u5bf9\u79f0\u6027\uff0c\u6211\u4eec\u53ea\u9700\u5c06\u53f3\u65cb\u7684\u5b9e\u73b0\u4ee3\u7801\u4e2d\u7684\u6240\u6709\u7684 left \u66ff\u6362\u4e3a right \uff0c\u5c06\u6240\u6709\u7684 right \u66ff\u6362\u4e3a left \uff0c\u5373\u53ef\u5f97\u5230\u5de6\u65cb\u7684\u5b9e\u73b0\u4ee3\u7801\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def left_rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u5de6\u65cb\u64cd\u4f5c\"\"\"\n    child = node.right\n    grand_child = child.left\n    # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grand_child\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    self.update_height(child)\n    # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n
    avl_tree.cpp
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child = node->right;\n    TreeNode *grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.java
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode leftRotate(TreeNode node) {\n    TreeNode child = node.right;\n    TreeNode grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.cs
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? LeftRotate(TreeNode? node) {\n    TreeNode? child = node?.right;\n    TreeNode? grandChild = child?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    UpdateHeight(node);\n    UpdateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.go
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc (t *aVLTree) leftRotate(node *TreeNode) *TreeNode {\n    child := node.Right\n    grandChild := child.Left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.Left = node\n    node.Right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    t.updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.swift
    /* \u5de6\u65cb\u64cd\u4f5c */\nfunc leftRotate(node: TreeNode?) -> TreeNode? {\n    let child = node?.right\n    let grandChild = child?.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child?.left = node\n    node?.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node: node)\n    updateHeight(node: child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.js
    /* \u5de6\u65cb\u64cd\u4f5c */\n#leftRotate(node) {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.#updateHeight(node);\n    this.#updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.ts
    /* \u5de6\u65cb\u64cd\u4f5c */\nleftRotate(node: TreeNode): TreeNode {\n    const child = node.right;\n    const grandChild = child.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node;\n    node.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    this.updateHeight(node);\n    this.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.dart
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode? leftRotate(TreeNode? node) {\n  TreeNode? child = node!.right;\n  TreeNode? grandChild = child!.left;\n  // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node;\n  node.right = grandChild;\n  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  updateHeight(node);\n  updateHeight(child);\n  // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return child;\n}\n
    avl_tree.rs
    /* \u5de6\u65cb\u64cd\u4f5c */\nfn left_rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    match node {\n        Some(node) => {\n            let child = node.borrow().right.clone().unwrap();\n            let grand_child = child.borrow().left.clone();\n            // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n            child.borrow_mut().left = Some(node.clone());\n            node.borrow_mut().right = grand_child;\n            // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n            Self::update_height(Some(node));\n            Self::update_height(Some(child.clone()));\n            // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(child)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5de6\u65cb\u64cd\u4f5c */\nTreeNode *leftRotate(TreeNode *node) {\n    TreeNode *child, *grandChild;\n    child = node->right;\n    grandChild = child->left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child->left = node;\n    node->right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    avl_tree.kt
    /* \u5de6\u65cb\u64cd\u4f5c */\nfun leftRotate(node: TreeNode?): TreeNode {\n    val child = node!!.right\n    val grandChild = child!!.left\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.left = node\n    node.right = grandChild\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node)\n    updateHeight(child)\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child\n}\n
    avl_tree.rb
    ### \u5de6\u65cb\u64cd\u4f5c ###\ndef left_rotate(node)\n  child = node.right\n  grand_child = child.left\n  # \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n  child.left = node\n  node.right = grand_child\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  update_height(child)\n  # \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n  child\nend\n
    avl_tree.zig
    // \u5de6\u65cb\u64cd\u4f5c\nfn leftRotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    var child = node.?.right;\n    var grandChild = child.?.left;\n    // \u4ee5 child \u4e3a\u539f\u70b9\uff0c\u5c06 node \u5411\u5de6\u65cb\u8f6c\n    child.?.left = node;\n    node.?.right = grandChild;\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.updateHeight(node);\n    self.updateHeight(child);\n    // \u8fd4\u56de\u65cb\u8f6c\u540e\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return child;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3","title":"3. \u00a0 \u5148\u5de6\u65cb\u540e\u53f3\u65cb","text":"

    \u5bf9\u4e8e\u56fe 7-30 \u4e2d\u7684\u5931\u8861\u8282\u70b9 3 \uff0c\u4ec5\u4f7f\u7528\u5de6\u65cb\u6216\u53f3\u65cb\u90fd\u65e0\u6cd5\u4f7f\u5b50\u6811\u6062\u590d\u5e73\u8861\u3002\u6b64\u65f6\u9700\u8981\u5148\u5bf9 child \u6267\u884c\u201c\u5de6\u65cb\u201d\uff0c\u518d\u5bf9 node \u6267\u884c\u201c\u53f3\u65cb\u201d\u3002

    \u56fe 7-30 \u00a0 \u5148\u5de6\u65cb\u540e\u53f3\u65cb

    "},{"location":"chapter_tree/avl_tree/#4","title":"4. \u00a0 \u5148\u53f3\u65cb\u540e\u5de6\u65cb","text":"

    \u5982\u56fe 7-31 \u6240\u793a\uff0c\u5bf9\u4e8e\u4e0a\u8ff0\u5931\u8861\u4e8c\u53c9\u6811\u7684\u955c\u50cf\u60c5\u51b5\uff0c\u9700\u8981\u5148\u5bf9 child \u6267\u884c\u201c\u53f3\u65cb\u201d\uff0c\u518d\u5bf9 node \u6267\u884c\u201c\u5de6\u65cb\u201d\u3002

    \u56fe 7-31 \u00a0 \u5148\u53f3\u65cb\u540e\u5de6\u65cb

    "},{"location":"chapter_tree/avl_tree/#5","title":"5. \u00a0 \u65cb\u8f6c\u7684\u9009\u62e9","text":"

    \u56fe 7-32 \u5c55\u793a\u7684\u56db\u79cd\u5931\u8861\u60c5\u51b5\u4e0e\u4e0a\u8ff0\u6848\u4f8b\u9010\u4e2a\u5bf9\u5e94\uff0c\u5206\u522b\u9700\u8981\u91c7\u7528\u53f3\u65cb\u3001\u5148\u5de6\u65cb\u540e\u53f3\u65cb\u3001\u5148\u53f3\u65cb\u540e\u5de6\u65cb\u3001\u5de6\u65cb\u7684\u64cd\u4f5c\u3002

    \u56fe 7-32 \u00a0 AVL \u6811\u7684\u56db\u79cd\u65cb\u8f6c\u60c5\u51b5

    \u5982\u4e0b\u8868\u6240\u793a\uff0c\u6211\u4eec\u901a\u8fc7\u5224\u65ad\u5931\u8861\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u4ee5\u53ca\u8f83\u9ad8\u4e00\u4fa7\u5b50\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50\u7684\u6b63\u8d1f\u53f7\uff0c\u6765\u786e\u5b9a\u5931\u8861\u8282\u70b9\u5c5e\u4e8e\u56fe 7-32 \u4e2d\u7684\u54ea\u79cd\u60c5\u51b5\u3002

    \u8868 7-3 \u00a0 \u56db\u79cd\u65cb\u8f6c\u60c5\u51b5\u7684\u9009\u62e9\u6761\u4ef6

    \u5931\u8861\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50 \u5b50\u8282\u70b9\u7684\u5e73\u8861\u56e0\u5b50 \u5e94\u91c7\u7528\u7684\u65cb\u8f6c\u65b9\u6cd5 \\(> 1\\) \uff08\u5de6\u504f\u6811\uff09 \\(\\geq 0\\) \u53f3\u65cb \\(> 1\\) \uff08\u5de6\u504f\u6811\uff09 \\(<0\\) \u5148\u5de6\u65cb\u540e\u53f3\u65cb \\(< -1\\) \uff08\u53f3\u504f\u6811\uff09 \\(\\leq 0\\) \u5de6\u65cb \\(< -1\\) \uff08\u53f3\u504f\u6811\uff09 \\(>0\\) \u5148\u53f3\u65cb\u540e\u5de6\u65cb

    \u4e3a\u4e86\u4fbf\u4e8e\u4f7f\u7528\uff0c\u6211\u4eec\u5c06\u65cb\u8f6c\u64cd\u4f5c\u5c01\u88c5\u6210\u4e00\u4e2a\u51fd\u6570\u3002\u6709\u4e86\u8fd9\u4e2a\u51fd\u6570\uff0c\u6211\u4eec\u5c31\u80fd\u5bf9\u5404\u79cd\u5931\u8861\u60c5\u51b5\u8fdb\u884c\u65cb\u8f6c\uff0c\u4f7f\u5931\u8861\u8282\u70b9\u91cd\u65b0\u6062\u590d\u5e73\u8861\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def rotate(self, node: TreeNode | None) -> TreeNode | None:\n    \"\"\"\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\"\"\"\n    # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    balance_factor = self.balance_factor(node)\n    # \u5de6\u504f\u6811\n    if balance_factor > 1:\n        if self.balance_factor(node.left) >= 0:\n            # \u53f3\u65cb\n            return self.right_rotate(node)\n        else:\n            # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = self.left_rotate(node.left)\n            return self.right_rotate(node)\n    # \u53f3\u504f\u6811\n    elif balance_factor < -1:\n        if self.balance_factor(node.right) <= 0:\n            # \u5de6\u65cb\n            return self.left_rotate(node)\n        else:\n            # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = self.right_rotate(node.right)\n            return self.left_rotate(node)\n    # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n
    avl_tree.cpp
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int _balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (_balanceFactor > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (_balanceFactor < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.java
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode rotate(TreeNode node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactor = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.cs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? Rotate(TreeNode? node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int balanceFactorInt = BalanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactorInt > 1) {\n        if (BalanceFactor(node?.left) >= 0) {\n            // \u53f3\u65cb\n            return RightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node!.left = LeftRotate(node!.left);\n            return RightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactorInt < -1) {\n        if (BalanceFactor(node?.right) <= 0) {\n            // \u5de6\u65cb\n            return LeftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node!.right = RightRotate(node!.right);\n            return LeftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.go
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc (t *aVLTree) rotate(node *TreeNode) *TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    // Go \u63a8\u8350\u77ed\u53d8\u91cf\uff0c\u8fd9\u91cc bf \u6307\u4ee3 t.balanceFactor\n    bf := t.balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if bf > 1 {\n        if t.balanceFactor(node.Left) >= 0 {\n            // \u53f3\u65cb\n            return t.rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.Left = t.leftRotate(node.Left)\n            return t.rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if bf < -1 {\n        if t.balanceFactor(node.Right) <= 0 {\n            // \u5de6\u65cb\n            return t.leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.Right = t.rightRotate(node.Right)\n            return t.leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.swift
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfunc rotate(node: TreeNode?) -> TreeNode? {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balanceFactor = balanceFactor(node: node)\n    // \u5de6\u504f\u6811\n    if balanceFactor > 1 {\n        if self.balanceFactor(node: node?.left) >= 0 {\n            // \u53f3\u65cb\n            return rightRotate(node: node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node?.left = leftRotate(node: node?.left)\n            return rightRotate(node: node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if balanceFactor < -1 {\n        if self.balanceFactor(node: node?.right) <= 0 {\n            // \u5de6\u65cb\n            return leftRotate(node: node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node?.right = rightRotate(node: node?.right)\n            return leftRotate(node: node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.js
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n#rotate(node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.#rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.#leftRotate(node.left);\n            return this.#rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.#leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.#rightRotate(node.right);\n            return this.#leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.ts
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nrotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    const balanceFactor = this.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (this.balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return this.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = this.leftRotate(node.left);\n            return this.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (this.balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return this.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = this.rightRotate(node.right);\n            return this.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.dart
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode? rotate(TreeNode? node) {\n  // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  int factor = balanceFactor(node);\n  // \u5de6\u504f\u6811\n  if (factor > 1) {\n    if (balanceFactor(node!.left) >= 0) {\n      // \u53f3\u65cb\n      return rightRotate(node);\n    } else {\n      // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = leftRotate(node.left);\n      return rightRotate(node);\n    }\n  }\n  // \u53f3\u504f\u6811\n  if (factor < -1) {\n    if (balanceFactor(node!.right) <= 0) {\n      // \u5de6\u65cb\n      return leftRotate(node);\n    } else {\n      // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = rightRotate(node.right);\n      return leftRotate(node);\n    }\n  }\n  // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  return node;\n}\n
    avl_tree.rs
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfn rotate(node: OptionTreeNodeRc) -> OptionTreeNodeRc {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    let balance_factor = Self::balance_factor(node.clone());\n    // \u5de6\u504f\u6811\n    if balance_factor > 1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().left.clone()) >= 0 {\n            // \u53f3\u65cb\n            Self::right_rotate(Some(node))\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            let left = node.borrow().left.clone();\n            node.borrow_mut().left = Self::left_rotate(left);\n            Self::right_rotate(Some(node))\n        }\n    }\n    // \u53f3\u504f\u6811\n    else if balance_factor < -1 {\n        let node = node.unwrap();\n        if Self::balance_factor(node.borrow().right.clone()) <= 0 {\n            // \u5de6\u65cb\n            Self::left_rotate(Some(node))\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            let right = node.borrow().right.clone();\n            node.borrow_mut().right = Self::right_rotate(right);\n            Self::left_rotate(Some(node))\n        }\n    } else {\n        // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n        node\n    }\n}\n
    avl_tree.c
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nTreeNode *rotate(TreeNode *node) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    int bf = balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (bf > 1) {\n        if (balanceFactor(node->left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node->left = leftRotate(node->left);\n            return rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (bf < -1) {\n        if (balanceFactor(node->right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node->right = rightRotate(node->right);\n            return leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    avl_tree.kt
    /* \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\nfun rotate(node: TreeNode): TreeNode {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    val balanceFactor = balanceFactor(node)\n    // \u5de6\u504f\u6811\n    if (balanceFactor > 1) {\n        if (balanceFactor(node.left) >= 0) {\n            // \u53f3\u65cb\n            return rightRotate(node)\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.left = leftRotate(node.left)\n            return rightRotate(node)\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balanceFactor < -1) {\n        if (balanceFactor(node.right) <= 0) {\n            // \u5de6\u65cb\n            return leftRotate(node)\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.right = rightRotate(node.right)\n            return leftRotate(node)\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n}\n
    avl_tree.rb
    ### \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 ###\ndef rotate(node)\n  # \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n  balance_factor = balance_factor(node)\n  # \u5de6\u904d\u6811\n  if balance_factor > 1\n    if balance_factor(node.left) >= 0\n      # \u53f3\u65cb\n      return right_rotate(node)\n    else\n      # \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n      node.left = left_rotate(node.left)\n      return right_rotate(node)\n    end\n  # \u53f3\u904d\u6811\n  elsif balance_factor < -1\n    if balance_factor(node.right) <= 0\n      # \u5de6\u65cb\n      return left_rotate(node)\n    else\n      # \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n      node.right = right_rotate(node.right)\n      return left_rotate(node)\n    end\n  end\n  # \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n  node\nend\n
    avl_tree.zig
    // \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\nfn rotate(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) {\n    // \u83b7\u53d6\u8282\u70b9 node \u7684\u5e73\u8861\u56e0\u5b50\n    var balance_factor = self.balanceFactor(node);\n    // \u5de6\u504f\u6811\n    if (balance_factor > 1) {\n        if (self.balanceFactor(node.?.left) >= 0) {\n            // \u53f3\u65cb\n            return self.rightRotate(node);\n        } else {\n            // \u5148\u5de6\u65cb\u540e\u53f3\u65cb\n            node.?.left = self.leftRotate(node.?.left);\n            return self.rightRotate(node);\n        }\n    }\n    // \u53f3\u504f\u6811\n    if (balance_factor < -1) {\n        if (self.balanceFactor(node.?.right) <= 0) {\n            // \u5de6\u65cb\n            return self.leftRotate(node);\n        } else {\n            // \u5148\u53f3\u65cb\u540e\u5de6\u65cb\n            node.?.right = self.rightRotate(node.?.right);\n            return self.leftRotate(node);\n        }\n    }\n    // \u5e73\u8861\u6811\uff0c\u65e0\u987b\u65cb\u8f6c\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#753-avl","title":"7.5.3 \u00a0 AVL \u6811\u5e38\u7528\u64cd\u4f5c","text":""},{"location":"chapter_tree/avl_tree/#1_2","title":"1. \u00a0 \u63d2\u5165\u8282\u70b9","text":"

    AVL \u6811\u7684\u8282\u70b9\u63d2\u5165\u64cd\u4f5c\u4e0e\u4e8c\u53c9\u641c\u7d22\u6811\u5728\u4e3b\u4f53\u4e0a\u7c7b\u4f3c\u3002\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff0c\u5728 AVL \u6811\u4e2d\u63d2\u5165\u8282\u70b9\u540e\uff0c\u4ece\u8be5\u8282\u70b9\u5230\u6839\u8282\u70b9\u7684\u8def\u5f84\u4e0a\u53ef\u80fd\u4f1a\u51fa\u73b0\u4e00\u7cfb\u5217\u5931\u8861\u8282\u70b9\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u9700\u8981\u4ece\u8fd9\u4e2a\u8282\u70b9\u5f00\u59cb\uff0c\u81ea\u5e95\u5411\u4e0a\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u6240\u6709\u5931\u8861\u8282\u70b9\u6062\u590d\u5e73\u8861\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def insert(self, val):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    self._root = self.insert_helper(self._root, val)\n\ndef insert_helper(self, node: TreeNode | None, val: int) -> TreeNode:\n    \"\"\"\u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return TreeNode(val)\n    # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if val < node.val:\n        node.left = self.insert_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.insert_helper(node.right, val)\n    else:\n        # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val)\n        node->left = insertHelper(node->left, val);\n    else if (val > node->val)\n        node->right = insertHelper(node->right, val);\n    else\n        return node;    // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n    root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode insertHelper(TreeNode node, int val) {\n    if (node == null)\n        return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = insertHelper(node.right, val);\n    else\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int val) {\n    root = InsertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? InsertHelper(TreeNode? node, int val) {\n    if (node == null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val)\n        node.left = InsertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = InsertHelper(node.right, val);\n    else\n        return node;     // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (t *aVLTree) insert(val int) {\n    t.root = t.insertHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return NewTreeNode(val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node.Val.(int) {\n        node.Left = t.insertHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.insertHelper(node.Right, val)\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(val: Int) {\n    root = insertHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc insertHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return TreeNode(x: val)\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if val < node!.val {\n        node?.left = insertHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = insertHelper(node: node?.right, val: val)\n    } else {\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val) {\n    this.root = this.#insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#insertHelper(node, val) {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) node.left = this.#insertHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#insertHelper(node.right, val);\n    else return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(val: number): void {\n    this.root = this.insertHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\ninsertHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return new TreeNode(val);\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node.val) {\n        node.left = this.insertHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.insertHelper(node.right, val);\n    } else {\n        return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int val) {\n  root = insertHelper(root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? insertHelper(TreeNode? node, int val) {\n  if (node == null) return TreeNode(val);\n  /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n  if (val < node.val)\n    node.left = insertHelper(node.left, val);\n  else if (val > node.val)\n    node.right = insertHelper(node.right, val);\n  else\n    return node; // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\nfn insert(&mut self, val: i32) {\n    self.root = Self::insert_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn insert_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n            match {\n                let node_val = node.borrow().val;\n                node_val\n            }\n            .cmp(&val)\n            {\n                Ordering::Greater => {\n                    let left = node.borrow().left.clone();\n                    node.borrow_mut().left = Self::insert_helper(left, val);\n                }\n                Ordering::Less => {\n                    let right = node.borrow().right.clone();\n                    node.borrow_mut().right = Self::insert_helper(right, val);\n                }\n                Ordering::Equal => {\n                    return Some(node); // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n                }\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => Some(TreeNode::new(val)),\n    }\n}\n
    avl_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(AVLTree *tree, int val) {\n    tree->root = insertHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *insertHelper(TreeNode *node, int val) {\n    if (node == NULL) {\n        return newTreeNode(val);\n    }\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (val < node->val) {\n        node->left = insertHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = insertHelper(node->right, val);\n    } else {\n        // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n        return node;\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(_val: Int) {\n    root = insertHelper(root, _val)\n}\n\n/* \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun insertHelper(n: TreeNode?, _val: Int): TreeNode {\n    if (n == null)\n        return TreeNode(_val)\n    var node = n\n    /* 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9 */\n    if (_val < node._val)\n        node.left = insertHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = insertHelper(node.right, _val)\n    else\n        return node // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(val)\n  @root = insert_helper(@root, val)\nend\n\n### \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef insert_helper(node, val)\n  return TreeNode.new(val) if node.nil?\n  # 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n  if val < node.val\n    node.left = insert_helper(node.left, val)\n  elsif val > node.val\n    node.right = insert_helper(node.right, val)\n  else\n    # \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    return node\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, val: T) !void {\n    self.root = (try self.insertHelper(self.root, val)).?;\n}\n\n// \u9012\u5f52\u63d2\u5165\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn insertHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) !?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) {\n        var tmp_node = try self.mem_allocator.create(inc.TreeNode(T));\n        tmp_node.init(val);\n        return tmp_node;\n    }\n    // 1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\u5e76\u63d2\u5165\u8282\u70b9\n    if (val < node.?.val) {\n        node.?.left = try self.insertHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = try self.insertHelper(node.?.right, val);\n    } else {\n        return node;            // \u91cd\u590d\u8282\u70b9\u4e0d\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\n    }\n    self.updateHeight(node);    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#2_2","title":"2. \u00a0 \u5220\u9664\u8282\u70b9","text":"

    \u7c7b\u4f3c\u5730\uff0c\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u5220\u9664\u8282\u70b9\u65b9\u6cd5\u7684\u57fa\u7840\u4e0a\uff0c\u9700\u8981\u4ece\u5e95\u81f3\u9876\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u6240\u6709\u5931\u8861\u8282\u70b9\u6062\u590d\u5e73\u8861\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig avl_tree.py
    def remove(self, val: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    self._root = self.remove_helper(self._root, val)\n\ndef remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None:\n    \"\"\"\u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\"\"\"\n    if node is None:\n        return None\n    # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if val < node.val:\n        node.left = self.remove_helper(node.left, val)\n    elif val > node.val:\n        node.right = self.remove_helper(node.right, val)\n    else:\n        if node.left is None or node.right is None:\n            child = node.left or node.right\n            # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child is None:\n                return None\n            # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else:\n                node = child\n        else:\n            # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp = node.right\n            while temp.left is not None:\n                temp = temp.left\n            node.right = self.remove_helper(node.right, temp.val)\n            node.val = temp.val\n    # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    self.update_height(node)\n    # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    return self.rotate(node)\n
    avl_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    if (node == nullptr)\n        return nullptr;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val)\n        node->left = removeHelper(node->left, val);\n    else if (val > node->val)\n        node->right = removeHelper(node->right, val);\n    else {\n        if (node->left == nullptr || node->right == nullptr) {\n            TreeNode *child = node->left != nullptr ? node->left : node->right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == nullptr) {\n                delete node;\n                return nullptr;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                delete node;\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != nullptr) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n    root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode removeHelper(TreeNode node, int val) {\n    if (node == null)\n        return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = removeHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode child = node.left != null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int val) {\n    root = RemoveHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? RemoveHelper(TreeNode? node, int val) {\n    if (node == null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val)\n        node.left = RemoveHelper(node.left, val);\n    else if (val > node.val)\n        node.right = RemoveHelper(node.right, val);\n    else {\n        if (node.left == null || node.right == null) {\n            TreeNode? child = node.left ?? node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode? temp = node.right;\n            while (temp.left != null) {\n                temp = temp.left;\n            }\n            node.right = RemoveHelper(node.right, temp.val!.Value);\n            node.val = temp.val;\n        }\n    }\n    UpdateHeight(node);  // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = Rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (t *aVLTree) remove(val int) {\n    t.root = t.removeHelper(t.root, val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nfunc (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node.Val.(int) {\n        node.Left = t.removeHelper(node.Left, val)\n    } else if val > node.Val.(int) {\n        node.Right = t.removeHelper(node.Right, val)\n    } else {\n        if node.Left == nil || node.Right == nil {\n            child := node.Left\n            if node.Right != nil {\n                child = node.Right\n            }\n            if child == nil {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                return nil\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            temp := node.Right\n            for temp.Left != nil {\n                temp = temp.Left\n            }\n            node.Right = t.removeHelper(node.Right, temp.Val.(int))\n            node.Val = temp.Val\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    t.updateHeight(node)\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = t.rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(val: Int) {\n    root = removeHelper(node: root, val: val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfunc removeHelper(node: TreeNode?, val: Int) -> TreeNode? {\n    var node = node\n    if node == nil {\n        return nil\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if val < node!.val {\n        node?.left = removeHelper(node: node?.left, val: val)\n    } else if val > node!.val {\n        node?.right = removeHelper(node: node?.right, val: val)\n    } else {\n        if node?.left == nil || node?.right == nil {\n            let child = node?.left ?? node?.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if child == nil {\n                return nil\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else {\n                node = child\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node?.right\n            while temp?.left != nil {\n                temp = temp?.left\n            }\n            node?.right = removeHelper(node: node?.right, val: temp!.val)\n            node?.val = temp!.val\n        }\n    }\n    updateHeight(node: node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node: node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(val) {\n    this.root = this.#removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\n#removeHelper(node, val) {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) node.left = this.#removeHelper(node.left, val);\n    else if (val > node.val)\n        node.right = this.#removeHelper(node.right, val);\n    else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else node = child;\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.#removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.#updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.#rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(val: number): void {\n    this.root = this.removeHelper(this.root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nremoveHelper(node: TreeNode, val: number): TreeNode {\n    if (node === null) return null;\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node.val) {\n        node.left = this.removeHelper(node.left, val);\n    } else if (val > node.val) {\n        node.right = this.removeHelper(node.right, val);\n    } else {\n        if (node.left === null || node.right === null) {\n            const child = node.left !== null ? node.left : node.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child === null) {\n                return null;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            let temp = node.right;\n            while (temp.left !== null) {\n                temp = temp.left;\n            }\n            node.right = this.removeHelper(node.right, temp.val);\n            node.val = temp.val;\n        }\n    }\n    this.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = this.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int val) {\n  root = removeHelper(root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nTreeNode? removeHelper(TreeNode? node, int val) {\n  if (node == null) return null;\n  /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n  if (val < node.val)\n    node.left = removeHelper(node.left, val);\n  else if (val > node.val)\n    node.right = removeHelper(node.right, val);\n  else {\n    if (node.left == null || node.right == null) {\n      TreeNode? child = node.left ?? node.right;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      if (child == null)\n        return null;\n      // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      else\n        node = child;\n    } else {\n      // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      TreeNode? temp = node.right;\n      while (temp!.left != null) {\n        temp = temp.left;\n      }\n      node.right = removeHelper(node.right, temp.val);\n      node.val = temp.val;\n    }\n  }\n  updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n  node = rotate(node);\n  // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n  return node;\n}\n
    avl_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\nfn remove(&self, val: i32) {\n    Self::remove_helper(self.root.clone(), val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfn remove_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {\n    match node {\n        Some(mut node) => {\n            /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n            if val < node.borrow().val {\n                let left = node.borrow().left.clone();\n                node.borrow_mut().left = Self::remove_helper(left, val);\n            } else if val > node.borrow().val {\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, val);\n            } else if node.borrow().left.is_none() || node.borrow().right.is_none() {\n                let child = if node.borrow().left.is_some() {\n                    node.borrow().left.clone()\n                } else {\n                    node.borrow().right.clone()\n                };\n                match child {\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n                    None => {\n                        return None;\n                    }\n                    // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                    Some(child) => node = child,\n                }\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n                let mut temp = node.borrow().right.clone().unwrap();\n                loop {\n                    let temp_left = temp.borrow().left.clone();\n                    if temp_left.is_none() {\n                        break;\n                    }\n                    temp = temp_left.unwrap();\n                }\n                let right = node.borrow().right.clone();\n                node.borrow_mut().right = Self::remove_helper(right, temp.borrow().val);\n                node.borrow_mut().val = temp.borrow().val;\n            }\n            Self::update_height(Some(node.clone())); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n\n            /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n            node = Self::rotate(Some(node)).unwrap();\n            // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n            Some(node)\n        }\n        None => None,\n    }\n}\n
    avl_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(AVLTree *tree, int val) {\n    TreeNode *root = removeHelper(tree->root, val);\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u51fd\u6570\uff09 */\nTreeNode *removeHelper(TreeNode *node, int val) {\n    TreeNode *child, *grandChild;\n    if (node == NULL) {\n        return NULL;\n    }\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (val < node->val) {\n        node->left = removeHelper(node->left, val);\n    } else if (val > node->val) {\n        node->right = removeHelper(node->right, val);\n    } else {\n        if (node->left == NULL || node->right == NULL) {\n            child = node->left;\n            if (node->right != NULL) {\n                child = node->right;\n            }\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == NULL) {\n                return NULL;\n            } else {\n                // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            TreeNode *temp = node->right;\n            while (temp->left != NULL) {\n                temp = temp->left;\n            }\n            int tempVal = temp->val;\n            node->right = removeHelper(node->right, temp->val);\n            node->val = tempVal;\n        }\n    }\n    // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    updateHeight(node);\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    avl_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(_val: Int) {\n    root = removeHelper(root, _val)\n}\n\n/* \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09 */\nfun removeHelper(n: TreeNode?, _val: Int): TreeNode? {\n    var node = n ?: return null\n    /* 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664 */\n    if (_val < node._val)\n        node.left = removeHelper(node.left, _val)\n    else if (_val > node._val)\n        node.right = removeHelper(node.right, _val)\n    else {\n        if (node.left == null || node.right == null) {\n            val child = if (node.left != null)\n                node.left\n            else\n                node.right\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null)\n                return null\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            else\n                node = child\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.right\n            while (temp!!.left != null) {\n                temp = temp.left\n            }\n            node.right = removeHelper(node.right, temp._val)\n            node._val = temp._val\n        }\n    }\n    updateHeight(node) // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    /* 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861 */\n    node = rotate(node)\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node\n}\n
    avl_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(val)\n  @root = remove_helper(@root, val)\nend\n\n### \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09###\ndef remove_helper(node, val)\n  return if node.nil?\n  # 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n  if val < node.val\n    node.left = remove_helper(node.left, val)\n  elsif val > node.val\n    node.right = remove_helper(node.right, val)\n  else\n    if node.left.nil? || node.right.nil?\n      child = node.left || node.right\n      # \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n      return if child.nil?\n      # \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n      node = child\n    else\n      # \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n      temp = node.right\n      while !temp.left.nil?\n        temp = temp.left\n      end\n      node.right = remove_helper(node.right, temp.val)\n      node.val = temp.val\n    end\n  end\n  # \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n  update_height(node)\n  # 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n  rotate(node)\nend\n
    avl_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, val: T) void {\n   self.root = self.removeHelper(self.root, val).?;\n}\n\n// \u9012\u5f52\u5220\u9664\u8282\u70b9\uff08\u8f85\u52a9\u65b9\u6cd5\uff09\nfn removeHelper(self: *Self, node_: ?*inc.TreeNode(T), val: T) ?*inc.TreeNode(T) {\n    var node = node_;\n    if (node == null) return null;\n    // 1. \u67e5\u627e\u8282\u70b9\u5e76\u5220\u9664\n    if (val < node.?.val) {\n        node.?.left = self.removeHelper(node.?.left, val);\n    } else if (val > node.?.val) {\n        node.?.right = self.removeHelper(node.?.right, val);\n    } else {\n        if (node.?.left == null or node.?.right == null) {\n            var child = if (node.?.left != null) node.?.left else node.?.right;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 0 \uff0c\u76f4\u63a5\u5220\u9664 node \u5e76\u8fd4\u56de\n            if (child == null) {\n                return null;\n            // \u5b50\u8282\u70b9\u6570\u91cf = 1 \uff0c\u76f4\u63a5\u5220\u9664 node\n            } else {\n                node = child;\n            }\n        } else {\n            // \u5b50\u8282\u70b9\u6570\u91cf = 2 \uff0c\u5219\u5c06\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e2a\u8282\u70b9\u5220\u9664\uff0c\u5e76\u7528\u8be5\u8282\u70b9\u66ff\u6362\u5f53\u524d\u8282\u70b9\n            var temp = node.?.right;\n            while (temp.?.left != null) {\n                temp = temp.?.left;\n            }\n            node.?.right = self.removeHelper(node.?.right, temp.?.val);\n            node.?.val = temp.?.val;\n        }\n    }\n    self.updateHeight(node); // \u66f4\u65b0\u8282\u70b9\u9ad8\u5ea6\n    // 2. \u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u8be5\u5b50\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\n    node = self.rotate(node);\n    // \u8fd4\u56de\u5b50\u6811\u7684\u6839\u8282\u70b9\n    return node;\n}\n
    "},{"location":"chapter_tree/avl_tree/#3_1","title":"3. \u00a0 \u67e5\u627e\u8282\u70b9","text":"

    AVL \u6811\u7684\u8282\u70b9\u67e5\u627e\u64cd\u4f5c\u4e0e\u4e8c\u53c9\u641c\u7d22\u6811\u4e00\u81f4\uff0c\u5728\u6b64\u4e0d\u518d\u8d58\u8ff0\u3002

    "},{"location":"chapter_tree/avl_tree/#754-avl","title":"7.5.4 \u00a0 AVL \u6811\u5178\u578b\u5e94\u7528","text":"
    • \u7ec4\u7ec7\u548c\u5b58\u50a8\u5927\u578b\u6570\u636e\uff0c\u9002\u7528\u4e8e\u9ad8\u9891\u67e5\u627e\u3001\u4f4e\u9891\u589e\u5220\u7684\u573a\u666f\u3002
    • \u7528\u4e8e\u6784\u5efa\u6570\u636e\u5e93\u4e2d\u7684\u7d22\u5f15\u7cfb\u7edf\u3002
    • \u7ea2\u9ed1\u6811\u4e5f\u662f\u4e00\u79cd\u5e38\u89c1\u7684\u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811\u3002\u76f8\u8f83\u4e8e AVL \u6811\uff0c\u7ea2\u9ed1\u6811\u7684\u5e73\u8861\u6761\u4ef6\u66f4\u5bbd\u677e\uff0c\u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\u6240\u9700\u7684\u65cb\u8f6c\u64cd\u4f5c\u66f4\u5c11\uff0c\u8282\u70b9\u589e\u5220\u64cd\u4f5c\u7684\u5e73\u5747\u6548\u7387\u66f4\u9ad8\u3002
    "},{"location":"chapter_tree/binary_search_tree/","title":"7.4 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811","text":"

    \u5982\u56fe 7-16 \u6240\u793a\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\uff08binary search tree\uff09\u6ee1\u8db3\u4ee5\u4e0b\u6761\u4ef6\u3002

    1. \u5bf9\u4e8e\u6839\u8282\u70b9\uff0c\u5de6\u5b50\u6811\u4e2d\u6240\u6709\u8282\u70b9\u7684\u503c \\(<\\) \u6839\u8282\u70b9\u7684\u503c \\(<\\) \u53f3\u5b50\u6811\u4e2d\u6240\u6709\u8282\u70b9\u7684\u503c\u3002
    2. \u4efb\u610f\u8282\u70b9\u7684\u5de6\u3001\u53f3\u5b50\u6811\u4e5f\u662f\u4e8c\u53c9\u641c\u7d22\u6811\uff0c\u5373\u540c\u6837\u6ee1\u8db3\u6761\u4ef6 1. \u3002

    \u56fe 7-16 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811

    "},{"location":"chapter_tree/binary_search_tree/#741","title":"7.4.1 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u64cd\u4f5c","text":"

    \u6211\u4eec\u5c06\u4e8c\u53c9\u641c\u7d22\u6811\u5c01\u88c5\u4e3a\u4e00\u4e2a\u7c7b BinarySearchTree \uff0c\u5e76\u58f0\u660e\u4e00\u4e2a\u6210\u5458\u53d8\u91cf root \uff0c\u6307\u5411\u6811\u7684\u6839\u8282\u70b9\u3002

    "},{"location":"chapter_tree/binary_search_tree/#1","title":"1. \u00a0 \u67e5\u627e\u8282\u70b9","text":"

    \u7ed9\u5b9a\u76ee\u6807\u8282\u70b9\u503c num \uff0c\u53ef\u4ee5\u6839\u636e\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6027\u8d28\u6765\u67e5\u627e\u3002\u5982\u56fe 7-17 \u6240\u793a\uff0c\u6211\u4eec\u58f0\u660e\u4e00\u4e2a\u8282\u70b9 cur \uff0c\u4ece\u4e8c\u53c9\u6811\u7684\u6839\u8282\u70b9 root \u51fa\u53d1\uff0c\u5faa\u73af\u6bd4\u8f83\u8282\u70b9\u503c cur.val \u548c num \u4e4b\u95f4\u7684\u5927\u5c0f\u5173\u7cfb\u3002

    • \u82e5 cur.val < num \uff0c\u8bf4\u660e\u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\uff0c\u56e0\u6b64\u6267\u884c cur = cur.right \u3002
    • \u82e5 cur.val > num \uff0c\u8bf4\u660e\u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\uff0c\u56e0\u6b64\u6267\u884c cur = cur.left \u3002
    • \u82e5 cur.val = num \uff0c\u8bf4\u660e\u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\u5e76\u8fd4\u56de\u8be5\u8282\u70b9\u3002
    <1><2><3><4>

    \u56fe 7-17 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u67e5\u627e\u8282\u70b9\u793a\u4f8b

    \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u67e5\u627e\u64cd\u4f5c\u4e0e\u4e8c\u5206\u67e5\u627e\u7b97\u6cd5\u7684\u5de5\u4f5c\u539f\u7406\u4e00\u81f4\uff0c\u90fd\u662f\u6bcf\u8f6e\u6392\u9664\u4e00\u534a\u60c5\u51b5\u3002\u5faa\u73af\u6b21\u6570\u6700\u591a\u4e3a\u4e8c\u53c9\u6811\u7684\u9ad8\u5ea6\uff0c\u5f53\u4e8c\u53c9\u6811\u5e73\u8861\u65f6\uff0c\u4f7f\u7528 \\(O(\\log n)\\) \u65f6\u95f4\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def search(self, num: int) -> TreeNode | None:\n    \"\"\"\u67e5\u627e\u8282\u70b9\"\"\"\n    cur = self._root\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur is not None:\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        elif cur.val > num:\n            cur = cur.left\n        # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else:\n            break\n    return cur\n
    binary_search_tree.cpp
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(int num) {\n    TreeNode *cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur->val > num)\n            cur = cur->left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.java
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode search(int num) {\n    TreeNode cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.cs
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? Search(int num) {\n    TreeNode? cur = root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur =\n            cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num)\n            cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.go
    /* \u67e5\u627e\u8282\u70b9 */\nfunc (bst *binarySearchTree) search(num int) *TreeNode {\n    node := bst.root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for node != nil {\n        if node.Val.(int) < num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            node = node.Right\n        } else if node.Val.(int) > num {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            node = node.Left\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return node\n}\n
    binary_search_tree.swift
    /* \u67e5\u627e\u8282\u70b9 */\nfunc search(num: Int) -> TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if cur!.val > num {\n            cur = cur?.left\n        }\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else {\n            break\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.js
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num) {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.ts
    /* \u67e5\u627e\u8282\u70b9 */\nsearch(num: number): TreeNode | null {\n    let cur = this.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur.val > num) cur = cur.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else break;\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.dart
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode? search(int _num) {\n  TreeNode? cur = _root;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else if (cur.val > _num)\n      cur = cur.left;\n    // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break;\n  }\n  // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n  return cur;\n}\n
    binary_search_tree.rs
    /* \u67e5\u627e\u8282\u70b9 */\npub fn search(&self, num: i32) -> OptionTreeNodeRc {\n    let mut cur = self.root.clone();\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => cur = node.borrow().right.clone(),\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => cur = node.borrow().left.clone(),\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n        }\n    }\n\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    cur\n}\n
    binary_search_tree.c
    /* \u67e5\u627e\u8282\u70b9 */\nTreeNode *search(BinarySearchTree *bst, int num) {\n    TreeNode *cur = bst->root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        if (cur->val < num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else if (cur->val > num) {\n            // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        } else {\n            // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    binary_search_tree.kt
    /* \u67e5\u627e\u8282\u70b9 */\nfun search(num: Int): TreeNode? {\n    var cur = root\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else if (cur._val > num)\n            cur.left\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        else\n            break\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur\n}\n
    binary_search_tree.rb
    ### \u67e5\u627e\u8282\u70b9 ###\ndef search(num)\n  cur = @root\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while !cur.nil?\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    elsif cur.val > num\n      cur = cur.left\n    # \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    else\n      break\n    end\n  end\n\n  cur\nend\n
    binary_search_tree.zig
    // \u67e5\u627e\u8282\u70b9\nfn search(self: *Self, num: T) ?*inc.TreeNode(T) {\n    var cur = self.root;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u76ee\u6807\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else if (cur.?.val > num) {\n            cur = cur.?.left;\n        // \u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        } else {\n            break;\n        }\n    }\n    // \u8fd4\u56de\u76ee\u6807\u8282\u70b9\n    return cur;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_search_tree/#2","title":"2. \u00a0 \u63d2\u5165\u8282\u70b9","text":"

    \u7ed9\u5b9a\u4e00\u4e2a\u5f85\u63d2\u5165\u5143\u7d20 num \uff0c\u4e3a\u4e86\u4fdd\u6301\u4e8c\u53c9\u641c\u7d22\u6811\u201c\u5de6\u5b50\u6811 < \u6839\u8282\u70b9 < \u53f3\u5b50\u6811\u201d\u7684\u6027\u8d28\uff0c\u63d2\u5165\u64cd\u4f5c\u6d41\u7a0b\u5982\u56fe 7-18 \u6240\u793a\u3002

    1. \u67e5\u627e\u63d2\u5165\u4f4d\u7f6e\uff1a\u4e0e\u67e5\u627e\u64cd\u4f5c\u76f8\u4f3c\uff0c\u4ece\u6839\u8282\u70b9\u51fa\u53d1\uff0c\u6839\u636e\u5f53\u524d\u8282\u70b9\u503c\u548c num \u7684\u5927\u5c0f\u5173\u7cfb\u5faa\u73af\u5411\u4e0b\u641c\u7d22\uff0c\u76f4\u5230\u8d8a\u8fc7\u53f6\u8282\u70b9\uff08\u904d\u5386\u81f3 None \uff09\u65f6\u8df3\u51fa\u5faa\u73af\u3002
    2. \u5728\u8be5\u4f4d\u7f6e\u63d2\u5165\u8282\u70b9\uff1a\u521d\u59cb\u5316\u8282\u70b9 num \uff0c\u5c06\u8be5\u8282\u70b9\u7f6e\u4e8e None \u7684\u4f4d\u7f6e\u3002

    \u56fe 7-18 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u63d2\u5165\u8282\u70b9

    \u5728\u4ee3\u7801\u5b9e\u73b0\u4e2d\uff0c\u9700\u8981\u6ce8\u610f\u4ee5\u4e0b\u4e24\u70b9\u3002

    • \u4e8c\u53c9\u641c\u7d22\u6811\u4e0d\u5141\u8bb8\u5b58\u5728\u91cd\u590d\u8282\u70b9\uff0c\u5426\u5219\u5c06\u8fdd\u53cd\u5176\u5b9a\u4e49\u3002\u56e0\u6b64\uff0c\u82e5\u5f85\u63d2\u5165\u8282\u70b9\u5728\u6811\u4e2d\u5df2\u5b58\u5728\uff0c\u5219\u4e0d\u6267\u884c\u63d2\u5165\uff0c\u76f4\u63a5\u8fd4\u56de\u3002
    • \u4e3a\u4e86\u5b9e\u73b0\u63d2\u5165\u8282\u70b9\uff0c\u6211\u4eec\u9700\u8981\u501f\u52a9\u8282\u70b9 pre \u4fdd\u5b58\u4e0a\u4e00\u8f6e\u5faa\u73af\u7684\u8282\u70b9\u3002\u8fd9\u6837\u5728\u904d\u5386\u81f3 None \u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u83b7\u53d6\u5230\u5176\u7236\u8282\u70b9\uff0c\u4ece\u800c\u5b8c\u6210\u8282\u70b9\u63d2\u5165\u64cd\u4f5c\u3002
    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def insert(self, num: int):\n    \"\"\"\u63d2\u5165\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self._root is None:\n        self._root = TreeNode(num)\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur.val == num:\n            return\n        pre = cur\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u63d2\u5165\u8282\u70b9\n    node = TreeNode(num)\n    if pre.val < num:\n        pre.right = node\n    else:\n        pre.left = node\n
    binary_search_tree.cpp
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == nullptr) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = new TreeNode(num);\n    if (pre->val < num)\n        pre->right = node;\n    else\n        pre->left = node;\n}\n
    binary_search_tree.java
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new TreeNode(num);\n    if (pre.val < num)\n        pre.right = node;\n    else\n        pre.left = node;\n}\n
    binary_search_tree.cs
    /* \u63d2\u5165\u8282\u70b9 */\nvoid Insert(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = new TreeNode(num);\n        return;\n    }\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val == num)\n            return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode node = new(num);\n    if (pre != null) {\n        if (pre.val < num)\n            pre.right = node;\n        else\n            pre.left = node;\n    }\n}\n
    binary_search_tree.go
    /* \u63d2\u5165\u8282\u70b9 */\nfunc (bst *binarySearchTree) insert(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if cur == nil {\n        bst.root = NewTreeNode(num)\n        return\n    }\n    // \u5f85\u63d2\u5165\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            return\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            cur = cur.Right\n        } else {\n            cur = cur.Left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    node := NewTreeNode(num)\n    if pre.Val.(int) < num {\n        pre.Right = node\n    } else {\n        pre.Left = node\n    }\n}\n
    binary_search_tree.swift
    /* \u63d2\u5165\u8282\u70b9 */\nfunc insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if root == nil {\n        root = TreeNode(x: num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if cur!.val == num {\n            return\n        }\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let node = TreeNode(x: num)\n    if pre!.val < num {\n        pre?.right = node\n    } else {\n        pre?.left = node\n    }\n}\n
    binary_search_tree.js
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre.val < num) pre.right = node;\n    else pre.left = node;\n}\n
    binary_search_tree.ts
    /* \u63d2\u5165\u8282\u70b9 */\ninsert(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (this.root === null) {\n        this.root = new TreeNode(num);\n        return;\n    }\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.val === num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u63d2\u5165\u8282\u70b9\n    const node = new TreeNode(num);\n    if (pre!.val < num) pre!.right = node;\n    else pre!.left = node;\n}\n
    binary_search_tree.dart
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if (_root == null) {\n    _root = TreeNode(_num);\n    return;\n  }\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    if (cur.val == _num) return;\n    pre = cur;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u63d2\u5165\u8282\u70b9\n  TreeNode? node = TreeNode(_num);\n  if (pre!.val < _num)\n    pre.right = node;\n  else\n    pre.left = node;\n}\n
    binary_search_tree.rs
    /* \u63d2\u5165\u8282\u70b9 */\npub fn insert(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if self.root.is_none() {\n        self.root = Some(TreeNode::new(num));\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n            Ordering::Equal => return,\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    let pre = pre.unwrap();\n    let node = Some(TreeNode::new(num));\n    if num > pre.borrow().val {\n        pre.borrow_mut().right = node;\n    } else {\n        pre.borrow_mut().left = node;\n    }\n}\n
    binary_search_tree.c
    /* \u63d2\u5165\u8282\u70b9 */\nvoid insert(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (bst->root == NULL) {\n        bst->root = newTreeNode(num);\n        return;\n    }\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur->val == num) {\n            return;\n        }\n        pre = cur;\n        if (cur->val < num) {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    TreeNode *node = newTreeNode(num);\n    if (pre->val < num) {\n        pre->right = node;\n    } else {\n        pre->left = node;\n    }\n}\n
    binary_search_tree.kt
    /* \u63d2\u5165\u8282\u70b9 */\nfun insert(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (root == null) {\n        root = TreeNode(num)\n        return\n    }\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur._val == num)\n            return\n        pre = cur\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u63d2\u5165\u8282\u70b9\n    val node = TreeNode(num)\n    if (pre?._val!! < num)\n        pre.right = node\n    else\n        pre.left = node\n}\n
    binary_search_tree.rb
    ### \u63d2\u5165\u8282\u70b9 ###\ndef insert(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n  if @root.nil?\n    @root = TreeNode.new(num)\n    return\n  end\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n    return if cur.val == num\n\n    pre = cur\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n\n  # \u63d2\u5165\u8282\u70b9\n  node = TreeNode.new(num)\n  if pre.val < num\n    pre.right = node\n  else\n    pre.left = node\n  end\nend\n
    binary_search_tree.zig
    // \u63d2\u5165\u8282\u70b9\nfn insert(self: *Self, num: T) !void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u5219\u521d\u59cb\u5316\u6839\u8282\u70b9\n    if (self.root == null) {\n        self.root = try self.mem_allocator.create(inc.TreeNode(T));\n        return;\n    }\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u91cd\u590d\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (cur.?.val == num) return;\n        pre = cur;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u63d2\u5165\u4f4d\u7f6e\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u63d2\u5165\u8282\u70b9\n    var node = try self.mem_allocator.create(inc.TreeNode(T));\n    node.init(num);\n    if (pre.?.val < num) {\n        pre.?.right = node;\n    } else {\n        pre.?.left = node;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    \u4e0e\u67e5\u627e\u8282\u70b9\u76f8\u540c\uff0c\u63d2\u5165\u8282\u70b9\u4f7f\u7528 \\(O(\\log n)\\) \u65f6\u95f4\u3002

    "},{"location":"chapter_tree/binary_search_tree/#3","title":"3. \u00a0 \u5220\u9664\u8282\u70b9","text":"

    \u5148\u5728\u4e8c\u53c9\u6811\u4e2d\u67e5\u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u518d\u5c06\u5176\u5220\u9664\u3002\u4e0e\u63d2\u5165\u8282\u70b9\u7c7b\u4f3c\uff0c\u6211\u4eec\u9700\u8981\u4fdd\u8bc1\u5728\u5220\u9664\u64cd\u4f5c\u5b8c\u6210\u540e\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u201c\u5de6\u5b50\u6811 < \u6839\u8282\u70b9 < \u53f3\u5b50\u6811\u201d\u7684\u6027\u8d28\u4ecd\u7136\u6ee1\u8db3\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u6839\u636e\u76ee\u6807\u8282\u70b9\u7684\u5b50\u8282\u70b9\u6570\u91cf\uff0c\u5206 0\u30011 \u548c 2 \u4e09\u79cd\u60c5\u51b5\uff0c\u6267\u884c\u5bf9\u5e94\u7684\u5220\u9664\u8282\u70b9\u64cd\u4f5c\u3002

    \u5982\u56fe 7-19 \u6240\u793a\uff0c\u5f53\u5f85\u5220\u9664\u8282\u70b9\u7684\u5ea6\u4e3a \\(0\\) \u65f6\uff0c\u8868\u793a\u8be5\u8282\u70b9\u662f\u53f6\u8282\u70b9\uff0c\u53ef\u4ee5\u76f4\u63a5\u5220\u9664\u3002

    \u56fe 7-19 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u5220\u9664\u8282\u70b9\uff08\u5ea6\u4e3a 0 \uff09

    \u5982\u56fe 7-20 \u6240\u793a\uff0c\u5f53\u5f85\u5220\u9664\u8282\u70b9\u7684\u5ea6\u4e3a \\(1\\) \u65f6\uff0c\u5c06\u5f85\u5220\u9664\u8282\u70b9\u66ff\u6362\u4e3a\u5176\u5b50\u8282\u70b9\u5373\u53ef\u3002

    \u56fe 7-20 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u5220\u9664\u8282\u70b9\uff08\u5ea6\u4e3a 1 \uff09

    \u5f53\u5f85\u5220\u9664\u8282\u70b9\u7684\u5ea6\u4e3a \\(2\\) \u65f6\uff0c\u6211\u4eec\u65e0\u6cd5\u76f4\u63a5\u5220\u9664\u5b83\uff0c\u800c\u9700\u8981\u4f7f\u7528\u4e00\u4e2a\u8282\u70b9\u66ff\u6362\u8be5\u8282\u70b9\u3002\u7531\u4e8e\u8981\u4fdd\u6301\u4e8c\u53c9\u641c\u7d22\u6811\u201c\u5de6\u5b50\u6811 \\(<\\) \u6839\u8282\u70b9 \\(<\\) \u53f3\u5b50\u6811\u201d\u7684\u6027\u8d28\uff0c\u56e0\u6b64\u8fd9\u4e2a\u8282\u70b9\u53ef\u4ee5\u662f\u53f3\u5b50\u6811\u7684\u6700\u5c0f\u8282\u70b9\u6216\u5de6\u5b50\u6811\u7684\u6700\u5927\u8282\u70b9\u3002

    \u5047\u8bbe\u6211\u4eec\u9009\u62e9\u53f3\u5b50\u6811\u7684\u6700\u5c0f\u8282\u70b9\uff08\u4e2d\u5e8f\u904d\u5386\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff09\uff0c\u5219\u5220\u9664\u64cd\u4f5c\u6d41\u7a0b\u5982\u56fe 7-21 \u6240\u793a\u3002

    1. \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\u5728\u201c\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217\u201d\u4e2d\u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\uff0c\u8bb0\u4e3a tmp \u3002
    2. \u7528 tmp \u7684\u503c\u8986\u76d6\u5f85\u5220\u9664\u8282\u70b9\u7684\u503c\uff0c\u5e76\u5728\u6811\u4e2d\u9012\u5f52\u5220\u9664\u8282\u70b9 tmp \u3002
    <1><2><3><4>

    \u56fe 7-21 \u00a0 \u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u5220\u9664\u8282\u70b9\uff08\u5ea6\u4e3a 2 \uff09

    \u5220\u9664\u8282\u70b9\u64cd\u4f5c\u540c\u6837\u4f7f\u7528 \\(O(\\log n)\\) \u65f6\u95f4\uff0c\u5176\u4e2d\u67e5\u627e\u5f85\u5220\u9664\u8282\u70b9\u9700\u8981 \\(O(\\log n)\\) \u65f6\u95f4\uff0c\u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u540e\u7ee7\u8282\u70b9\u9700\u8981 \\(O(\\log n)\\) \u65f6\u95f4\u3002\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_search_tree.py
    def remove(self, num: int):\n    \"\"\"\u5220\u9664\u8282\u70b9\"\"\"\n    # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self._root is None:\n        return\n    # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    cur, pre = self._root, None\n    while cur is not None:\n        # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur.val == num:\n            break\n        pre = cur\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur.val < num:\n            cur = cur.right\n        # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else:\n            cur = cur.left\n    # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur is None:\n        return\n\n    # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur.left is None or cur.right is None:\n        # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        child = cur.left or cur.right\n        # \u5220\u9664\u8282\u70b9 cur\n        if cur != self._root:\n            if pre.left == cur:\n                pre.left = child\n            else:\n                pre.right = child\n        else:\n            # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            self._root = child\n    # \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else:\n        # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp: TreeNode = cur.right\n        while tmp.left is not None:\n            tmp = tmp.left\n        # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.val)\n        # \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val\n
    binary_search_tree.cpp
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == nullptr)\n        return;\n    TreeNode *cur = root, *pre = nullptr;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != nullptr) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur->val < num)\n            cur = cur->right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur->left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == nullptr)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur->left == nullptr || cur->right == nullptr) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != nullptr ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre->left == cur)\n                pre->left = child;\n            else\n                pre->right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        delete cur;\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != nullptr) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.java
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode child = cur.left != null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.cs
    /* \u5220\u9664\u8282\u70b9 */\nvoid Remove(int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return;\n    TreeNode? cur = root, pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val == num)\n            break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num)\n            cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        TreeNode? child = cur.left ?? cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!.left == cur)\n                pre.left = child;\n            else\n                pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode? tmp = cur.right;\n        while (tmp.left != null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        Remove(tmp.val!.Value);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.go
    /* \u5220\u9664\u8282\u70b9 */\nfunc (bst *binarySearchTree) remove(num int) {\n    cur := bst.root\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5f85\u5220\u9664\u8282\u70b9\u4e4b\u524d\u7684\u8282\u70b9\u4f4d\u7f6e\n    var pre *TreeNode = nil\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    for cur != nil {\n        if cur.Val == num {\n            break\n        }\n        pre = cur\n        if cur.Val.(int) < num {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u53f3\u5b50\u6811\u4e2d\n            cur = cur.Right\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728\u5de6\u5b50\u6811\u4e2d\n            cur = cur.Left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u4e3a 0 \u6216 1\n    if cur.Left == nil || cur.Right == nil {\n        var child *TreeNode = nil\n        // \u53d6\u51fa\u5f85\u5220\u9664\u8282\u70b9\u7684\u5b50\u8282\u70b9\n        if cur.Left != nil {\n            child = cur.Left\n        } else {\n            child = cur.Right\n        }\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur != bst.root {\n            if pre.Left == cur {\n                pre.Left = child\n            } else {\n                pre.Right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            bst.root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u4e3a 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d\u5f85\u5220\u9664\u8282\u70b9 cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        tmp := cur.Right\n        for tmp.Left != nil {\n            tmp = tmp.Left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        bst.remove(tmp.Val.(int))\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.Val = tmp.Val\n    }\n}\n
    binary_search_tree.swift
    /* \u5220\u9664\u8282\u70b9 */\nfunc remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if root == nil {\n        return\n    }\n    var cur = root\n    var pre: TreeNode?\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while cur != nil {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if cur!.val == num {\n            break\n        }\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if cur!.val < num {\n            cur = cur?.right\n        }\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else {\n            cur = cur?.left\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur == nil {\n        return\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if cur?.left == nil || cur?.right == nil {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        let child = cur?.left ?? cur?.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if cur !== root {\n            if pre?.left === cur {\n                pre?.left = child\n            } else {\n                pre?.right = child\n            }\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur?.right\n        while tmp?.left != nil {\n            tmp = tmp?.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(num: tmp!.val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur?.val = tmp!.val\n    }\n}\n
    binary_search_tree.js
    /* \u5220\u9664\u8282\u70b9 */\nremove(num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur = this.root,\n        pre = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child = cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre.left === cur) pre.left = child;\n            else pre.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp = cur.right;\n        while (tmp.left !== null) {\n            tmp = tmp.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp.val;\n    }\n}\n
    binary_search_tree.ts
    /* \u5220\u9664\u8282\u70b9 */\nremove(num: number): void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (this.root === null) return;\n    let cur: TreeNode | null = this.root,\n        pre: TreeNode | null = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur !== null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.val === num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.val < num) cur = cur.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else cur = cur.left;\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur === null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left === null || cur.right === null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        const child: TreeNode | null =\n            cur.left !== null ? cur.left : cur.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur !== this.root) {\n            if (pre!.left === cur) pre!.left = child;\n            else pre!.right = child;\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            this.root = child;\n        }\n    }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        let tmp: TreeNode | null = cur.right;\n        while (tmp!.left !== null) {\n            tmp = tmp!.left;\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        this.remove(tmp!.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.val = tmp!.val;\n    }\n}\n
    binary_search_tree.dart
    /* \u5220\u9664\u8282\u70b9 */\nvoid remove(int _num) {\n  // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  if (_root == null) return;\n  TreeNode? cur = _root;\n  TreeNode? pre = null;\n  // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  while (cur != null) {\n    // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    if (cur.val == _num) break;\n    pre = cur;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if (cur.val < _num)\n      cur = cur.right;\n    // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left;\n  }\n  // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u76f4\u63a5\u8fd4\u56de\n  if (cur == null) return;\n  // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if (cur.left == null || cur.right == null) {\n    // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    TreeNode? child = cur.left ?? cur.right;\n    // \u5220\u9664\u8282\u70b9 cur\n    if (cur != _root) {\n      if (pre!.left == cur)\n        pre.left = child;\n      else\n        pre.right = child;\n    } else {\n      // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      _root = child;\n    }\n  } else {\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    TreeNode? tmp = cur.right;\n    while (tmp!.left != null) {\n      tmp = tmp.left;\n    }\n    // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val);\n    // \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val;\n  }\n}\n
    binary_search_tree.rs
    /* \u5220\u9664\u8282\u70b9 */\npub fn remove(&mut self, num: i32) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if self.root.is_none() {\n        return;\n    }\n    let mut cur = self.root.clone();\n    let mut pre = None;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while let Some(node) = cur.clone() {\n        match num.cmp(&node.borrow().val) {\n            // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n            Ordering::Equal => break,\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n            Ordering::Greater => {\n                pre = cur.clone();\n                cur = node.borrow().right.clone();\n            }\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n            Ordering::Less => {\n                pre = cur.clone();\n                cur = node.borrow().left.clone();\n            }\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if cur.is_none() {\n        return;\n    }\n    let cur = cur.unwrap();\n    let (left_child, right_child) = (cur.borrow().left.clone(), cur.borrow().right.clone());\n    match (left_child.clone(), right_child.clone()) {\n        // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n        (None, None) | (Some(_), None) | (None, Some(_)) => {\n            // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n            let child = left_child.or(right_child);\n            let pre = pre.unwrap();\n            // \u5220\u9664\u8282\u70b9 cur\n            if !Rc::ptr_eq(&cur, self.root.as_ref().unwrap()) {\n                let left = pre.borrow().left.clone();\n                if left.is_some() && Rc::ptr_eq(&left.as_ref().unwrap(), &cur) {\n                    pre.borrow_mut().left = child;\n                } else {\n                    pre.borrow_mut().right = child;\n                }\n            } else {\n                // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n                self.root = child;\n            }\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n        (Some(_), Some(_)) => {\n            // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n            let mut tmp = cur.borrow().right.clone();\n            while let Some(node) = tmp.clone() {\n                if node.borrow().left.is_some() {\n                    tmp = node.borrow().left.clone();\n                } else {\n                    break;\n                }\n            }\n            let tmpval = tmp.unwrap().borrow().val;\n            // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n            self.remove(tmpval);\n            // \u7528 tmp \u8986\u76d6 cur\n            cur.borrow_mut().val = tmpval;\n        }\n    }\n}\n
    binary_search_tree.c
    /* \u5220\u9664\u8282\u70b9 */\n// \u7531\u4e8e\u5f15\u5165\u4e86 stdio.h \uff0c\u6b64\u5904\u65e0\u6cd5\u4f7f\u7528 remove \u5173\u952e\u8bcd\nvoid removeItem(BinarySearchTree *bst, int num) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (bst->root == NULL)\n        return;\n    TreeNode *cur = bst->root, *pre = NULL;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != NULL) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur->val == num)\n            break;\n        pre = cur;\n        if (cur->val < num) {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u53f3\u5b50\u6811\u4e2d\n            cur = cur->right;\n        } else {\n            // \u5f85\u5220\u9664\u8282\u70b9\u5728 root \u7684\u5de6\u5b50\u6811\u4e2d\n            cur = cur->left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == NULL)\n        return;\n    // \u5224\u65ad\u5f85\u5220\u9664\u8282\u70b9\u662f\u5426\u5b58\u5728\u5b50\u8282\u70b9\n    if (cur->left == NULL || cur->right == NULL) {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1 */\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = nullptr / \u8be5\u5b50\u8282\u70b9\n        TreeNode *child = cur->left != NULL ? cur->left : cur->right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre->left == cur) {\n            pre->left = child;\n        } else {\n            pre->right = child;\n        }\n        // \u91ca\u653e\u5185\u5b58\n        free(cur);\n    } else {\n        /* \u5b50\u8282\u70b9\u6570\u91cf = 2 */\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        TreeNode *tmp = cur->right;\n        while (tmp->left != NULL) {\n            tmp = tmp->left;\n        }\n        int tmpVal = tmp->val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        removeItem(bst, tmp->val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur->val = tmpVal;\n    }\n}\n
    binary_search_tree.kt
    /* \u5220\u9664\u8282\u70b9 */\nfun remove(num: Int) {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (root == null)\n        return\n    var cur = root\n    var pre: TreeNode? = null\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur._val == num)\n            break\n        pre = cur\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        cur = if (cur._val < num)\n            cur.right\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        else\n            cur.left\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null)\n        return\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.left == null || cur.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        val child = if (cur.left != null)\n            cur.left\n        else\n            cur.right\n        // \u5220\u9664\u8282\u70b9 cur\n        if (cur != root) {\n            if (pre!!.left == cur)\n                pre.left = child\n            else\n                pre.right = child\n        } else {\n            // \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n            root = child\n        }\n        // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.right\n        while (tmp!!.left != null) {\n            tmp = tmp.left\n        }\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        remove(tmp._val)\n        // \u7528 tmp \u8986\u76d6 cur\n        cur._val = tmp._val\n    }\n}\n
    binary_search_tree.rb
    ### \u5220\u9664\u8282\u70b9 ###\ndef remove(num)\n  # \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n  return if @root.nil?\n\n  # \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n  cur, pre = @root, nil\n  while !cur.nil?\n    # \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n    break if cur.val == num\n\n    pre = cur\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n    if cur.val < num\n      cur = cur.right\n    # \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n    else\n      cur = cur.left\n    end\n  end\n  # \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n  return if cur.nil?\n\n  # \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n  if cur.left.nil? || cur.right.nil?\n    # \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n    child = cur.left || cur.right\n    # \u5220\u9664\u8282\u70b9 cur\n    if cur != @root\n      if pre.left == cur\n        pre.left = child\n      else\n        pre.right = child\n      end\n    else\n      # \u82e5\u5220\u9664\u8282\u70b9\u4e3a\u6839\u8282\u70b9\uff0c\u5219\u91cd\u65b0\u6307\u5b9a\u6839\u8282\u70b9\n      @root = child\n    end\n  # \u5b50\u8282\u70b9\u6570\u91cf = 2\n  else\n    # \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n    tmp = cur.right\n    while !tmp.left.nil?\n      tmp = tmp.left\n    end\n    # \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n    remove(tmp.val)\n    # \u7528 tmp \u8986\u76d6 cur\n    cur.val = tmp.val\n  end\nend\n
    binary_search_tree.zig
    // \u5220\u9664\u8282\u70b9\nfn remove(self: *Self, num: T) void {\n    // \u82e5\u6811\u4e3a\u7a7a\uff0c\u76f4\u63a5\u63d0\u524d\u8fd4\u56de\n    if (self.root == null) return;\n    var cur = self.root;\n    var pre: ?*inc.TreeNode(T) = null;\n    // \u5faa\u73af\u67e5\u627e\uff0c\u8d8a\u8fc7\u53f6\u8282\u70b9\u540e\u8df3\u51fa\n    while (cur != null) {\n        // \u627e\u5230\u5f85\u5220\u9664\u8282\u70b9\uff0c\u8df3\u51fa\u5faa\u73af\n        if (cur.?.val == num) break;\n        pre = cur;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u53f3\u5b50\u6811\u4e2d\n        if (cur.?.val < num) {\n            cur = cur.?.right;\n        // \u5f85\u5220\u9664\u8282\u70b9\u5728 cur \u7684\u5de6\u5b50\u6811\u4e2d\n        } else {\n            cur = cur.?.left;\n        }\n    }\n    // \u82e5\u65e0\u5f85\u5220\u9664\u8282\u70b9\uff0c\u5219\u76f4\u63a5\u8fd4\u56de\n    if (cur == null) return;\n    // \u5b50\u8282\u70b9\u6570\u91cf = 0 or 1\n    if (cur.?.left == null or cur.?.right == null) {\n        // \u5f53\u5b50\u8282\u70b9\u6570\u91cf = 0 / 1 \u65f6\uff0c child = null / \u8be5\u5b50\u8282\u70b9\n        var child = if (cur.?.left != null) cur.?.left else cur.?.right;\n        // \u5220\u9664\u8282\u70b9 cur\n        if (pre.?.left == cur) {\n            pre.?.left = child;\n        } else {\n            pre.?.right = child;\n        }\n    // \u5b50\u8282\u70b9\u6570\u91cf = 2\n    } else {\n        // \u83b7\u53d6\u4e2d\u5e8f\u904d\u5386\u4e2d cur \u7684\u4e0b\u4e00\u4e2a\u8282\u70b9\n        var tmp = cur.?.right;\n        while (tmp.?.left != null) {\n            tmp = tmp.?.left;\n        }\n        var tmp_val = tmp.?.val;\n        // \u9012\u5f52\u5220\u9664\u8282\u70b9 tmp\n        self.remove(tmp.?.val);\n        // \u7528 tmp \u8986\u76d6 cur\n        cur.?.val = tmp_val;\n    }\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_search_tree/#4","title":"4. \u00a0 \u4e2d\u5e8f\u904d\u5386\u6709\u5e8f","text":"

    \u5982\u56fe 7-22 \u6240\u793a\uff0c\u4e8c\u53c9\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u9075\u5faa\u201c\u5de6 \\(\\rightarrow\\) \u6839 \\(\\rightarrow\\) \u53f3\u201d\u7684\u904d\u5386\u987a\u5e8f\uff0c\u800c\u4e8c\u53c9\u641c\u7d22\u6811\u6ee1\u8db3\u201c\u5de6\u5b50\u8282\u70b9 \\(<\\) \u6839\u8282\u70b9 \\(<\\) \u53f3\u5b50\u8282\u70b9\u201d\u7684\u5927\u5c0f\u5173\u7cfb\u3002

    \u8fd9\u610f\u5473\u7740\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u8fdb\u884c\u4e2d\u5e8f\u904d\u5386\u65f6\uff0c\u603b\u662f\u4f1a\u4f18\u5148\u904d\u5386\u4e0b\u4e00\u4e2a\u6700\u5c0f\u8282\u70b9\uff0c\u4ece\u800c\u5f97\u51fa\u4e00\u4e2a\u91cd\u8981\u6027\u8d28\uff1a\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217\u662f\u5347\u5e8f\u7684\u3002

    \u5229\u7528\u4e2d\u5e8f\u904d\u5386\u5347\u5e8f\u7684\u6027\u8d28\uff0c\u6211\u4eec\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u83b7\u53d6\u6709\u5e8f\u6570\u636e\u4ec5\u9700 \\(O(n)\\) \u65f6\u95f4\uff0c\u65e0\u987b\u8fdb\u884c\u989d\u5916\u7684\u6392\u5e8f\u64cd\u4f5c\uff0c\u975e\u5e38\u9ad8\u6548\u3002

    \u56fe 7-22 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u4e2d\u5e8f\u904d\u5386\u5e8f\u5217

    "},{"location":"chapter_tree/binary_search_tree/#742","title":"7.4.2 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6548\u7387","text":"

    \u7ed9\u5b9a\u4e00\u7ec4\u6570\u636e\uff0c\u6211\u4eec\u8003\u8651\u4f7f\u7528\u6570\u7ec4\u6216\u4e8c\u53c9\u641c\u7d22\u6811\u5b58\u50a8\u3002\u89c2\u5bdf\u8868 7-2 \uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u5404\u9879\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u90fd\u662f\u5bf9\u6570\u9636\uff0c\u5177\u6709\u7a33\u5b9a\u4e14\u9ad8\u6548\u7684\u6027\u80fd\u3002\u53ea\u6709\u5728\u9ad8\u9891\u6dfb\u52a0\u3001\u4f4e\u9891\u67e5\u627e\u5220\u9664\u6570\u636e\u7684\u573a\u666f\u4e0b\uff0c\u6570\u7ec4\u6bd4\u4e8c\u53c9\u641c\u7d22\u6811\u7684\u6548\u7387\u66f4\u9ad8\u3002

    \u8868 7-2 \u00a0 \u6570\u7ec4\u4e0e\u641c\u7d22\u6811\u7684\u6548\u7387\u5bf9\u6bd4

    \u65e0\u5e8f\u6570\u7ec4 \u4e8c\u53c9\u641c\u7d22\u6811 \u67e5\u627e\u5143\u7d20 \\(O(n)\\) \\(O(\\log n)\\) \u63d2\u5165\u5143\u7d20 \\(O(1)\\) \\(O(\\log n)\\) \u5220\u9664\u5143\u7d20 \\(O(n)\\) \\(O(\\log n)\\)

    \u5728\u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u4e8c\u53c9\u641c\u7d22\u6811\u662f\u201c\u5e73\u8861\u201d\u7684\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728 \\(\\log n\\) \u8f6e\u5faa\u73af\u5185\u67e5\u627e\u4efb\u610f\u8282\u70b9\u3002

    \u7136\u800c\uff0c\u5982\u679c\u6211\u4eec\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\u4e0d\u65ad\u5730\u63d2\u5165\u548c\u5220\u9664\u8282\u70b9\uff0c\u53ef\u80fd\u5bfc\u81f4\u4e8c\u53c9\u6811\u9000\u5316\u4e3a\u56fe 7-23 \u6240\u793a\u7684\u94fe\u8868\uff0c\u8fd9\u65f6\u5404\u79cd\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u4f1a\u9000\u5316\u4e3a \\(O(n)\\) \u3002

    \u56fe 7-23 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u9000\u5316

    "},{"location":"chapter_tree/binary_search_tree/#743","title":"7.4.3 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u5e38\u89c1\u5e94\u7528","text":"
    • \u7528\u4f5c\u7cfb\u7edf\u4e2d\u7684\u591a\u7ea7\u7d22\u5f15\uff0c\u5b9e\u73b0\u9ad8\u6548\u7684\u67e5\u627e\u3001\u63d2\u5165\u3001\u5220\u9664\u64cd\u4f5c\u3002
    • \u4f5c\u4e3a\u67d0\u4e9b\u641c\u7d22\u7b97\u6cd5\u7684\u5e95\u5c42\u6570\u636e\u7ed3\u6784\u3002
    • \u7528\u4e8e\u5b58\u50a8\u6570\u636e\u6d41\uff0c\u4ee5\u4fdd\u6301\u5176\u6709\u5e8f\u72b6\u6001\u3002
    "},{"location":"chapter_tree/binary_tree/","title":"7.1 \u00a0 \u4e8c\u53c9\u6811","text":"

    \u4e8c\u53c9\u6811\uff08binary tree\uff09\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u4ee3\u8868\u201c\u7956\u5148\u201d\u4e0e\u201c\u540e\u4ee3\u201d\u4e4b\u95f4\u7684\u6d3e\u751f\u5173\u7cfb\uff0c\u4f53\u73b0\u4e86\u201c\u4e00\u5206\u4e3a\u4e8c\u201d\u7684\u5206\u6cbb\u903b\u8f91\u3002\u4e0e\u94fe\u8868\u7c7b\u4f3c\uff0c\u4e8c\u53c9\u6811\u7684\u57fa\u672c\u5355\u5143\u662f\u8282\u70b9\uff0c\u6bcf\u4e2a\u8282\u70b9\u5305\u542b\u503c\u3001\u5de6\u5b50\u8282\u70b9\u5f15\u7528\u548c\u53f3\u5b50\u8282\u70b9\u5f15\u7528\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig
    class TreeNode:\n    \"\"\"\u4e8c\u53c9\u6811\u8282\u70b9\u7c7b\"\"\"\n    def __init__(self, val: int):\n        self.val: int = val                # \u8282\u70b9\u503c\n        self.left: TreeNode | None = None  # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n        self.right: TreeNode | None = None # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct TreeNode {\n    int val;          // \u8282\u70b9\u503c\n    TreeNode *left;   // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    TreeNode *right;  // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n};\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    int val;         // \u8282\u70b9\u503c\n    TreeNode left;   // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    TreeNode right;  // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n    TreeNode(int x) { val = x; }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode(int? x) {\n    public int? val = x;    // \u8282\u70b9\u503c\n    public TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    public TreeNode? right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\ntype TreeNode struct {\n    Val   int\n    Left  *TreeNode\n    Right *TreeNode\n}\n/* \u6784\u9020\u65b9\u6cd5 */\nfunc NewTreeNode(v int) *TreeNode {\n    return &TreeNode{\n        Left:  nil, // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n        Right: nil, // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n        Val:   v,   // \u8282\u70b9\u503c\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    var val: Int // \u8282\u70b9\u503c\n    var left: TreeNode? // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    var right: TreeNode? // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n\n    init(x: Int) {\n        val = x\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val; // \u8282\u70b9\u503c\n    left; // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    right; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n    constructor(val, left, right) {\n        this.val = val === undefined ? 0 : val;\n        this.left = left === undefined ? null : left;\n        this.right = right === undefined ? null : right;\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n    val: number;\n    left: TreeNode | null;\n    right: TreeNode | null;\n\n    constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n        this.val = val === undefined ? 0 : val; // \u8282\u70b9\u503c\n        this.left = left === undefined ? null : left; // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n        this.right = right === undefined ? null : right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode {\n  int val;         // \u8282\u70b9\u503c\n  TreeNode? left;  // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n  TreeNode? right; // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n  TreeNode(this.val, [this.left, this.right]);\n}\n
    use std::rc::Rc;\nuse std::cell::RefCell;\n\n/* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\nstruct TreeNode {\n    val: i32,                               // \u8282\u70b9\u503c\n    left: Option<Rc<RefCell<TreeNode>>>,    // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    right: Option<Rc<RefCell<TreeNode>>>,   // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n\nimpl TreeNode {\n    /* \u6784\u9020\u65b9\u6cd5 */\n    fn new(val: i32) -> Rc<RefCell<Self>> {\n        Rc::new(RefCell::new(Self {\n            val,\n            left: None,\n            right: None\n        }))\n    }\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7ed3\u6784\u4f53 */\ntypedef struct TreeNode {\n    int val;                // \u8282\u70b9\u503c\n    int height;             // \u8282\u70b9\u9ad8\u5ea6\n    struct TreeNode *left;  // \u5de6\u5b50\u8282\u70b9\u6307\u9488\n    struct TreeNode *right; // \u53f3\u5b50\u8282\u70b9\u6307\u9488\n} TreeNode;\n\n/* \u6784\u9020\u51fd\u6570 */\nTreeNode *newTreeNode(int val) {\n    TreeNode *node;\n\n    node = (TreeNode *)malloc(sizeof(TreeNode));\n    node->val = val;\n    node->height = 0;\n    node->left = NULL;\n    node->right = NULL;\n    return node;\n}\n
    /* \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b */\nclass TreeNode(val _val: Int) {  // \u8282\u70b9\u503c\n    val left: TreeNode? = null   // \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n    val right: TreeNode? = null  // \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n}\n
    ### \u4e8c\u53c9\u6811\u8282\u70b9\u7c7b ###\nclass TreeNode\n  attr_accessor :val    # \u8282\u70b9\u503c\n  attr_accessor :left   # \u5de6\u5b50\u8282\u70b9\u5f15\u7528\n  attr_accessor :right  # \u53f3\u5b50\u8282\u70b9\u5f15\u7528\n\n  def initialize(val)\n    @val = val\n  end\nend\n
    \n

    \u6bcf\u4e2a\u8282\u70b9\u90fd\u6709\u4e24\u4e2a\u5f15\u7528\uff08\u6307\u9488\uff09\uff0c\u5206\u522b\u6307\u5411\u5de6\u5b50\u8282\u70b9\uff08left-child node\uff09\u548c\u53f3\u5b50\u8282\u70b9\uff08right-child node\uff09\uff0c\u8be5\u8282\u70b9\u88ab\u79f0\u4e3a\u8fd9\u4e24\u4e2a\u5b50\u8282\u70b9\u7684\u7236\u8282\u70b9\uff08parent node\uff09\u3002\u5f53\u7ed9\u5b9a\u4e00\u4e2a\u4e8c\u53c9\u6811\u7684\u8282\u70b9\u65f6\uff0c\u6211\u4eec\u5c06\u8be5\u8282\u70b9\u7684\u5de6\u5b50\u8282\u70b9\u53ca\u5176\u4ee5\u4e0b\u8282\u70b9\u5f62\u6210\u7684\u6811\u79f0\u4e3a\u8be5\u8282\u70b9\u7684\u5de6\u5b50\u6811\uff08left subtree\uff09\uff0c\u540c\u7406\u53ef\u5f97\u53f3\u5b50\u6811\uff08right subtree\uff09\u3002

    \u5728\u4e8c\u53c9\u6811\u4e2d\uff0c\u9664\u53f6\u8282\u70b9\u5916\uff0c\u5176\u4ed6\u6240\u6709\u8282\u70b9\u90fd\u5305\u542b\u5b50\u8282\u70b9\u548c\u975e\u7a7a\u5b50\u6811\u3002\u5982\u56fe 7-1 \u6240\u793a\uff0c\u5982\u679c\u5c06\u201c\u8282\u70b9 2\u201d\u89c6\u4e3a\u7236\u8282\u70b9\uff0c\u5219\u5176\u5de6\u5b50\u8282\u70b9\u548c\u53f3\u5b50\u8282\u70b9\u5206\u522b\u662f\u201c\u8282\u70b9 4\u201d\u548c\u201c\u8282\u70b9 5\u201d\uff0c\u5de6\u5b50\u6811\u662f\u201c\u8282\u70b9 4 \u53ca\u5176\u4ee5\u4e0b\u8282\u70b9\u5f62\u6210\u7684\u6811\u201d\uff0c\u53f3\u5b50\u6811\u662f\u201c\u8282\u70b9 5 \u53ca\u5176\u4ee5\u4e0b\u8282\u70b9\u5f62\u6210\u7684\u6811\u201d\u3002

    \u56fe 7-1 \u00a0 \u7236\u8282\u70b9\u3001\u5b50\u8282\u70b9\u3001\u5b50\u6811

    "},{"location":"chapter_tree/binary_tree/#711","title":"7.1.1 \u00a0 \u4e8c\u53c9\u6811\u5e38\u89c1\u672f\u8bed","text":"

    \u4e8c\u53c9\u6811\u7684\u5e38\u7528\u672f\u8bed\u5982\u56fe 7-2 \u6240\u793a\u3002

    • \u6839\u8282\u70b9\uff08root node\uff09\uff1a\u4f4d\u4e8e\u4e8c\u53c9\u6811\u9876\u5c42\u7684\u8282\u70b9\uff0c\u6ca1\u6709\u7236\u8282\u70b9\u3002
    • \u53f6\u8282\u70b9\uff08leaf node\uff09\uff1a\u6ca1\u6709\u5b50\u8282\u70b9\u7684\u8282\u70b9\uff0c\u5176\u4e24\u4e2a\u6307\u9488\u5747\u6307\u5411 None \u3002
    • \u8fb9\uff08edge\uff09\uff1a\u8fde\u63a5\u4e24\u4e2a\u8282\u70b9\u7684\u7ebf\u6bb5\uff0c\u5373\u8282\u70b9\u5f15\u7528\uff08\u6307\u9488\uff09\u3002
    • \u8282\u70b9\u6240\u5728\u7684\u5c42\uff08level\uff09\uff1a\u4ece\u9876\u81f3\u5e95\u9012\u589e\uff0c\u6839\u8282\u70b9\u6240\u5728\u5c42\u4e3a 1 \u3002
    • \u8282\u70b9\u7684\u5ea6\uff08degree\uff09\uff1a\u8282\u70b9\u7684\u5b50\u8282\u70b9\u7684\u6570\u91cf\u3002\u5728\u4e8c\u53c9\u6811\u4e2d\uff0c\u5ea6\u7684\u53d6\u503c\u8303\u56f4\u662f 0\u30011\u30012 \u3002
    • \u4e8c\u53c9\u6811\u7684\u9ad8\u5ea6\uff08height\uff09\uff1a\u4ece\u6839\u8282\u70b9\u5230\u6700\u8fdc\u53f6\u8282\u70b9\u6240\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u3002
    • \u8282\u70b9\u7684\u6df1\u5ea6\uff08depth\uff09\uff1a\u4ece\u6839\u8282\u70b9\u5230\u8be5\u8282\u70b9\u6240\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u3002
    • \u8282\u70b9\u7684\u9ad8\u5ea6\uff08height\uff09\uff1a\u4ece\u8ddd\u79bb\u8be5\u8282\u70b9\u6700\u8fdc\u7684\u53f6\u8282\u70b9\u5230\u8be5\u8282\u70b9\u6240\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u3002

    \u56fe 7-2 \u00a0 \u4e8c\u53c9\u6811\u7684\u5e38\u7528\u672f\u8bed

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u6211\u4eec\u901a\u5e38\u5c06\u201c\u9ad8\u5ea6\u201d\u548c\u201c\u6df1\u5ea6\u201d\u5b9a\u4e49\u4e3a\u201c\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u201d\uff0c\u4f46\u6709\u4e9b\u9898\u76ee\u6216\u6559\u6750\u53ef\u80fd\u4f1a\u5c06\u5176\u5b9a\u4e49\u4e3a\u201c\u7ecf\u8fc7\u7684\u8282\u70b9\u7684\u6570\u91cf\u201d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u9ad8\u5ea6\u548c\u6df1\u5ea6\u90fd\u9700\u8981\u52a0 1 \u3002

    "},{"location":"chapter_tree/binary_tree/#712","title":"7.1.2 \u00a0 \u4e8c\u53c9\u6811\u57fa\u672c\u64cd\u4f5c","text":""},{"location":"chapter_tree/binary_tree/#1","title":"1. \u00a0 \u521d\u59cb\u5316\u4e8c\u53c9\u6811","text":"

    \u4e0e\u94fe\u8868\u7c7b\u4f3c\uff0c\u9996\u5148\u521d\u59cb\u5316\u8282\u70b9\uff0c\u7136\u540e\u6784\u5efa\u5f15\u7528\uff08\u6307\u9488\uff09\u3002

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # \u521d\u59cb\u5316\u4e8c\u53c9\u6811\n# \u521d\u59cb\u5316\u8282\u70b9\nn1 = TreeNode(val=1)\nn2 = TreeNode(val=2)\nn3 = TreeNode(val=3)\nn4 = TreeNode(val=4)\nn5 = TreeNode(val=5)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.cpp
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode* n1 = new TreeNode(1);\nTreeNode* n2 = new TreeNode(2);\nTreeNode* n3 = new TreeNode(3);\nTreeNode* n4 = new TreeNode(4);\nTreeNode* n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.java
    // \u521d\u59cb\u5316\u8282\u70b9\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.cs
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode n1 = new(1);\nTreeNode n2 = new(2);\nTreeNode n3 = new(3);\nTreeNode n4 = new(4);\nTreeNode n5 = new(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.go
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nn1 := NewTreeNode(1)\nn2 := NewTreeNode(2)\nn3 := NewTreeNode(3)\nn4 := NewTreeNode(4)\nn5 := NewTreeNode(5)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.Left = n2\nn1.Right = n3\nn2.Left = n4\nn2.Right = n5\n
    binary_tree.swift
    // \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = TreeNode(x: 1)\nlet n2 = TreeNode(x: 2)\nlet n3 = TreeNode(x: 3)\nlet n4 = TreeNode(x: 4)\nlet n5 = TreeNode(x: 5)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.js
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.ts
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = new TreeNode(1),\n    n2 = new TreeNode(2),\n    n3 = new TreeNode(3),\n    n4 = new TreeNode(4),\n    n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.dart
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode n1 = new TreeNode(1);\nTreeNode n2 = new TreeNode(2);\nTreeNode n3 = new TreeNode(3);\nTreeNode n4 = new TreeNode(4);\nTreeNode n5 = new TreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2;\nn1.right = n3;\nn2.left = n4;\nn2.right = n5;\n
    binary_tree.rs
    // \u521d\u59cb\u5316\u8282\u70b9\nlet n1 = TreeNode::new(1);\nlet n2 = TreeNode::new(2);\nlet n3 = TreeNode::new(3);\nlet n4 = TreeNode::new(4);\nlet n5 = TreeNode::new(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.borrow_mut().left = Some(n2.clone());\nn1.borrow_mut().right = Some(n3);\nn2.borrow_mut().left = Some(n4);\nn2.borrow_mut().right = Some(n5);\n
    binary_tree.c
    /* \u521d\u59cb\u5316\u4e8c\u53c9\u6811 */\n// \u521d\u59cb\u5316\u8282\u70b9\nTreeNode *n1 = newTreeNode(1);\nTreeNode *n2 = newTreeNode(2);\nTreeNode *n3 = newTreeNode(3);\nTreeNode *n4 = newTreeNode(4);\nTreeNode *n5 = newTreeNode(5);\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1->left = n2;\nn1->right = n3;\nn2->left = n4;\nn2->right = n5;\n
    binary_tree.kt
    // \u521d\u59cb\u5316\u8282\u70b9\nval n1 = TreeNode(1)\nval n2 = TreeNode(2)\nval n3 = TreeNode(3)\nval n4 = TreeNode(4)\nval n5 = TreeNode(5)\n// \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.rb
    # \u521d\u59cb\u5316\u4e8c\u53c9\u6811\n# \u521d\u59cb\u5316\u8282\u70b9\nn1 = TreeNode.new(1)\nn2 = TreeNode.new(2)\nn3 = TreeNode.new(3)\nn4 = TreeNode.new(4)\nn5 = TreeNode.new(5)\n# \u6784\u5efa\u8282\u70b9\u4e4b\u95f4\u7684\u5f15\u7528\uff08\u6307\u9488\uff09\nn1.left = n2\nn1.right = n3\nn2.left = n4\nn2.right = n5\n
    binary_tree.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_tree/#2","title":"2. \u00a0 \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9","text":"

    \u4e0e\u94fe\u8868\u7c7b\u4f3c\uff0c\u5728\u4e8c\u53c9\u6811\u4e2d\u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\u53ef\u4ee5\u901a\u8fc7\u4fee\u6539\u6307\u9488\u6765\u5b9e\u73b0\u3002\u56fe 7-3 \u7ed9\u51fa\u4e86\u4e00\u4e2a\u793a\u4f8b\u3002

    \u56fe 7-3 \u00a0 \u5728\u4e8c\u53c9\u6811\u4e2d\u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree.py
    # \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\np = TreeNode(0)\n# \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = p\np.left = n2\n# \u5220\u9664\u8282\u70b9 P\nn1.left = n2\n
    binary_tree.cpp
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode* P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1->left = P;\nP->left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1->left = n2;\n
    binary_tree.java
    TreeNode P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.cs
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode P = new(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.go
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\np := NewTreeNode(0)\nn1.Left = p\np.Left = n2\n// \u5220\u9664\u8282\u70b9 P\nn1.Left = n2\n
    binary_tree.swift
    let P = TreeNode(x: 0)\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P\nP.left = n2\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2\n
    binary_tree.js
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nlet P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.ts
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nconst P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.dart
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode P = new TreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P;\nP.left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2;\n
    binary_tree.rs
    let p = TreeNode::new(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.borrow_mut().left = Some(p.clone());\np.borrow_mut().left = Some(n2.clone());\n// \u5220\u9664\u8282\u70b9 p\nn1.borrow_mut().left = Some(n2);\n
    binary_tree.c
    /* \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9 */\nTreeNode *P = newTreeNode(0);\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1->left = P;\nP->left = n2;\n// \u5220\u9664\u8282\u70b9 P\nn1->left = n2;\n
    binary_tree.kt
    val P = TreeNode(0)\n// \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 P\nn1.left = P\nP.left = n2\n// \u5220\u9664\u8282\u70b9 P\nn1.left = n2\n
    binary_tree.rb
    # \u63d2\u5165\u4e0e\u5220\u9664\u8282\u70b9\n_p = TreeNode.new(0)\n# \u5728 n1 -> n2 \u4e2d\u95f4\u63d2\u5165\u8282\u70b9 _p\nn1.left = _p\n_p.left = n2\n# \u5220\u9664\u8282\u70b9\nn1.left = n2\n
    binary_tree.zig
    \n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    Tip

    \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u63d2\u5165\u8282\u70b9\u53ef\u80fd\u4f1a\u6539\u53d8\u4e8c\u53c9\u6811\u7684\u539f\u6709\u903b\u8f91\u7ed3\u6784\uff0c\u800c\u5220\u9664\u8282\u70b9\u901a\u5e38\u610f\u5473\u7740\u5220\u9664\u8be5\u8282\u70b9\u53ca\u5176\u6240\u6709\u5b50\u6811\u3002\u56e0\u6b64\uff0c\u5728\u4e8c\u53c9\u6811\u4e2d\uff0c\u63d2\u5165\u4e0e\u5220\u9664\u901a\u5e38\u662f\u7531\u4e00\u5957\u64cd\u4f5c\u914d\u5408\u5b8c\u6210\u7684\uff0c\u4ee5\u5b9e\u73b0\u6709\u5b9e\u9645\u610f\u4e49\u7684\u64cd\u4f5c\u3002

    "},{"location":"chapter_tree/binary_tree/#713","title":"7.1.3 \u00a0 \u5e38\u89c1\u4e8c\u53c9\u6811\u7c7b\u578b","text":""},{"location":"chapter_tree/binary_tree/#1_1","title":"1. \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-4 \u6240\u793a\uff0c\u5b8c\u7f8e\u4e8c\u53c9\u6811\uff08perfect binary tree\uff09\u6240\u6709\u5c42\u7684\u8282\u70b9\u90fd\u88ab\u5b8c\u5168\u586b\u6ee1\u3002\u5728\u5b8c\u7f8e\u4e8c\u53c9\u6811\u4e2d\uff0c\u53f6\u8282\u70b9\u7684\u5ea6\u4e3a \\(0\\) \uff0c\u5176\u4f59\u6240\u6709\u8282\u70b9\u7684\u5ea6\u90fd\u4e3a \\(2\\) \uff1b\u82e5\u6811\u7684\u9ad8\u5ea6\u4e3a \\(h\\) \uff0c\u5219\u8282\u70b9\u603b\u6570\u4e3a \\(2^{h+1} - 1\\) \uff0c\u5448\u73b0\u6807\u51c6\u7684\u6307\u6570\u7ea7\u5173\u7cfb\uff0c\u53cd\u6620\u4e86\u81ea\u7136\u754c\u4e2d\u5e38\u89c1\u7684\u7ec6\u80de\u5206\u88c2\u73b0\u8c61\u3002

    Tip

    \u8bf7\u6ce8\u610f\uff0c\u5728\u4e2d\u6587\u793e\u533a\u4e2d\uff0c\u5b8c\u7f8e\u4e8c\u53c9\u6811\u5e38\u88ab\u79f0\u4e3a\u6ee1\u4e8c\u53c9\u6811\u3002

    \u56fe 7-4 \u00a0 \u5b8c\u7f8e\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#2_1","title":"2. \u00a0 \u5b8c\u5168\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-5 \u6240\u793a\uff0c\u5b8c\u5168\u4e8c\u53c9\u6811\uff08complete binary tree\uff09\u53ea\u6709\u6700\u5e95\u5c42\u7684\u8282\u70b9\u672a\u88ab\u586b\u6ee1\uff0c\u4e14\u6700\u5e95\u5c42\u8282\u70b9\u5c3d\u91cf\u9760\u5de6\u586b\u5145\u3002

    \u56fe 7-5 \u00a0 \u5b8c\u5168\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#3","title":"3. \u00a0 \u5b8c\u6ee1\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-6 \u6240\u793a\uff0c\u5b8c\u6ee1\u4e8c\u53c9\u6811\uff08full binary tree\uff09\u9664\u4e86\u53f6\u8282\u70b9\u4e4b\u5916\uff0c\u5176\u4f59\u6240\u6709\u8282\u70b9\u90fd\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\u3002

    \u56fe 7-6 \u00a0 \u5b8c\u6ee1\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#4","title":"4. \u00a0 \u5e73\u8861\u4e8c\u53c9\u6811","text":"

    \u5982\u56fe 7-7 \u6240\u793a\uff0c\u5e73\u8861\u4e8c\u53c9\u6811\uff08balanced binary tree\uff09\u4e2d\u4efb\u610f\u8282\u70b9\u7684\u5de6\u5b50\u6811\u548c\u53f3\u5b50\u6811\u7684\u9ad8\u5ea6\u4e4b\u5dee\u7684\u7edd\u5bf9\u503c\u4e0d\u8d85\u8fc7 1 \u3002

    \u56fe 7-7 \u00a0 \u5e73\u8861\u4e8c\u53c9\u6811

    "},{"location":"chapter_tree/binary_tree/#714","title":"7.1.4 \u00a0 \u4e8c\u53c9\u6811\u7684\u9000\u5316","text":"

    \u56fe 7-8 \u5c55\u793a\u4e86\u4e8c\u53c9\u6811\u7684\u7406\u60f3\u7ed3\u6784\u4e0e\u9000\u5316\u7ed3\u6784\u3002\u5f53\u4e8c\u53c9\u6811\u7684\u6bcf\u5c42\u8282\u70b9\u90fd\u88ab\u586b\u6ee1\u65f6\uff0c\u8fbe\u5230\u201c\u5b8c\u7f8e\u4e8c\u53c9\u6811\u201d\uff1b\u800c\u5f53\u6240\u6709\u8282\u70b9\u90fd\u504f\u5411\u4e00\u4fa7\u65f6\uff0c\u4e8c\u53c9\u6811\u9000\u5316\u4e3a\u201c\u94fe\u8868\u201d\u3002

    • \u5b8c\u7f8e\u4e8c\u53c9\u6811\u662f\u7406\u60f3\u60c5\u51b5\uff0c\u53ef\u4ee5\u5145\u5206\u53d1\u6325\u4e8c\u53c9\u6811\u201c\u5206\u6cbb\u201d\u7684\u4f18\u52bf\u3002
    • \u94fe\u8868\u5219\u662f\u53e6\u4e00\u4e2a\u6781\u7aef\uff0c\u5404\u9879\u64cd\u4f5c\u90fd\u53d8\u4e3a\u7ebf\u6027\u64cd\u4f5c\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u9000\u5316\u81f3 \\(O(n)\\) \u3002

    \u56fe 7-8 \u00a0 \u4e8c\u53c9\u6811\u7684\u6700\u4f73\u7ed3\u6784\u4e0e\u6700\u5dee\u7ed3\u6784

    \u5982\u8868 7-1 \u6240\u793a\uff0c\u5728\u6700\u4f73\u7ed3\u6784\u548c\u6700\u5dee\u7ed3\u6784\u4e0b\uff0c\u4e8c\u53c9\u6811\u7684\u53f6\u8282\u70b9\u6570\u91cf\u3001\u8282\u70b9\u603b\u6570\u3001\u9ad8\u5ea6\u7b49\u8fbe\u5230\u6781\u5927\u503c\u6216\u6781\u5c0f\u503c\u3002

    \u8868 7-1 \u00a0 \u4e8c\u53c9\u6811\u7684\u6700\u4f73\u7ed3\u6784\u4e0e\u6700\u5dee\u7ed3\u6784

    \u5b8c\u7f8e\u4e8c\u53c9\u6811 \u94fe\u8868 \u7b2c \\(i\\) \u5c42\u7684\u8282\u70b9\u6570\u91cf \\(2^{i-1}\\) \\(1\\) \u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u6811\u7684\u53f6\u8282\u70b9\u6570\u91cf \\(2^h\\) \\(1\\) \u9ad8\u5ea6\u4e3a \\(h\\) \u7684\u6811\u7684\u8282\u70b9\u603b\u6570 \\(2^{h+1} - 1\\) \\(h + 1\\) \u8282\u70b9\u603b\u6570\u4e3a \\(n\\) \u7684\u6811\u7684\u9ad8\u5ea6 \\(\\log_2 (n+1) - 1\\) \\(n - 1\\)"},{"location":"chapter_tree/binary_tree_traversal/","title":"7.2 \u00a0 \u4e8c\u53c9\u6811\u904d\u5386","text":"

    \u4ece\u7269\u7406\u7ed3\u6784\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u6811\u662f\u4e00\u79cd\u57fa\u4e8e\u94fe\u8868\u7684\u6570\u636e\u7ed3\u6784\uff0c\u56e0\u6b64\u5176\u904d\u5386\u65b9\u5f0f\u662f\u901a\u8fc7\u6307\u9488\u9010\u4e2a\u8bbf\u95ee\u8282\u70b9\u3002\u7136\u800c\uff0c\u6811\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u8fd9\u4f7f\u5f97\u904d\u5386\u6811\u6bd4\u904d\u5386\u94fe\u8868\u66f4\u52a0\u590d\u6742\uff0c\u9700\u8981\u501f\u52a9\u641c\u7d22\u7b97\u6cd5\u6765\u5b9e\u73b0\u3002

    \u4e8c\u53c9\u6811\u5e38\u89c1\u7684\u904d\u5386\u65b9\u5f0f\u5305\u62ec\u5c42\u5e8f\u904d\u5386\u3001\u524d\u5e8f\u904d\u5386\u3001\u4e2d\u5e8f\u904d\u5386\u548c\u540e\u5e8f\u904d\u5386\u7b49\u3002

    "},{"location":"chapter_tree/binary_tree_traversal/#721","title":"7.2.1 \u00a0 \u5c42\u5e8f\u904d\u5386","text":"

    \u5982\u56fe 7-9 \u6240\u793a\uff0c\u5c42\u5e8f\u904d\u5386\uff08level-order traversal\uff09\u4ece\u9876\u90e8\u5230\u5e95\u90e8\u9010\u5c42\u904d\u5386\u4e8c\u53c9\u6811\uff0c\u5e76\u5728\u6bcf\u4e00\u5c42\u6309\u7167\u4ece\u5de6\u5230\u53f3\u7684\u987a\u5e8f\u8bbf\u95ee\u8282\u70b9\u3002

    \u5c42\u5e8f\u904d\u5386\u672c\u8d28\u4e0a\u5c5e\u4e8e\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\uff08breadth-first traversal\uff09\uff0c\u4e5f\u79f0\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\uff08breadth-first search, BFS\uff09\uff0c\u5b83\u4f53\u73b0\u4e86\u4e00\u79cd\u201c\u4e00\u5708\u4e00\u5708\u5411\u5916\u6269\u5c55\u201d\u7684\u9010\u5c42\u904d\u5386\u65b9\u5f0f\u3002

    \u56fe 7-9 \u00a0 \u4e8c\u53c9\u6811\u7684\u5c42\u5e8f\u904d\u5386

    "},{"location":"chapter_tree/binary_tree_traversal/#1","title":"1. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u901a\u5e38\u501f\u52a9\u201c\u961f\u5217\u201d\u6765\u5b9e\u73b0\u3002\u961f\u5217\u9075\u5faa\u201c\u5148\u8fdb\u5148\u51fa\u201d\u7684\u89c4\u5219\uff0c\u800c\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u5219\u9075\u5faa\u201c\u9010\u5c42\u63a8\u8fdb\u201d\u7684\u89c4\u5219\uff0c\u4e24\u8005\u80cc\u540e\u7684\u601d\u60f3\u662f\u4e00\u81f4\u7684\u3002\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_bfs.py
    def level_order(root: TreeNode | None) -> list[int]:\n    \"\"\"\u5c42\u5e8f\u904d\u5386\"\"\"\n    # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue: deque[TreeNode] = deque()\n    queue.append(root)\n    # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    res = []\n    while queue:\n        node: TreeNode = queue.popleft()  # \u961f\u5217\u51fa\u961f\n        res.append(node.val)  # \u4fdd\u5b58\u8282\u70b9\u503c\n        if node.left is not None:\n            queue.append(node.left)  # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if node.right is not None:\n            queue.append(node.right)  # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    return res\n
    binary_tree_bfs.cpp
    /* \u5c42\u5e8f\u904d\u5386 */\nvector<int> levelOrder(TreeNode *root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue<TreeNode *> queue;\n    queue.push(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    vector<int> vec;\n    while (!queue.empty()) {\n        TreeNode *node = queue.front();\n        queue.pop();              // \u961f\u5217\u51fa\u961f\n        vec.push_back(node->val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node->left != nullptr)\n            queue.push(node->left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node->right != nullptr)\n            queue.push(node->right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return vec;\n}\n
    binary_tree_bfs.java
    /* \u5c42\u5e8f\u904d\u5386 */\nList<Integer> levelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new LinkedList<>();\n    queue.add(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<Integer> list = new ArrayList<>();\n    while (!queue.isEmpty()) {\n        TreeNode node = queue.poll(); // \u961f\u5217\u51fa\u961f\n        list.add(node.val);           // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left);   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right);  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.cs
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> LevelOrder(TreeNode root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    Queue<TreeNode> queue = new();\n    queue.Enqueue(root);\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    List<int> list = [];\n    while (queue.Count != 0) {\n        TreeNode node = queue.Dequeue(); // \u961f\u5217\u51fa\u961f\n        list.Add(node.val!.Value);       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.Enqueue(node.left);    // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.Enqueue(node.right);   // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.go
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root *TreeNode) []any {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    queue := list.New()\n    queue.PushBack(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5207\u7247\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    nums := make([]any, 0)\n    for queue.Len() > 0 {\n        // \u961f\u5217\u51fa\u961f\n        node := queue.Remove(queue.Front()).(*TreeNode)\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        nums = append(nums, node.Val)\n        if node.Left != nil {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Left)\n        }\n        if node.Right != nil {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue.PushBack(node.Right)\n        }\n    }\n    return nums\n}\n
    binary_tree_bfs.swift
    /* \u5c42\u5e8f\u904d\u5386 */\nfunc levelOrder(root: TreeNode) -> [Int] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    var queue: [TreeNode] = [root]\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list: [Int] = []\n    while !queue.isEmpty {\n        let node = queue.removeFirst() // \u961f\u5217\u51fa\u961f\n        list.append(node.val) // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let left = node.left {\n            queue.append(left) // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let right = node.right {\n            queue.append(right) // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list\n}\n
    binary_tree_bfs.js
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list = [];\n    while (queue.length) {\n        let node = queue.shift(); // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right) queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list;\n}\n
    binary_tree_bfs.ts
    /* \u5c42\u5e8f\u904d\u5386 */\nfunction levelOrder(root: TreeNode | null): number[] {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const queue = [root];\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    const list: number[] = [];\n    while (queue.length) {\n        let node = queue.shift() as TreeNode; // \u961f\u5217\u51fa\u961f\n        list.push(node.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left) {\n            queue.push(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right) {\n            queue.push(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }\n    }\n    return list;\n}\n
    binary_tree_bfs.dart
    /* \u5c42\u5e8f\u904d\u5386 */\nList<int> levelOrder(TreeNode? root) {\n  // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  Queue<TreeNode?> queue = Queue();\n  queue.add(root);\n  // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  List<int> res = [];\n  while (queue.isNotEmpty) {\n    TreeNode? node = queue.removeFirst(); // \u961f\u5217\u51fa\u961f\n    res.add(node!.val); // \u4fdd\u5b58\u8282\u70b9\u503c\n    if (node.left != null) queue.add(node.left); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    if (node.right != null) queue.add(node.right); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  }\n  return res;\n}\n
    binary_tree_bfs.rs
    /* \u5c42\u5e8f\u904d\u5386 */\nfn level_order(root: &Rc<RefCell<TreeNode>>) -> Vec<i32> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    let mut que = VecDeque::new();\n    que.push_back(root.clone());\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    let mut vec = Vec::new();\n\n    while let Some(node) = que.pop_front() {\n        // \u961f\u5217\u51fa\u961f\n        vec.push(node.borrow().val); // \u4fdd\u5b58\u8282\u70b9\u503c\n        if let Some(left) = node.borrow().left.as_ref() {\n            que.push_back(left.clone()); // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if let Some(right) = node.borrow().right.as_ref() {\n            que.push_back(right.clone()); // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        };\n    }\n    vec\n}\n
    binary_tree_bfs.c
    /* \u5c42\u5e8f\u904d\u5386 */\nint *levelOrder(TreeNode *root, int *size) {\n    /* \u8f85\u52a9\u961f\u5217 */\n    int front, rear;\n    int index, *arr;\n    TreeNode *node;\n    TreeNode **queue;\n\n    /* \u8f85\u52a9\u961f\u5217 */\n    queue = (TreeNode **)malloc(sizeof(TreeNode *) * MAX_SIZE);\n    // \u961f\u5217\u6307\u9488\n    front = 0, rear = 0;\n    // \u52a0\u5165\u6839\u8282\u70b9\n    queue[rear++] = root;\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    /* \u8f85\u52a9\u6570\u7ec4 */\n    arr = (int *)malloc(sizeof(int) * MAX_SIZE);\n    // \u6570\u7ec4\u6307\u9488\n    index = 0;\n    while (front < rear) {\n        // \u961f\u5217\u51fa\u961f\n        node = queue[front++];\n        // \u4fdd\u5b58\u8282\u70b9\u503c\n        arr[index++] = node->val;\n        if (node->left != NULL) {\n            // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->left;\n        }\n        if (node->right != NULL) {\n            // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n            queue[rear++] = node->right;\n        }\n    }\n    // \u66f4\u65b0\u6570\u7ec4\u957f\u5ea6\u7684\u503c\n    *size = index;\n    arr = realloc(arr, sizeof(int) * (*size));\n\n    // \u91ca\u653e\u8f85\u52a9\u6570\u7ec4\u7a7a\u95f4\n    free(queue);\n    return arr;\n}\n
    binary_tree_bfs.kt
    /* \u5c42\u5e8f\u904d\u5386 */\nfun levelOrder(root: TreeNode?): MutableList<Int> {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    val queue = LinkedList<TreeNode?>()\n    queue.add(root)\n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    val list = mutableListOf<Int>()\n    while (queue.isNotEmpty()) {\n        val node = queue.poll()      // \u961f\u5217\u51fa\u961f\n        list.add(node?._val!!)       // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null)\n            queue.offer(node.left)   // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        if (node.right != null)\n            queue.offer(node.right)  // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n    }\n    return list\n}\n
    binary_tree_bfs.rb
    ### \u5c42\u5e8f\u904d\u5386 ###\ndef level_order(root)\n  # \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n  queue = [root]\n  # \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n  res = []\n  while !queue.empty?\n    node = queue.shift # \u961f\u5217\u51fa\u961f\n    res << node.val # \u4fdd\u5b58\u8282\u70b9\u503c\n    queue << node.left unless node.left.nil? # \u5de6\u5b50\u8282\u70b9\u5165\u961f\n    queue << node.right unless node.right.nil? # \u53f3\u5b50\u8282\u70b9\u5165\u961f\n  end\n  res\nend\n
    binary_tree_bfs.zig
    // \u5c42\u5e8f\u904d\u5386\nfn levelOrder(comptime T: type, mem_allocator: std.mem.Allocator, root: *inc.TreeNode(T)) !std.ArrayList(T) {\n    // \u521d\u59cb\u5316\u961f\u5217\uff0c\u52a0\u5165\u6839\u8282\u70b9\n    const L = std.TailQueue(*inc.TreeNode(T));\n    var queue = L{};\n    var root_node = try mem_allocator.create(L.Node);\n    root_node.data = root;\n    queue.append(root_node); \n    // \u521d\u59cb\u5316\u4e00\u4e2a\u5217\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u904d\u5386\u5e8f\u5217\n    var list = std.ArrayList(T).init(std.heap.page_allocator);\n    while (queue.len > 0) {\n        var queue_node = queue.popFirst().?;    // \u961f\u5217\u51fa\u961f\n        var node = queue_node.data;\n        try list.append(node.val);              // \u4fdd\u5b58\u8282\u70b9\u503c\n        if (node.left != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.left.?;\n            queue.append(tmp_node);             // \u5de6\u5b50\u8282\u70b9\u5165\u961f\n        }\n        if (node.right != null) {\n            var tmp_node = try mem_allocator.create(L.Node);\n            tmp_node.data = node.right.?;\n            queue.append(tmp_node);             // \u53f3\u5b50\u8282\u70b9\u5165\u961f\n        }        \n    }\n    return list;\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    "},{"location":"chapter_tree/binary_tree_traversal/#2","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u6240\u6709\u8282\u70b9\u88ab\u8bbf\u95ee\u4e00\u6b21\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\uff0c\u5176\u4e2d \\(n\\) \u4e3a\u8282\u70b9\u6570\u91cf\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u5373\u6ee1\u4e8c\u53c9\u6811\u65f6\uff0c\u904d\u5386\u5230\u6700\u5e95\u5c42\u4e4b\u524d\uff0c\u961f\u5217\u4e2d\u6700\u591a\u540c\u65f6\u5b58\u5728 \\((n + 1) / 2\\) \u4e2a\u8282\u70b9\uff0c\u5360\u7528 \\(O(n)\\) \u7a7a\u95f4\u3002
    "},{"location":"chapter_tree/binary_tree_traversal/#722","title":"7.2.2 \u00a0 \u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386","text":"

    \u76f8\u5e94\u5730\uff0c\u524d\u5e8f\u3001\u4e2d\u5e8f\u548c\u540e\u5e8f\u904d\u5386\u90fd\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u904d\u5386\uff08depth-first traversal\uff09\uff0c\u4e5f\u79f0\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\uff08depth-first search, DFS\uff09\uff0c\u5b83\u4f53\u73b0\u4e86\u4e00\u79cd\u201c\u5148\u8d70\u5230\u5c3d\u5934\uff0c\u518d\u56de\u6eaf\u7ee7\u7eed\u201d\u7684\u904d\u5386\u65b9\u5f0f\u3002

    \u56fe 7-10 \u5c55\u793a\u4e86\u5bf9\u4e8c\u53c9\u6811\u8fdb\u884c\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u7684\u5de5\u4f5c\u539f\u7406\u3002\u6df1\u5ea6\u4f18\u5148\u904d\u5386\u5c31\u50cf\u662f\u7ed5\u7740\u6574\u68f5\u4e8c\u53c9\u6811\u7684\u5916\u56f4\u201c\u8d70\u201d\u4e00\u5708\uff0c\u5728\u6bcf\u4e2a\u8282\u70b9\u90fd\u4f1a\u9047\u5230\u4e09\u4e2a\u4f4d\u7f6e\uff0c\u5206\u522b\u5bf9\u5e94\u524d\u5e8f\u904d\u5386\u3001\u4e2d\u5e8f\u904d\u5386\u548c\u540e\u5e8f\u904d\u5386\u3002

    \u56fe 7-10 \u00a0 \u4e8c\u53c9\u641c\u7d22\u6811\u7684\u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386

    "},{"location":"chapter_tree/binary_tree_traversal/#1_1","title":"1. \u00a0 \u4ee3\u7801\u5b9e\u73b0","text":"

    \u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u901a\u5e38\u57fa\u4e8e\u9012\u5f52\u5b9e\u73b0\uff1a

    PythonC++JavaC#GoSwiftJSTSDartRustCKotlinRubyZig binary_tree_dfs.py
    def pre_order(root: TreeNode | None):\n    \"\"\"\u524d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    res.append(root.val)\n    pre_order(root=root.left)\n    pre_order(root=root.right)\n\ndef in_order(root: TreeNode | None):\n    \"\"\"\u4e2d\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    in_order(root=root.left)\n    res.append(root.val)\n    in_order(root=root.right)\n\ndef post_order(root: TreeNode | None):\n    \"\"\"\u540e\u5e8f\u904d\u5386\"\"\"\n    if root is None:\n        return\n    # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    post_order(root=root.left)\n    post_order(root=root.right)\n    res.append(root.val)\n
    binary_tree_dfs.cpp
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    vec.push_back(root->val);\n    preOrder(root->left);\n    preOrder(root->right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left);\n    vec.push_back(root->val);\n    inOrder(root->right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root) {\n    if (root == nullptr)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left);\n    postOrder(root->right);\n    vec.push_back(root->val);\n}\n
    binary_tree_dfs.java
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.add(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode root) {\n    if (root == null)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.add(root.val);\n}\n
    binary_tree_dfs.cs
    /* \u524d\u5e8f\u904d\u5386 */\nvoid PreOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.Add(root.val!.Value);\n    PreOrder(root.left);\n    PreOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid InOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    InOrder(root.left);\n    list.Add(root.val!.Value);\n    InOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid PostOrder(TreeNode? root) {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    PostOrder(root.left);\n    PostOrder(root.right);\n    list.Add(root.val!.Value);\n}\n
    binary_tree_dfs.go
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    nums = append(nums, node.Val)\n    preOrder(node.Left)\n    preOrder(node.Right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(node.Left)\n    nums = append(nums, node.Val)\n    inOrder(node.Right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(node *TreeNode) {\n    if node == nil {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(node.Left)\n    postOrder(node.Right)\n    nums = append(nums, node.Val)\n}\n
    binary_tree_dfs.swift
    /* \u524d\u5e8f\u904d\u5386 */\nfunc preOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.append(root.val)\n    preOrder(root: root.left)\n    preOrder(root: root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunc inOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root: root.left)\n    list.append(root.val)\n    inOrder(root: root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunc postOrder(root: TreeNode?) {\n    guard let root = root else {\n        return\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root: root.left)\n    postOrder(root: root.right)\n    list.append(root.val)\n}\n
    binary_tree_dfs.js
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root) {\n    if (root === null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.ts
    /* \u524d\u5e8f\u904d\u5386 */\nfunction preOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.push(root.val);\n    preOrder(root.left);\n    preOrder(root.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfunction inOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left);\n    list.push(root.val);\n    inOrder(root.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfunction postOrder(root: TreeNode | null): void {\n    if (root === null) {\n        return;\n    }\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left);\n    postOrder(root.right);\n    list.push(root.val);\n}\n
    binary_tree_dfs.dart
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  list.add(node.val);\n  preOrder(node.left);\n  preOrder(node.right);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  inOrder(node.left);\n  list.add(node.val);\n  inOrder(node.right);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode? node) {\n  if (node == null) return;\n  // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  postOrder(node.left);\n  postOrder(node.right);\n  list.add(node.val);\n}\n
    binary_tree_dfs.rs
    /* \u524d\u5e8f\u904d\u5386 */\nfn pre_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n        result.push(node.borrow().val);\n        result.extend(pre_order(node.borrow().left.as_ref()));\n        result.extend(pre_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfn in_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n        result.extend(in_order(node.borrow().left.as_ref()));\n        result.push(node.borrow().val);\n        result.extend(in_order(node.borrow().right.as_ref()));\n    }\n    result\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfn post_order(root: Option<&Rc<RefCell<TreeNode>>>) -> Vec<i32> {\n    let mut result = vec![];\n\n    if let Some(node) = root {\n        // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n        result.extend(post_order(node.borrow().left.as_ref()));\n        result.extend(post_order(node.borrow().right.as_ref()));\n        result.push(node.borrow().val);\n    }\n    result\n}\n
    binary_tree_dfs.c
    /* \u524d\u5e8f\u904d\u5386 */\nvoid preOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    arr[(*size)++] = root->val;\n    preOrder(root->left, size);\n    preOrder(root->right, size);\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nvoid inOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root->left, size);\n    arr[(*size)++] = root->val;\n    inOrder(root->right, size);\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nvoid postOrder(TreeNode *root, int *size) {\n    if (root == NULL)\n        return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root->left, size);\n    postOrder(root->right, size);\n    arr[(*size)++] = root->val;\n}\n
    binary_tree_dfs.kt
    /* \u524d\u5e8f\u904d\u5386 */\nfun preOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    list.add(root._val)\n    preOrder(root.left)\n    preOrder(root.right)\n}\n\n/* \u4e2d\u5e8f\u904d\u5386 */\nfun inOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    inOrder(root.left)\n    list.add(root._val)\n    inOrder(root.right)\n}\n\n/* \u540e\u5e8f\u904d\u5386 */\nfun postOrder(root: TreeNode?) {\n    if (root == null) return\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    postOrder(root.left)\n    postOrder(root.right)\n    list.add(root._val)\n}\n
    binary_tree_dfs.rb
    ### \u524d\u5e8f\u904d\u5386 ###\ndef pre_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n  $res << root.val\n  pre_order(root.left)\n  pre_order(root.right)\nend\n\n### \u4e2d\u5e8f\u904d\u5386 ###\ndef in_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n  in_order(root.left)\n  $res << root.val\n  in_order(root.right)\nend\n\n### \u540e\u5e8f\u904d\u5386 ###\ndef post_order(root)\n  return if root.nil?\n\n  # \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n  post_order(root.left)\n  post_order(root.right)\n  $res << root.val\nend\n
    binary_tree_dfs.zig
    // \u524d\u5e8f\u904d\u5386\nfn preOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u6839\u8282\u70b9 -> \u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811\n    try list.append(root.?.val);\n    try preOrder(T, root.?.left);\n    try preOrder(T, root.?.right);\n}\n\n// \u4e2d\u5e8f\u904d\u5386\nfn inOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u6839\u8282\u70b9 -> \u53f3\u5b50\u6811\n    try inOrder(T, root.?.left);\n    try list.append(root.?.val);\n    try inOrder(T, root.?.right);\n}\n\n// \u540e\u5e8f\u904d\u5386\nfn postOrder(comptime T: type, root: ?*inc.TreeNode(T)) !void {\n    if (root == null) return;\n    // \u8bbf\u95ee\u4f18\u5148\u7ea7\uff1a\u5de6\u5b50\u6811 -> \u53f3\u5b50\u6811 -> \u6839\u8282\u70b9\n    try postOrder(T, root.?.left);\n    try postOrder(T, root.?.right);\n    try list.append(root.?.val);\n}\n
    \u53ef\u89c6\u5316\u8fd0\u884c

    \u5168\u5c4f\u89c2\u770b >

    Tip

    \u6df1\u5ea6\u4f18\u5148\u641c\u7d22\u4e5f\u53ef\u4ee5\u57fa\u4e8e\u8fed\u4ee3\u5b9e\u73b0\uff0c\u6709\u5174\u8da3\u7684\u8bfb\u8005\u53ef\u4ee5\u81ea\u884c\u7814\u7a76\u3002

    \u56fe 7-11 \u5c55\u793a\u4e86\u524d\u5e8f\u904d\u5386\u4e8c\u53c9\u6811\u7684\u9012\u5f52\u8fc7\u7a0b\uff0c\u5176\u53ef\u5206\u4e3a\u201c\u9012\u201d\u548c\u201c\u5f52\u201d\u4e24\u4e2a\u9006\u5411\u7684\u90e8\u5206\u3002

    1. \u201c\u9012\u201d\u8868\u793a\u5f00\u542f\u65b0\u65b9\u6cd5\uff0c\u7a0b\u5e8f\u5728\u6b64\u8fc7\u7a0b\u4e2d\u8bbf\u95ee\u4e0b\u4e00\u4e2a\u8282\u70b9\u3002
    2. \u201c\u5f52\u201d\u8868\u793a\u51fd\u6570\u8fd4\u56de\uff0c\u4ee3\u8868\u5f53\u524d\u8282\u70b9\u5df2\u7ecf\u8bbf\u95ee\u5b8c\u6bd5\u3002
    <1><2><3><4><5><6><7><8><9><10><11>

    \u56fe 7-11 \u00a0 \u524d\u5e8f\u904d\u5386\u7684\u9012\u5f52\u8fc7\u7a0b

    "},{"location":"chapter_tree/binary_tree_traversal/#2_1","title":"2. \u00a0 \u590d\u6742\u5ea6\u5206\u6790","text":"
    • \u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u6240\u6709\u8282\u70b9\u88ab\u8bbf\u95ee\u4e00\u6b21\uff0c\u4f7f\u7528 \\(O(n)\\) \u65f6\u95f4\u3002
    • \u7a7a\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \uff1a\u5728\u6700\u5dee\u60c5\u51b5\u4e0b\uff0c\u5373\u6811\u9000\u5316\u4e3a\u94fe\u8868\u65f6\uff0c\u9012\u5f52\u6df1\u5ea6\u8fbe\u5230 \\(n\\) \uff0c\u7cfb\u7edf\u5360\u7528 \\(O(n)\\) \u6808\u5e27\u7a7a\u95f4\u3002
    "},{"location":"chapter_tree/summary/","title":"7.6 \u00a0 \u5c0f\u7ed3","text":""},{"location":"chapter_tree/summary/#1","title":"1. \u00a0 \u91cd\u70b9\u56de\u987e","text":"
    • \u4e8c\u53c9\u6811\u662f\u4e00\u79cd\u975e\u7ebf\u6027\u6570\u636e\u7ed3\u6784\uff0c\u4f53\u73b0\u201c\u4e00\u5206\u4e3a\u4e8c\u201d\u7684\u5206\u6cbb\u903b\u8f91\u3002\u6bcf\u4e2a\u4e8c\u53c9\u6811\u8282\u70b9\u5305\u542b\u4e00\u4e2a\u503c\u4ee5\u53ca\u4e24\u4e2a\u6307\u9488\uff0c\u5206\u522b\u6307\u5411\u5176\u5de6\u5b50\u8282\u70b9\u548c\u53f3\u5b50\u8282\u70b9\u3002
    • \u5bf9\u4e8e\u4e8c\u53c9\u6811\u4e2d\u7684\u67d0\u4e2a\u8282\u70b9\uff0c\u5176\u5de6\uff08\u53f3\uff09\u5b50\u8282\u70b9\u53ca\u5176\u4ee5\u4e0b\u5f62\u6210\u7684\u6811\u88ab\u79f0\u4e3a\u8be5\u8282\u70b9\u7684\u5de6\uff08\u53f3\uff09\u5b50\u6811\u3002
    • \u4e8c\u53c9\u6811\u7684\u76f8\u5173\u672f\u8bed\u5305\u62ec\u6839\u8282\u70b9\u3001\u53f6\u8282\u70b9\u3001\u5c42\u3001\u5ea6\u3001\u8fb9\u3001\u9ad8\u5ea6\u548c\u6df1\u5ea6\u7b49\u3002
    • \u4e8c\u53c9\u6811\u7684\u521d\u59cb\u5316\u3001\u8282\u70b9\u63d2\u5165\u548c\u8282\u70b9\u5220\u9664\u64cd\u4f5c\u4e0e\u94fe\u8868\u64cd\u4f5c\u65b9\u6cd5\u7c7b\u4f3c\u3002
    • \u5e38\u89c1\u7684\u4e8c\u53c9\u6811\u7c7b\u578b\u6709\u5b8c\u7f8e\u4e8c\u53c9\u6811\u3001\u5b8c\u5168\u4e8c\u53c9\u6811\u3001\u5b8c\u6ee1\u4e8c\u53c9\u6811\u548c\u5e73\u8861\u4e8c\u53c9\u6811\u3002\u5b8c\u7f8e\u4e8c\u53c9\u6811\u662f\u6700\u7406\u60f3\u7684\u72b6\u6001\uff0c\u800c\u94fe\u8868\u662f\u9000\u5316\u540e\u7684\u6700\u5dee\u72b6\u6001\u3002
    • \u4e8c\u53c9\u6811\u53ef\u4ee5\u7528\u6570\u7ec4\u8868\u793a\uff0c\u65b9\u6cd5\u662f\u5c06\u8282\u70b9\u503c\u548c\u7a7a\u4f4d\u6309\u5c42\u5e8f\u904d\u5386\u987a\u5e8f\u6392\u5217\uff0c\u5e76\u6839\u636e\u7236\u8282\u70b9\u4e0e\u5b50\u8282\u70b9\u4e4b\u95f4\u7684\u7d22\u5f15\u6620\u5c04\u5173\u7cfb\u6765\u5b9e\u73b0\u6307\u9488\u3002
    • \u4e8c\u53c9\u6811\u7684\u5c42\u5e8f\u904d\u5386\u662f\u4e00\u79cd\u5e7f\u5ea6\u4f18\u5148\u641c\u7d22\u65b9\u6cd5\uff0c\u5b83\u4f53\u73b0\u4e86\u201c\u4e00\u5708\u4e00\u5708\u5411\u5916\u6269\u5c55\u201d\u7684\u9010\u5c42\u904d\u5386\u65b9\u5f0f\uff0c\u901a\u5e38\u901a\u8fc7\u961f\u5217\u6765\u5b9e\u73b0\u3002
    • \u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386\u7686\u5c5e\u4e8e\u6df1\u5ea6\u4f18\u5148\u641c\u7d22\uff0c\u5b83\u4eec\u4f53\u73b0\u4e86\u201c\u5148\u8d70\u5230\u5c3d\u5934\uff0c\u518d\u56de\u6eaf\u7ee7\u7eed\u201d\u7684\u904d\u5386\u65b9\u5f0f\uff0c\u901a\u5e38\u4f7f\u7528\u9012\u5f52\u6765\u5b9e\u73b0\u3002
    • \u4e8c\u53c9\u641c\u7d22\u6811\u662f\u4e00\u79cd\u9ad8\u6548\u7684\u5143\u7d20\u67e5\u627e\u6570\u636e\u7ed3\u6784\uff0c\u5176\u67e5\u627e\u3001\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u5747\u4e3a \\(O(\\log n)\\) \u3002\u5f53\u4e8c\u53c9\u641c\u7d22\u6811\u9000\u5316\u4e3a\u94fe\u8868\u65f6\uff0c\u5404\u9879\u65f6\u95f4\u590d\u6742\u5ea6\u4f1a\u52a3\u5316\u81f3 \\(O(n)\\) \u3002
    • AVL \u6811\uff0c\u4e5f\u79f0\u5e73\u8861\u4e8c\u53c9\u641c\u7d22\u6811\uff0c\u5b83\u901a\u8fc7\u65cb\u8f6c\u64cd\u4f5c\u786e\u4fdd\u5728\u4e0d\u65ad\u63d2\u5165\u548c\u5220\u9664\u8282\u70b9\u540e\u6811\u4ecd\u7136\u4fdd\u6301\u5e73\u8861\u3002
    • AVL \u6811\u7684\u65cb\u8f6c\u64cd\u4f5c\u5305\u62ec\u53f3\u65cb\u3001\u5de6\u65cb\u3001\u5148\u53f3\u65cb\u518d\u5de6\u65cb\u3001\u5148\u5de6\u65cb\u518d\u53f3\u65cb\u3002\u5728\u63d2\u5165\u6216\u5220\u9664\u8282\u70b9\u540e\uff0cAVL \u6811\u4f1a\u4ece\u5e95\u5411\u9876\u6267\u884c\u65cb\u8f6c\u64cd\u4f5c\uff0c\u4f7f\u6811\u91cd\u65b0\u6062\u590d\u5e73\u8861\u3002
    "},{"location":"chapter_tree/summary/#2-q-a","title":"2. \u00a0 Q & A","text":"

    Q\uff1a\u5bf9\u4e8e\u53ea\u6709\u4e00\u4e2a\u8282\u70b9\u7684\u4e8c\u53c9\u6811\uff0c\u6811\u7684\u9ad8\u5ea6\u548c\u6839\u8282\u70b9\u7684\u6df1\u5ea6\u90fd\u662f \\(0\\) \u5417\uff1f

    \u662f\u7684\uff0c\u56e0\u4e3a\u9ad8\u5ea6\u548c\u6df1\u5ea6\u901a\u5e38\u5b9a\u4e49\u4e3a\u201c\u7ecf\u8fc7\u7684\u8fb9\u7684\u6570\u91cf\u201d\u3002

    Q\uff1a\u4e8c\u53c9\u6811\u4e2d\u7684\u63d2\u5165\u4e0e\u5220\u9664\u4e00\u822c\u7531\u4e00\u5957\u64cd\u4f5c\u914d\u5408\u5b8c\u6210\uff0c\u8fd9\u91cc\u7684\u201c\u4e00\u5957\u64cd\u4f5c\u201d\u6307\u4ec0\u4e48\u5462\uff1f\u53ef\u4ee5\u7406\u89e3\u4e3a\u8d44\u6e90\u7684\u5b50\u8282\u70b9\u7684\u8d44\u6e90\u91ca\u653e\u5417\uff1f

    \u62ff\u4e8c\u53c9\u641c\u7d22\u6811\u6765\u4e3e\u4f8b\uff0c\u5220\u9664\u8282\u70b9\u64cd\u4f5c\u8981\u5206\u4e09\u79cd\u60c5\u51b5\u5904\u7406\uff0c\u5176\u4e2d\u6bcf\u79cd\u60c5\u51b5\u90fd\u9700\u8981\u8fdb\u884c\u591a\u4e2a\u6b65\u9aa4\u7684\u8282\u70b9\u64cd\u4f5c\u3002

    Q\uff1a\u4e3a\u4ec0\u4e48 DFS \u904d\u5386\u4e8c\u53c9\u6811\u6709\u524d\u3001\u4e2d\u3001\u540e\u4e09\u79cd\u987a\u5e8f\uff0c\u5206\u522b\u6709\u4ec0\u4e48\u7528\u5462\uff1f

    \u4e0e\u987a\u5e8f\u548c\u9006\u5e8f\u904d\u5386\u6570\u7ec4\u7c7b\u4f3c\uff0c\u524d\u5e8f\u3001\u4e2d\u5e8f\u3001\u540e\u5e8f\u904d\u5386\u662f\u4e09\u79cd\u4e8c\u53c9\u6811\u904d\u5386\u65b9\u6cd5\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5b83\u4eec\u5f97\u5230\u4e00\u4e2a\u7279\u5b9a\u987a\u5e8f\u7684\u904d\u5386\u7ed3\u679c\u3002\u4f8b\u5982\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4e2d\uff0c\u7531\u4e8e\u8282\u70b9\u5927\u5c0f\u6ee1\u8db3 \u5de6\u5b50\u8282\u70b9\u503c < \u6839\u8282\u70b9\u503c < \u53f3\u5b50\u8282\u70b9\u503c \uff0c\u56e0\u6b64\u6211\u4eec\u53ea\u8981\u6309\u7167\u201c\u5de6 \\(\\rightarrow\\) \u6839 \\(\\rightarrow\\) \u53f3\u201d\u7684\u4f18\u5148\u7ea7\u904d\u5386\u6811\uff0c\u5c31\u53ef\u4ee5\u83b7\u5f97\u6709\u5e8f\u7684\u8282\u70b9\u5e8f\u5217\u3002

    Q\uff1a\u53f3\u65cb\u64cd\u4f5c\u662f\u5904\u7406\u5931\u8861\u8282\u70b9 node\u3001child\u3001grand_child \u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u90a3 node \u7684\u7236\u8282\u70b9\u548c node \u539f\u6765\u7684\u8fde\u63a5\u4e0d\u9700\u8981\u7ef4\u62a4\u5417\uff1f\u53f3\u65cb\u64cd\u4f5c\u540e\u5c82\u4e0d\u662f\u65ad\u6389\u4e86\uff1f

    \u6211\u4eec\u9700\u8981\u4ece\u9012\u5f52\u7684\u89c6\u89d2\u6765\u770b\u8fd9\u4e2a\u95ee\u9898\u3002\u53f3\u65cb\u64cd\u4f5c right_rotate(root) \u4f20\u5165\u7684\u662f\u5b50\u6811\u7684\u6839\u8282\u70b9\uff0c\u6700\u7ec8 return child \u8fd4\u56de\u65cb\u8f6c\u4e4b\u540e\u7684\u5b50\u6811\u7684\u6839\u8282\u70b9\u3002\u5b50\u6811\u7684\u6839\u8282\u70b9\u548c\u5176\u7236\u8282\u70b9\u7684\u8fde\u63a5\u662f\u5728\u8be5\u51fd\u6570\u8fd4\u56de\u540e\u5b8c\u6210\u7684\uff0c\u4e0d\u5c5e\u4e8e\u53f3\u65cb\u64cd\u4f5c\u7684\u7ef4\u62a4\u8303\u56f4\u3002

    Q\uff1a\u5728 C++ \u4e2d\uff0c\u51fd\u6570\u88ab\u5212\u5206\u5230 private \u548c public \u4e2d\uff0c\u8fd9\u65b9\u9762\u6709\u4ec0\u4e48\u8003\u91cf\u5417\uff1f\u4e3a\u4ec0\u4e48\u8981\u5c06 height() \u51fd\u6570\u548c updateHeight() \u51fd\u6570\u5206\u522b\u653e\u5728 public \u548c private \u4e2d\u5462\uff1f

    \u4e3b\u8981\u770b\u65b9\u6cd5\u7684\u4f7f\u7528\u8303\u56f4\uff0c\u5982\u679c\u65b9\u6cd5\u53ea\u5728\u7c7b\u5185\u90e8\u4f7f\u7528\uff0c\u90a3\u4e48\u5c31\u8bbe\u8ba1\u4e3a private \u3002\u4f8b\u5982\uff0c\u7528\u6237\u5355\u72ec\u8c03\u7528 updateHeight() \u662f\u6ca1\u6709\u610f\u4e49\u7684\uff0c\u5b83\u53ea\u662f\u63d2\u5165\u3001\u5220\u9664\u64cd\u4f5c\u4e2d\u7684\u4e00\u6b65\u3002\u800c height() \u662f\u8bbf\u95ee\u8282\u70b9\u9ad8\u5ea6\uff0c\u7c7b\u4f3c\u4e8e vector.size() \uff0c\u56e0\u6b64\u8bbe\u7f6e\u6210 public \u4ee5\u4fbf\u4f7f\u7528\u3002

    Q\uff1a\u5982\u4f55\u4ece\u4e00\u7ec4\u8f93\u5165\u6570\u636e\u6784\u5efa\u4e00\u68f5\u4e8c\u53c9\u641c\u7d22\u6811\uff1f\u6839\u8282\u70b9\u7684\u9009\u62e9\u662f\u4e0d\u662f\u5f88\u91cd\u8981\uff1f

    \u662f\u7684\uff0c\u6784\u5efa\u6811\u7684\u65b9\u6cd5\u5df2\u5728\u4e8c\u53c9\u641c\u7d22\u6811\u4ee3\u7801\u4e2d\u7684 build_tree() \u65b9\u6cd5\u4e2d\u7ed9\u51fa\u3002\u81f3\u4e8e\u6839\u8282\u70b9\u7684\u9009\u62e9\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5c06\u8f93\u5165\u6570\u636e\u6392\u5e8f\uff0c\u7136\u540e\u5c06\u4e2d\u70b9\u5143\u7d20\u4f5c\u4e3a\u6839\u8282\u70b9\uff0c\u518d\u9012\u5f52\u5730\u6784\u5efa\u5de6\u53f3\u5b50\u6811\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u6700\u5927\u7a0b\u5ea6\u4fdd\u8bc1\u6811\u7684\u5e73\u8861\u6027\u3002

    Q\uff1a\u5728 Java \u4e2d\uff0c\u5b57\u7b26\u4e32\u5bf9\u6bd4\u662f\u5426\u4e00\u5b9a\u8981\u7528 equals() \u65b9\u6cd5\uff1f

    \u5728 Java \u4e2d\uff0c\u5bf9\u4e8e\u57fa\u672c\u6570\u636e\u7c7b\u578b\uff0c== \u7528\u4e8e\u5bf9\u6bd4\u4e24\u4e2a\u53d8\u91cf\u7684\u503c\u662f\u5426\u76f8\u7b49\u3002\u5bf9\u4e8e\u5f15\u7528\u7c7b\u578b\uff0c\u4e24\u79cd\u7b26\u53f7\u7684\u5de5\u4f5c\u539f\u7406\u662f\u4e0d\u540c\u7684\u3002

    • == \uff1a\u7528\u6765\u6bd4\u8f83\u4e24\u4e2a\u53d8\u91cf\u662f\u5426\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5373\u5b83\u4eec\u5728\u5185\u5b58\u4e2d\u7684\u4f4d\u7f6e\u662f\u5426\u76f8\u540c\u3002
    • equals()\uff1a\u7528\u6765\u5bf9\u6bd4\u4e24\u4e2a\u5bf9\u8c61\u7684\u503c\u662f\u5426\u76f8\u7b49\u3002

    \u56e0\u6b64\uff0c\u5982\u679c\u8981\u5bf9\u6bd4\u503c\uff0c\u6211\u4eec\u5e94\u8be5\u4f7f\u7528 equals() \u3002\u7136\u800c\uff0c\u901a\u8fc7 String a = \"hi\"; String b = \"hi\"; \u521d\u59cb\u5316\u7684\u5b57\u7b26\u4e32\u90fd\u5b58\u50a8\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u6c60\u4e2d\uff0c\u5b83\u4eec\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u7528 a == b \u6765\u6bd4\u8f83\u4e24\u4e2a\u5b57\u7b26\u4e32\u7684\u5185\u5bb9\u3002

    Q\uff1a\u5e7f\u5ea6\u4f18\u5148\u904d\u5386\u5230\u6700\u5e95\u5c42\u4e4b\u524d\uff0c\u961f\u5217\u4e2d\u7684\u8282\u70b9\u6570\u91cf\u662f \\(2^h\\) \u5417\uff1f

    \u662f\u7684\uff0c\u4f8b\u5982\u9ad8\u5ea6 \\(h = 2\\) \u7684\u6ee1\u4e8c\u53c9\u6811\uff0c\u5176\u8282\u70b9\u603b\u6570 \\(n = 7\\) \uff0c\u5219\u5e95\u5c42\u8282\u70b9\u6570\u91cf \\(4 = 2^h = (n + 1) / 2\\) \u3002

    "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index dcd0f3a7d..97ee12206 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,532 +2,532 @@ https://www.hello-algo.com/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_appendix/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_appendix/contribution/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_appendix/installation/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_appendix/terminology/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_array_and_linkedlist/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_array_and_linkedlist/array/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_array_and_linkedlist/linked_list/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_array_and_linkedlist/list/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_array_and_linkedlist/ram_and_cache/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_array_and_linkedlist/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_backtracking/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_backtracking/backtracking_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_backtracking/n_queens_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_backtracking/permutations_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_backtracking/subset_sum_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_backtracking/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_computational_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_computational_complexity/iteration_and_recursion/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_computational_complexity/performance_evaluation/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_computational_complexity/space_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_computational_complexity/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_computational_complexity/time_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_data_structure/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_data_structure/basic_data_types/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_data_structure/character_encoding/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_data_structure/classification_of_data_structure/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_data_structure/number_encoding/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_data_structure/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_divide_and_conquer/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_divide_and_conquer/binary_search_recur/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_divide_and_conquer/build_binary_tree_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_divide_and_conquer/divide_and_conquer/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_divide_and_conquer/hanota_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_divide_and_conquer/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/dp_problem_features/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/dp_solution_pipeline/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/edit_distance_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/intro_to_dynamic_programming/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/knapsack_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_dynamic_programming/unbounded_knapsack_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_graph/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_graph/graph/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_graph/graph_operations/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_graph/graph_traversal/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_graph/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_greedy/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_greedy/fractional_knapsack_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_greedy/greedy_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_greedy/max_capacity_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_greedy/max_product_cutting_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_greedy/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_hashing/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_hashing/hash_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_hashing/hash_collision/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_hashing/hash_map/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_hashing/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_heap/build_heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_heap/heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_heap/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_heap/top_k/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_hello_algo/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_introduction/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_introduction/algorithms_are_everywhere/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_introduction/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_introduction/what_is_dsa/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_paperbook/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_preface/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_preface/about_the_book/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_preface/suggestions/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_preface/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_reference/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/binary_search/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/binary_search_edge/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/binary_search_insertion/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/replace_linear_by_hashing/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/searching_algorithm_revisited/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_searching/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/bubble_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/bucket_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/counting_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/heap_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/insertion_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/merge_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/quick_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/radix_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/selection_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/sorting_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_sorting/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_stack_and_queue/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_stack_and_queue/deque/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_stack_and_queue/queue/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_stack_and_queue/stack/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_stack_and_queue/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/array_representation_of_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/avl_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/binary_search_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/binary_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/binary_tree_traversal/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/chapter_tree/summary/ - 2024-04-28 + 2024-04-30 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 6ee63b3febbcc0711f19fb1d2da9e03e612ed422..179b13bcafd1f0ba5b0fa836c47c094b8448c1ca 100644 GIT binary patch delta 946 zcmV;j15Nz%2lEGiABzYG%ycnk0{?SqbY*Q}a4vXlYyjPx&649L5XbNP6jQ#B?QHgt zq&(hRo?!P(wV*9gMu7S7$J+-ajXkcK9CAtVUmq-iDf!pX-82o_eZP+8<;)>!XWv%8 zt+%Tew$dqW`?uB4AAi68vHHIMvdh6lPA{dgjc=uJ&JE%BMbHzMDQfd}F^x{`ziz*N zd){Gas91r;1K90$SPs9J+d-7COqJ&5)XU66_|aFNgZgMsw9

    0|Cn z6fBBiBC@ydP0GDrw1do4GJMqu6uK;e!c;vu_P{b&Ppd3UVT$1%To}np7JMd?+mFxx zRhH{?>e|XPFLD3hCs1I7s z6M#DaYmv=k2RaN0K2qtklhpw+6=rEHfkElwKF~Ne@6)~l#Y#X8LE-lU03j5oaDGYuMHu81s2&9&13--6Bl@zCP!NcRnroS} zbYQM)!k;f7TX_rfNLL}rlho;k)Yp}};HoT>kU6EghYEy`;5P<}L+gR(J7c|q7~T`I zbjIlB_v4yb(XSO^p2);oW*0?uhk3|0(E7~M?Hi(})MrFwGxO=C`}of@sQ?(3gG z?=xx?6zY)+4!6s|jqe;jiGW~gPr#RflF(78NKHd~@*Fzn+I9~<@PQ;lFjD7o5@}!o z)2%W0J;(O*OAp@my+J`O9@aLlwDUfD>+8b@<e)q_T6sL05^@T`*J}6MGQ7zb@f1f`+)OH_+<$iII>OmH+Mkj&jy6_IYj}*3(dkj;(c51Go7eBvO;d$vknFd(I~Dd;Yz zGQJqZ+QvkG#t;s1DU8}W~UcdqUSP->o&}kTP_^mi*W*dbMt}_fo?#on}(=@jO(#PDD zC|DH3L}YK@o0NOMXa||8WcZ>JD0Eo_g{gXS?15!io>p0y!W6^ZyD*ZKEciqww;!MX zR+i|gNP(_i&<36K2r~kT5{Z~XmMI5DLhUGOIaj8u=ZM5!s>{?>e|XPFLD3hCsP|gV z6M)+TYmv=k2RaN0K2qtElhpw+6>4cLfkElwKF~Ne@6Ri!jJ3P(2Dl27nmBNAzVOp&$_VHPA+mqgg;+Ew(=I{kuE}#C#lmFsjn+{!Btr%A#+M~4;2U>!EX!{ht>nncgA`JF}w$4 z>5S3M@5enL*CUk(un;E3t#^NB1)S587_1nSFuIwX7l+0%OZDXXo5q|{J2hHq-Pb>W z-e%M&DAXet9Ioeq8{av65COr|9)QmSC848Gk(!3~kE+zMFs#z9bHJxYsJFY<*qY46+w9Ap}ypR!Yf_2 zQxY16xUTPUXm4`}4)VyM2eP_y|Uf*T+*Cix@V*>gs{|_5tUY@XHc3aAccqZ|;E5p9~1;V~PTb84ecYNZ*A0 UpLw$B5;^Vu1$<*S1O7??0D}S7a{vGU diff --git a/zh-hant/sitemap.xml b/zh-hant/sitemap.xml index 0c74c3c6b..e126f1b6a 100644 --- a/zh-hant/sitemap.xml +++ b/zh-hant/sitemap.xml @@ -2,527 +2,527 @@ https://www.hello-algo.com/zh-hant/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_appendix/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_appendix/contribution/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_appendix/installation/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_appendix/terminology/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_array_and_linkedlist/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_array_and_linkedlist/array/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_array_and_linkedlist/linked_list/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_array_and_linkedlist/list/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_array_and_linkedlist/ram_and_cache/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_array_and_linkedlist/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_backtracking/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_backtracking/backtracking_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_backtracking/n_queens_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_backtracking/permutations_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_backtracking/subset_sum_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_backtracking/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_computational_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_computational_complexity/iteration_and_recursion/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_computational_complexity/performance_evaluation/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_computational_complexity/space_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_computational_complexity/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_computational_complexity/time_complexity/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_data_structure/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_data_structure/basic_data_types/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_data_structure/character_encoding/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_data_structure/classification_of_data_structure/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_data_structure/number_encoding/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_data_structure/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_divide_and_conquer/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_divide_and_conquer/binary_search_recur/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_divide_and_conquer/build_binary_tree_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_divide_and_conquer/divide_and_conquer/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_divide_and_conquer/hanota_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_divide_and_conquer/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/dp_problem_features/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/dp_solution_pipeline/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/edit_distance_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/intro_to_dynamic_programming/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/knapsack_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_dynamic_programming/unbounded_knapsack_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_graph/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_graph/graph/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_graph/graph_operations/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_graph/graph_traversal/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_graph/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_greedy/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_greedy/fractional_knapsack_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_greedy/greedy_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_greedy/max_capacity_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_greedy/max_product_cutting_problem/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_greedy/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_hashing/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_hashing/hash_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_hashing/hash_collision/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_hashing/hash_map/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_hashing/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_heap/build_heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_heap/heap/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_heap/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_heap/top_k/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_hello_algo/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_introduction/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_introduction/algorithms_are_everywhere/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_introduction/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_introduction/what_is_dsa/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_preface/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_preface/about_the_book/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_preface/suggestions/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_preface/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_reference/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/binary_search/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/binary_search_edge/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/binary_search_insertion/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/replace_linear_by_hashing/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/searching_algorithm_revisited/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_searching/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/bubble_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/bucket_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/counting_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/heap_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/insertion_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/merge_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/quick_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/radix_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/selection_sort/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/sorting_algorithm/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_sorting/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_stack_and_queue/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_stack_and_queue/deque/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_stack_and_queue/queue/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_stack_and_queue/stack/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_stack_and_queue/summary/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/array_representation_of_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/avl_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/binary_search_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/binary_tree/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/binary_tree_traversal/ - 2024-04-28 + 2024-04-30 daily https://www.hello-algo.com/zh-hant/chapter_tree/summary/ - 2024-04-28 + 2024-04-30 daily \ No newline at end of file diff --git a/zh-hant/sitemap.xml.gz b/zh-hant/sitemap.xml.gz index ea8de2075cf0d66dbefecef6dccf01e77f70aa04..182284d2411e695f24649e280ab299119eb507c1 100644 GIT binary patch literal 1009 zcmVidCiph5Hc^E|qjBd2VGe_MQAZ5A)= zbuiZVZ;M}l{ki;Y@pJp-wIr8WUh2(0zbyul_{VyEI-OS83Xc@?Dx`j$^-vReea&2N zR=+Q{Uta33ySccH_tAD9aek_S@#$ zkLBja^82RVa?Sg2o32myyi0u88nW*4y8e(e1FdgF|BjMfJi`U?hlN_0`=jdIrS**Kd87ktXZ#h*_Vb{$~TCmN?LO|_rH zm66LhQo=BWj`Utq{Zq#yc)%YMsy&jd3?rTnuMUOTXBAWE90Mwdwd*Z1jTwMdtO3XS)Vz3YHRPt0XZ75H zgxwRgE?>qDyjqZatFcFGc%DcHUndp`6}z*(7P`tzNe}Zt3RX(7&Zw&(Nz70aj86nT zPb;g}Lp65r`hfCK7f)jyaMU926OAKGr|=24iSI2(?U-6;k&(6J;HD)j6>Vf^J;RD& zW2G8OmTAfgW!;~sv0hS85}wL-_MT!Uy@#(Ibmv=q7m7D*6l9fD9dQ66h2&KsUc;Ih z4qXzpEjZ+W$dPXedDj#rf5;R zh_p3mKp9AWW}rNv40zvJ+Y!t_AJBDh&cdu;KA^WPvPjTSrpPFT+d${=D;6^rEnM4` z5Y-+8w_cvQ5D45URMkdBD1F8Q@U5rLic;I^!s&7v7-Z%3K?;&dK7gMF5@oY8nIPa} z;vH#*Vx=w=Q8KXVLfAv0=hF9_aUxN7ZXA28$kpe0kVZZ45I~t3-f15;I3TktHa$ZN zus(Bw8M53}B#y4_Vr^@+lvH>M+Zjy f7-E5BhlK{)^f=-FZyse+hWFT~%2K_wS3p{`_P4bMb5YZBvrVEHCwDpWhdQNc?@hKAldhY=uXPc@&U&bcyuN0x zUst~^w%=aruf1SCn|>P?^tQbvUtcq@b74uY4=WwU_20vCATR69y50EsIm$8yvweGg z`>}lev3&bkZ@K1ux=q)od)_5JYzdDK_F2UgI>&$tV(og1Ok)OM6}fbE z6t1cPBWu9%J~c01TMfA><@js`9KKG@(v&@Q42gA_W`EeCs)6r98p&%`d?Z(J<_G_( zDMzYmo~7A6h2e`G;cCQ?kjj#ZmXa6|xub0LoGF*c8Bs&cu3cce@DX2wR8euV-B~?% zAYu0et;?6O1Fse&-)ij98lET8!PkjJLdEW^uZ6BMQ_{mckb;#`tTXB=ND?#D1mg=q z&(q54^-zr+ygr~j)Wy?S2OPD?`$Xdi(8vzG(pD~rW#9NKwkcYa zE+TCW8c+t3pBX3*ChIiVB4GzfcicQbZ z0<6!RV1_Jr6^Wy3yI9*=EhW`mpn@cK9k;W4tfV@jqivtM8Z<3Hjy{JZFsjSGahzk#~QPJUyoo5 zIyZWxfr+#=`L@ONP`EH8v*80MIc}LxX-sk;>ujGe;DFBmrlC%i6KD2v`?d;9#nFKg gKZaN!*hPub@o;0PgGZS^xk5